/*
プロジェクトへの参照の追加(参照タブ)
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;
#define RGB(r,g,b) (((r)<<16) | ((g)<<8) | (b))
ref class MainForm : Form
{
private:
Device^ dev;
PresentParameters^ pp;
VertexBuffer^ vb;
IndexBuffer^ ib;
Direct3D::Font^ font;
int nSec;
int nFps;
int nFrame;
public:
MainForm()
{
MinimumSize = Drawing::Size(160, 120);
MaximizeBox = false;
ClientSize = Drawing::Size(640, 480);
Text = "ClrD3D";
}
bool DXInitialize()
{
try {
pp = gcnew PresentParameters;
pp->Windowed = true;
pp->SwapEffect = SwapEffect::Discard;
dev = gcnew Device(0, DeviceType::Hardware, this,
CreateFlags::HardwareVertexProcessing, pp);
CreateVertex();
CreateFont();
return true;
}
catch (Exception^) {
return false;
}
}
void Render()
{
if (dev == nullptr) return;
if (WindowState == FormWindowState::Minimized) return;
dev->Transform->World =
Matrix::RotationY(Environment::TickCount / 3000.0f) *
Matrix::RotationX(Environment::TickCount / 4000.0f);
dev->RenderState->CullMode = Cull::None;
nFrame++;
if (nSec != DateTime::Now.Second) {
nSec = DateTime::Now.Second;
nFps = nFrame;
nFrame = 0;
}
// カメラの設定
dev->Transform->View = Matrix::LookAtLH(
Vector3(5.0f, 5.0f, 5.0f),
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 / ClientSize.Height, 3.0f, 15.0f);
dev->RenderState->Lighting = false;
dev->Clear(ClearFlags::Target, 0x7f7fff, 1.0f, 0);
dev->BeginScene();
dev->SetStreamSource(0, vb, 0);
dev->Indices = ib;
dev->VertexFormat = CustomVertex::PositionColored::Format;
dev->DrawIndexedPrimitives(PrimitiveType::TriangleList, 0, 0, 8, 0, 12);
font->DrawText(nullptr, "fps=" + nFps, 0, 0, Color::White);
dev->EndScene();
try {
dev->Present();
}
catch (DeviceLostException^) {
ResetDevice();
}
}
private:
void CreateVertex()
{
vb = gcnew VertexBuffer(CustomVertex::PositionColored::typeid, 8, dev,
(Usage)0, CustomVertex::PositionColored::Format, Pool::Managed);
// 頂点データ
array<CustomVertex::PositionColored>^ v =
gcnew array<CustomVertex::PositionColored>(8);
for (int n = 0; n < 8; n++) {
v[n].Position = Vector3((float)(n&4), (float)(n&2), (float)(n&1));
v[n].Color = RGB(0xff*((n>>2)&1), 0xff*((n>>1)&1), 0xff*(n&1));
}
GraphicsStream^ gs = vb->Lock(0, 0, (LockFlags)0);
gs->Write(v);
vb->Unlock();
ib = gcnew IndexBuffer(Int16::typeid, 36, dev, (Usage)0, Pool::Managed);
// 索引データ
array<Int16>^ data = { // 平面:正面から見て
0,4,2,6,2,4, // yz:左
7,5,3,1,3,5, // yz:右
0,2,1,3,1,2, // xy:前
7,6,5,4,5,6, // xy:後
0,1,4,5,4,1, // zx:下
7,3,6,2,6,3, // zx:上
};
ib->SetData(data, 0, (LockFlags)0);
}
void CreateFont()
{
FontDescription fd;
fd.Height = 20;
fd.FaceName = "MS ゴシック";
font = gcnew Direct3D::Font(dev, fd);
}
void ResetDevice()
{
int hResult;
if (!dev->CheckCooperativeLevel(hResult)) {
switch (hResult) {
case ResultCode::DeviceLost:
Thread::Sleep(10);
break;
case ResultCode::DeviceNotReset:
dev->Reset(pp);
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;
}