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方法,参数如下:
Model::Draw(
ID3D11DeviceContext* deviceContext,
CommonStates& states,
FXMMATRIX world,
CXMMATRIX view,
CXMMATRIX projection,
bool wireframe,
std::function<void()> setCustomState )
第一个参数是设备上下文指针,第二个参数是CommonStates对象,接下来三个参数是world view proj矩阵,下个参数是是否采用线框模式绘制默认为false,最后一个
参数默认为nullptr。
下面是全部代码,其中使用了上个教程实现的Camera:
MeshDemo.h
#pragma once
#include <memory>
#include "Dx11Base.h"
#include "CommonStates.h"
#include "Model.h"
#include "Effects.h"
#include "Camera.h" class MeshDemo : public Dx11Base
{
public:
MeshDemo(HINSTANCE hInst, std::wstring title = L"BlendDemo", int width = , int height = );
~MeshDemo(); bool Init() override;
void Update(float dt);
void Render(); bool OnResize() override; void OnMouseDown(WPARAM btnState, int x, int y);
void OnMouseUp(WPARAM btnState, int x, int y);
void OnMouseMove(WPARAM btnState, int x, int y); private:
bool BuildModels(); //创建mesh对象
private:
std::unique_ptr<Model> m_model;
std::unique_ptr<EffectFactory> m_fxFactory;
std::unique_ptr<CommonStates> m_states; Camera m_camera; XMFLOAT4X4 m_world;
XMFLOAT4X4 m_view;
XMFLOAT4X4 m_proj; //鼠标控制参数
POINT m_lastMousePos;
};
MeshDemo.cpp
#include "MeshDemo.h"
#include "Utility.h"
using namespace DirectX; MeshDemo::MeshDemo(HINSTANCE hInst, std::wstring title, int width, int height)
:Dx11Base(hInst,title,width,height)
{
XMVECTOR Eye = XMVectorSet(0.0f, 3.0f, -10.0f, 0.0f);
XMVECTOR At = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
m_camera.LookAtXM(Eye, At, Up);
//设置投影矩阵
m_camera.SetLens(XM_PIDIV4, AspectRatio(), 0.1f, .f); XMStoreFloat4x4(&m_world, XMMatrixIdentity());
} MeshDemo::~MeshDemo()
{
} bool MeshDemo::Init()
{
if (!Dx11Base::Init())
return false;
if (!BuildModels())
return false;
return true;
} void MeshDemo::Update(float dt)
{
//前后左右行走
if (KeyDown('A'))
{
m_camera.Strafe(-.f*dt);
}
else if (KeyDown('D'))
{
m_camera.Strafe(.f*dt);
}
if (KeyDown('W'))
{
m_camera.Walk(.f*dt);
}
else if (KeyDown('S'))
{
m_camera.Walk(-.f*dt);
}
m_camera.UpdateViewMatrix(); XMStoreFloat4x4(&m_view, m_camera.GetView());
XMStoreFloat4x4(&m_proj, m_camera.GetProj());
} void MeshDemo::Render()
{
m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, Colors::Silver);
m_pImmediateContext->ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, ); XMVECTOR qid = XMQuaternionIdentity();
const XMVECTORF32 scale = { 0.01f, 0.01f, 0.01f };
const XMVECTORF32 translate = { .f, .f, .f };
XMMATRIX world = XMLoadFloat4x4(&m_world);
XMVECTOR rotate = XMQuaternionRotationRollPitchYaw(, XM_PI / .f, XM_PI / .f);
rotate = XMQuaternionRotationRollPitchYaw(, XM_PI / .f, XM_PI / .f);
XMMATRIX local = XMMatrixMultiply(world, XMMatrixTransformation(
g_XMZero, qid, scale, g_XMZero, rotate, translate));
local *= XMMatrixRotationZ(XM_PIDIV2);
m_model->Draw(m_pImmediateContext, *m_states, local, XMLoadFloat4x4(&m_view),
XMLoadFloat4x4(&m_proj)); m_pSwapChain->Present(, );
} bool MeshDemo::OnResize()
{
if (!Dx11Base::OnResize())
return false;
//更新camera参数
m_camera.SetLens(XM_PIDIV4, AspectRatio(), .f, .f); return true;
} void MeshDemo::OnMouseDown(WPARAM btnState, int x, int y)
{
m_lastMousePos.x = x;
m_lastMousePos.y = y;
SetCapture(m_hWnd);
} void MeshDemo::OnMouseUp(WPARAM btnState, int x, int y)
{
ReleaseCapture();
} void MeshDemo::OnMouseMove(WPARAM btnState, int x, int y)
{
if ((btnState & MK_LBUTTON) != )
{
float dx = XMConvertToRadians(0.25f*(x - m_lastMousePos.x));
float dy = XMConvertToRadians(0.25f*(y - m_lastMousePos.y)); m_camera.Pitch(dy);
m_camera.RotateY(dx);
} m_lastMousePos.x = x;
m_lastMousePos.y = y;
} bool MeshDemo::BuildModels()
{
m_fxFactory.reset(new EffectFactory(m_pd3dDevice));
m_states.reset(new CommonStates(m_pd3dDevice));
m_model = Model::CreateFromSDKMESH(m_pd3dDevice, L"tiny.sdkmesh", *m_fxFactory,true,true);
return true;
} int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow)
{
std::shared_ptr<Dx11Base> bd(new MeshDemo(hInstance));
if (!bd->Init())
return -;
return bd->Run();
}
3.效果截图

