Directx11学习笔记【二十】 使用DirectX Tool Kit加载mesh

  本文由zhangbaochong原创,转载请注明出处:http://www.cnblogs.com/zhangbaochong/p/5788482.html

  现在directx已经不再支持.x文件了,意味着D3DXLoadMeshFromX加载mesh的方法已经不能用了。要加载mesh除了自己解析文件外,最简单的方法是利用微软开源的工具DirectXTK中的Model类或者DXUT中的CDXUTSDKMesh类。这里以DirectXTK为例,看看如何加载的吧!

1.格式转化

  DirectXTK中的Model类支持.sdkmesh和.cmo格式,所以下载的.obj、.fbx等格式的文件必须转化成支持的格式才行。利用vs2015中的content pipeline可以很方便的转化成.cmo,下面是具体步骤:

  首先,右键项目->生成依赖项->生成自定义->勾上MeshContentTask->点击ok

  

  添加模型文件到项目工程中,这里以.fbx文件为例,右键模型文件,在常规中选择Mesh Content Pipeline,然后确定。

  

  最后,右键模型选择编译,然后就可以在Debug目录下(如果没改生成目录)找到.cmo以及贴图等相关文件了,是不是很简单呢?

2.加载Mesh

  首先要去下载DirectXTK,然后在工程中添加引用。

  用DirectXTK加载mesh其实很简单,主要就是两个步骤:加载和绘制。

  加载需要调用Model类的一个方法,针对sdkmesh是CreateFromSDKMESH方法,针对cmo就是CreateFromCMO了。这里以sdkmesh格式为例,cmo与此类似不再说明了。

  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.效果截图

  

posted @ 2016-08-19 17:39  zhangbaochong  阅读(3394)  评论(1编辑  收藏  举报