//============================================================================= // WalkTerrainDemo.cpp by Frank Luna (C) 2005 All Rights Reserved. // // Demonstrates how to walk the camera on the terrain. // // Controls: Use mouse to look and 'W', 'S', 'A', and 'D' keys to move. //============================================================================= #include "d3dApp.h" #include "DirectInput.h" #include #include "GfxStats.h" #include #include "Terrain.h" #include "Camera.h" class WalkTerrainDemo : public D3DApp { public: WalkTerrainDemo(HINSTANCE hInstance, std::string winCaption, D3DDEVTYPE devType, DWORD requestedVP); ~WalkTerrainDemo(); bool checkDeviceCaps(); void onLostDevice(); void onResetDevice(); void updateScene(float dt); void drawScene(); private: GfxStats* mGfxStats; Terrain* mTerrain; }; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd) { // Enable run-time memory check for debug builds. #if defined(DEBUG) | defined(_DEBUG) _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif // Construct camera before application, since the application uses the camera. Camera camera; gCamera = &camera; WalkTerrainDemo app(hInstance, "Walk Terrain Demo", D3DDEVTYPE_HAL, D3DCREATE_HARDWARE_VERTEXPROCESSING); gd3dApp = &app; DirectInput di(DISCL_NONEXCLUSIVE|DISCL_FOREGROUND, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND); gDInput = &di; return gd3dApp->run(); } WalkTerrainDemo::WalkTerrainDemo(HINSTANCE hInstance, std::string winCaption, D3DDEVTYPE devType, DWORD requestedVP) : D3DApp(hInstance, winCaption, devType, requestedVP) { if(!checkDeviceCaps()) { MessageBox(0, "checkDeviceCaps() Failed", 0, 0); PostQuitMessage(0); } InitAllVertexDeclarations(); mGfxStats = new GfxStats(); // World space units are meters. So (256*10.0f)x(256*10.0f) is (2.56)^2 square // kilometers. mTerrain = new Terrain(257, 257, 10.0f, 10.0f, "heightmap17_257.raw", "grass.dds", "dirt.dds", "stone.dds", "blend_hm17.dds", 3.0f, 0.0f); mTerrain->setDirToSunW(D3DXVECTOR3(0.0f, 1.0f, 0.0f)); mGfxStats->addVertices(mTerrain->getNumVertices()); mGfxStats->addTriangles(mTerrain->getNumTriangles()); onResetDevice(); } WalkTerrainDemo::~WalkTerrainDemo() { delete mGfxStats; delete mTerrain; DestroyAllVertexDeclarations(); } bool WalkTerrainDemo::checkDeviceCaps() { D3DCAPS9 caps; HR(gd3dDevice->GetDeviceCaps(&caps)); // Check for vertex shader version 2.0 support. if( caps.VertexShaderVersion < D3DVS_VERSION(2, 0) ) return false; // Check for pixel shader version 2.0 support. if( caps.PixelShaderVersion < D3DPS_VERSION(2, 0) ) return false; return true; } void WalkTerrainDemo::onLostDevice() { mGfxStats->onLostDevice(); mTerrain->onLostDevice(); } void WalkTerrainDemo::onResetDevice() { mGfxStats->onResetDevice(); mTerrain->onResetDevice(); // The aspect ratio depends on the backbuffer dimensions, which can // possibly change after a reset. So rebuild the projection matrix. float w = (float)md3dPP.BackBufferWidth; float h = (float)md3dPP.BackBufferHeight; gCamera->setLens(D3DX_PI * 0.25f, w/h, 0.01f, 5000.0f); } void WalkTerrainDemo::updateScene(float dt) { mGfxStats->update(dt); gDInput->poll(); gCamera->update(dt, mTerrain, 2.5f); } void WalkTerrainDemo::drawScene() { // Clear the backbuffer and depth buffer. HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffeeeeee, 1.0f, 0)); HR(gd3dDevice->BeginScene()); mTerrain->draw(); mGfxStats->display(); HR(gd3dDevice->EndScene()); // Present the backbuffer. HR(gd3dDevice->Present(0, 0, 0, 0)); }