配置FBX_SDK

1.介绍

FBX格式是现在最主流的用于游戏的3D模型格式,要使用DirectX12绘制模型,当然需要先用这个库来解析模型数据。它的版权协议如下:

不是开源的并且是非商用的,假设你完成了一个引擎到时候还需要联系他们讨论版权的问题,不过前提是你想盈利。出于研究技术的目的,所以不用考虑这么多,大不了到时候再换一个格式即可。

先在官网下载对应的安装文件:

https://www.autodesk.com/developer-network/platform-technologies/fbx-sdk-2020-2

我现在用上了vs2019,所以下载的是2020.2 vs2019的版本。

2.复制文件

安装之后就有include和lib文件了,同时也要拷贝上License文件到我们的项目里。如下:

所以附加包含目录如下:

$(SolutionDir)\FBX_SDK\include

库目录如下:

$(SolutionDir)FBX_SDK\lib\vs2019\$(PlatformName)\$(Configuration)

由于$(PlatformName)返回的平台名是Win32,而不是x86,所以需要改一下文件夹的名字,如下:

最后附加依赖项添加上:

libfbxsdk.lib

官网的教程说还需要加上预处理器定义FBXSDK_SHARED,因为我们是以动态链接的方式使用的。所以dll文件还需要拷贝一下,是在exe目录:

3.准备一个茶壶

用3ds max创建一个茶壶并导出fbx格式的文件,当然也可以用网上找别人的fbx文件,不过我想从最简单的一步一步做起这样不容易出错,我用的3ds max 2021。

导出fbx拷贝到对应的资源目录(这里还包含上一章的shader文件,和生成的log文件):

4.示例代码

我先快速的测试官方给出的示例代码,这样更方便理解并测试有没有配置成功:

DNDFBX.h

/**
* @file        DNDFBX.h
* @brief   用于封装FBX SDK解析FBX文件
*
*
* @version 1.0
* @author  lveyou
* @date        21_03_27
* 修订说明:  1
*/#pragma once#include <fbxsdk.h>#include "DNDDebug.h"namespace DND
{/*** Print the required number of tabs.*/void PrintTabs();/*** Return a string-based representation based on the attribute type.*/FbxString GetAttributeTypeName(FbxNodeAttribute::EType type);/*** Print an attribute.*/void PrintAttribute(FbxNodeAttribute* pAttribute);/*** Print a node, its attributes, and all its children recursively.*/void PrintNode(FbxNode* pNode);class DNDFBX{public:void _init();private:FbxManager* _lSdkManager;};extern DNDFBX g_fbx;
}

DNDFBX.cpp

