📄 game.cpp
字号:
#include "Game.h"
//Game类构造函数
CGame::CGame()
{
//log文件开启标志
m_fEnableLogging = false;
//D3D对象接口指针
m_pD3D = NULL;
//设备接口指针
m_pD3DDevice = NULL;
//桢计数
m_dwFrames = 0;
//开始时间
m_dwStartTime = 0;
//结束时间
m_dwEndTime = 0;
//指向立方体对象的指针
m_pCube1 = NULL;
m_pCube2 = NULL;
m_pCube3 = NULL;
m_pCube4 = NULL;
m_pCube5 = NULL;
}
//Game类析构函数
CGame::~CGame()
{
//Game finished, so record time
//Game结束时,记录当前时间
m_dwEndTime = timeGetTime();
//计算Game运行时间
DWORD dwDuration = (m_dwEndTime - m_dwStartTime) / 1000;
//Log stats
//向日志中写入统计信息
WriteToLog("Statistics:");
WriteToLog("\tStart Time (ms): %d", m_dwStartTime);//Game开始时间
WriteToLog("\tEnd Time (ms): %d", m_dwEndTime);//Game结束时间
WriteToLog("\tDuration (s): %d", dwDuration);//Game总耗时
WriteToLog("\tTotal Frame Count: %d", m_dwFrames);//Game总帧数
WriteToLog("\tAverage FPS: %d", (m_dwFrames / dwDuration));//每秒显示帧数
//Clean up objects/interfaces
//清理Game运行期间生成的立方体对象和调用的接口指针还有设备资源
SafeDelete(m_pCube1);
SafeDelete(m_pCube2);
SafeDelete(m_pCube3);
SafeDelete(m_pCube4);
SafeDelete(m_pCube5);
SafeRelease(m_pD3DDevice);
SafeRelease(m_pD3D);
}
//初始化D3D对象
bool CGame::Initialise(HWND hWnd, UINT nWidth, UINT nHeight)
{
//调用InitialiseD3D函数初始化Game对象。
if(SUCCEEDED(InitialiseD3D(hWnd, nWidth, nHeight)))
{
return InitialiseGame();
}
else
{
return false;
}
return true;
}
//初始化游戏对象
bool CGame::InitialiseGame()
{
//Setup games objects here
//生成游戏对象
m_pCube1 = new CCuboid(m_pD3DDevice);
m_pCube1->SetPosition(-27.0, 0.0, 0.0);
m_pCube1->SetTexture("1.bmp");
m_pCube2 = new CCuboid(m_pD3DDevice);
m_pCube2->SetPosition(-9.0, 0.0, 0.0);
m_pCube2->SetTexture("2.bmp");
m_pCube3 = new CCuboid(m_pD3DDevice);
m_pCube3->SetPosition(9.0, 0.0, 0.0);
m_pCube3->SetTexture("3.bmp");
m_pCube4 = new CCuboid(m_pD3DDevice);
m_pCube4->SetPosition(27.0, 0.0, 0.0);
m_pCube4->SetTexture("4.bmp");
m_pCube5 = new CCuboid(m_pD3DDevice);
m_pCube5->SetPosition(0.0, 15.0, 0.0);
m_pCube5->SetTexture("5.bmp");
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;
}
//初始化D3D对象
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.
//创建D3D对象,创建成功返回一个指向IDirect3D8接口的指针。
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
//选择最大深度缓冲,选择32,24或16位色彩
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.
//创建Direct3D设备对象
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 off lighting becuase we are specifying that our vertices have colour
//关闭光照运算,因为已经指定顶点色彩
m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
//Turn on Depth Buffering
//开启深度缓冲
m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
WriteToLog("InitialiseD3D Finished OK");
return S_OK;
}
//获取设备指针
LPDIRECT3DDEVICE8 CGame::GetDevice()
{
return m_pD3DDevice;
}
//Game循环方法
void CGame::GameLoop()
{
//Enter the game loop
//游戏循环开始
MSG msg;
BOOL fMessage;
//PeekMessage用于处理消息队列中的消息
PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
//Game started, so record time
//开始Game,记录开始时间
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 matRotationX, matRotationY, matRotationZ, matRotationUser1;
//声明平移矩阵
D3DXMATRIX matMoveRight27, matMoveLeft27, matMoveRight9, matMoveLeft9, matMoveDown15, matMoveUp15;
//声明变换后的结果矩阵
D3DXMATRIX matTransformation2, matTransformation3, matTransformation4, matTransformation5;
//声明缩放矩阵
D3DXMATRIX matScaleUp1p5;
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 x, y and z axis
//创建围绕x,y,z轴旋转的矩阵
D3DXMatrixRotationX(&matRotationX, timeGetTime()/400.0f);
D3DXMatrixRotationY(&matRotationY, timeGetTime()/400.0f);
D3DXMatrixRotationZ(&matRotationZ, timeGetTime()/400.0f);
//Create the rotation transformation matrices around our user defined axis
//创建绕自定义轴旋转的矩阵
D3DXMatrixRotationAxis(&matRotationUser1, &D3DXVECTOR3(1.0f, 1.0f, 0.0f), timeGetTime()/400.0f);
//Create the translation (move) matrices
//创建平移变换矩阵
D3DXMatrixTranslation(&matMoveRight27, 27.0, 0.0, 0.0);
D3DXMatrixTranslation(&matMoveLeft27, -27.0, 0.0, 0.0);
D3DXMatrixTranslation(&matMoveRight9, 9.0, 0.0, 0.0);
D3DXMatrixTranslation(&matMoveLeft9, -9.0, 0.0, 0.0);
D3DXMatrixTranslation(&matMoveDown15, 0.0, -15.0, 0.0);
D3DXMatrixTranslation(&matMoveUp15, 0.0, 15.0, 0.0);
//Create a scale transformation
//创建缩放矩阵
D3DXMatrixScaling(&matScaleUp1p5, 1.5, 1.5, 1.5);
//Combine the matrices to form 4 transformation matrices
//将四种变换矩阵进行复合(相乘)。
D3DXMatrixMultiply(&matTransformation2, &matMoveRight9, &matRotationY);
D3DXMatrixMultiply(&matTransformation2, &matTransformation2, &matMoveLeft9);
D3DXMatrixMultiply(&matTransformation3, &matMoveLeft9, &matRotationZ);
D3DXMatrixMultiply(&matTransformation3, &matTransformation3, &matMoveRight9);
D3DXMatrixMultiply(&matTransformation4, &matMoveLeft27, &matRotationUser1);
D3DXMatrixMultiply(&matTransformation4, &matTransformation4, &matMoveRight27);
D3DXMatrixMultiply(&matTransformation5, &matMoveDown15, &matRotationY);
D3DXMatrixMultiply(&matTransformation5, &matTransformation5, &matRotationX);
D3DXMatrixMultiply(&matTransformation5, &matTransformation5, &matRotationZ);
D3DXMatrixMultiply(&matTransformation5, &matTransformation5, &matMoveUp15);
D3DXMatrixMultiply(&matTransformation5, &matTransformation5, &matScaleUp1p5);
//Apply the transformations and render our objects
//将复合后的矩阵应用到渲染对象。
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matRotationX);
m_pCube1->Render();
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matTransformation2);
m_pCube2->Render();
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matTransformation3);
m_pCube3->Render();
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matTransformation4);
m_pCube4->Render();
m_pD3DDevice->SetTransform(D3DTS_WORLD, &matTransformation5);
m_pCube5->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, 0, -100)
//Look at Position: (0, 0, 0)
//Up direction: Y-Axis.
//声明视图矩阵用以设置相机的位置,
//在这里设置相机的位置为Z轴的-100坐标上。
//设置Y轴方向为“上”
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 0.0f,-150.0f), //Camera Position相机位置
&D3DXVECTOR3(0.0f, 0.0f, 0.0f), //Look At Position观察者位置
&D3DXVECTOR3(1.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, //近视图平面
500.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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -