game.cpp

来自「对游戏编程感兴趣的 朋友可以 下载下来看看 对DX讲解的很很详细」· C++ 代码 · 共 582 行 · 第 1/2 页

CPP
582
字号
// Game.cpp: implementation of the CGame class.
//
//////////////////////////////////////////////////////////////////////

#include "Game.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGame::CGame()
{
	m_pD3D = NULL;
	m_pD3DDevice = NULL;
	m_dwFrames = 0;
	m_dwStartTime = 0;
	m_dwEndTime = 0;
	m_dwTotalPolygons = 0;

	m_pMesh1 = NULL;
	m_pMesh2 = NULL;
	m_pMesh3 = NULL;

	m_pFont = NULL;
	m_pPanel1 = NULL;
	m_pPanel2 = NULL;
	m_pPanel3 = NULL;
}

CGame::~CGame()
{
	//Game finished, so destroy game objects
	LogInfo("<br>Finish Game:");

	SafeDelete(m_pMesh1);
	SafeDelete(m_pMesh2);
	SafeDelete(m_pMesh3);
	SafeDelete(m_pFont);
	SafeDelete(m_pPanel1);
	SafeDelete(m_pPanel2);
	SafeDelete(m_pPanel3);

	SafeRelease(m_pD3DDevice);
	SafeRelease(m_pD3D);

	//Game finished, so save statistics to log
	DWORD dwDuration = (m_dwEndTime - m_dwStartTime) / 1000;
	
	if((dwDuration != 0)&&(m_dwFrames != 0))
	{
		//Log stats
		LogInfo("<br>Statistics:");
		LogInfo("<li>Start Time (ms): %d", m_dwStartTime);
		LogInfo("<li>End Time (ms): %d", m_dwEndTime);
		LogInfo("<li>Duration (s): %d", dwDuration);
		LogInfo("<li>Total Frame Count: %d", m_dwFrames);
		LogInfo("<li>Average FPS: %d", (m_dwFrames / dwDuration));
		LogInfo("<li>Total Polygons: %d", m_dwTotalPolygons);
		LogInfo("<li>Average Polygons per Frame: %d", (m_dwTotalPolygons / m_dwFrames));
	}
	else
	{
		LogInfo("<br>No statistics to report");
	}

	StopLogging();
}

bool CGame::Initialise(HWND hWnd, UINT nWidth, UINT nHeight)
{
	if(InitialiseD3D(hWnd, nWidth, nHeight))
	{
		if(InitialiseLights()) 
		{
			return InitialiseGame();
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
		
	return true;
}

bool CGame::InitialiseGame()
{
	LogInfo("<br>Initialise Game:");

	//Setup games objects here
	m_pMesh1 = new CMesh(m_pD3DDevice, "Spaceship01.x");
	m_pMesh2 = new CMesh(m_pD3DDevice, "Spaceship01.x");
	m_pMesh3 = new CMesh(m_pD3DDevice, "Spaceship01.x");

	
	//Setup fonts here
	m_pFont = new CFont(m_pD3DDevice, "Verdana", 12, false, false, false);

	
	//Setup panels for 2D
	m_pPanel1 = new CPanel(m_pD3DDevice, 256, 64, m_nScreenWidth, m_nScreenHeight);
	m_pPanel1->SetTexture("EnergyBar.bmp", D3DCOLOR_XRGB(0, 0, 0));	//Load the texture and set the key colour

	m_pPanel2 = new CPanel(m_pD3DDevice, 128, 128, m_nScreenWidth, m_nScreenHeight);
	m_pPanel2->SetTexture("Left.bmp", D3DCOLOR_XRGB(0, 0, 0));		//Load the texture and set the key colour

	m_pPanel3 = new CPanel(m_pD3DDevice, 128, 128, m_nScreenWidth, m_nScreenHeight);
	m_pPanel3->SetTexture("Right.bmp", D3DCOLOR_XRGB(0, 0, 0));		//Load the texture and set the key colour


	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;
}

bool CGame::InitialiseD3D(HWND hWnd, UINT nWidth, UINT nHeight)
{
	LogInfo("<br>Initialise Direct3D:");

    //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)
    {
		LogError("<li>Unable to create DirectX8 interface.");
        return false;
    }

    //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;

		LogInfo("<li>%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;

			LogInfo("<li>%d x %d x 16bit back buffer format selected. Format = %d.", nWidth, nHeight, d3ddm.Format);
		}
        else
		{
			LogError("<li>Unable to select back buffer format for %d x %d.", nWidth, nHeight);
            return false;
        }
	}

	
    //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;

	m_nScreenWidth = d3ddm.Width;
	m_nScreenHeight = d3ddm.Height;

	//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;

		LogInfo("<li>32bit 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;

		LogInfo("<li>24bit 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;

		LogInfo("<li>16bit depth buffer selected");
	}
    else
	{
        d3dpp.EnableAutoDepthStencil = FALSE;
		LogError("<li>Unable to select depth buffer.");
	}


    //Create a Direct3D device.
    if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pD3DDevice)))
    {
		LogError("<li>Unable to create device.");
        return false;
    }
    
	//Turn on back face culling. This is becuase we want to hide the back of our polygons
	if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW)))
	{
		LogError("<li>SetRenderState: D3DRS_CULLMODE Failed");
		return false;
	}
	else
	{
		LogInfo("<li>SetRenderState: D3DRS_CULLMODE OK");
	}


	//Turn on Depth Buffering
	if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE)))
	{
		LogError("<li>SetRenderState: D3DRS_ZENABLE Failed");
		return false;
	}
	else
	{
		LogInfo("<li>SetRenderState: D3DRS_ZENABLE OK");
	}


	//Set fill state. Possible values: D3DFILL_POINT, D3DFILL_WIREFRAME, D3DFILL_SOLID
	if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID)))
	{
		LogError("<li>SetRenderState: D3DRS_FILLMODE Failed");
		return false;
	}
	else
	{
		LogInfo("<li>SetRenderState: D3DRS_FILLMODE OK");
	}

	//Set the D3DRS_NORMALIZENORMALS render state to fix the problem when scaling the objects get darker
	if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE)))
	{
		LogError("<li>SetRenderState: D3DRS_NORMALIZENORMALS Failed");
		return false;
	}
	else
	{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?