Directx11学习笔记【二十】 使用DirectX Tool Kit加载mesh的更多相关文章
- python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码
python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...
- python3.4学习笔记(二十五) Python 调用mysql redis实例代码
python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...
- python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法
python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...
- python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字
python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字在字符串里面插入指定分割符的方法,先把字符串变成list然后用join方法变成字符串str=' ...
- python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法
python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法 在Python中字符串处理函数里有三个去空格(包括'\n', '\r', '\t', ' ')的函数 ...
- Android 学习笔记之Volley(七)实现Json数据加载和解析...
学习内容: 1.使用Volley实现异步加载Json数据... Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...
- Redis深入学习笔记(一)Redis启动数据加载流程
这两年使用Redis从单节点到主备,从主备到一主多从,再到现在使用集群,碰到很多坑,所以决定深入学习下Redis工作原理并予以记录. 本系列主要记录了Redis工作原理的一些要点,当然配置搭建和使用这 ...
- Java基础学习笔记二十六 JDBC
什么是JDBC JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库.原来我们操作数据库是在控制台使用SQL语句来操作数据库,J ...
- (C/C++学习笔记) 二十四. 知识补充
二十四. 知识补充 ● 子类调用父类构造函数 ※ 为什么子类要调用父类的构造函数? 因为子类继承父类,会继承到父类中的数据,所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程. ...
随机推荐
- map size mismatch; abort
数据库启动时有莫名的提示map size mismatch; abort 原帖在这里:http://t.askmaclean.com/thread-1397-1-1.html 今天帮网友(centos ...
- Android ARM汇编语言
简介 ARM是Advanced RISC Machine的首字母缩写,它可以称之为一家嵌入式处理器的提供商,也可以理解为一种处理器的架构,还可以将它作为一套完整的处理器指令集. 原生程序与ARM汇编语 ...
- Android开发四大组件概述
这个文章主要是讲Android开发的四大组件,本文主要分为 一.Activity具体解释 二.Service具体解释 三.Broadcast Receiver具体解释 四.Content Provid ...
- spring-bean属性配置解析
autowire属性值有 byName 根据Bean定义时的“id"属性上指定的别名与Setter名称是否一致进行自动装配 byType 根据PoJo的setXXX()方法所接受的类型判断b ...
- SE 2014年5月23日
两站点 A 和 B,由于业务往来需要,所以工程师提出vpn技术,同时需要保证业务流在internet上的安全性,同时在这里站点均为固定ip地址. 通过分析以上信息,确定这里使用 IPSec VPN的主 ...
- poj1947(树形dp)
题目链接:http://poj.org/problem?id=1947 题意:给n(n<=150)个点的一棵树,求删掉最少边数k使得最后该树只剩下p(1<=p<=n)个节点.(求最小 ...
- bloom filter与dawgdic(一种trie树)
我有一个做了一款移动浏览器的朋友. 他有这样一个需求:当用户输入一个站点的url时候.移动浏览器须要识别这个网址是否是一个恶意网址.另外.他有一个恶意网址库. 或许这种解决方法有多种. 当中一种就是把 ...
- 泛泰A850 (高通8064+720p)刷4.4专用中文recovery TWRP2.7.1.3版
欢迎关注泛泰非盈利专业第三方开发团队 VegaDevTeam (本team 由 syhost suky zhaochengw(z大) xuefy(大星星) tenfar(R大师) loogeo cr ...
- Extjs4.10Model模型具体解释
一.创建Model模型 Extjs4.10提供了两种方法来创建Model模型,也就是创建类 方法一: Ext.define('person',{ extend:'Ext.da ...
- 有关信息ACM/ICPC竞争环境GCC/G++叠插件研究记录的扩展
0.起因 有时.DFS总是比BFS受人喜爱--毕竟DFS简单粗暴,更,而有些东西BFS不要启动,DFS它似乎是一个可行的选择-- 但是有一个问题,DFS默认直接写入到系统堆栈.系统堆栈和足够浅,此时O ...