|
|
一个问题困扰好久的问题,我把主要的程序贴出来。这个是主程序
int APIENTRY WinMain(HINSTANCE hInstance, //传入的窗口句柄
HINSTANCE hPrevInstance, //已存在的窗口句柄
LPSTR lpCmdLine, //传入的命令行参数
int nCmdShow) //设置窗口的显示方式
{
CGameEngine_App GameEngine_App;
MSG msg;
if(!GameEngine_App.CreateWnd("骨骼动画例子",hInstance,hPrevInstance,nCmdShow)){
return false;
}
hWnd=GameEngine_App.GetHWnd(); //取得已创建的窗口句柄
if(!GameEngine_Input.CreateInput(hInstance,hWnd)){ //初始化输入设备
MessageBox(NULL,"初始化输入设备失败.","警告",MB_OK|MB_ICONINFORMATION);
return false;
}
ShowCursor(true);
GameEngine_Timer.InitGameTime(); //初始化游戏时间
if(!CreateD3DDevice(hWnd,true)){ //创建D3D设备
return false;
}
SetupView(); //设置摄影机位置
SetupProjection(); //设置透视投影
//装入骨骼动画文件tiny.x
g_pRole=new CSkinMesh(g_pIDirect3DDevice);
g_pRole->LoadFromXFile("tiny.x");
//初始化地图
g_pMap=new CSimpleMap(g_pIDirect3DDevice,10000,10000);
g_pMap->InitMap("grass.bmp");
//上次游戏时间
g_fGameLastTime=GameEngine_Timer.GetGamePlayTime();
while(msg.message!=WM_QUIT){
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{
if(DoFrame()==false) break; //渲染一帧动画
}
}
Shutdown();
UnregisterClass(WNDCLASSNAME, hInstance);
CoUninitialize(); //注销所有COM对象
return true;
}
bool CreateD3DDevice(HWND hWnd,bool bFullScreen){
//创建IDirect3D9对象
g_pIDirect3D=Direct3DCreate9(D3D_SDK_VERSION);
if(g_pIDirect3D==NULL){
return false;
}
D3DCAPS9 d3dcaps;
g_pIDirect3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&d3dcaps);
bool bHarwareProcess;
if(d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT){
bHarwareProcess=true;
}
else{
bHarwareProcess=false;
}
//取得显示模式
D3DDISPLAYMODE d3dDisplayMode;
if(FAILED(g_pIDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3dDisplayMode))){
return false;
}
//设置d3d设备的渲染参数
D3DPRESENT_PARAMETERS d3dPresent_Param; //渲染参数结构体
ZeroMemory(&d3dPresent_Param, sizeof(d3dPresent_Param)); //结构体清0
d3dPresent_Param.BackBufferWidth=800;
d3dPresent_Param.BackBufferHeight=600;
d3dPresent_Param.BackBufferFormat=d3dDisplayMode.Format;
d3dPresent_Param.BackBufferCount=1;
d3dPresent_Param.hDeviceWindow=hWnd; //
d3dPresent_Param.Windowed=!bFullScreen; //false为全屏幕显示方式
d3dPresent_Param.SwapEffect=D3DSWAPEFFECT_FLIP;
d3dPresent_Param.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;
d3dPresent_Param.EnableAutoDepthStencil=TRUE;
d3dPresent_Param.AutoDepthStencilFormat=D3DFMT_D16;
//创建d3d设备
if(bHarwareProcess){
if(FAILED(g_pIDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dPresent_Param,
&g_pIDirect3DDevice))){ //已改为软件处理
return false;
}
}
else{
if(FAILED(g_pIDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dPresent_Param,
&g_pIDirect3DDevice))){
return false;
}
}
return true;
}
void Shutdown(){
delete g_pMap;g_pMap=NULL;
delete g_pRole;g_pRole=NULL;
SafeRelease(g_pIDirect3DDevice);
SafeRelease(g_pIDirect3D);
}
//调整摄影机的距离
void Zoom(float fStep)
{
g_vEyePt+=(g_vEyePt - g_vLookatPt)*fStep;
}
//旋转摄影机
void CameraRotate(float fAngle){
D3DXVECTOR3 vRotateAxis=D3DXVECTOR3(0,1,0);
D3DXMATRIX matRotate;
D3DXMatrixRotationAxis(&matRotate,&vRotateAxis,fAngle);
D3DXVec3TransformCoord(&g_vEyePt,&g_vEyePt,&matRotate);
}
//设置摄影机位置
void SetupView()
{
D3DXMATRIX matView;
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMatrixLookAtLH( &matView, &g_vEyePt, &g_vLookatPt, &vUpVec );
g_pIDirect3DDevice->SetTransform( D3DTS_VIEW, &matView );
}
//设置透视投影
void SetupProjection()
{
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 100.0f, 100000.0f );
g_pIDirect3DDevice->SetTransform( D3DTS_PROJECTION, &matProj);
}
//设置世界空间
void SetupWorld()
{
D3DXMATRIX matWorld;
D3DXMatrixIdentity(&matWorld);
g_pIDirect3DDevice->SetTransform( D3DTS_WORLD, &matWorld );
}
//渲染一动画帧
bool DoFrame()
{
D3DXVECTOR3 g_vCurrentMousePt;
D3DXMATRIX matProj,matView,matWorld;
D3DVIEWPORT9 viewPort;
POINT ptCursor;
D3DXVECTOR3 vScreen,vOut;
D3DXPLANE plane;
D3DXVECTOR3 v1(1.0f,0.0f,1.0f);
D3DXVECTOR3 v2(-1.0f,0.0f,1.0f);
D3DXVECTOR3 v3(-1.0f,0.0f,-1.0f);
float fAngle;
//读取键盘输入
if(GameEngine_Input.ReadKeyboard()){
if(GameEngine_Input.IsKeyPressed(DIK_ESCAPE)){
return false;
}
if(GameEngine_Input.IsKeyPressed(DIK_UP)){
Zoom(-fZoomStep);
}
if(GameEngine_Input.IsKeyPressed(DIK_DOWN)){
Zoom(fZoomStep);
}
if(GameEngine_Input.IsKeyPressed(DIK_LEFT)){
CameraRotate(-ROTATE_ANGLE);
}
if(GameEngine_Input.IsKeyPressed(DIK_RIGHT)){
CameraRotate(ROTATE_ANGLE);
}
}
//读取鼠标
if(GameEngine_Input.ReadMouse()){
if(GameEngine_Input.IsLButtonPressed()){
g_pRole->SetAnim(true);
g_bRoleMove=true;
g_bMoveLoop=true;
}
}
if(GameEngine_Timer.GetGamePlayTime()<g_fGameLastTime +30){
return true;
}
//若Clear函数成功执行,清屏
g_pIDirect3DDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,255),1.0f,0);
g_pIDirect3DDevice->BeginScene();
SetupWorld(); //设置世界矩阵为单位矩阵,重置数据
SetupView();
g_pMap->Render(); //绘制地图
//角色绘制
if(g_bRoleMove){
g_pIDirect3DDevice->GetTransform( D3DTS_PROJECTION, &matProj );
g_pIDirect3DDevice->GetTransform( D3DTS_VIEW, &matView );
g_pIDirect3DDevice->GetTransform( D3DTS_WORLD,&matWorld );
g_pIDirect3DDevice->GetViewport(&viewPort);
GetCursorPos(&ptCursor);
ScreenToClient(hWnd, &ptCursor);
vScreen=D3DXVECTOR3((float)ptCursor.x,(float)ptCursor.y,0.0f);
D3DXVec3Unproject(&vOut,&vScreen,&viewPort,&matProj,&matView,&matWorld);
D3DXPlaneFromPoints(&plane, &v1, &v2, &v3);
D3DXPlaneIntersectLine(&g_vCurrentMousePt, &plane, &g_vEyePt, &vOut); //y=0平面交点
fAngle=3*D3DX_PI/2-(float)atan2(g_vCurrentMousePt.z-g_vLastMousePt.z , g_vCurrentMousePt.x-g_vLastMousePt.x); //鼠标点在世界空间的坐标
g_pRole->SetRotateAngle(fAngle);
g_vRoleEndPt=g_vCurrentMousePt; //可以替换
g_vLastMousePt=g_vCurrentMousePt;
g_bRoleMove=false;
}
if(g_bMoveLoop){
RoleMove(g_vRoleStartPt,g_vRoleEndPt,g_iRolePos);
g_iRolePos++;
}
g_pRole->Render();
g_pIDirect3DDevice->EndScene();
g_pIDirect3DDevice-> resent(NULL,NULL,NULL,NULL);
return true;
}
//角色行走
void RoleMove(D3DXVECTOR3 vStartPoint,D3DXVECTOR3 vEndPoint,int iPos){
D3DXVECTOR3 vCurrentPos;
D3DXMATRIX matStep;
if(iPos<=STEPCOUNT){
vCurrentPos=(vEndPoint-vStartPoint)*(float)iPos/STEPCOUNT + vStartPoint;
D3DXMatrixTranslation(&matStep,
vCurrentPos.x-g_vLastRolePt.x,
vCurrentPos.y-g_vLastRolePt.y,
vCurrentPos.z-g_vLastRolePt.z);
g_pRole->m_matMoveMatrices=g_pRole->m_matMoveMatrices * matStep;
g_vLastRolePt=vCurrentPos;
}
else{
g_pRole->SetAnim(false);
g_iRolePos=0;
g_bRoleMove=false;
g_bMoveLoop=false;
g_vRoleStartPt=g_vRoleEndPt;
}
}
然后还有一个叫GameEngine_ScnenManager的类
CGameEngine_SceneManager::CGameEngine_SceneManager(){
}
CGameEngine_SceneManager::~CGameEngine_SceneManager(){
Closedown();
}
bool CGameEngine_SceneManager::Init(){
//创建IDirect3D9对象
m_pIDirect3D=Direct3DCreate9(D3D_SDK_VERSION);
if(m_pIDirect3D==NULL){
return false;
}
return true;
}
bool CGameEngine_SceneManager::SetRenderMode(HWND hWnd,bool bFullScreen,int iWidth,int iHeight){
//取得显示模式
D3DDISPLAYMODE d3dDisplayMode;
RECT clientRect;
RECT wndRect;
int iWndPosX,iWndPosY,iTitlebarWidth,iTitlebarHeight;
m_hWnd=hWnd;
if(FAILED(m_pIDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3dDisplayMode)))
return false;
//设置屏幕窗口大小
if(bFullScreen){
m_iWidth=iWidth;
m_iHeight=iHeight;
}
else{
if(iWidth>0 && iHeight>0){
m_iWidth=iWidth;
m_iHeight=iHeight;
GetClientRect(m_hWnd,&clientRect);
}
else
return false;
}
//窗口,则移动到屏幕中央位置
if(!bFullScreen){
iWndPosX=(d3dDisplayMode.Width - m_iWidth)/2;
iWndPosY=(d3dDisplayMode.Height - m_iHeight)/2;
GetWindowRect(m_hWnd,&wndRect);
iTitlebarWidth=(wndRect.right - wndRect.left) - clientRect.right;
iTitlebarHeight=(wndRect.bottom - wndRect.top) - clientRect.bottom;
MoveWindow(m_hWnd,iWndPosX,iWndPosY,iTitlebarWidth+m_iWidth,iTitlebarHeight+m_iHeight,true);
}
//设置D3D设备的属性参数
D3DPRESENT_PARAMETERS d3dPresent_Param; //渲染参数结构体
ZeroMemory(&d3dPresent_Param, sizeof(d3dPresent_Param)); //结构体清0
d3dPresent_Param.BackBufferFormat=d3dDisplayMode.Format;
if(bFullScreen){ //全屏幕方式
d3dPresent_Param.BackBufferWidth=m_iWidth;
d3dPresent_Param.BackBufferHeight=m_iHeight;
d3dPresent_Param.BackBufferCount=1;
d3dPresent_Param.hDeviceWindow=m_hWnd;
d3dPresent_Param.Windowed=false; //false为全屏幕显示方式
d3dPresent_Param.SwapEffect=D3DSWAPEFFECT_FLIP;
d3dPresent_Param.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;
d3dPresent_Param.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;
d3dPresent_Param.EnableAutoDepthStencil=true;
d3dPresent_Param.AutoDepthStencilFormat=D3DFMT_D24S8;
}
else{
d3dPresent_Param.Windowed=true;
d3dPresent_Param.SwapEffect=D3DSWAPEFFECT_DISCARD;
}
//简单的硬件、软件渲染选择
D3DCAPS9 d3dcaps;
bool bHardwareProcess;
m_pIDirect3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&d3dcaps);
if(d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT){
bHardwareProcess=true;
}
else{
bHardwareProcess=false;
}
//创建d3d设备
if(bHardwareProcess){
if(FAILED(m_pIDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dPresent_Param,
&m_pIDirect3DDevice))){
return false;
}
}
else{
if(FAILED(m_pIDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dPresent_Param,
&m_pIDirect3DDevice))){
return false;
}
}
//设置渲染状态
m_pIDirect3DDevice->SetRenderState(D3DRS_LIGHTING,false);
m_pIDirect3DDevice->SetRenderState(D3DRS_ZENABLE,true);
m_pIDirect3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE,false);
m_pIDirect3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,false);
m_pIDirect3DDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
m_pIDirect3DDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
//创建精灵
if(FAILED(D3DXCreateSprite(m_pIDirect3DDevice,&m_pSprite)))
return false;
return true;
}
大家可以看到关于场景初始化的部分有重复,我想用GameEngine_SceneManager里的Init()和SetRenderMode()函数对main里的场景初始化的部分进行代替,可是代替之后,骨骼动画就用不了了,问题是怎样对g_pIDirect3DDevice进行变换,有兴趣的朋友可以加我QQ:739880612
我可以把所有代码发给你
|
|