【DirectX12】3.配置FBX_SDK

2023-11-12

配置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绘制出这个茶壶!

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【DirectX12】3.配置FBX_SDK 的相关文章

  • DCGAN、WGAN、WGAN-GP、LSGAN、BEGAN原理总结及对比

    GAN系列学习 2 前生今世 本文已投稿至微信公众号 机器学习算法工程师 欢迎关注 本文是GAN系列学习 前世今生第二篇 在第一篇中主要介绍了GAN的原理部分 在此篇文章中 主要总结了常用的GAN包括DCGAN WGAN WGAN GP L
  • 记一次Vulnstack靶场内网渗透(五)

    实验环境搭建 VMware新建网卡VMnet14 选择仅主机模式 并将网段IP设置为192 168 138 0 然后将Windows 7和Windows 2008绑在这个VMnet14上 除此之外 还需要给Windows 7 新增一个网卡
  • C#实现俄罗斯方块游戏

    还记得小时候经常拿袖珍电子游戏机或者小霸王玩过最多的就是俄罗斯方块 冒险岛 超级玛丽还有魂斗罗之类的 这些游戏由于其中简单易上上手的特点 曾经风靡了全世界 俄罗斯方块的基本规则是移动 旋转和摆放游戏自动输出的各种方块 使之排列成完整的一行或
  • Linux开机&关机

    走进Linux系统 开机登录 开机会启动许多程序 它们在Windows叫做 服务 service 在Linux就叫做 守护进程 daemon 开机成功后 它会显示一个文本登录界面 这个界面就是我们经常看到的登录界面 在这个登录界面会提示用户
  • 关于String内存分配的深入探讨

    2019独角兽企业重金招聘Python工程师标准 gt gt gt public class Test public static final String MESSAGE taobao public static void main St
  • Sqli-labs之Less-34

    Less 34 基于错误 POST 单引号 字符型 addslashes 宽字节注入 这一关是POST型的注入 同样的将post传递过来的内容进行了转义处理 过滤了单引号 反斜杠 有之前的例子我们可以看到 df可以将转义的反斜杠给吃掉 而G
  • 数据结构 十进制和十六进制进制间的相互转换

    一 十进制转十六进制 例题 输入十进制数 654321 输出十六进制数 9FBF1 解题步骤 十进制数对16取余 因为最终结果是从下往上依次书写 说以我们可以利用栈的特性 先进 的后出 将余数存入栈中依次弹出 再将弹出的数进行拼接输出即可
  • C++迭代器-------array的基本用法总结

    基本用法中主要总结有 遍历和比较大小 注意 加上头文件 include
  • 利用python来制作动态二维码

    前言 为什么要学习python 是因为不仅很多工作需要用到python 同时我们可以利用python做很多好玩儿的事儿 今天就来教大家如何利用python制作动态二维码 代码说明 我们以小猪佩奇gif图片为例 如果我们利用的背景图是gif动
  • 工厂实施MES系统可以带来哪些效益?

    众多工厂生产现状 1 设施设备先进 但是管理方式落后 手工管理模式的存在 造成数据的不准确和不完全 没有完全实现信息化管理 2 生产计划协调性差 作业调度困难 生产作业计划主要依据调度员的经验制定 设备利用率低 任务进度监控难 紧急插单普遍
  • C++虚基类

    问题引出 问题 A中数据 在D中保存了两份 虚继承 虚继承的目的是让某个类做出声明 承诺愿意共享它的基类 其中 这个被共享的基类就称为虚基类 Virtual Base Class 虚派生只影响从指定了虚基类的派生类中进一步派生出来的类 它不
  • 扎心!为何HR看了你的简历却不通知面试?

    还只是老老实实地写简历 投简历 默默地等待面试通知 那只有两种可能 你太天真 或者是 你真的很久没有 求职 了 如果你细心观察会发现 当你完成一份简历之后 它的状态也会有变化 然而 却有很多求职者并没有搞清楚这些 状态 到底代表着什么 但小
  • idea 配置 JavaWeb 项目的 tomcat

    目录 第一步 单击 idea 靠右上部位的 添加配置 Add Config Run Config 第二步 点击 添加新 或者图中箭头指向的任意一个地方 第三步 选择 Tomcat 服务器 本地 不是 TomEE 第四步 若以前从未配置 To

