?? game.cpp
字號(hào):
// Game.cpp: implementation of the CGame class.
//
//////////////////////////////////////////////////////////////////////
#include "Game.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGame::CGame()
{
m_fEnableLogging = false;
m_pD3D = NULL;
m_pD3DDevice = NULL;
m_dwFrames = 0;
m_dwStartTime = 0;
m_dwEndTime = 0;
m_dwTotalPolygons = 0;
m_pCube1 = NULL;
m_pTerrain1 = NULL;
}
CGame::~CGame()
{
//Game finished, so record time
if(m_dwStartTime > 0)
{
m_dwEndTime = timeGetTime();
}
else
{
m_dwEndTime = 0;
}
DWORD dwDuration = (m_dwEndTime - m_dwStartTime) / 1000;
//Log stats
WriteToLog("Statistics:");
WriteToLog("\tStart Time (ms): %d", m_dwStartTime);
WriteToLog("\tEnd Time (ms): %d", m_dwEndTime);
WriteToLog("\tDuration (s): %d", dwDuration);
WriteToLog("\tTotal Frame Count: %d", m_dwFrames);
WriteToLog("\tAverage FPS: %d", (m_dwFrames / dwDuration));
WriteToLog("\tTotal Polygons: %d", m_dwTotalPolygons);
WriteToLog("\tAverage Polygons per Frame: %d", (m_dwTotalPolygons / m_dwFrames));
SafeDelete(m_pCube1);
SafeDelete(m_pTerrain1);
SafeRelease(m_pD3DDevice);
SafeRelease(m_pD3D);
}
bool CGame::Initialise(HWND hWnd, UINT nWidth, UINT nHeight)
{
if(SUCCEEDED(InitialiseD3D(hWnd, nWidth, nHeight)))
{
if(InitialiseLights())
{
return InitialiseGame();
}
else
{
return false;
}
}
else
{
return false;
}
return true;
}
bool CGame::InitialiseGame()
{
//Setup games objects here
m_pCube1 = new CCuboid(m_pD3DDevice, 0, 100, 0);
m_pCube1->SetSize(30, 30, 30);
m_pCube1->SetTexture("Cube.bmp");
//Create our terrain object (device, tile rows, tile cols, tile size, max height)
m_pTerrain1 = new CTerrain(m_pD3DDevice, 20, 20, 10.0, 15);
m_pTerrain1->SetTexture("Grass.bmp");
WriteToLog("InitialiseGame Finished OK");
return true;
}
D3DFORMAT CGame::CheckDisplayMode(UINT nWidth, UINT nHeight, UINT nDepth)
{
UINT x;
D3DDISPLAYMODE d3ddm;
for(x = 0; x < m_pD3D->GetAdapterModeCount(0); x++)
{
m_pD3D->EnumAdapterModes(0, x, &d3ddm);
if(d3ddm.Width == nWidth)
{
if(d3ddm.Height == nHeight)
{
if((d3ddm.Format == D3DFMT_R5G6B5) || (d3ddm.Format == D3DFMT_X1R5G5B5) || (d3ddm.Format == D3DFMT_X4R4G4B4))
{
if(nDepth == 16)
{
return d3ddm.Format;
}
}
else if((d3ddm.Format == D3DFMT_R8G8B8) || (d3ddm.Format == D3DFMT_X8R8G8B8))
{
if(nDepth == 32)
{
return d3ddm.Format;
}
}
}
}
}
return D3DFMT_UNKNOWN;
}
HRESULT CGame::InitialiseD3D(HWND hWnd, UINT nWidth, UINT nHeight)
{
WriteToLog("InitialiseD3D Started...");
//First of all, create the main D3D object. If it is created successfully we
//should get a pointer to an IDirect3D8 interface.
m_pD3D = Direct3DCreate8(D3D_SDK_VERSION);
if(m_pD3D == NULL)
{
WriteToLog("\tUnable to create DirectX8 interface.");
return E_FAIL;
}
//Get the current display mode
D3DDISPLAYMODE d3ddm;
d3ddm.Format = CheckDisplayMode(nWidth, nHeight, 32);
if(d3ddm.Format != D3DFMT_UNKNOWN)
{
//Width x Height x 32bit has been selected
d3ddm.Width = nWidth;
d3ddm.Height = nHeight;
WriteToLog("\t%d x %d x 32bit back buffer format selected. Format = %d.", nWidth, nHeight, d3ddm.Format);
}
else
{
d3ddm.Format = CheckDisplayMode(nWidth, nHeight, 16);
if(d3ddm.Format != D3DFMT_UNKNOWN)
{
//Width x Height x 16bit has been selected
d3ddm.Width = nWidth;
d3ddm.Height = nHeight;
WriteToLog("\t%d x %d x 16bit back buffer format selected. Format = %d.", nWidth, nHeight, d3ddm.Format);
}
else
{
WriteToLog("\tUnable to select back buffer format for %d x %d.", nWidth, nHeight);
return E_FAIL;
}
}
//Create a structure to hold the settings for our device
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = FALSE;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.BackBufferWidth = d3ddm.Width;
d3dpp.BackBufferHeight = d3ddm.Height;
d3dpp.hDeviceWindow = hWnd;
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
//Select the best depth buffer, select 32, 24 or 16 bit
if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32) == D3D_OK)
{
d3dpp.AutoDepthStencilFormat = D3DFMT_D32;
d3dpp.EnableAutoDepthStencil = TRUE;
WriteToLog("\t32bit depth buffer selected");
}
else if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8) == D3D_OK)
{
d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
d3dpp.EnableAutoDepthStencil = TRUE;
WriteToLog("\t24bit depth buffer selected");
}
else if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16) == D3D_OK)
{
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.EnableAutoDepthStencil = TRUE;
WriteToLog("\t16bit depth buffer selected");
}
else
{
d3dpp.EnableAutoDepthStencil = FALSE;
WriteToLog("\tUnable to select depth buffer.");
}
//Create a Direct3D device.
if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pD3DDevice)))
{
WriteToLog("\tUnable to create device.");
return E_FAIL;
}
//Turn on back face culling. This is becuase we want to hide the back of our polygons
m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
//Turn on Depth Buffering
m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
//Set fill state. Possible values: D3DFILL_POINT, D3DFILL_WIREFRAME, D3DFILL_SOLID
m_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
WriteToLog("InitialiseD3D Finished OK");
return S_OK;
}
bool CGame::InitialiseLights()
{
WriteToLog("InitialiseLights Started...");
D3DLIGHT8 d3dLight;
//Initialize the light structure.
ZeroMemory(&d3dLight, sizeof(D3DLIGHT8));
d3dLight.Type = D3DLIGHT_DIRECTIONAL;
d3dLight.Diffuse.r = 1.0f;
d3dLight.Diffuse.g = 1.0f;
d3dLight.Diffuse.b = 1.0f;
d3dLight.Ambient.r = 0.0f;
d3dLight.Ambient.g = 0.0f;
d3dLight.Ambient.b = 0.0f;
d3dLight.Specular.r = 0.0f;
d3dLight.Specular.g = 0.0f;
d3dLight.Specular.b = 0.0f;
d3dLight.Direction = D3DXVECTOR3(-1.0, -1.0, 0.0);
//Assign the point light to our device in poisition (index) 0
if(FAILED(m_pD3DDevice->SetLight(0, &d3dLight)))
{
WriteToLog("\tSetLight Failed");
return false;
}
else
{
WriteToLog("\tSetLight OK");
}
//Enable our point light in position (index) 0
if(FAILED(m_pD3DDevice->LightEnable(0, TRUE)))
{
WriteToLog("\tLightEnable Failed");
return false;
}
else
{
WriteToLog("\tLightEnable OK");
}
//Turn on lighting
if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE)))
{
WriteToLog("\tSetRenderState: D3DRS_LIGHTING Failed");
return false;
}
else
{
WriteToLog("\tSetRenderState: D3DRS_LIGHTING OK");
}
//Set ambient light level
if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(60, 60, 60))))
{
WriteToLog("\tSetRenderState: D3DRS_AMBIENT Failed");
return false;
}
else
{
WriteToLog("\tSetRenderState: D3DRS_AMBIENT OK");
}
WriteToLog("InitialiseLights Finished OK");
return true;
}
LPDIRECT3DDEVICE8 CGame::GetDevice()
{
return m_pD3DDevice;
}
void CGame::GameLoop()
{
//Enter the game loop
MSG msg;
BOOL fMessage;
PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
//Game started, so record time
m_dwStartTime = timeGetTime();
while(msg.message != WM_QUIT)
{
fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
if(fMessage)
{
//Process message
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//No message to process, so render the current scene
Render();
}
}
}
void CGame::Render()
{
D3DXMATRIX matWorldY;
if(m_pD3DDevice == NULL)
{
return;
}
//Clear the back buffer and depth buffer
m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
//Begin the scene
m_pD3DDevice->BeginScene();
//Setup camera and perspective
SetupCamera();
//Create the rotation transformation matrices around the Y axis
D3DXMatrixRotationY(&matWorldY, timeGetTime()/2000.0f);
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorldY);
//Render our objects
m_dwTotalPolygons += m_pCube1->Render();
m_dwTotalPolygons += m_pTerrain1->Render();
//End the scene
m_pD3DDevice->EndScene();
//Filp the back and front buffers so that whatever has been rendered on the back buffer
//will now be visible on screen (front buffer).
m_pD3DDevice->Present(NULL, NULL, NULL, NULL);
//Count Frames
m_dwFrames++;
}
void CGame::SetupCamera()
{
//Here we will setup the camera.
//The camera has three settings: "Camera Position", "Look at Position" and "Up Direction"
//We have set the following:
//Camera Position: (0, 200, -300)
//Look at Position: (0, 0, 0)
//Up direction: Y-Axis.
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 200.0f, -300.0f), //Camera Position
&D3DXVECTOR3(0.0f, 0.0f, 0.0f), //Look At Position
&D3DXVECTOR3(0.0f, 1.0f, 0.0f)); //Up Direction
m_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
//Here we specify the field of view, aspect ration and near and far clipping planes.
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 2000.0f);
m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}
void CGame::WriteToLog(char *lpszText, ...)
{
if(m_fEnableLogging)
{
va_list argList;
FILE *pFile;
//Initialize variable argument list
va_start(argList, lpszText);
//Open the log file for appending
pFile = fopen("log.txt", "a+");
//Write the text and a newline
vfprintf(pFile, lpszText, argList);
putc('\n', pFile);
//Close the file
fclose(pFile);
va_end(argList);
}
}
void CGame::EnableLogging()
{
m_fEnableLogging = true;
FILE* pFile;
//Clear the file contents
pFile = fopen("log.txt", "wb");
//Close it up and return success
fclose(pFile);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -