dx sample의 tiger.x와 tiger.bmp를 소스 폴더에 넣어주어야 제대로 동작합니다.
#include <Windows.h> using namespace System; using namespace System::Windows::Forms; using namespace System::Drawing; using namespace SlimDX; using namespace SlimDX::Direct3D9; struct TextureVertex { Vector3 positon; int color; float tu, tv; }; public ref class WndForm : public Form { Direct3D^ direct3D; PresentParameters^ presentParams; Device^ device; Mesh^ mesh; array<Material^>^ meshMaterials; array<Texture^>^ meshTextures; SlimDX::Direct3D9::Font^ font; public: String^ lastError; String^ fps1; String^ fps2; Int32 staticFPS; Int32 variableFPS; WndForm(void) { this->ClientSize = System::Drawing::Size(400, 300); this->StartPosition = FormStartPosition::CenterScreen; this->Text = "D3D Tutorial 8"; } ~WndForm() { this->!WndForm(); } !WndForm() { Release(); } bool InitD3D() { try { // 환경변수 세팅 direct3D = gcnew Direct3D(); presentParams = gcnew PresentParameters(); presentParams->Windowed = true; presentParams->SwapEffect = SwapEffect::Discard; presentParams->DeviceWindowHandle = this->Handle; presentParams->EnableAutoDepthStencil = true; presentParams->AutoDepthStencilFormat = Format::D16; device = gcnew Device(direct3D, 0, DeviceType::Hardware, this->Handle, CreateFlags::SoftwareVertexProcessing, presentParams); // render state device->SetRenderState(RenderState::CullMode, Cull::None); device->SetRenderState(RenderState::ZEnable, true); device->SetRenderState(RenderState::Ambient, 0xffffff); // model mesh = Mesh::FromFile(device, "tiger.x", MeshFlags::SystemMemory); array<ExtendedMaterial>^ materials = mesh->GetMaterials(); meshMaterials = gcnew array<Material^>(materials->Length); meshTextures = gcnew array<Texture^>(materials->Length); for (int i = 0; i < materials->Length; i++) { meshMaterials[i] = materials[i].MaterialD3D; meshMaterials[i]->Ambient = meshMaterials[i]->Diffuse; meshTextures[i] = Texture::FromFile(device, materials[i].TextureFileName); } // font System::Drawing::Font^ nfont = gcnew System::Drawing::Font("Arial", 15);; font = gcnew SlimDX::Direct3D9::Font(device, nfont); return true; } catch (Direct3D9Exception^ ex) { lastError = ex->ToString(); return false; } } void Release() { if (mesh) delete mesh; for (int i = 0; i < meshMaterials->Length; i++) delete meshMaterials[i]; for (int i = 0; i < meshTextures->Length; i++) delete meshTextures[i]; if (font) delete font; if (direct3D) delete direct3D; if (device) delete device; } void SetupMatrix() { device->SetTransform(TransformState::World, Matrix::RotationY(Environment::TickCount / 1000.0f)); device->SetTransform(TransformState::View, Matrix::LookAtLH(Vector3(0.0f, 3.0f, -5.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f))); device->SetTransform(TransformState::Projection, Matrix::PerspectiveFovLH((float)Math::PI / 4, 1.0f, 1.0f, 100.0f)); } void Render() { if (!device) return; // 렌더링 시작 device->Clear(ClearFlags::Target | ClearFlags::ZBuffer, System::Drawing::Color::Black, 1.0f, 0); device->BeginScene(); SetupMatrix(); // 렌더링 font->DrawString(nullptr, fps1, 20, 20, 0xffff0000); font->DrawString(nullptr, fps2, 20, 40, 0xffff0000); for (int i = 0; i < meshMaterials->Length; i++) { device->Material = *meshMaterials[i]; device->SetTexture(0, meshTextures[i]); mesh->DrawSubset(i); } // 렌더링 끝 device->EndScene(); device->Present(); } void SetFPS(int sFPS, int vFPS) { staticFPS = sFPS; variableFPS = vFPS; fps1 = staticFPS.ToString(); fps2 = variableFPS.ToString(); } }; ref class FrameControl { float timer; float frameRate; public: FrameControl() { SetFrameRate(60.0f); } ~FrameControl() { } void SetFrameRate(float fps) { frameRate = 1.0f / fps; } bool Update(float dt) { timer += dt; if (timer < 0) return false; timer -= frameRate; return true; } bool FrameMove() { if (timer >= 0) return true; return false; } }; INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, INT) { WndForm^ frm = gcnew WndForm(); FrameControl^ fc = gcnew FrameControl(); if (!frm->InitD3D()) { MessageBox::Show(frm->lastError); delete frm; return 0; } frm->Show(); frm->fps1 = ""; frm->fps2 = ""; fc->SetFrameRate(60.0f); int curTick = Environment::TickCount; int lastTick = curTick; int tickGap; int staticFrame, variableFrame; int lastStaticFrame = 0; int lastVariableFrame = 0; while (frm->Created) { // ms단위의 delta time tickGap = Environment::TickCount - curTick; curTick = Environment::TickCount; // 언제나 고정적으로 해야하는 작업 (intput, network etc..) if (fc->Update((float)tickGap / 1000.0f)) staticFrame++; // 상황에 따라 많이 할수도 적게 할수도 있는 작업 (rendering etc..) if (!fc->FrameMove()) { variableFrame++; frm->Render(); Application::DoEvents(); // 작업의 부하를 테스트하기 위해 밑의 값을 변동해보면 어떻게 동작하는지 볼 수 있습니다. (10~50ms) //Sleep(30); } // 초당 프레임율을 계산해서 문자열로 변환 if ((Environment::TickCount - lastTick) > 1000) { staticFrame -= lastStaticFrame; variableFrame -= lastVariableFrame; frm->SetFPS(staticFrame, variableFrame); lastTick = Environment::TickCount; lastStaticFrame = staticFrame; lastVariableFrame = variableFrame; } } delete frm; return 0; }
0 개의 댓글:
댓글 쓰기