DX骨骼动画,地形简单的演示

来源:互联网 发布:数据结构出栈算法程序 编辑:程序博客网 时间:2024/04/30 08:37

 给出主文件

头文件:

Code:
  1. //  
  2. //D3D主文件类  
  3. //作者:CYM  
  4. //  
  5. #pragma once  
  6. #include <d3dx9.h>  
  7. #include <string>  
  8. #include "D3DFrame.h"  
  9. #include "Model.h"  
  10. #include "Camera.h"  
  11. #include "Light.h"  
  12. #include "Material.h"  
  13. #include "Text.h"  
  14. #include "AllocateHierarchy.h"  
  15. #include "WorldMatrix.h"  
  16. #include "Terrain.h"  
  17. class CMain  
  18. {  
  19. public:  
  20.     CMain(void);  
  21.     ~CMain(void);  
  22.     bool Setup(void);  
  23.     bool Display(float fTimeDelta);  
  24.     bool Input(float timeDelta);  
  25.     void Cleanup(void);  
  26.   
  27. public:  
  28.     CModel* _Ship;      //模型飞船类  
  29.     Camera* _Camera;    //摄像机类  
  30.     CLight* _Light1;    //灯光类1  
  31.     CMaterial*  _Material1; //材质类1  
  32.     CText*  _Text1;     //文字类1  
  33.     CTerrain*   _pTerrain;  //地形对象1  
  34.   
  35.     //关于骨骼动画的数据  
  36.     LPD3DXFRAME _pFrameRoot;                        //根框架  
  37.     D3DXMATRIX* _pBoneMatrices;                     //骨骼的变化矩阵  
  38.     CAllocateHierarchy* _pAllocateHier;             //CAllocateHierarchy对象  
  39.     LPD3DXANIMATIONCONTROLLER   _pAnimController;   //动画控制器对象  
  40.     CWorldMatrix*   _pRoleMatrix;                       //人物骨骼动画的矩阵  
  41. };  

CPP文件

