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 + -
显示快捷键?