Game.cpp
上传用户:whgydz
上传日期:2007-01-12
资源大小:2259k
文件大小:12k
源码类别:

其他书籍

开发平台:

HTML/CSS

  1. // Game.cpp: implementation of the CGame class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "Game.h"
  5. //////////////////////////////////////////////////////////////////////
  6. // Construction/Destruction
  7. //////////////////////////////////////////////////////////////////////
  8. CGame::CGame()
  9. {
  10. m_pD3D = NULL;
  11. m_pD3DDevice = NULL;
  12. m_dwFrames = 0;
  13. m_dwStartTime = 0;
  14. m_dwEndTime = 0;
  15. m_dwTotalPolygons = 0;
  16. m_pMesh1 = NULL;
  17. m_pMesh2 = NULL;
  18. m_pMesh3 = NULL;
  19. }
  20. CGame::~CGame()
  21. {
  22. //Game finished, so destroy game objects
  23. LogInfo("<br>Finish Game:");
  24. SafeDelete(m_pMesh1);
  25. SafeDelete(m_pMesh2);
  26. SafeDelete(m_pMesh3);
  27. SafeRelease(m_pD3DDevice);
  28. SafeRelease(m_pD3D);
  29. //Game finished, so save statistics to log
  30. DWORD dwDuration = (m_dwEndTime - m_dwStartTime) / 1000;
  31. if((dwDuration != 0)&&(m_dwFrames != 0))
  32. {
  33. //Log stats
  34. LogInfo("<br>Statistics:");
  35. LogInfo("<li>Start Time (ms): %d", m_dwStartTime);
  36. LogInfo("<li>End Time (ms): %d", m_dwEndTime);
  37. LogInfo("<li>Duration (s): %d", dwDuration);
  38. LogInfo("<li>Total Frame Count: %d", m_dwFrames);
  39. LogInfo("<li>Average FPS: %d", (m_dwFrames / dwDuration));
  40. LogInfo("<li>Total Polygons: %d", m_dwTotalPolygons);
  41. LogInfo("<li>Average Polygons per Frame: %d", (m_dwTotalPolygons / m_dwFrames));
  42. }
  43. else
  44. {
  45. LogInfo("<br>No statistics to report");
  46. }
  47. StopLogging();
  48. }
  49. bool CGame::Initialise(HWND hWnd, UINT nWidth, UINT nHeight)
  50. {
  51. if(InitialiseD3D(hWnd, nWidth, nHeight))
  52. {
  53. if(InitialiseLights()) 
  54. {
  55. return InitialiseGame();
  56. }
  57. else
  58. {
  59. return false;
  60. }
  61. }
  62. else
  63. {
  64. return false;
  65. }
  66. return true;
  67. }
  68. bool CGame::InitialiseGame()
  69. {
  70. LogInfo("<br>Initialise Game:");
  71. //Setup games objects here
  72. m_pMesh1 = new CMesh(m_pD3DDevice, "Spaceship01.x");
  73. m_pMesh2 = new CMesh(m_pD3DDevice, "Spaceship01.x");
  74. m_pMesh3 = new CMesh(m_pD3DDevice, "Spaceship01.x");
  75. return true;
  76. }
  77. D3DFORMAT CGame::CheckDisplayMode(UINT nWidth, UINT nHeight, UINT nDepth)
  78. {
  79. UINT x;
  80. D3DDISPLAYMODE d3ddm;
  81. for(x = 0; x < m_pD3D->GetAdapterModeCount(0); x++)
  82. {
  83. m_pD3D->EnumAdapterModes(0, x, &d3ddm);
  84. if(d3ddm.Width == nWidth)
  85. {
  86. if(d3ddm.Height == nHeight)
  87. {
  88. if((d3ddm.Format == D3DFMT_R5G6B5) || (d3ddm.Format == D3DFMT_X1R5G5B5) || (d3ddm.Format == D3DFMT_X4R4G4B4))
  89. {
  90. if(nDepth == 16)
  91. {
  92. return d3ddm.Format;
  93. }
  94. }
  95. else if((d3ddm.Format == D3DFMT_R8G8B8) || (d3ddm.Format == D3DFMT_X8R8G8B8))
  96. {
  97. if(nDepth == 32)
  98. {
  99. return d3ddm.Format;
  100. }
  101. }
  102. }
  103. }
  104. }
  105. return D3DFMT_UNKNOWN;
  106. }
  107. bool CGame::InitialiseD3D(HWND hWnd, UINT nWidth, UINT nHeight)
  108. {
  109. LogInfo("<br>Initialise Direct3D:");
  110.     //First of all, create the main D3D object. If it is created successfully we 
  111.     //should get a pointer to an IDirect3D8 interface.
  112.     m_pD3D = Direct3DCreate8(D3D_SDK_VERSION);
  113.     if(m_pD3D == NULL)
  114.     {
  115. LogError("<li>Unable to create DirectX8 interface.");
  116.         return false;
  117.     }
  118.     //Get the current display mode
  119.     D3DDISPLAYMODE d3ddm;
  120. d3ddm.Format = CheckDisplayMode(nWidth, nHeight, 32);
  121. if(d3ddm.Format != D3DFMT_UNKNOWN)
  122. {
  123. //Width x Height x 32bit has been selected
  124. d3ddm.Width = nWidth;
  125. d3ddm.Height = nHeight;
  126. LogInfo("<li>%d x %d x 32bit back buffer format selected. Format = %d.", nWidth, nHeight, d3ddm.Format);
  127. }
  128. else
  129. {
  130. d3ddm.Format = CheckDisplayMode(nWidth, nHeight, 16);
  131. if(d3ddm.Format != D3DFMT_UNKNOWN)
  132. {
  133.             //Width x Height x 16bit has been selected
  134. d3ddm.Width = nWidth;
  135. d3ddm.Height = nHeight;
  136. LogInfo("<li>%d x %d x 16bit back buffer format selected. Format = %d.", nWidth, nHeight, d3ddm.Format);
  137. }
  138.         else
  139. {
  140. LogError("<li>Unable to select back buffer format for %d x %d.", nWidth, nHeight);
  141.             return false;
  142.         }
  143. }
  144.     //Create a structure to hold the settings for our device
  145.     D3DPRESENT_PARAMETERS d3dpp; 
  146.     ZeroMemory(&d3dpp, sizeof(d3dpp));
  147. d3dpp.Windowed = FALSE;
  148.     d3dpp.BackBufferCount = 1;
  149.     d3dpp.BackBufferFormat = d3ddm.Format;
  150.     d3dpp.BackBufferWidth = d3ddm.Width;
  151.     d3dpp.BackBufferHeight = d3ddm.Height;
  152.     d3dpp.hDeviceWindow = hWnd;
  153.     d3dpp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
  154. d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  155.     d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
  156. //Select the best depth buffer, select 32, 24 or 16 bit
  157.     if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32) == D3D_OK)
  158. {
  159.         d3dpp.AutoDepthStencilFormat = D3DFMT_D32;
  160.         d3dpp.EnableAutoDepthStencil = TRUE;
  161. LogInfo("<li>32bit depth buffer selected");
  162.     }
  163.     else if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8) == D3D_OK)
  164.     {
  165. d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
  166.         d3dpp.EnableAutoDepthStencil = TRUE;
  167. LogInfo("<li>24bit depth buffer selected");
  168. }
  169.     else if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16) == D3D_OK)
  170.     {
  171. d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
  172.         d3dpp.EnableAutoDepthStencil = TRUE;
  173. LogInfo("<li>16bit depth buffer selected");
  174. }
  175.     else
  176. {
  177.         d3dpp.EnableAutoDepthStencil = FALSE;
  178. LogError("<li>Unable to select depth buffer.");
  179. }
  180.     //Create a Direct3D device.
  181.     if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
  182.                                    D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pD3DDevice)))
  183.     {
  184. LogError("<li>Unable to create device.");
  185.         return false;
  186.     }
  187.     
  188. //Turn on back face culling. This is becuase we want to hide the back of our polygons
  189. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW)))
  190. {
  191. LogError("<li>SetRenderState: D3DRS_CULLMODE Failed");
  192. return false;
  193. }
  194. else
  195. {
  196. LogInfo("<li>SetRenderState: D3DRS_CULLMODE OK");
  197. }
  198. //Turn on Depth Buffering
  199. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE)))
  200. {
  201. LogError("<li>SetRenderState: D3DRS_ZENABLE Failed");
  202. return false;
  203. }
  204. else
  205. {
  206. LogInfo("<li>SetRenderState: D3DRS_ZENABLE OK");
  207. }
  208. //Set fill state. Possible values: D3DFILL_POINT, D3DFILL_WIREFRAME, D3DFILL_SOLID
  209. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID)))
  210. {
  211. LogError("<li>SetRenderState: D3DRS_FILLMODE Failed");
  212. return false;
  213. }
  214. else
  215. {
  216. LogInfo("<li>SetRenderState: D3DRS_FILLMODE OK");
  217. }
  218. //Set the D3DRS_NORMALIZENORMALS render state to fix the problem when scaling the objects get darker
  219. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE)))
  220. {
  221. LogError("<li>SetRenderState: D3DRS_NORMALIZENORMALS Failed");
  222. return false;
  223. }
  224. else
  225. {
  226. LogInfo("<li>SetRenderState: D3DRS_NORMALIZENORMALS OK");
  227. }
  228.     return true;
  229. }
  230. bool CGame::InitialiseLights()
  231. {
  232. LogInfo("<br>Initialise Lights:");
  233. D3DLIGHT8 d3dLight;
  234. //Initialize the light structure.
  235. ZeroMemory(&d3dLight, sizeof(D3DLIGHT8));
  236. d3dLight.Type = D3DLIGHT_POINT;
  237. d3dLight.Position.x = 0.0f;
  238. d3dLight.Position.y = 10.0f;
  239. d3dLight.Position.z = 0.0f;
  240. d3dLight.Attenuation0 = 1.0f; 
  241. d3dLight.Attenuation1 = 0.0f; 
  242. d3dLight.Attenuation2 = 0.0f; 
  243. d3dLight.Range = 1000.0f;
  244. d3dLight.Diffuse.r = 1.0f;
  245. d3dLight.Diffuse.g = 1.0f;
  246. d3dLight.Diffuse.b = 1.0f;
  247. d3dLight.Ambient.r = 0.0f;
  248. d3dLight.Ambient.g = 0.0f;
  249. d3dLight.Ambient.b = 0.0f;
  250. d3dLight.Specular.r = 0.0f;
  251. d3dLight.Specular.g = 0.0f;
  252. d3dLight.Specular.b = 0.0f;
  253. //Assign the point light to our device in poisition (index) 0
  254. if(FAILED(m_pD3DDevice->SetLight(0, &d3dLight)))
  255. {
  256. LogError("<li>SetLight Failed");
  257. return false;
  258. }
  259. else
  260. {
  261. LogInfo("<li>SetLight OK");
  262. }
  263. //Enable our point light in position (index) 0
  264. if(FAILED(m_pD3DDevice->LightEnable(0, TRUE)))
  265. {
  266. LogError("<li>LightEnable Failed");
  267. return false;
  268. }
  269. else
  270. {
  271. LogInfo("<li>LightEnable OK");
  272. }
  273. //Turn on lighting
  274.     if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE)))
  275. {
  276. LogError("<li>SetRenderState: D3DRS_LIGHTING Failed");
  277. return false;
  278. }
  279. else
  280. {
  281. LogInfo("<li>SetRenderState: D3DRS_LIGHTING OK");
  282. }
  283. //Set ambient light level
  284. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(60, 60, 60))))
  285. {
  286. LogError("<li>SetRenderState: D3DRS_AMBIENT Failed");
  287. return false;
  288. }
  289. else
  290. {
  291. LogInfo("<li>SetRenderState: D3DRS_AMBIENT OK");
  292. }
  293. return true;
  294. }
  295. LPDIRECT3DDEVICE8 CGame::GetDevice()
  296. {
  297. return m_pD3DDevice;
  298. }
  299. void CGame::GameLoop()
  300. {
  301.     //Enter the game loop
  302.     MSG msg; 
  303.     BOOL fMessage;
  304.     PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
  305. //Game started, so record time
  306. m_dwStartTime = timeGetTime();
  307.     while(msg.message != WM_QUIT)
  308.     {
  309.         fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
  310.         if(fMessage)
  311.         {
  312.             //Process message
  313.             TranslateMessage(&msg);
  314.             DispatchMessage(&msg);
  315.         }
  316.         else
  317.         {
  318.             //No message to process, so render the current scene
  319.             Render();
  320.         }
  321.     }
  322. //Game finished, so record time
  323. m_dwEndTime = timeGetTime();
  324. }
  325. void CGame::Render()
  326. {
  327. D3DXMATRIX matMove1, matMove3;
  328. D3DXMATRIX matShip1, matShip2, matShip3;
  329. D3DXMATRIX matRotateX, matRotateY, matRotateZ, matScale1, matScale2;
  330. if(m_pD3DDevice == NULL)
  331.     {
  332.         return;
  333.     }
  334.     //Clear the back buffer and depth buffer
  335.     m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
  336.     
  337.     //Begin the scene
  338.     m_pD3DDevice->BeginScene();
  339.     
  340. //Setup camera and perspective
  341. SetupCamera();
  342. //Create the transformation matrices
  343. D3DXMatrixRotationX(&matRotateX, timeGetTime()/1000.0f);
  344. D3DXMatrixRotationY(&matRotateY, timeGetTime()/1000.0f);
  345. D3DXMatrixRotationZ(&matRotateZ, timeGetTime()/1000.0f);
  346. D3DXMatrixScaling(&matScale1, 2.0f, 2.0f, 2.0f);
  347. D3DXMatrixScaling(&matScale2, 0.5f, 0.5f, 0.5f);
  348. D3DXMatrixTranslation(&matMove1, -20.0f, 15.0f, 0.0f);
  349. D3DXMatrixTranslation(&matMove3, 20.0f, 15.0f, 0.0f);
  350. D3DXMatrixMultiply(&matShip1, &matScale2, &matRotateX);
  351. D3DXMatrixMultiply(&matShip2, &matScale1, &matRotateY);
  352. D3DXMatrixMultiply(&matShip3, &matScale2, &matRotateZ);
  353. D3DXMatrixMultiply(&matShip1, &matShip1, &matMove1);
  354. D3DXMatrixMultiply(&matShip3, &matShip3, &matMove3);
  355. //Render our objects
  356. m_pD3DDevice->SetTransform(D3DTS_WORLD, &matShip1);
  357. m_dwTotalPolygons += m_pMesh1->Render();
  358. m_pD3DDevice->SetTransform(D3DTS_WORLD, &matShip2);
  359. m_dwTotalPolygons += m_pMesh2->Render();
  360. m_pD3DDevice->SetTransform(D3DTS_WORLD, &matShip3);
  361. m_dwTotalPolygons += m_pMesh3->Render();
  362.     //End the scene
  363.     m_pD3DDevice->EndScene();
  364.     
  365.     //Filp the back and front buffers so that whatever has been rendered on the back buffer
  366.     //will now be visible on screen (front buffer).
  367.     m_pD3DDevice->Present(NULL, NULL, NULL, NULL);
  368. //Count Frames
  369. m_dwFrames++;
  370. }
  371. void CGame::SetupCamera()
  372. {
  373. //Here we will setup the camera.
  374. //The camera has three settings: "Camera Position", "Look at Position" and "Up Direction"
  375. //We have set the following:
  376. //Camera Position: (0, 15, -50)
  377. //Look at Position: (0, 0, 0)
  378. //Up direction: Y-Axis.
  379.     D3DXMATRIX matView;
  380.     D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 15.0f, -50.0f), //Camera Position
  381.                                  &D3DXVECTOR3(0.0f, 0.0f, 0.0f), //Look At Position
  382.                                  &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); //Up Direction
  383.     m_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
  384. //Here we specify the field of view, aspect ration and near and far clipping planes.
  385.     D3DXMATRIX matProj;
  386.     D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.25f, 1.0f, 2000.0f);
  387.     m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
  388. }