LearnOpenGLwithQt——模型加载:Qt搭建Assimp环境
如果你是中途开始学习本教程的,即使你对OpenGL已经⾮常熟悉,请⾄少了解以下⼏个章节,因为Qt中提供了OpenGL的很多便捷操作,熟悉这些操作可以让我们在Qt中⾼效的使⽤OpenGL进⾏绘图。
Assimp
到⽬前为⽌,我们已经在所有的场景中⼤⾯积滥⽤了我们的容器盒⼩盆友,但就是容器盒是我们的好朋友,时间久了我们也会喜新厌旧。⼀些图形应⽤⾥经常会使⽤很多复杂且好玩⼉的模型,它们看起来⽐静态的容器盒可爱多了。但是,我们⽆法像定义容器盒⼀样⼿动地去指定房⼦、货车或⼈形⾓⾊这些复杂模型的顶点、法线和纹理坐标。我们需要做的也是应该要做的,是把这些模型导⼊到应⽤程序中,⽽设计制作这些3D模型的⼯作应该交给像、或者这样的⼯具软件。
那些3D建模⼯具,可以让美⼯们构建⼀些复杂的形状,并将贴图应⽤到形状上去,即纹理映射。然后,在导出模型⽂件时,建模⼯具会⾃⼰⽣成所有的顶点坐标、顶点法线和纹理坐标。这样,美⼯们可以不⽤了解⼤量的图像技术细节,就能有⼤量的⼯具集去随⼼地构建⾼品质的模型。所有的技术细节内容都隐藏在⾥导出的模型⽂件⾥。⽽我们,这些图形开发者,就必须得去关注这些技术细节了。
因此,我们的⼯作就是去解析这些导出的模型⽂件,并将其中的模型数据存储为OpenGL能够使⽤的数据。
⼀个常见的问题是,导出的模型⽂件通常有⼏⼗种格式,不同的⼯具会根据不同的⽂件协议把模型数据导出到不同格式的模型⽂件中。有的模型⽂件格式只包含模型的静态形状数据和颜⾊、漫反射贴图、⾼光贴图这些基本的材质信息,⽐如Wavefront的.obj⽂件。⽽有的模型⽂件则采⽤XML来记录数据,且包含了丰富的模型、光照、各种材质、动画、摄像机信息和完整的场景信息等,⽐如Collada⽂件格式。Wavefront的obj格式是为了考虑到通⽤性⽽设计的⼀种便于解析的模型格式。建议去Wavefront的Wiki上看看obj⽂件格式是如何封装的。这会给你形成⼀个对模型⽂件格式的⼀个基本概念和印象。
模型加载库
现在市⾯上有⼀个很流⾏的模型加载库,叫做Assimp,全称为Open Asset Import Library。Assimp可以导⼊⼏⼗种不同格式的模型⽂件(同样也可以导出部分模型格式)。只要Assimp加载完了模型⽂件,我们就可以从Assimp上获取所有我们需要的模型数据。Assimp把不同的模型⽂件都转换为⼀个统⼀的数据结构,所有⽆论我们导⼊何种格式的模型⽂件,都可以⽤同⼀个⽅式去访问我们需要的模型数据。
当导⼊⼀个模型⽂件时,即Assimp加载⼀整个包含所有模型和场景数据的模型⽂件到⼀个scene对象时,Assimp会为这个模型⽂件中的所有场景节点、模型节点都⽣成⼀个具有对应关系的数据结构,且将这些场景中的各种元素与模型数据对应起来。下图展⽰了⼀个简化的Assimp⽣成的模型⽂件数据结构:
所有的模型、场景数据都包含在scene对象中,如所有的材质和Mesh。同样,场景的根节点引⽤也包含在这个scene对象中
场景的根节点可能也会包含很多⼦节点和⼀个指向保存模型点云数据mMeshes[]的索引集合。根节点上的mMeshes[]⾥保存了实际了Mesh对象,⽽每个⼦节点上的mMesshes[]都只是指向根节点中的mMeshes[]的⼀个引⽤(译者注:C/C++称为指针,Java/C#称为引⽤)
⼀个Mesh对象本⾝包含渲染所需的所有相关数据,⽐如顶点位置、法线向量、纹理坐标、⾯⽚及物体的材质
⼀个Mesh会包含多个⾯⽚。⼀个Face(⾯⽚)表⽰渲染中的⼀个最基本的形状单位,即图元(基本图元有点、线、三⾓⾯⽚、矩形⾯⽚)。⼀个⾯⽚记录了⼀个图元的顶点索引,通过这个索引,可以在mMeshes[]中寻到对应的顶点位置数据。顶点数据和索引分开存放,可以便于我们使⽤缓存(VBO、NBO、TBO、IBO)来⾼速渲染物体。(详见)
⼀个Mesh还会包含⼀个Material(材质)对象⽤于指定物体的⼀些材质属性。如颜⾊、纹理贴图(漫反射贴图、⾼光贴图等)
所以我们要做的第⼀件事,就是加载⼀个模型⽂件为scene对象,然后获取每个节点对应的Mesh对象(我们需要递归搜索每个节点的⼦节
点来获取所有的节点),并处理每个Mesh对象对应的顶点数据、索引以及它的材质属性。最终我们得到⼀个只包含我们需要的数据的
Mesh集合。
⽤建模⼯具构建物体时,美⼯通常不会直接使⽤单个形状来构建⼀个完整的模型。⼀般来说,⼀个模型
会由⼏个⼦模型/形状组合拼接⽽成。⽽模型中的那些⼦模型
获取Assimp
因为Assimp官⽅的已编译库不能很好地覆盖在所有平台上运⾏,我们需要借助CMake来重新编译⼀个当前环境能够使⽤的库。
因此,你还需要⼀个CMake(同样你可以点击,下载博主的Cmake资源)
构建Assimp
博主的Qt使⽤的是32位MinGw编译,因此需要构建⼀个专门的assimp库。
步骤:
1、添加Cmake/bin环境变量:把刚刚下载的Cmake安装好,把安装⽬录下的/bin⽬录添加到系统环境变量,配置成功后,使⽤cmd输⼊
cmake可以看到⼀系列指令,说明配置成功。
2、添加MinGW环境变量:把Qt的根⽬录下./Tool/mingw530_32/bin⽬录也添加到环境变量中,添加成功能在cmd中使mingw32-
make指令
3、使⽤cmake构建Assimp库:
编辑指令:将下⽅指令中的路径修改为你本地Qt的MinGW路径:
cmake -G "MinGW Makefiles" -DENABLE_BOOST_WORKAROUND=ON -DBUILD_STATIC_LIB=ON -
DCMAKE_RC_COMPILER=E:/Qt5.10.0/Tools/mingw530_32/ -
DCMAKE_MAKE_PROGRAM=E:/Qt5.10.0/Tools/mingw530_32/ -DCMAKE_LFLAGS=-static -
DCMAKE_LFLAGS_DLL=-static -DDX9_INCLUDE_PATH=E:/Qt5.10.0/Tools/mingw530_32/i686-w64-mingw32/include -
DD3D9_LIBRARY=E:/Qt5.10.0/Tools/mingw530_32/i686-w64-mingw32/lib/libd3d9.a -
DD3DX9_LIBRARY=E:/Qt5.10.0/Tools/mingw530_32/i686-w64-mingw32/lib/libd3dx9.a .
cd到Assimp的根⽬录,粘贴上⽅修改后的指令,回车运⾏。
构建完成后,不要关闭控制台窗⼝,进⾏下⼀步。
4、使⽤MinGW编译上⾯的Assimp库:
输⼊如下指令
mingw32-make -j 4
然后开始编译,如果你编译中途出错 ,可能是你对Assimp库进⾏了不正当的操作,可以把assimp删了,重新解压⼀个出来。
中途停住了,可以敲⼏下回车。
出现上图的情况,说明我们的Assimp已经可以使⽤了!
在项⽬中使⽤Assimp库
这⾥我重新创建⼀个QWidget项⽬⽤于测试
右键项⽬名——添加库——外部库
库⽂件为:...\assimp-4.1.0\lib\libassimp.dll.a
包含路径为:...\assimp-4.1.0\include
然后我们就成功导⼊Assimp库了,导⼊之后pro项⽬⽂件增加了
然后在main.cpp中使⽤⼀个Assimp对象看看
#include "widget.h"
#include <QApplication>
#include <assimp/Importer.hpp>
int main(int argc, char *argv[])
{
cmake如何使用QApplication a(argc, argv);
Widget w;
w.show();
Assimp::Importer importer;
();
}
运⾏没出错就说明成功导⼊
如果崩溃了,说明你可能需要⼿动导⼊⼀下dll
将assimp4.1.0/bin/⽬录下的两个dll
复制到你的项⽬⽣成⽬录 ⽐如你是debug模式运⾏,把dll复制到如下⽬录中
注意初次导⼊库可能会导致代码提⽰功能没有更新,需要重新打开⼀下QtCreator
好了,现在我们已经能够使⽤Assimp库了,下⼀节我们将开始使⽤Assimp来导⼊3D模型。
结语
笔者在完成这⼀节的教程真可谓是⼀波未平⼀波⼜起,learnopengl的⽹站不知怎么的,这⼏天进不去,⽽且原learnOpenGL所封装的模型加载库并不适⽤于Qt,因此需要做很多调整,耽搁了⼏天。废话不多说,下节我们来玩个好玩的东西!
Assimp环境的配置⼗分感谢下⾯两位博主的博⽂!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论