#include "DNDFBX.h"
#include "DNDString.h"namespace DND
{DNDFBX g_fbx;/* Tab character ("\t") counter */int numTabs = 0;void PrintTabs(){for (int i = 0; i < numTabs; i++){g_debug.Write(L"\t");}}FbxString GetAttributeTypeName(FbxNodeAttribute::EType type){switch (type) {case FbxNodeAttribute::eUnknown: return "unidentified";case FbxNodeAttribute::eNull: return "null";case FbxNodeAttribute::eMarker: return "marker";case FbxNodeAttribute::eSkeleton: return "skeleton";case FbxNodeAttribute::eMesh: return "mesh";case FbxNodeAttribute::eNurbs: return "nurbs";case FbxNodeAttribute::ePatch: return "patch";case FbxNodeAttribute::eCamera: return "camera";case FbxNodeAttribute::eCameraStereo: return "stereo";case FbxNodeAttribute::eCameraSwitcher: return "camera switcher";case FbxNodeAttribute::eLight: return "light";case FbxNodeAttribute::eOpticalReference: return "optical reference";case FbxNodeAttribute::eOpticalMarker: return "marker";case FbxNodeAttribute::eNurbsCurve: return "nurbs curve";case FbxNodeAttribute::eTrimNurbsSurface: return "trim nurbs surface";case FbxNodeAttribute::eBoundary: return "boundary";case FbxNodeAttribute::eNurbsSurface: return "nurbs surface";case FbxNodeAttribute::eShape: return "shape";case FbxNodeAttribute::eLODGroup: return "lodgroup";case FbxNodeAttribute::eSubDiv: return "subdiv";default: return "unknown";}}void PrintAttribute(FbxNodeAttribute* pAttribute){if (!pAttribute) return;FbxString typeName = GetAttributeTypeName(pAttribute->GetAttributeType());FbxString attrName = pAttribute->GetName();PrintTabs();// Note: to retrieve the character array of a FbxString, use its Buffer() method.//printf(, );//g_debug.Line(String::Format(L"<attribute type='%s' name='%s'/>", String::Mbtowc(typeName.Buffer()).c_str(), String::Mbtowc(attrName.Buffer()).c_str()));}void PrintNode(FbxNode* pNode){PrintTabs();const char* nodeName = pNode->GetName();FbxDouble3 translation = pNode->LclTranslation.Get();FbxDouble3 rotation = pNode->LclRotation.Get();FbxDouble3 scaling = pNode->LclScaling.Get();// Print the contents of the node.g_debug.Line(String::Format(L"<node name='%s' translation='(%f, %f, %f)' rotation='(%f, %f, %f)' scaling='(%f, %f, %f)'>",String::Mbtowc(nodeName).c_str(),translation[0], translation[1], translation[2],rotation[0], rotation[1], rotation[2],scaling[0], scaling[1], scaling[2]));numTabs++;// Print the node's attributes.for (int i = 0; i < pNode->GetNodeAttributeCount(); i++)PrintAttribute(pNode->GetNodeAttributeByIndex(i));// Recursively print the children.for (int j = 0; j < pNode->GetChildCount(); j++)PrintNode(pNode->GetChild(j));numTabs--;PrintTabs();g_debug.Line(L"</node>");}void DNDFBX::_init(){// Change the following filename to a suitable filename value.const char* lFilename = "teapot.fbx";// Initialize the SDK manager. This object handles all our memory management._lSdkManager = FbxManager::Create();// Create the IO settings object.FbxIOSettings* ios = FbxIOSettings::Create(_lSdkManager, IOSROOT);_lSdkManager->SetIOSettings(ios);// Create an importer using the SDK manager.FbxImporter* lImporter = FbxImporter::Create(_lSdkManager, "");// Use the first argument as the filename for the importer.if (!lImporter->Initialize(lFilename, -1, _lSdkManager->GetIOSettings())) {g_debug.Line(L"Call to FbxImporter::Initialize() failed.");g_debug.Line(String::Mbtowc((string("Error returned: ") + string(lImporter->GetStatus().GetErrorString())).c_str(), false));auto v = lImporter->GetStatus().GetCode();exit(-1);}// Create a new scene so that it can be populated by the imported file.FbxScene* lScene = FbxScene::Create(_lSdkManager, "myScene");// Import the contents of the file into the scene.lImporter->Import(lScene);// The file is imported; so get rid of the importer.lImporter->Destroy();// Print the nodes of the scene and their attributes recursively.// Note that we are not printing the root node because it should// not contain any attributes.FbxNode* lRootNode = lScene->GetRootNode();if (lRootNode) {for (int i = 0; i < lRootNode->GetChildCount(); i++)PrintNode(lRootNode->GetChild(i));}// Destroy the SDK manager and all the other objects it was handling._lSdkManager->Destroy();return;}}

前面几个函数均是读取数据并打印,而_init函数是最基础的使用方式,其中lImporter->Initialize总是失败,我一直以为是我导出的fbx文件设置不对,实际上只是文件放错位置了,没有读取到文件。但是它错误提示竟然是Unexpected file type,很坑人啊。最后成功的打印出了一些数据。

下一步我的目标就是用DirectX12绘制出这个茶壶!

【DirectX12】3.配置FBX_SDK相关推荐

  1. 【DirectX12】4.用FBX_SDK读取网格数据

    用FBX_SDK读取网格数据 1.前言 前一篇讲了如何配置FBX_SDK,这一篇来看如何读取模型的网格数据,效果如下: 2.导出 首先随便创建一个场景,然后导出: 在导出的时候勾选上三角算法,将网格全 ...

  2. DirectX12(D3D12)基础教程(四)——初识DirectXMath库、使用独立堆创建常量缓冲、理解管线状态对象、理解围栏同步

    目录 1.前言及本章内容提要 2.初识DirectXMath库 3.使用独立堆创建常量缓冲 4.理解管线状态对象 5.理解围栏同步 6.完整代码 1.前言及本章内容提要 经过了之前3篇教程的跨度有点大 ...

  3. DirectX12 之HelloWorld

    DirectX12 之HelloWorld 如果用DX12书写一个最基础的图形程序,一个仅包含几何体顶点位置和顶点色的Box的程序会是怎样的呢?这个程序是DX12龙书第六章的案例.同时它也常常被图形界 ...

  4. DirectX12 简单入门(一)

    在很久以前写过关于DirectX9的一些应用,直到现在DirectX12已经普及了.写完几个DirectX12测试代码之后,写一篇DirectX12简单入门介绍一下基本概念,以及环境搭建和编程过程. ...

  5. DirectX12(D3D12)基础教程(十)——DXR(DirectX Raytracing)基础教程(下)

    本文接上篇:DirectX12(D3D12)基础教程(十)--DXR(DirectX Raytracing)基础教程(上) 目录 5.C/C++代码中的其它准备工作 6.DXR编程的基本框架 7.枚举 ...

  6. nginx配置http、https访问,nginx指定ssl证书,阿里云腾讯云华为云设置nginx https安全访问

    nginx配置http.https访问 要设置https访问需要从对应的云厂商申请证书,并下载Nginx证书到服务器. 我这里从阿里云申请了免费的域名证书,然后将证书放置在服务器的/etc/ssl/. ...

  7. 在kotlin companion object中读取spring boot配置文件,静态类使用@Value注解配置

    在kotlin companion object中读取配置文件 静态类使用@Value注解配置 class Config {@Value("\${name}")fun setNam ...

  8. 大数据学习01——配置虚拟机节点相关网络

    1.配置mac地址和ip (1)更改适配器设置 找到这个后开始设置windows中的网络连接 (2)接着对三台虚拟机的mac地址和ip进行设置 1.mac地址设置 进入linux节点中的这个位置进行设 ...

  9. plsql配置多数据源,想换哪个换哪个

    现在的公司内部普遍使用plsql对数据库进行管理.而数据库非常多,从测试到线上环境数据库那么多,我们通常使用同一配置管理,便于切换.那么配置数据库连接就成为了很重要的一步. 1.安装plsql (这里 ...

最新文章

  1. 基于VC++的GDI常用坐标系统及应用
  2. 不小心删表删库了,还能救
  3. python基础===将Flask用于实现Mock-server
  4. 使用extern C改善显式调用dll
  5. 2020蓝桥杯省赛---java---A---2(既分数组)
  6. 软件项目可行性分析定义_如何定义最低可行产品
  7. [css] padding会影响到元素的大小,那不想让它影响到元素的宽度应该怎么办?
  8. Mysql复制-Slave库设置复制延迟
  9. Zabbix4.2安装和4.0升级4.2笔记
  10. Ubuntu和windows下修改hosts
  11. 自学java开发android开发_自学android开发 从零开始学Android
  12. 机顶盒文件服务器,智能网络机顶盒常见的六大玩法,别浪费了资源!
  13. leetcode 左程云笔记
  14. 双指缩放canvas图片_JS实现移动端双指缩放和旋转方法
  15. 新网银行模型竞赛点评-小微风控算法大赛-早期风险识别
  16. WIN7系统的虚拟机C盘扩容步骤
  17. 北森2020未来人才管理论坛:HR变革驱动中国企业转型
  18. Cadence Orcad Capture主要工作窗口介绍
  19. 如何用计算机扫描图片变成文字,如何把文字图片或者扫描的文件变成word文档?详细步骤...
  20. java 移动目录_java 移动文件夹内的文件,从一个目录移动到另外一个目录

热门文章

  1. 饼图的引导线怎么加_第0004期,复工了,这个Excel渠道分析(矩阵)图送给大家...
  2. pytorch 入门Tensor(一)
  3. 当推荐系统遇上图学习:基于图学习的推荐系统最新综述
  4. 预训练永不止步,游戏问答语言模型实操
  5. BP反向传播矩阵推导图示详解​
  6. NLP免费直播 | 两周讲透图卷积神经网络、BERT、知识图谱、对话生成
  7. 【归并排序】求逆序数算法
  8. 语言中拟合函数 计算aic_Go语言函数深度解析(中)
  9. python openpyxl读写xlsx_python高阶教程-python操作xlsx文件(openpyxl)
  10. render在python中的含义_python-/ render()上的Django TypeError获得了意外的...