Code:
  1. //  
  2. //D3D主文件类  
  3. //作者:CYM  
  4. //  
  5. #include <d3d9.h>  
  6. #include <d3dx9.h>  
  7. #include <string>  
  8. #include "Main.h"  
  9. #include "D3DFrame.h"  
  10.   
  11. #ifndef SAFE_DELETE  
  12. #define SAFE_DELETE(p)       { if(p) { delete (p);     (p)=NULL; } }  
  13. #endif      
  14. #ifndef SAFE_DELETE_ARRAY  
  15. #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p);   (p)=NULL; } }  
  16. #endif      
  17. #ifndef SAFE_RELEASE  
  18. #define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } }  
  19. #endif  
  20.   
  21. //全局设置  
  22. IDirect3DDevice9* Device=NULL;   
  23. CD3DFrame D3DFrame;  
  24. CMain   Main;  
  25.   
  26. D3DMATERIAL9    Material1;  //材质 
  27. D3DLIGHT9   Light1;     //灯光  
  28. D3DXMATRIX  V;          //视图矩阵  
  29.   
  30. static D3DXVECTOR3 position( 0.0f, 100.0f, -140.0f );       //摄像机位置  
  31. static D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);            //摄像机观察目标  
  32. static D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);                //摄像机高度*/  
  33.   
  34. const int Width  = 640;     //窗口的宽高  
  35. const int Height = 480;  
  36.   
  37. CMain::CMain(void)  
  38. {  
  39.     _Ship=NULL;  
  40.     _Camera=NULL;  
  41.     _Light1=NULL;  
  42.     _Material1=NULL;  
  43.     _Text1=NULL;  
  44.     _pTerrain=NULL;  
  45.     _pAllocateHier=NULL;  
  46.     _pRoleMatrix=NULL;  
  47. }  
  48.   
  49.   
  50. CMain::~CMain(void)  
  51. {  
  52.     D3DFrame.Delete<CModel*>(_Ship);  
  53.     D3DFrame.Delete<Camera*>(_Camera);  
  54.     D3DFrame.Delete<CLight*>(_Light1);  
  55.     D3DFrame.Delete<CMaterial*>(_Material1);  
  56.     D3DFrame.Delete<CText*>(_Text1);  
  57.     D3DFrame.Delete<CAllocateHierarchy*>(_pAllocateHier);  
  58.     D3DFrame.Delete<CWorldMatrix*>(_pRoleMatrix);  
  59.     D3DFrame.Delete<CTerrain*>(_pTerrain);  
  60. }  
  61.   
  62.   
  63. bool CMain::Setup()  
  64. {  
  65.     _Ship = new CModel(Device);                     //创建_Ship  
  66.     _Camera = new Camera(Camera::AIRCRAFT);         //创建_Camera  
  67.     _Light1 = new CLight();                         //创建_Light1  
  68.     _Material1 = new CMaterial();                   //创建_Material(暂时无效,看不出效果因为被覆盖)  
  69.     _Text1= new CText(Device);                      //创建_Text1  
  70.     _pAllocateHier= new CAllocateHierarchy();       //创建_pAllocateHier  
  71.     _pRoleMatrix= new CWorldMatrix();               //创建_pRoleMatrix世界矩阵用于骨骼  
  72.     _pTerrain= new CTerrain(Device);                //创建_pTerrain地形对象  
  73.   
  74.     //载入模型  
  75.     _Ship->LoadMesh("Media//bigship1.x",D3DXMESH_MANAGED);  
  76.   
  77.     //设置摄像机的初始位置  
  78.     _Camera->SetPosition(&position);  
  79.     _Camera->SetLookAt(&target);  
  80.     _Camera->SetUp(&up);  
  81.   
  82.     //设置平行光  
  83.     _Light1->SetLightType(D3DLIGHT_DIRECTIONAL);  
  84.     //_Light1->SetLightPos(0.0f,3.0f,0.0f);  
  85.     _Light1->SetLightDir(1.0f,-1.0f,0.0f);  
  86.     _Light1->SetLightDiffuseCol(1.0f,1.0f,1.0f,1.0f);  
  87.     _Light1->SetLightSpecularCol(1.0f,1.0f,1.0f,1.0f);  
  88.     _Light1->SetLightAmbientCol(1.0f,1.0f,1.0f,1.0f);  
  89.     _Light1->GetLightStru(&Light1);  
  90.     Device->SetLight(0,&Light1);  
  91.     Device->LightEnable(0, true);  
  92.   
  93.     //设置材质(暂时无效,看不出效果因为被覆盖)  
  94.     _Material1->SetMaterialDiffuseCol(1.0f,1.0f,1.0f,1.0f);  
  95.     _Material1->SetMaterialAmbientCol(1.0f,1.0f,1.0f,1.0f);  
  96.     _Material1->SetMaterialEmissiveCol(1.0f,1.0f,1.0f,1.0f);  
  97.     _Material1->SetMaterialPower(1.0f);  
  98.     _Material1->GetMaterialStru(&Material1);  
  99.   
  100.     //创建字体  
  101.     RECT rect={10,10,110,110};  
  102.     _Text1->SetDrawRect(&rect);  
  103.     _Text1->SetFont(20,10,FW_BOLD);  
  104.     _Text1->SetFontCol(D3DXCOLOR(1.0,0.0f,0.0f,1.0f));  
  105.     _Text1->CreateFontA();  
  106.   
  107.     //载入X文件  
  108.     D3DXLoadMeshHierarchyFromX("Model//warrior.x",D3DXMESH_MANAGED,Device,  
  109.         _pAllocateHier,NULL,&_pFrameRoot,&_pAnimController);  
  110.     //设置好各级框架的组合矩阵  
  111.     SetupBoneMatrixPointers(_pFrameRoot,_pFrameRoot);  
  112.   
  113.     //加载地形的高度图,和纹理  
  114.     _pTerrain->LoadTerrain("Media//mountain.raw","Media//desert.bmp");  
  115.     //初始化地形  
  116.     _pTerrain->InitTerrain(64,64,10.0f,0.4f);  
  117.   
  118.   
  119.     //设置投影矩阵  
  120.     D3DXMATRIX proj;  
  121.     D3DXMatrixPerspectiveFovLH(  
  122.             &proj,  
  123.             D3DX_PI * 0.5f, // 90 - degree  
  124.             (float)Width / (float)Height,  
  125.             1.0f,  
  126.             1000.0f);  
  127.     Device->SetTransform(D3DTS_PROJECTION, &proj);  
  128.   
  129.      //设置光照  
  130.     Device->SetRenderState(D3DRS_LIGHTING, true);  
  131.     Device->SetRenderState(D3DRS_AMBIENT, D3DXCOLOR(0.4f, 0.4f, 0.4f, 1.0f));  
  132.     Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW/*D3DCULL_NONE*/);  // 剔除背面  
  133.     Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);   //正常的渲染等级  
  134.     Device->SetRenderState(D3DRS_SPECULARENABLE, true);     //镜面高光  
  135.     return true;  
  136. }  
  137.   
  138. void CMain::Cleanup()  
  139. {  
  140.     D3DFrame.Release<IDirect3DDevice9*>(Device);  
  141.     D3DXFrameDestroy(_pFrameRoot,_pAllocateHier);  
  142.     D3DFrame.Release<LPD3DXANIMATIONCONTROLLER>(_pAnimController);  
  143. }  
  144.   
  145.   
  146. bool CMain::Display(float fTimeDelta)  
  147. {  
  148.     if( Device )   
  149.     {  
  150.         //外部输入设备消息处理  
  151.         Input(fTimeDelta);  
  152.   
  153.         // Instruct the device to set each pixel on the back buffer black -  
  154.         // D3DCLEAR_TARGET: 0x00000000 (black) - and to set each pixel on  
  155.         // the depth buffer to a value of 1.0 - D3DCLEAR_ZBUFFER: 1.0f.  
  156.         Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DXCOLOR(0.0,0.0,0.0,1.0), 1.0f, 0);  
  157.         Device->BeginScene();  
  158.           
  159.         //*灯光效果测试  
  160.         //Device->SetLight(0,&Light1);  
  161.         //***********  
  162.   
  163.         //*材质类效果测试
  164.         Device->SetMaterial(&Material1);  
  165.         //***********  
  166.   
  167.         //*绘制文本  
  168.         RECT    Rect={10,10,110,110};  
  169.         _Text1->SetDrawRect(&Rect);  
  170.         _Text1->DrawTextA("dx简单的测试程序(角色已死亡)");  
  171.   
  172.         Rect.top=30;  
  173.         _Text1->SetDrawRect(&Rect);  
  174.         _Text1->DrawTextA("按1:站立");  
  175.   
  176.         Rect.top=50;  
  177.         _Text1->SetDrawRect(&Rect);  
  178.         _Text1->DrawTextA(" 2:行走");  
  179.   
  180.         Rect.top=70;  
  181.         _Text1->SetDrawRect(&Rect);  
  182.         _Text1->DrawTextA(" 3:进攻");  
  183.   
  184.         Rect.top=90;  
  185.         _Text1->SetDrawRect(&Rect);  
  186.         _Text1->DrawTextA(" 4:受伤");  
  187.   
  188.         Rect.top=110;  
  189.         _Text1->SetDrawRect(&Rect);  
  190.         _Text1->DrawTextA(" 5:死亡瞬间");  
  191.   
  192.         Rect.top=130;  
  193.         _Text1->SetDrawRect(&Rect);  
  194.         _Text1->DrawTextA(" 6:死亡");  
  195.         //**********  
  196.   
  197.         //绘制飞船  
  198.         _Ship->DrawMesh(D3DXVECTOR3(20.0f,10.0f,0.0f),D3DXVECTOR3(0.0f,0.0f,0.0f),D3DXVECTOR3(5.0f,5.0f,5.0f));  
  199.   
  200.   
  201.         //角色的世界矩阵操作变化  
  202.         // 控制运动方向  
  203.         static FLOAT fMoveAngle = 180.0f;  
  204.         static D3DXVECTOR3 vRolePos = D3DXVECTOR3(0.0f, 2.0f, 0.0f);  
  205.         if (::GetAsyncKeyState('A') & 0x8000f) fMoveAngle += 0.01f;  
  206.         if (::GetAsyncKeyState('D') & 0x8000f) fMoveAngle -= 0.01f;  
  207.   
  208.         // 设置世界变换矩阵  
  209.         D3DXMATRIX  matRole;  
  210.         D3DXMatrixIdentity(&matRole);  
  211.         _pRoleMatrix->Scale(0.5f,0.5f,0.5f);  
  212.         _pRoleMatrix->Rotate(0,fMoveAngle,0);  
  213.         matRole=*_pRoleMatrix->GetMatrix();  
  214.   
  215.         // 更新骨骼动画  
  216.         Device->SetTransform(D3DTS_WORLD, &matRole);  
  217.         _pAnimController->AdvanceTime(fTimeDelta, NULL);  
  218.         UpdateFrameMatrices(_pFrameRoot, &matRole);  
  219.         // 绘制蒙皮网格  
  220.         DrawFrame(Device, _pFrameRoot);  
  221.   
  222.         //渲染地形(暂时关闭灯光)  
  223.         Device->SetRenderState(D3DRS_LIGHTING, false);  
  224.         D3DXMATRIX  matTerrain;  
  225.         //D3DXMatrixIdentity(&matTerrain);  
  226.         D3DXMatrixTranslation(&matTerrain,0.0f,-50.0f,0.0f);  
  227.         _pTerrain->DrawTerrain(&matTerrain,FALSE);  
  228.         Device->SetRenderState(D3DRS_LIGHTING,true);  
  229.   
  230.         //设置视觉矩阵  
  231.         _Camera->GetViewMatrix(&V);  
  232.         Device->SetTransform(D3DTS_VIEW, &V);  
  233.   
  234.         Device->EndScene();  
  235.   
  236.         // Swap the back and front buffers.  
  237.         Device->Present(0, 0, 0, 0);  
  238.     }  
  239.     return true;  
  240. }  
  241.   
  242.   
  243. //外部设备输出处理函数  
  244. bool CMain::Input(float timeDelta)  
  245. {  
  246.         // Update: Update the camera.  
  247.         //移动摄像机  
  248.         if( ::GetAsyncKeyState('W') & 0x8000f )  
  249.             _Camera->Walk(0.04f);  
  250.   
  251.         if( ::GetAsyncKeyState('S') & 0x8000f )  
  252.             _Camera->Walk(-0.04f);  
  253.   
  254.         if( ::GetAsyncKeyState('A') & 0x8000f )  
  255.             _Camera->Strafe(-0.04f);  
  256.   
  257.         if( ::GetAsyncKeyState('D') & 0x8000f )  
  258.             _Camera->Strafe(0.04f);  
  259.   
  260.         if( ::GetAsyncKeyState('R') & 0x8000f )  
  261.             _Camera->Fly(0.04f);  
  262.   
  263.         if( ::GetAsyncKeyState('F') & 0x8000f )  
  264.             _Camera->Fly(-0.04f);  
  265.   
  266.         //旋转摄像机  
  267.         if( ::GetAsyncKeyState(VK_UP) & 0x8000f )  
  268.             _Camera->Pitch(0.0004f);  
  269.   
  270.         if( ::GetAsyncKeyState(VK_DOWN) & 0x8000f )  
  271.             _Camera->Pitch(-0.0004f);  
  272.   
  273.         if( (::GetAsyncKeyState('Q') & 0x8000f) || (::GetAsyncKeyState(VK_LEFT) & 0x8000f) )  
  274.             _Camera->Yaw(-0.0008f);  
  275.               
  276.         if( (::GetAsyncKeyState('E') & 0x8000f) || (::GetAsyncKeyState(VK_RIGHT) & 0x8000f) )  
  277.             _Camera->Yaw(0.0008f);  
  278.   
  279.         if( ::GetAsyncKeyState('N') & 0x8000f )  
  280.             _Camera->Roll(-0.0004f);  
  281.   
  282.         if( ::GetAsyncKeyState('M') & 0x8000f )  
  283.             _Camera->Roll(0.0004f);  
  284.         // Update the view matrix representing the cameras   
  285.         // new position/orientation.  
  286.   
  287.         //控制骨骼动画的播放  
  288.         static float fCurrTime=0.0f;  
  289.         fCurrTime+=timeDelta;  
  290.         LPD3DXANIMATIONSET pAnimationSet = NULL;  
  291.         if (::GetAsyncKeyState(0x31) & 0x8000f)   
  292.         {  
  293.             //fMoveSpeed = 0.0f;  
  294.             _pAnimController->GetAnimationSetByName("stay", &pAnimationSet);  
  295.             SmoothChangeAnimation(_pAnimController, pAnimationSet, fCurrTime);  
  296.         }  
  297.         if (::GetAsyncKeyState(0x32) & 0x8000f)  
  298.         {  
  299.             //fMoveSpeed = 0.8f;  
  300.             _pAnimController->GetAnimationSetByName("walk", &pAnimationSet);  
  301.             SmoothChangeAnimation(_pAnimController, pAnimationSet, fCurrTime);  
  302.         }  
  303.         if (::GetAsyncKeyState(0x33) & 0x8000f)   
  304.         {  
  305.             //fMoveSpeed = 0.0f;  
  306.             _pAnimController->GetAnimationSetByName("attack", &pAnimationSet);  
  307.             SmoothChangeAnimation(_pAnimController, pAnimationSet, fCurrTime);  
  308.         }  
  309.         if (::GetAsyncKeyState(0x34) & 0x8000f)  
  310.         {  
  311.             //fMoveSpeed = 0.0f;  
  312.             _pAnimController->GetAnimationSetByName("behit", &pAnimationSet);  
  313.             SmoothChangeAnimation(_pAnimController, pAnimationSet, fCurrTime);  
  314.         }  
  315.         if (::GetAsyncKeyState(0x35) & 0x8000f)   
  316.         {  
  317.             //fMoveSpeed = 0.0f;  
  318.             _pAnimController->GetAnimationSetByName("dieing", &pAnimationSet);  
  319.             SmoothChangeAnimation(_pAnimController, pAnimationSet, fCurrTime);  
  320.         }  
  321.         if (::GetAsyncKeyState(0x36) & 0x8000f)   
  322.         {  
  323.             //fMoveSpeed = 0.0f;  
  324.             _pAnimController->GetAnimationSetByName("dead", &pAnimationSet);  
  325.             SmoothChangeAnimation(_pAnimController, pAnimationSet, fCurrTime);  
  326.         }  
  327.   
  328.         SAFE_RELEASE(pAnimationSet);  
  329.   
  330.         return true;  
  331. }  
  332.   
  333.   
  334. //  
  335. //应用程序入口函数  
  336. //  
  337.   
  338. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);  
  339.   
  340. int WINAPI WinMain(HINSTANCE hinstance,  
  341.                    HINSTANCE prevInstance,   
  342.                    PSTR cmdLine,  
  343.                    int showCmd)  
  344. {  
  345.     //定义和初始化窗口类  
  346.     WNDCLASS wc;  
  347.     wc.style         = CS_HREDRAW | CS_VREDRAW;  
  348.     wc.lpfnWndProc   = WndProc;  
  349.     wc.cbClsExtra    = 0;  
  350.     wc.cbWndExtra    = 0;  
  351.     wc.hInstance     = hinstance;  
  352.     wc.hIcon         = LoadIcon(0, IDI_APPLICATION);  
  353.     wc.hCursor       = LoadCursor(0, IDC_ARROW);  
  354.     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);  
  355.     wc.lpszMenuName  = 0;  
  356.     wc.lpszClassName = "Direct3D9App";  
  357.   
  358.     //初始化窗口  
  359.     if(!D3DFrame.InitD3D(wc,  
  360.         640, 480, true, D3DDEVTYPE_HAL, &Device))  
  361.     {  
  362.         ::MessageBox(0, "InitD3D() - FAILED", 0, 0);  
  363.         return 0;  
  364.     }  
  365.       
  366.     //加载需要用到的资源  
  367.     if(!Main.Setup())  
  368.     {  
  369.         ::MessageBox(0, "Setup() - FAILED", 0, 0);  
  370.         return 0;  
  371.     }  
  372.   
  373.     //进入消息循环  
  374.     MSG msg;  
  375.     ZeroMemory(&msg, sizeof(msg));  
  376.     while(msg.message != WM_QUIT)  
  377.         {  
  378.             if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))  
  379.                 {  
  380.                     TranslateMessage(&msg);  
  381.                     DispatchMessage(&msg);  
  382.                 }  
  383.             else  
  384.             {  
  385.                 static FLOAT fLastTime  = (float)::timeGetTime();  
  386.                 static FLOAT fCurrTime  = (float)::timeGetTime();  
  387.                 static FLOAT fTimeDelta = 0.0f;  
  388.                 fCurrTime  = (float)::timeGetTime();  
  389.                 fTimeDelta = (fCurrTime - fLastTime) / 1000.0f;  
  390.                 fLastTime  = fCurrTime;  
  391.                   
  392.                 Main.Display(fTimeDelta);       //渲染要显示的动画  
  393.             }  
  394.          }  
  395.   
  396.     //结束释放资源  
  397.     Main.Cleanup();  
  398.   
  399.     return 0;  
  400. }  
  401.   
  402. //  
  403. // 消息响应函数  
  404. //  
  405. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)  
  406. {  
  407.     switch( msg )  
  408.     {  
  409.     case WM_DESTROY:  
  410.         ::PostQuitMessage(0);  
  411.         break;  
  412.     case WM_KEYDOWN:  
  413.         if( wParam == VK_ESCAPE )  
  414.             ::DestroyWindow(hwnd);  
  415.         break;  
  416.     }  
  417.     return ::DefWindowProc(hwnd, msg, wParam, lParam);  
  418. }  

 

原创粉丝点击