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

本文由zhangbaochong原创,转载请注明出处:

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

  

分类: Directx

时间: 2024-08-08 13:42:47

Directx11学习笔记【二十】 使用DirectX Tool Kit加载mesh的相关文章

马哥学习笔记二十四——分布式复制快设备drbd

DRBD: 主从 primary: 可执行读.写操作 secondary: 文件系统不能挂载 DRBD: dual primay, 双主(基于集群文件系统的高可用集群) 磁盘调度器:合并读请求,合并写请求: Procotol:drbd数据同步协议 A: Async, 异步  数据发送到本机tcp/ip协议栈 B:semi sync, 半同步  数据发送到对方tcp/ip协议 C:sync, 同步  数据到达对方存储设备 DRBD Source: DRBD资源 资源名称:可以是除了空白字符外的任意

【Unity 3D】学习笔记二十八:unity工具类

unity为开发者提供了很多方便开发的工具,他们都是由系统封装的一些功能和方法.比如说:实现时间的time类,获取随机数的Random.Range( )方法等等. 时间类 time类,主要用来获取当前的系统时间. using UnityEngine; using System.Collections; public class Script_04_13 : MonoBehaviour { void OnGUI() { GUILayout.Label("当前游戏时间:" + Time.t

angular学习笔记(二十八)-$http(6)-使用ngResource模块构建RESTful架构

ngResource模块是angular专门为RESTful架构而设计的一个模块,它提供了'$resource'模块,$resource模块是基于$http的一个封装.下面来看看它的详细用法 1.引入angular-resource.min.js文件 2.在模块中依赖ngResourece,在服务中注入$resource var HttpREST = angular.module('HttpREST',['ngResource']); HttpREST.factory('cardResource

Android学习笔记二十九之SwipeRefreshLayout、RecyclerView和CardView

Android学习笔记二十九之SwipeRefreshLayout.RecyclerView和CardView 前面我们介绍了AlertDialog和几个常用的Dialog,ProgressDialog进度条提示框.DatePickerDialog日期选择对话框和TimePickerDialog时间选择对话框.这一节我们介绍几个新的API控件SwipeRefreshLayout.RecyclerView和CardView,这几个API控件都是google在Android5.0推出的.下面我们来学

【Unity 3D】学习笔记二十六:unity游戏脚本(六)

在3D游戏世界中,任何一个游戏对象在创建的时候都会附带Transform(变换)组件,并且该组件是无法删除的,也不应该删除.在unity中,Transform面板一共有3个属性: Position  (位置) Rotation(旋转) Scale(缩放) 这三个值都是用来调整游戏对象在游戏界面中的位置,状态等相关参数. Position  (位置) 任何一个游戏对象的三维坐标都保存在Vector3容器中,该容器记录对象在X轴,Y轴,Z轴的坐标.一旦Vector33容器中的坐标发生变化,那么Sce

angular学习笔记(二十六)-$http(4)-设置请求超时

本篇主要讲解$http(config)的config中的timeout项: $http({ timeout: number }) 数值,从发出请求开始计算,等待的毫秒数,超过这个数还没有响应,则返回错误 demo: html: <!DOCTYPE html> <html ng-app = 'HttpGet'> <head> <title>18.4 $http(2)</title> <meta charset="utf-8"

【Unity 3D】学习笔记二十九:游戏实例——简单小地图制作

任何的学习,光看不练是学不好的.所以这次就总结回顾下怎么制作MMROPG类游戏中的小地图.在MMROPG类游戏里,主角在游戏世界里走动时,一般在屏幕右上角都会有一个区域来显示当前游戏场景的小地图.主角在游戏世界里走动,小地图里代表着主角的小标记也会随之移动.那怎么实现咧? 首先需要确定两个贴图,第一个是右上角的小地图背景贴图,应该是从Y轴俯视向下截取主角所在的位置大地图.第二个就是主角的位置大贴图.在本例中,因为没有学习unity地图制作,所以地图用一个面对象代替,主角用立方体代替,使用GUI来

Android学习笔记二十之Toast吐司、Notification通知、PopupWindow弹出窗

Android学习笔记二十之Toast吐司.Notification通知.PopupWindow弹出窗 Toast吐司 Toast吐司是我们经常用到的一个控件,Toast是AndroidOS用来显示消息的一种机制,它与Dialog不同,Toast不会获取到焦点,通常显示一段时间之后就会自动消失,下面我们来介绍Toast的几种常用方式: 第一种,默认显示方式,也是最常用的方式: Toast.makeText(MainActivity.this, "这是默认的显示方式", Toast.LE

马哥学习笔记二十五——ISCSI协议,架构及其安装配置

ISCSI监听在tcp/3260端口 iSCSI Target:iscsi-target-utils 客户端认正方式: 1.基于IP 2.基于用户,CHAP tgtadm:命令行工具,模式化命令 --mode 常用模式:target,logicalunit,account target --op new.delete.show.update.bind.unbind logicalunit --op new.delete account --op new.delete.bind.unbind --