随机推荐

  • 使用SARIMA做季节时间序列预测全流程(附MATLAB代码)

    在之前的专栏中我们用ARIMA的方法做了时间序列的趋势性预测 不过我们经常还会遇到一种情况 即某些时间序列中存在明显的周期性变化 这种周期是由于季节性变化 季度 月度等 引起的 如下图所示 为1949年到1960年每月国际航空公司的乘客人数
  • C# pdf文件加数字证书,防篡改

    C 指定文件夹内新创建pdf文件加签数字证书 代码实现 引用 Spire Pdf string files Directory GetFiles Config pdfPath 需加数字证书pdf存放文件夹地址 string filesLis
  • 进程信号生命周期详解

    信号和信号量半毛钱关系都没有 每个信号都有一个编号和一个宏定义名称 这些宏定义可以在signal h中找到 例如其中有定 义 define SIGINT 2 查看信号的机制 如默认处理动作man 7 signal SIGINT的默认处理动作
  • c++自定义类型和预处理

    struct 内部初始化变量时 不能用 struct data int x 12 float f 122 5f int pi x data da cout lt lt da f lt lt endl data dap new data 使用
  • 配置 nginx 遇到错误排查(初级)

    系统版本 ubuntu 14 04 nginx 版本 nginx 1 4 6 Ubuntu 本文不是一步步搭建 nginx 的过程 而是我在使用 nginx 的过程中 整理自己遇到的的一些问题 适用于 nginx 遇到问题 排查问题的 ch
  • Neo4J 初次启动与密码

    初次安装成功Neo4J在安装的文件中会有一个bin文件夹 powershell进入bin文件夹执行 neo4j sonsole会有以下结果 D neo4j bin gt neo4j console 2020 09 04 00 57 31 0
  • Python基于PyTorch实现卷积神经网络分类模型(CNN分类算法)项目实战

    说明 这是一个机器学习实战项目 附带数据 代码 文档 视频讲解 如需数据 代码 文档 视频讲解可以直接到文章最后获取 1 项目背景 卷积神经网络 简称为卷积网络 与普通神经网络的区别是它的卷积层内的神经元只覆盖输入特征局部范围的单元 具有稀
  • oracle 9i在线重定义,在oracle 9i下在线重定义表

    9i提供了联机重定义表的方法 可以让你在基本不影响原表的DML情况下修改表结构 实际上 联机重定义表并不是完全的联机重定义 在最后交换表名的时候会短暂地锁定原表和中间表 但这个过程很短暂 相对于传统方法来说 这是一个进步 9i提供了联机重定
  • CNN、BiGRU、BiLSTM代码

    toxicCommentsclassification BiLSTMAttentionNetwork py at master AmritSatpathy toxicCommentsclassification GitHubtoxic co
  • BlueStore 架构及原理分析

    BlueStore 架构及原理分析 Ceph 底层存储引擎经过了数次变迁 目前最常用的是 BlueStore 在 Jewel 版本中引入 用来取代 FileStore 与 FileStore 相比 Bluesore 越过本地文件系统 直接操
  • 算法训练营第四十一天(9.2)

    Leecode 1143 最长公共子序列 题目地址 力扣 LeetCode 官网 全球极客挚爱的技术成长平台 题目类型 最长子序列 class Solution public int longestCommonSubsequence str
  • cython代码编译和setup.py文件编写

    Cython 官方文档 https cython readthedocs io en latest 中文文档 https www bookstack cn read cython doc zh https cython apachecn o
  • visjs DataSet支持的数据类型和选择

    数据类型 DataSet 支持以下数据类型 Name Description Examples Boolean A JavaScript Boolean true false Number A JavaScript Number 32 2
  • MFC的ActiveX控件 - 1

    转自 https blog csdn net babykangaroo article details 45795079 本文是入门学习ActiveX的学习笔记 属于系统学习整个框架部分 具体细节自己写代码时再深入 学习参考书籍是 MFC
  • 找环

    文章目录 找环 1 算法分析 1 1 判断是否存在环 1 2 找出所有环上的所有点 1 3 类拓扑排序找出与度数有关的点集 gt 退化到度数为2的环 1 4 找到以s为源点的最小环 1 5 floyd找到有向图 无向图的最小环 2 模板 2
  • 神秘时代服务器信息没汉化,[聊天

    Server thread ERROR Could not load plugins Msgreplace1 0 jar in folder plugins org bukkit plugin InvalidPluginException
  • Qt界面小技巧之设置不同模块不同颜色

    文章目录 一 效果图 二 使用场景 三 使用方法及分析 3 1 步骤 3 2 分析 总结 一 效果图 下图为不同模块不同颜色的效果图 下方每一个字符都是独立的QLabel控件 模块对应的颜色码 1 rgb 170 85 255 2 rgb
  • 日志异常检测初步实践与探索

    1 背景 日志的主要目的是记录系统 包括服务和业务等 状态和重要的事件帮助定位系统的问题 日志对于理解系统状态和定位性能问题至关重要 因此 日志是在线监控和异常检测的一个重要信息源 在很多业务和服务的故障自愈过程中 日志异常检测与根因分析是
  • 人工智能3d建模算法_从2D到3D的跨越,康云全球首创“人工智能AI+3D自动化建模与展示技术”...

    康云 人工智能AI 3D自动化建模与展示技术 第八届中国创新创业大赛 广东赛区 暨第七届 珠江天使杯 科技创新创业大赛 获奖项目巡礼系列报道八 你还在使用传统的3D建模技术 传统3D建模 模型制作成本高耗时耗力 模型体积大不方便传输 传播
  • 【DirectX12】3.配置FBX_SDK

    配置FBX SDK 1 介绍 FBX格式是现在最主流的用于游戏的3D模型格式 要使用DirectX12绘制模型 当然需要先用这个库来解析模型数据 它的版权协议如下 不是开源的并且是非商用的 假设你完成了一个引擎到时候还需要联系他们讨论版权的