/*
#26 メッシュとライト
プロジェクトへの参照の追加(参照タブ)
C:\WINDOWS\Microsoft.NET\DirectX for Managed Code\1.0.2902.0
Microsoft.DirectX.dll
Microsoft.DirectX.Direct3D.dll
Microsoft.DirectX.Direct3DX.dll
*/
#pragma comment(linker, "/subsystem:windows /entry:main")
// アセンブリ
#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
// 名前空間
using namespace System;
using namespace System::Drawing;
using namespace System::Threading;
using namespace System::Windows::Forms;
using namespace Microsoft::DirectX;
using namespace Microsoft::DirectX::Direct3D;
ref class MainForm : Form
{
private:
Device^ dev;
PresentParameters^ pp;
Mesh^ meshBox;
Mesh^ meshSphere;
float fDist; // 原点との距離
float fAlt; // 高度
int nCamAngle; // カメラの方位角
public:
MainForm()
{
MinimumSize = Drawing::Size(80, 60);
ClientSize = Drawing::Size(800, 600);
Text = "ClrD3D";
fDist = 5.0f;
fAlt = 2.0f;
nCamAngle = 210;
KeyDown += gcnew KeyEventHandler(this, &MainForm::OnKeyDown);
}
bool DXInitialize()
{
try {
pp = gcnew PresentParameters;
pp->Windowed = true;
pp->SwapEffect = SwapEffect::Discard;
pp->AutoDepthStencilFormat = DepthFormat::D16;
pp->EnableAutoDepthStencil = true;
dev = gcnew Device(0, DeviceType::Hardware, this,
CreateFlags::HardwareVertexProcessing, pp);
CreateMesh();
return true;
}
catch (Exception^) {
return false;
}
}
void Render()
{
if (dev == nullptr) return;
if (WindowState == FormWindowState::Minimized) return;
dev->RenderState->ZBufferEnable = true;
dev->RenderState->ZBufferWriteEnable = true;
// カメラの設定
float fRad = nCamAngle * (float)Math::PI / 180;
float fPosX = (float)Math::Sin(fRad) * fDist;
float fPosZ = (float)Math::Cos(fRad) * fDist;
dev->Transform->View = Matrix::LookAtLH(
Vector3(fPosX, fAlt, fPosZ),
Vector3( 0.0f, 0.0f, 0.0f),
Vector3( 0.0f, 1.0f, 0.0f));
dev->Transform->Projection = Matrix::PerspectiveFovLH((float)Math::PI / 4,
(float)ClientSize.Width / (float)ClientSize.Height, 0.1f, 100.0f);
// ライトの設定
// dev->RenderState->Lighting = false;
dev->RenderState->Ambient = Color::FromArgb(0x00,0x00,0x7f);
dev->Lights[0]->Type = LightType::Directional;
dev->Lights[0]->Direction = Vector3::Normalize(Vector3(1, -2, 3));
dev->Lights[0]->Ambient = Color::FromArgb(0x00,0x7f,0x00);
dev->Lights[0]->Diffuse = Color::FromArgb(0xff,0x00,0x00);
dev->Lights[0]->Enabled = true;
dev->Lights[0]->Update();
dev->Clear(ClearFlags::Target | ClearFlags::ZBuffer, 0x7f7fff, 1.0f, 0);
dev->BeginScene();
// メッシュ描画
Material mat;
mat.AmbientColor = ColorValue(1.0f, 1.0f, 1.0f);
mat.DiffuseColor = ColorValue(1.0f, 1.0f, 1.0f);
dev->Material = mat;
dev->Transform->World = Matrix::Translation(Vector3(-1.0f, 0.0f, 0.0f));
meshBox->DrawSubset(0);
dev->Transform->World = Matrix::Translation(Vector3( 1.0f, 0.0f, 0.0f));
meshSphere->DrawSubset(0);
dev->EndScene();
try {
dev->Present();
}
catch (DeviceLostException^) {
ResetDevice();
}
}
private:
void CreateMesh()
{
meshBox = Mesh::Box(dev, 1, 1, 1);
meshSphere = Mesh::Sphere(dev, 0.5f, 16, 8);
}
void ResetDevice()
{
int hResult;
if (!dev->CheckCooperativeLevel(hResult)) {
switch (hResult) {
case ResultCode::DeviceLost:
Thread::Sleep(10);
break;
case ResultCode::DeviceNotReset:
dev->Reset(pp);
break;
}
}
}
void OnKeyDown(Object^ sender, KeyEventArgs^ e)
{
switch (e->KeyCode) {
case Keys::W:
fDist -= 0.5f;
break;
case Keys::S:
fDist += 0.5f;
break;
case Keys::Up:
fAlt += 0.5f;
break;
case Keys::Down:
fAlt -= 0.5f;
break;
case Keys::Left:
nCamAngle += 5;
break;
case Keys::Right:
nCamAngle -= 5;
break;
case Keys::Escape:
Close();
break;
}
}
};
int main()
{
MainForm^ form = gcnew MainForm;
if (!form->DXInitialize()) {
MessageBox::Show("Direct3Dの初期化に失敗しました。", "ClrD3D");
return 0;
}
form->Show();
while (form->Created) {
form->Render();
Application::DoEvents();
}
return 0;
}