本文由zhangbaochong原創,轉載請註明出處:http://www.cnblogs.com/zhangbaochong/p/5788482.htmlhtml
如今directx已經再也不支持.x文件了,意味着D3DXLoadMeshFromX加載mesh的方法已經不能用了。要加載mesh除了本身解析文件外,最簡單的方法是利用微軟開源的工具DirectXTK中的Model類或者DXUT中的CDXUTSDKMesh類。這裏以DirectXTK爲例,看看如何加載的吧!git
DirectXTK中的Model類支持.sdkmesh和.cmo格式,因此下載的.obj、.fbx等格式的文件必須轉化成支持的格式才行。利用vs2015中的content pipeline能夠很方便的轉化成.cmo,下面是具體步驟:github
首先,右鍵項目->生成依賴項->生成自定義->勾上MeshContentTask->點擊okide
添加模型文件到項目工程中,這裏以.fbx文件爲例,右鍵模型文件,在常規中選擇Mesh Content Pipeline,而後肯定。函數
最後,右鍵模型選擇編譯,而後就能夠在Debug目錄下(若是沒改生成目錄)找到.cmo以及貼圖等相關文件了,是否是很簡單呢?工具
首先要去下載DirectXTK,而後在工程中添加引用。ui
用DirectXTK加載mesh其實很簡單,主要就是兩個步驟:加載和繪製。spa
加載須要調用Model類的一個方法,針對sdkmesh是CreateFromSDKMESH方法,針對cmo就是CreateFromCMO了。這裏以sdkmesh格式爲例,cmo與此相似再也不說明了。3d
CreateFromSDKMESH函數參數以下:指針
std::unique_ptr<Model> DirectX::Model::CreateFromSDKMESH( ID3D11Device* d3dDevice, const wchar_t* szFileName, IEffectFactory& fxFactory, bool ccw, bool pmalpha )
第一個參數是一個設備指針,第二個參數是模型路徑,第三個參數是一個IEffectFactory,後面兩個參數設爲true。
繪製時須要調用Model::Draw方法,參數以下:
1 Model::Draw( 2 ID3D11DeviceContext* deviceContext, 3 CommonStates& states, 4 FXMMATRIX world, 5 CXMMATRIX view, 6 CXMMATRIX projection, 7 bool wireframe, 8 std::function<void()> setCustomState )
第一個參數是設備上下文指針,第二個參數是CommonStates對象,接下來三個參數是world view proj矩陣,下個參數是是否採用線框模式繪製默認爲false,最後一個
參數默認爲nullptr。
下面是所有代碼,其中使用了上個教程實現的Camera:
MeshDemo.h
1 #pragma once 2 #include <memory> 3 #include "Dx11Base.h" 4 #include "CommonStates.h" 5 #include "Model.h" 6 #include "Effects.h" 7 #include "Camera.h" 8 9 class MeshDemo : public Dx11Base 10 { 11 public: 12 MeshDemo(HINSTANCE hInst, std::wstring title = L"BlendDemo", int width = 800, int height = 640); 13 ~MeshDemo(); 14 15 bool Init() override; 16 void Update(float dt); 17 void Render(); 18 19 bool OnResize() override; 20 21 void OnMouseDown(WPARAM btnState, int x, int y); 22 void OnMouseUp(WPARAM btnState, int x, int y); 23 void OnMouseMove(WPARAM btnState, int x, int y); 24 25 private: 26 bool BuildModels(); //建立mesh對象 27 private: 28 std::unique_ptr<Model> m_model; 29 std::unique_ptr<EffectFactory> m_fxFactory; 30 std::unique_ptr<CommonStates> m_states; 31 32 Camera m_camera; 33 34 XMFLOAT4X4 m_world; 35 XMFLOAT4X4 m_view; 36 XMFLOAT4X4 m_proj; 37 38 //鼠標控制參數 39 POINT m_lastMousePos; 40 };
MeshDemo.cpp
1 #include "MeshDemo.h" 2 #include "Utility.h" 3 using namespace DirectX; 4 5 MeshDemo::MeshDemo(HINSTANCE hInst, std::wstring title, int width, int height) 6 :Dx11Base(hInst,title,width,height) 7 { 8 XMVECTOR Eye = XMVectorSet(0.0f, 3.0f, -10.0f, 0.0f); 9 XMVECTOR At = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f); 10 XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); 11 m_camera.LookAtXM(Eye, At, Up); 12 //設置投影矩陣 13 m_camera.SetLens(XM_PIDIV4, AspectRatio(), 0.1f, 1000.f); 14 15 XMStoreFloat4x4(&m_world, XMMatrixIdentity()); 16 } 17 18 MeshDemo::~MeshDemo() 19 { 20 } 21 22 23 bool MeshDemo::Init() 24 { 25 if (!Dx11Base::Init()) 26 return false; 27 if (!BuildModels()) 28 return false; 29 return true; 30 } 31 32 void MeshDemo::Update(float dt) 33 { 34 //先後左右行走 35 if (KeyDown('A')) 36 { 37 m_camera.Strafe(-6.f*dt); 38 } 39 else if (KeyDown('D')) 40 { 41 m_camera.Strafe(6.f*dt); 42 } 43 if (KeyDown('W')) 44 { 45 m_camera.Walk(6.f*dt); 46 } 47 else if (KeyDown('S')) 48 { 49 m_camera.Walk(-6.f*dt); 50 } 51 m_camera.UpdateViewMatrix(); 52 53 XMStoreFloat4x4(&m_view, m_camera.GetView()); 54 XMStoreFloat4x4(&m_proj, m_camera.GetProj()); 55 } 56 57 void MeshDemo::Render() 58 { 59 m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, Colors::Silver); 60 m_pImmediateContext->ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); 61 62 XMVECTOR qid = XMQuaternionIdentity(); 63 const XMVECTORF32 scale = { 0.01f, 0.01f, 0.01f }; 64 const XMVECTORF32 translate = { 0.f, 0.f, 0.f }; 65 XMMATRIX world = XMLoadFloat4x4(&m_world); 66 XMVECTOR rotate = XMQuaternionRotationRollPitchYaw(0, XM_PI / 2.f, XM_PI / 2.f); 67 rotate = XMQuaternionRotationRollPitchYaw(0, XM_PI / 2.f, XM_PI / 2.f); 68 XMMATRIX local = XMMatrixMultiply(world, XMMatrixTransformation( 69 g_XMZero, qid, scale, g_XMZero, rotate, translate)); 70 local *= XMMatrixRotationZ(XM_PIDIV2); 71 m_model->Draw(m_pImmediateContext, *m_states, local, XMLoadFloat4x4(&m_view), 72 XMLoadFloat4x4(&m_proj)); 73 74 m_pSwapChain->Present(0, 0); 75 } 76 77 bool MeshDemo::OnResize() 78 { 79 if (!Dx11Base::OnResize()) 80 return false; 81 //更新camera參數 82 m_camera.SetLens(XM_PIDIV4, AspectRatio(), 1.f, 1000.f); 83 84 return true; 85 } 86 87 void MeshDemo::OnMouseDown(WPARAM btnState, int x, int y) 88 { 89 m_lastMousePos.x = x; 90 m_lastMousePos.y = y; 91 SetCapture(m_hWnd); 92 } 93 94 void MeshDemo::OnMouseUp(WPARAM btnState, int x, int y) 95 { 96 ReleaseCapture(); 97 } 98 99 void MeshDemo::OnMouseMove(WPARAM btnState, int x, int y) 100 { 101 if ((btnState & MK_LBUTTON) != 0) 102 { 103 float dx = XMConvertToRadians(0.25f*(x - m_lastMousePos.x)); 104 float dy = XMConvertToRadians(0.25f*(y - m_lastMousePos.y)); 105 106 m_camera.Pitch(dy); 107 m_camera.RotateY(dx); 108 } 109 110 m_lastMousePos.x = x; 111 m_lastMousePos.y = y; 112 } 113 114 bool MeshDemo::BuildModels() 115 { 116 m_fxFactory.reset(new EffectFactory(m_pd3dDevice)); 117 m_states.reset(new CommonStates(m_pd3dDevice)); 118 m_model = Model::CreateFromSDKMESH(m_pd3dDevice, L"tiny.sdkmesh", *m_fxFactory,true,true); 119 return true; 120 } 121 122 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow) 123 { 124 std::shared_ptr<Dx11Base> bd(new MeshDemo(hInstance)); 125 if (!bd->Init()) 126 return -1; 127 return bd->Run(); 128 }