Directx11學習筆記【二十】 使用DirectX Tool Kit加載mesh

  本文由zhangbaochong原創,轉載請註明出處:http://www.cnblogs.com/zhangbaochong/p/5788482.htmlhtml

  如今directx已經再也不支持.x文件了,意味着D3DXLoadMeshFromX加載mesh的方法已經不能用了。要加載mesh除了本身解析文件外,最簡單的方法是利用微軟開源的工具DirectXTK中的Model類或者DXUT中的CDXUTSDKMesh類。這裏以DirectXTK爲例,看看如何加載的吧!git

1.格式轉化

  DirectXTK中的Model類支持.sdkmesh和.cmo格式,因此下載的.obj、.fbx等格式的文件必須轉化成支持的格式才行。利用vs2015中的content pipeline能夠很方便的轉化成.cmo,下面是具體步驟:github

  首先,右鍵項目->生成依賴項->生成自定義->勾上MeshContentTask->點擊okide

  

  添加模型文件到項目工程中,這裏以.fbx文件爲例,右鍵模型文件,在常規中選擇Mesh Content Pipeline,而後肯定。函數

  

  最後,右鍵模型選擇編譯,而後就能夠在Debug目錄下(若是沒改生成目錄)找到.cmo以及貼圖等相關文件了,是否是很簡單呢?工具

2.加載Mesh

  首先要去下載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 }

3.效果截圖

  

相關文章
相關標籤/搜索