game.cpp

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

CPP
949
字号
        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
	{
		LogInfo("<li>SetRenderState: D3DRS_NORMALIZENORMALS OK");
	}


	//Enable alpha blending so we can use transparent textures
	if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,  TRUE)))
	{
		LogError("<li>SetRenderState: D3DRS_ALPHABLENDENABLE Failed");
		return false;
	}
	else
	{
		//Set how the texture should be blended (use alpha)
		m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
		m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
		LogInfo("<li>SetRenderState: D3DRS_ALPHABLENDENABLE OK");
	}
	

    return true;
}

bool CGame::InitialiseLights()
{
	LogInfo("<br>Initialise Lights:");

	D3DLIGHT8 d3dLight;

	//Initialize the light structure.
	ZeroMemory(&d3dLight, sizeof(D3DLIGHT8));

	d3dLight.Type = D3DLIGHT_POINT;
	
	d3dLight.Position.x = -30.0f;
	d3dLight.Position.y = 0.0f;
	d3dLight.Position.z = -15.0f;

	d3dLight.Attenuation0 = 1.0f; 
	d3dLight.Attenuation1 = 0.0f; 
	d3dLight.Attenuation2 = 0.0f; 
	d3dLight.Range = 1000.0f;	

	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;

	//Assign the point light to our device in poisition (index) 0
	if(FAILED(m_pD3DDevice->SetLight(0, &d3dLight)))
	{
		LogError("<li>SetLight Failed");
		return false;
	}
	else
	{
		LogInfo("<li>SetLight OK");
	}

	//Enable our point light in position (index) 0
	if(FAILED(m_pD3DDevice->LightEnable(0, TRUE)))
	{
		LogError("<li>LightEnable Failed");
		return false;
	}
	else
	{
		LogInfo("<li>LightEnable OK");
	}

	//Turn on lighting
    if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE)))
	{
		LogError("<li>SetRenderState: D3DRS_LIGHTING Failed");
		return false;
	}
	else
	{
		LogInfo("<li>SetRenderState: D3DRS_LIGHTING OK");
	}

	//Set ambient light level
	if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(100, 100, 100))))	
	{
		LogError("<li>SetRenderState: D3DRS_AMBIENT Failed");
		return false;
	}
	else
	{
		LogInfo("<li>SetRenderState: D3DRS_AMBIENT 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) && (!m_fQuit))
    {
        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();
        }
    }

	//Game finished, so record time
	m_dwEndTime = timeGetTime();
}

void CGame::Render()
{

	if(m_pD3DDevice == NULL)
    {
        return;
    }

	//Process keyboard and mouse user input
	ProcessKeyboard();
	ProcessMouse();

	if(!m_fQuit)
	{
		//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 the camera ready for 3D elements
		Setup3DCamera();
		
		//Now that the 3D camera is setup, render the 3D objects
		Render3D();
		

		//Setup the camera ready for 2D elements
		Setup2DCamera();
		
		//Now that the 2D camera is setup, render the 2D objects
		Render2D();

		//Now render the text
		RenderText();


		//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::Setup2DCamera()
{
	D3DXMATRIX matOrtho;	
	D3DXMATRIX matIdentity;
	
	//Setup the orthogonal projection matrix and the default world/view matrix
	D3DXMatrixOrthoLH(&matOrtho, (float)m_nScreenWidth, (float)m_nScreenHeight, 0.0f, 1.0f);
	D3DXMatrixIdentity(&matIdentity);

	m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matOrtho);
	m_pD3DDevice->SetTransform(D3DTS_WORLD, &matIdentity);
	m_pD3DDevice->SetTransform(D3DTS_VIEW, &matIdentity);

	//Make sure that the z-buffer and lighting are disabled
	m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
	m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
}

void CGame::Setup3DCamera()
{
	//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, 15, -50)
	//Look at Position: (0, 0, 0)
	//Up direction:		Y-Axis.
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 15.0f, -50.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.25f, 1.0f, 2000.0f);
    m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);

	//Make sure that the z-buffer and lighting are enabled
	m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
	m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
}

