game.cpp

来自「DirectInput的基本实现 只是基本应用」· C++ 代码 · 共 206 行

CPP
206
字号
#include "Game.h"

CGame::CGame()
{
	m_pStaticMesh=NULL;
	m_bIsRota=false;
	Angle=0.0f;
}

CGame::~CGame()
{
	ClearUp();
}

HRESULT CGame::InitD3D(HWND hWnd)
{
	CoInitialize(NULL);
	m_pD3D=Direct3DCreate9(D3D_SDK_VERSION);
	D3DDISPLAYMODE d3ddm;//用来存储显卡的显示模式
	ZeroMemory(&d3ddm,sizeof(d3ddm));
	m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm);//获取显卡的显示模式
	D3DPRESENT_PARAMETERS d3dpp;//设备的详细信息
	ZeroMemory(&d3dpp,sizeof(d3dpp));
	d3dpp.BackBufferCount=1;// 背表面缓冲区的个数
	d3dpp.Windowed=true;//代表当前要创建的窗口 是 窗口模式
	d3dpp.BackBufferFormat=d3ddm.Format;//背表面格式
	d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;//翻转模式,选择DISCARD最高效

	d3dpp.EnableAutoDepthStencil=TRUE;
	d3dpp.AutoDepthStencilFormat=D3DFMT_D16;

	d3dpp.MultiSampleType=D3DMULTISAMPLE_8_SAMPLES;//全屏抗锯齿等级

	m_pD3D->CheckDeviceMultiSampleType (D3DADAPTER_DEFAULT,//显卡的标识
		D3DDEVTYPE_HAL,//硬件抽象层
		d3ddm.Format,//表面格式
		true,//全屏反锯齿
		D3DMULTISAMPLE_8_SAMPLES,//抗锯齿等级
		NULL);

	m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,	hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&m_pDevice);
	
	m_pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,true);
	
	m_pDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
	m_pDevice->SetRenderState(D3DRS_ZENABLE,TRUE);

	return S_OK;
}

HRESULT CGame::ClearUp()
{
 
	SAFE_RELEASE(m_pDevice);
	SAFE_RELEASE(m_pD3D);
	return S_OK;
}

HRESULT CGame::SetFog()
{
 		m_pDevice->SetRenderState( D3DRS_FOGENABLE,   TRUE );//开启雾化效果
		m_pDevice->SetRenderState( D3DRS_FOGCOLOR , 0xffffffff);//定义一个雾的颜色

		float start=0.01f;//雾化的起始位置
		float end=12000.0f;//雾化的结束位置

		m_pDevice->SetRenderState( D3DRS_FOGSTART   ,   *(DWORD*)&start);  //设置雾化的起始位置
		m_pDevice->SetRenderState( D3DRS_FOGEND   ,  *(DWORD*)&end);		  //设置雾化的结束位置
		m_pDevice->SetRenderState( D3DRS_FOGTABLEMODE ,  D3DFOG_LINEAR);	  //设置雾化的方式
 
		return S_OK;
}

HRESULT CGame::InitGame()
{
	SetEyes();
	SetFog();
	m_pStaticMesh=new CStaticMesh(m_pDevice);
	m_pStaticMesh->InitMesh("ball.X");

	m_boundSphere._center=D3DXVECTOR3(0.0f,0.0f,0.0f);
	m_boundSphere.radius=3.0f;

	return S_OK;

}

HRESULT CGame::SetEyes()
{
	D3DXMATRIX matView;
	D3DXVECTOR3 EyePt(0.0f,5.0f,-8.0f);
	D3DXVECTOR3 LookAt(0.0f,0.0f, 0.0f);
	D3DXVECTOR3 EyeUp(0.0f,1.0f, 0.0f);
	D3DXMatrixLookAtLH(&matView,&EyePt,&LookAt,&EyeUp);
	m_pDevice->SetTransform(D3DTS_VIEW ,& matView);

	D3DXMATRIX matProj;
	D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,4.0f/3.0f,1.0f,1000.0f);
	m_pDevice->SetTransform(D3DTS_PROJECTION ,& matProj);

	return S_OK;
}
 
HRESULT CGame::GameLogic(float fElapsedTime)
{
 
	if(m_bIsRota)
		 Angle = timeGetTime()/350.0f;
	
	m_pStaticMesh->SetMatrix(D3DXVECTOR3(0.0f,0.0f,0.0f),Angle,1.0f);

	return S_OK;
}

HRESULT CGame::GameRender(float fElapsedTime)
{
	m_pDevice->Clear(0, NULL , D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB(123,123,234), 1.0f , 0 );
	m_pDevice->BeginScene();

	m_pStaticMesh->Render();
 
	m_pDevice->EndScene();
	m_pDevice->Present(NULL,NULL,NULL,NULL);
	return S_OK;
}

Ray CGame::CalculateRay(int x, int y)//根据鼠标在屏幕上的像素位置计算射线
{
	float px=0.0f;
	float py=0.0f;
	//获取视口大小
	D3DVIEWPORT9 vp;
	m_pDevice->GetViewport(&vp);
	//获取投影矩阵
	D3DXMATRIX proj;
	m_pDevice->GetTransform(D3DTS_PROJECTION,&proj);

	//计算拾取射线
	px=(((2.0f*x)/vp.Width)-1.0f)/proj._11;
	py=(((-2.0f*y)/vp.Height)+1.0f)/proj._22;
	Ray ray;
	ray._origin = D3DXVECTOR3(0.0f,0.0f,0.0f);
	ray._dirction = D3DXVECTOR3(px,py,1.0f);
	return ray;
}

Ray CGame::TransformRay(Ray ray, D3DXMATRIX* InvMatView)//转换射线,从视图空间变换到世界空间
{
	Ray transRay;
	//转换射线的起点
	D3DXVec3TransformCoord(&transRay._origin,&ray._origin,InvMatView);
	//转换射线的方向
	D3DXVec3TransformNormal(&transRay._dirction,&ray._dirction,InvMatView);
	D3DXVec3Normalize(&transRay._dirction,&transRay._dirction);
	return transRay;
}

BOOL CGame::CheckIntersection(Ray* ray, BoundSphere* sphere)//计算与球是否相交
{
	//计算t0与t1的值
	D3DXVECTOR3 v = ray->_origin-sphere->_center;
	float b = 2.0f*D3DXVec3Dot(&ray->_dirction,&v);
	float c = D3DXVec3Dot(&v,&v)-(sphere->radius*sphere->radius);

	float n = (b*b)-(4.0f*c);
	if (n<0.0f)
	{
		return false;
	}
	n = sqrtf(n);
	float t0 = (-b+n)/2.0f;
	float t1 = (-b-n)/2.0f;
	//判断是否相交
	if (t0>=0||t1>=0)
	{
		return true;
	}
	return false;
}

void CGame::HandleMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)//消息传递
{
	switch (message)
	{
	case WM_LBUTTONDOWN:
		{
			POINT pt;
			GetCursorPos(&pt);
			ScreenToClient(hWnd, &pt);

			Ray ray = CalculateRay(pt.x, pt.y);
			D3DXMATRIX matView,InvMatView;
			m_pDevice->GetTransform(D3DTS_VIEW, &matView);
			D3DXMatrixInverse(&InvMatView, NULL, &matView);
			ray = TransformRay(ray, &InvMatView);

			if( CheckIntersection(&ray, &m_boundSphere) )
				m_bIsRota = true;
			else
				m_bIsRota = false;

		}
		break;
	}
}

⌨️ 快捷键说明

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