game.cpp
来自「DirectInput的基本实现 只是基本应用」· C++ 代码 · 共 258 行
CPP
258 行
#include "StdAfx.h"
#include ".\game.h"
CGame::CGame(void) :
m_pD3D(NULL),
m_pDevice(NULL),
m_bDeviceLost(false),
m_pFont(NULL)
{
for(int i=0; i<2; ++i)
m_pBall[i] = NULL;
}
CGame::~CGame(void)
{
SAFE_RELEASE(m_pD3D);
SAFE_RELEASE(m_pDevice);
SAFE_RELEASE(m_pFont);
for(int i=0; i<2; ++i)
SAFE_DELETE(m_pBall[i]);
}
bool CGame::Init( HINSTANCE hInstance, HWND hWnd )
{
// COM初始化
CoInitialize(NULL);
if(FAILED(_InitD3D(hWnd)))
return false;
// 创建字体
D3DXCreateFont( m_pDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
"Arial", &m_pFont );
for(int i=0; i<2; ++i)
{
m_pBall[i] = new CStaticMesh;
m_pBall[i]->Init( m_pDevice, "ball.X" );
m_pBall[i]->SetTextureFromFile( 0, "texture.dds" );
m_boundSphere[i]._center = D3DXVECTOR3(-5.0f + i*10.0f, 0.0f, 0.0f);
m_boundSphere[i].radius = 3.0f;
m_bRotate[i] = false;
m_fAngle[i] = 0.0f;
}
return true;
}
HRESULT CGame::_InitD3D(HWND hWnd)
{
// COM interface
if( NULL == ( m_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
// current display mode
D3DDISPLAYMODE d3ddm;
if( FAILED(m_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm)))
return E_FAIL;
RECT rect;
GetClientRect(hWnd, &rect);
ZeroMemory(&m_d3dpp, sizeof(m_d3dpp));
m_d3dpp.Windowed = TRUE/*FALSE*/;
m_d3dpp.BackBufferCount = 1;
m_d3dpp.BackBufferFormat = d3ddm.Format;
m_d3dpp.BackBufferWidth = rect.right - rect.left;
m_d3dpp.BackBufferHeight = rect.bottom - rect.top;
//m_d3dpp.BackBufferWidth = d3ddm.Width;
//m_d3dpp.BackBufferHeight = d3ddm.Height;
m_d3dpp.hDeviceWindow = hWnd;
m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
m_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
m_d3dpp.EnableAutoDepthStencil = TRUE;
// Create D3D Device
if( FAILED( m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&m_d3dpp, &m_pDevice ) ) )
{
return E_FAIL;
}
return S_OK;
}
void CGame::Update(float fElapsedTime)
{
D3DXMATRIX matRroj;
D3DXMatrixPerspectiveFovLH( &matRroj, D3DX_PI/4, 4.f/3.f, 1.f, 500.0f );
m_pDevice->SetTransform(D3DTS_PROJECTION, &matRroj);
// 更新视矩阵
D3DXMATRIX matView;
D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3(13.0f, 13.0f, 13.0f), &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f) );
m_pDevice->SetTransform(D3DTS_VIEW, &matView);
}
void CGame::Render(float fElapsedTime)
{
// 在每次渲染前判断是否发生设备丢失
HRESULT hr;
// 后备缓冲区须与窗口大小一致才能正确获得D3DERR_DEVICENOTRESET
// 否则检测系统协调层级只能获得D3DERR_DEVICELOST
if( m_bDeviceLost == true )
{
Sleep( 100 ); // 100 milliseconds
// 检查系统协调层级,系统可以根据函数返回值判断设备丢失时采取的措施
if( FAILED( hr = m_pDevice->TestCooperativeLevel() ) )
{
if( hr == D3DERR_DEVICELOST )
return;
// 设备丢失能够被自动重置,这时候返回进行再次尝试
if( hr == D3DERR_DEVICENOTRESET )
{
// 清空内存资源
InvalidateDeviceObjects();
// 调用Reset函数重置设备
hr = m_pDevice->Reset( &m_d3dpp );
if( FAILED(hr ) )
return;
// 重新设置内存资源里的数据
RestoreDeviceObjects();
return;
}
}
m_bDeviceLost = false;
}
m_pDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
m_pDevice->BeginScene();
m_pDevice->SetRenderState( D3DRS_LIGHTING, false );
D3DXMATRIX matWorld;
for(int i=0; i<2; ++i)
{
if(m_bRotate[i])
m_fAngle[i] += 1.5f * fElapsedTime;
D3DXMatrixRotationY(&matWorld, m_fAngle[i]);
matWorld._41 = -5.0f + i*10.0f;
matWorld._42 = 0.0f;
matWorld._43 = 0.0f;
m_pDevice->SetTransform( D3DTS_WORLD, &matWorld );
m_pBall[i]->Render(matWorld);
}
m_pDevice->EndScene();
hr = m_pDevice->Present( NULL, NULL, NULL, NULL );
if( hr == D3DERR_DEVICELOST )
m_bDeviceLost = true;
}
void CGame::InvalidateDeviceObjects(void)
{
m_pFont->OnLostDevice();
}
void CGame::RestoreDeviceObjects(void)
{
m_pFont->OnResetDevice();
}
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 mat;
m_pDevice->GetTransform(D3DTS_VIEW, &mat);
D3DXMatrixInverse(&mat, NULL, &mat);
ray = TransformRay(ray, &mat);
for(int i=0; i<2; ++i)
{
if( CheckIntersection(&ray, &m_boundSphere[i]) )
m_bRotate[i] = true;
else
m_bRotate[i] = false;
}
}
break;
}
}
CGame::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;
}
CGame::Ray CGame::TransformRay(Ray ray, D3DXMATRIX* T)
{
Ray transRay;
//转换射线的起点
D3DXVec3TransformCoord(&transRay._origin,&ray._origin,T);
//转换射线的方向
D3DXVec3TransformNormal(&transRay._dirction,&ray._dirction,T);
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;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?