void CGame::Render2D()
{
	//Render our 2D objects
	m_pPanel1->MoveTo(136, 86);
	m_dwTotalPolygons += m_pPanel1->Render();

	m_pPanel2->MoveTo(536, 86);
	m_dwTotalPolygons += m_pPanel2->Render();

	m_pPanel3->MoveTo(136, 386);
	m_dwTotalPolygons += m_pPanel3->Render();

	m_pPanel4->MoveTo(536, 386);
	m_dwTotalPolygons += m_pPanel4->Render();

	//Render mouse panel last so that it is on top
	m_pPanelMouse->MoveTo(m_nMouseX, m_nMouseY);
	m_dwTotalPolygons += m_pPanelMouse->Render();

	
	//Play sounds
	if(m_nMouseLeft == 1)
	{
		//Left mouse button is down, which sound do we play?
		if(m_pPanel1->IsPointInsidePanel(m_nMouseX, m_nMouseY))
		{
			m_pSound1->Play();
		}
		else if(m_pPanel2->IsPointInsidePanel(m_nMouseX, m_nMouseY))
		{
			m_pSound2->Play();
		}
		else if(m_pPanel3->IsPointInsidePanel(m_nMouseX, m_nMouseY))
		{
			m_pSound3->Play();
		}
		else if(m_pPanel4->IsPointInsidePanel(m_nMouseX, m_nMouseY))
		{
			m_pSound4->Play();
		}
		else
		{
			//Play "Error" sound
			m_pSoundFailed->Play();
		}		
	}

	//Start background music on first frame
	if(m_dwFrames == 1)
	{
		m_pSoundBG->Play();
	}
	else if(m_dwFrames > 1)
	{
		//Make the background music loop
		if(!m_pSoundBG->IsPlaying())
		{
			m_pSoundBG->Play();
		}
	}
	
}

void CGame::Render3D()
{
	//Render our 3D objects
}

void CGame::RenderText()
{
	//Draw some text at the top of the screen showing stats
	char buffer[255];
	DWORD dwDuration = (timeGetTime() - m_dwStartTime) / 1000;
	
	if(dwDuration > 0)
	{
		sprintf(buffer, "Duration: %d seconds. Frames: %d. FPS: %d. Left: %d. Right: %d. X = %d. Y = %d.", dwDuration, m_dwFrames, (m_dwFrames / dwDuration), m_nMouseLeft, m_nMouseRight, m_nMouseX, m_nMouseY);
	}
	else
	{
		sprintf(buffer, "Calculating...");
	}
		
	m_pFont->DrawText(buffer, 0, 0, D3DCOLOR_XRGB(255, 255, 255));
}

void CGame::ProcessKeyboard()
{
    char KeyboardState[256]; 
     
    if(FAILED(m_pKeyboard->GetDeviceState(sizeof(KeyboardState),(LPVOID)&KeyboardState)))
    { 
		return; 
    } 
 
	if(KEYDOWN(KeyboardState, DIK_ESCAPE))
	{
        //Escape key pressed. Quit game.
		m_fQuit = true;
	}
}

void CGame::ProcessMouse()
{
	DIMOUSESTATE MouseState;

	if(FAILED(m_pMouse->GetDeviceState(sizeof(MouseState),(LPVOID)&MouseState)))
    { 
		return; 
    } 

	//Is the left mouse button down?
	if(MOUSEBUTTONDOWN(MouseState.rgbButtons[MOUSEBUTTON_LEFT]))
	{
		m_nMouseLeft = 1;
	}
	else
	{
		m_nMouseLeft = 0;
	}

	//Is the right mouse button down?
	if(MOUSEBUTTONDOWN(MouseState.rgbButtons[MOUSEBUTTON_RIGHT]))
	{
		m_nMouseRight = 1;
	}
	else
	{
		m_nMouseRight = 0;
	}
    
	m_nMouseX += MouseState.lX;
	m_nMouseY += MouseState.lY;
}




⌨️ 快捷键说明

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