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

其他书籍

开发平台:

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_dwTotalPolygons = 0;
  17. m_pCube1 = NULL;
  18. m_pTerrain1 = NULL;
  19. }
  20. CGame::~CGame()
  21. {
  22. //Game finished, so record time
  23. if(m_dwStartTime > 0)
  24. {
  25. m_dwEndTime = timeGetTime();
  26. }
  27. else
  28. {
  29. m_dwEndTime = 0;
  30. }
  31. DWORD dwDuration = (m_dwEndTime - m_dwStartTime) / 1000;
  32. //Log stats
  33. WriteToLog("Statistics:");
  34. WriteToLog("tStart Time (ms): %d", m_dwStartTime);
  35. WriteToLog("tEnd Time (ms): %d", m_dwEndTime);
  36. WriteToLog("tDuration (s): %d", dwDuration);
  37. WriteToLog("tTotal Frame Count: %d", m_dwFrames);
  38. WriteToLog("tAverage FPS: %d", (m_dwFrames / dwDuration));
  39. WriteToLog("tTotal Polygons: %d", m_dwTotalPolygons);
  40. WriteToLog("tAverage Polygons per Frame: %d", (m_dwTotalPolygons / m_dwFrames));
  41. SafeDelete(m_pCube1);
  42. SafeDelete(m_pTerrain1);
  43. SafeRelease(m_pD3DDevice);
  44. SafeRelease(m_pD3D);
  45. }
  46. bool CGame::Initialise(HWND hWnd, UINT nWidth, UINT nHeight)
  47. {
  48. if(SUCCEEDED(InitialiseD3D(hWnd, nWidth, nHeight)))
  49. {
  50. if(InitialiseLights()) 
  51. {
  52. return InitialiseGame();
  53. }
  54. else
  55. {
  56. return false;
  57. }
  58. }
  59. else
  60. {
  61. return false;
  62. }
  63. return true;
  64. }
  65. bool CGame::InitialiseGame()
  66. {
  67. //Setup games objects here
  68. m_pCube1 = new CCuboid(m_pD3DDevice, 0, 100, 0);
  69. m_pCube1->SetSize(30, 30, 30);
  70. m_pCube1->SetTexture("Cube.bmp");
  71. //Create our terrain object (device, tile rows, tile cols, tile size, max height)
  72. m_pTerrain1 = new CTerrain(m_pD3DDevice, 20, 20, 10.0, 15);
  73. m_pTerrain1->SetTexture("Grass.bmp");
  74. WriteToLog("InitialiseGame Finished OK");
  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. HRESULT CGame::InitialiseD3D(HWND hWnd, UINT nWidth, UINT nHeight)
  108. {
  109. WriteToLog("InitialiseD3D Started...");
  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. WriteToLog("tUnable to create DirectX8 interface.");
  116.         return E_FAIL;
  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. WriteToLog("t%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. WriteToLog("t%d x %d x 16bit back buffer format selected. Format = %d.", nWidth, nHeight, d3ddm.Format);
  137. }
  138.         else
  139. {
  140. WriteToLog("tUnable to select back buffer format for %d x %d.", nWidth, nHeight);
  141.             return E_FAIL;
  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. WriteToLog("t32bit 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. WriteToLog("t24bit 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. WriteToLog("t16bit depth buffer selected");
  174. }
  175.     else
  176. {
  177.         d3dpp.EnableAutoDepthStencil = FALSE;
  178. WriteToLog("tUnable 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. WriteToLog("tUnable to create device.");
  185.         return E_FAIL;
  186.     }
  187.     
  188. //Turn on back face culling. This is becuase we want to hide the back of our polygons
  189.     m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
  190. //Turn on Depth Buffering
  191.     m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
  192. //Set fill state. Possible values: D3DFILL_POINT, D3DFILL_WIREFRAME, D3DFILL_SOLID
  193. m_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); 
  194. WriteToLog("InitialiseD3D Finished OK");
  195.     return S_OK;
  196. }
  197. bool CGame::InitialiseLights()
  198. {
  199. WriteToLog("InitialiseLights Started...");
  200. D3DLIGHT8 d3dLight;
  201. //Initialize the light structure.
  202. ZeroMemory(&d3dLight, sizeof(D3DLIGHT8));
  203. d3dLight.Type = D3DLIGHT_DIRECTIONAL;
  204. d3dLight.Diffuse.r = 1.0f;
  205. d3dLight.Diffuse.g = 1.0f;
  206. d3dLight.Diffuse.b = 1.0f;
  207. d3dLight.Ambient.r = 0.0f;
  208. d3dLight.Ambient.g = 0.0f;
  209. d3dLight.Ambient.b = 0.0f;
  210. d3dLight.Specular.r = 0.0f;
  211. d3dLight.Specular.g = 0.0f;
  212. d3dLight.Specular.b = 0.0f;
  213. d3dLight.Direction = D3DXVECTOR3(-1.0, -1.0, 0.0);
  214. //Assign the point light to our device in poisition (index) 0
  215. if(FAILED(m_pD3DDevice->SetLight(0, &d3dLight)))
  216. {
  217. WriteToLog("tSetLight Failed");
  218. return false;
  219. }
  220. else
  221. {
  222. WriteToLog("tSetLight OK");
  223. }
  224. //Enable our point light in position (index) 0
  225. if(FAILED(m_pD3DDevice->LightEnable(0, TRUE)))
  226. {
  227. WriteToLog("tLightEnable Failed");
  228. return false;
  229. }
  230. else
  231. {
  232. WriteToLog("tLightEnable OK");
  233. }
  234. //Turn on lighting
  235.     if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE)))
  236. {
  237. WriteToLog("tSetRenderState: D3DRS_LIGHTING Failed");
  238. return false;
  239. }
  240. else
  241. {
  242. WriteToLog("tSetRenderState: D3DRS_LIGHTING OK");
  243. }
  244. //Set ambient light level
  245. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(60, 60, 60))))
  246. {
  247. WriteToLog("tSetRenderState: D3DRS_AMBIENT Failed");
  248. return false;
  249. }
  250. else
  251. {
  252. WriteToLog("tSetRenderState: D3DRS_AMBIENT OK");
  253. }
  254. WriteToLog("InitialiseLights Finished OK");
  255. return true;
  256. }
  257. LPDIRECT3DDEVICE8 CGame::GetDevice()
  258. {
  259. return m_pD3DDevice;
  260. }
  261. void CGame::GameLoop()
  262. {
  263.     //Enter the game loop
  264.     MSG msg; 
  265.     BOOL fMessage;
  266.     PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
  267. //Game started, so record time
  268. m_dwStartTime = timeGetTime();
  269.     while(msg.message != WM_QUIT)
  270.     {
  271.         fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
  272.         if(fMessage)
  273.         {
  274.             //Process message
  275.             TranslateMessage(&msg);
  276.             DispatchMessage(&msg);
  277.         }
  278.         else
  279.         {
  280.             //No message to process, so render the current scene
  281.             Render();
  282.         }
  283.     }
  284. }
  285. void CGame::Render()
  286. {
  287.     D3DXMATRIX matWorldY;
  288. if(m_pD3DDevice == NULL)
  289.     {
  290.         return;
  291.     }
  292.     //Clear the back buffer and depth buffer
  293.     m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
  294.     
  295.     //Begin the scene
  296.     m_pD3DDevice->BeginScene();
  297.     
  298. //Setup camera and perspective
  299. SetupCamera();
  300. //Create the rotation transformation matrices around the Y axis
  301. D3DXMatrixRotationY(&matWorldY, timeGetTime()/2000.0f);
  302. m_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorldY);
  303. //Render our objects
  304. m_dwTotalPolygons += m_pCube1->Render();
  305. m_dwTotalPolygons += m_pTerrain1->Render();
  306.     //End the scene
  307.     m_pD3DDevice->EndScene();
  308.     
  309.     //Filp the back and front buffers so that whatever has been rendered on the back buffer
  310.     //will now be visible on screen (front buffer).
  311.     m_pD3DDevice->Present(NULL, NULL, NULL, NULL);
  312. //Count Frames
  313. m_dwFrames++;
  314. }
  315. void CGame::SetupCamera()
  316. {
  317. //Here we will setup the camera.
  318. //The camera has three settings: "Camera Position", "Look at Position" and "Up Direction"
  319. //We have set the following:
  320. //Camera Position: (0, 200, -300)
  321. //Look at Position: (0, 0, 0)
  322. //Up direction: Y-Axis.
  323.     D3DXMATRIX matView;
  324.     D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 200.0f, -300.0f), //Camera Position
  325.                                  &D3DXVECTOR3(0.0f, 0.0f, 0.0f), //Look At Position
  326.                                  &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); //Up Direction
  327.     m_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
  328. //Here we specify the field of view, aspect ration and near and far clipping planes.
  329.     D3DXMATRIX matProj;
  330.     D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 2000.0f);
  331.     m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
  332. }
  333. void CGame::WriteToLog(char *lpszText, ...)
  334. {
  335. if(m_fEnableLogging)
  336. {
  337. va_list argList;
  338. FILE *pFile;
  339. //Initialize variable argument list
  340. va_start(argList, lpszText);
  341. //Open the log file for appending
  342. pFile = fopen("log.txt", "a+");
  343. //Write the text and a newline
  344. vfprintf(pFile, lpszText, argList);
  345. putc('n', pFile);
  346. //Close the file
  347. fclose(pFile);
  348. va_end(argList);
  349. }
  350. }
  351. void CGame::EnableLogging()
  352. {
  353. m_fEnableLogging = true;
  354. FILE* pFile;
  355. //Clear the file contents
  356. pFile = fopen("log.txt", "wb");
  357. //Close it up and return success
  358. fclose(pFile);
  359. }