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