zoukankan      html  css  js  c++  java
  • 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.效果截图

      

  • 相关阅读:
    利用iframe实现ajax 跨域通信的解决方案
    C++中事件机制的简洁实现
    java远程类加载与轻客户端
    iOS开发那些事性能优化–内存泄露问题的解决
    Asp.net项目的开发流程
    LVS配置教程
    PowerShell之东扯西谈
    响应式设计专题
    2013年最值得关注的网页设计流行趋势
    HTTP Live Streaming直播技术分析与实现
  • 原文地址:https://www.cnblogs.com/zhangbaochong/p/5788482.html
Copyright © 2011-2022 走看看