本文介绍assimp 库的下载和编译,为我们用opengl 显示复杂3D 做准备。 前面模型库说明部分引用 https://learnopengl-cn.github.io/ 。
到目前为止的所有场景中,我们一直都在滥用我们的箱子朋友,但时间久了甚至是我们最好的朋友也会感到无聊。在日常的图形程序中,通常都会使用非常复杂且好玩的模型,它们比静态的箱子要好看多了。然而,和箱子对象不同,我们不太能够对像是房子、汽车或者人形角色这样的复杂形状手工定义所有的顶点、法线和纹理坐标。我们想要的是将这些模型(Model)导入(Import)到程序当中。模型通常都由3D艺术家在Blender、3DS Max或者Maya这样的工具中精心制作。
这些所谓的3D建模工具(3D Modeling Tool)可以让艺术家创建复杂的形状,并使用一种叫做UV映射(uv-mapping)的手段来应用贴图。这些工具将会在导出到模型文件的时候自动生成所有的顶点坐标、顶点法线以及纹理坐标。这样子艺术家们即使不了解图形技术细节的情况下,也能拥有一套强大的工具来构建高品质的模型了。所有的技术细节都隐藏在了导出的模型文件中。但是,作为图形开发者,我们就必须要了解这些技术细节了。
所以,我们的工作就是解析这些导出的模型文件以及提取所有有用的信息,将它们储存为OpenGL能够理解的格式。一个很常见的问题是,模型的文件格式有很多种,每一种都会以它们自己的方式来导出模型数据。像是Wavefront的.obj这样的模型格式,只包含了模型数据以及材质信息,像是模型颜色和漫反射/镜面光贴图。而以XML为基础的Collada文件格式则非常的丰富,包含模型、光照、多种材质、动画数据、摄像机、完整的场景信息等等。Wavefront的.obj格式通常被认为是一个易于解析的模型格式。建议至少去Wavefront的wiki页面上看看文件格式的信息是如何封装的。这应该能让你认识到模型文件的基本结构。
总而言之,不同种类的文件格式有很多,它们之间通常并没有一个通用的结构。所以如果我们想从这些文件格式中导入模型的话,我们必须要去自己对每一种需要导入的文件格式写一个导入器。很幸运的是,正好有一个库专门处理这个问题。
一个非常流行的模型导入库是Assimp,它是Open Asset Import Library(开放的资源导入库)的缩写。Assimp能够导入很多种不同的模型文件格式(并也能够导出部分的格式),它会将所有的模型数据加载至Assimp的通用数据结构中。当Assimp加载完模型之后,我们就能够从Assimp的数据结构中提取我们所需的所有数据了。由于Assimp的数据结构保持不变,不论导入的是什么种类的文件格式,它都能够将我们从这些不同的文件格式中抽象出来,用同一种方式访问我们需要的数据。
当使用Assimp导入一个模型的时候,它通常会将整个模型加载进一个场景(Scene)对象,它会包含导入的模型/场景中的所有数据。Assimp会将场景载入为一系列的节点(Node),每个节点包含了场景对象中所储存数据的索引,每个节点都可以有任意数量的子节点。Assimp数据结构的(简化)模型如下
所以,我们需要做的第一件事是将一个物体加载到Scene对象中,遍历节点,获取对应的Mesh对象(我们需要递归搜索每个节点的子节点),并处理每个Mesh对象来获取顶点数据、索引以及它的材质属性。最终的结果是一系列的网格数据,我们会将它们包含在一个Model
对象中。
1: 下载assimp源代码
可以到 http://assimp.org/index.php/downloads 选择你要下载的版本,我选择目前最新的,指引我到 https://github.com/assimp/assimp/releases/tag/v4.1.0/
2:安装boost
assimp是依赖boost库的,如果没有boost库只能编译出一个功能受限的版本。
boost官方链接:www.boost.org
我的系统上visual studio 2010,2017 ,那么我该用哪个版本的boost , 都可以,我就下载现在最新发行版 1.69。
assimp没有用到boost需要编译的部分,所以boost只需要下载解压就可以了。
3:assimp view依赖directx sdk
如果需要编译assimp view,需要先安装directx sdk。
你可以从这里下载SDK。
点击exe文件进行安装,安装后,如果不重新启动至少需要注销后,directx sdk的环境配置才会起作用。
4:安装cmake
cmake官方链接:www.cmake.org
运行cmake
选择assimp源码目录,编译二进制文件的目录可以先建立好,也可以这时输入,我是复制源码目录,后面添加bin或bin7。然后点Add Entry,添加BOOST_ROOT变量,type选STRING,value添加boost的目录(此步骤也可以不做,编译出的assimp可能是功能受限的)。添加后效果如下:
点Config ,第一次点的时候会问你选择哪个版本的编译器。
再点一次Config, 然点Generate,就产生好了工程。然后Open project, 编译链接(build)。
这需要些时间,对我而言, visual studio 2010总是编译结果为:
========== Rebuild All: 5 succeeded, 4 failed, 6 skipped ==========
也就是不成功。
但是visual studio 2017 却是成功的。既然有个成功的就用了再说。
5: assimp 的使用
做好了这些准备,就可以用assimp 库导入各种3D文件了。
6:c++应用简单例子
建立一个 Assimp::Importer 类的实例,或者做些设置,然后调用l Assimp::Importer::ReadFile(). 就能读取文件并处理数据,处理好的数据放在 aiScene 类指针的对象里。你可以提取需要的数据。importer 管理本身的所有资源。其消失的时候也释放了他所有的资源。所以最简单的办法是本地建立一个实例,利用完其结果后,让他自然超出作用域范围。
C++ 例子如下:
#include // C++ importer interface
#include // Output data structure
#include // Post processing flags
bool DoTheImportThing( const std::string& pFile)
{
// Create an instance of the Importer class
Assimp::Importer importer;
// And have it read the given file with some example postprocessing
// Usually - if speed is not the most important aspect for you - you'll
// propably to request more postprocessing than we do in this example.
const aiScene* scene = importer.ReadFile( pFile,
aiProcess_CalcTangentSpace |
aiProcess_Triangulate |
aiProcess_JoinIdenticalVertices |
aiProcess_SortByPType);
// If the import failed, report it
if( !scene)
{
DoTheErrorLogging( importer.GetErrorString());
return false;
}
// Now we can access the file's contents.
DoTheSceneProcessing( scene);
// We're done. Everything will be cleaned up by the importer destructor
return true;
}