第二十二课 使用Assimp加载模型
原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载)
背景
到现在为止我们都在使用手动生成的模型。正如你所想的,指明每个顶点的位置和其他属性有点时候并不是十分方便。对于一个箱子、锥体和简单平面还好,但是像人们的脸怎么办?现实的商业应用和游戏中,程序中使用模型一般都是由美术人员通过如 Blender, Maya 或 3ds Max 等建模软件来解决这个问题。这些软件提供了高级的工具帮助他们创造很复杂的模型。模型完成后可以以不同格式的文件保存。文件中包含了这个模型的所有几何解释。这些文件可以被加载到一个游戏引擎(提供支持特定格式的引擎)里面,文件中的内容可用来填充到渲染所需要的顶点缓存和索引缓存中。使用这些专业的模型对于场景效果的提升是十分关键的。
自己开发解析器将耗费你很长的时间。如果你想从不同格式的模型文件中加载模型,你需要学习每一种格式然后为其开发一个特定的解释器。有些模型的格式简单,但是一些也很复杂,你最终可能花费很多时间在这些并不是 3D 设计的核心内容上。因此,这章介绍的内容就是使用外加的库负责从文件中解释和加载模型。
Open Asset Import Library,也称 Assimp,是一个可以处理许多 3D 格式的开源库,包括最受欢迎的二进制反码格式。它是跨平台的,可用于 Linux 和 Windows,非常容易使用和嵌入到以 C/C++ 程序中。
这课没有太多的理论。让我们直接去看如何使用 Assimp 库中提供的函数来导入 3D 模型。在开始之前,请先确认你已经从上面的链接安装了 Assimp。
代码
(mesh.h:50)
class Mesh
{
public:
Mesh();
~Mesh();
bool LoadMesh(const std::string& Filename);
void Render();
private:
bool InitFromScene(const aiScene* pScene, const std::string& Filename);
void InitMesh(unsigned int Index, const aiMesh* paiMesh);
bool InitMaterials(const aiScene* pScene, const std::string& Filename);
void Clear();
#define INVALID_MATERIAL 0xFFFFFFFF
struct MeshEntry {
MeshEntry();
~MeshEntry();
bool Init(const std::vector& Vertices,
const std::vector& Indices);
GLuint VB;
GLuint IB;
unsigned int NumIndices;
unsigned int MaterialIndex;
};
std::vector<MeshEntry> m_Entries;
std::vector<Texture*> m_Textures;
};
这个 Mesh 类是 Assimp 和 OpenGL 程序之间的接口。这个类使用一个文件名参数作为 LoadMesh() 函数的参数,借助于 Assimp 加载模型,然后我们对加载进的模型数据进行解析,并将这些模型数据填充到顶点缓存、索引缓存以及纹理对象。为了渲染 mesh,我们定义了 Render() 函数。Mesh 类的内部结构与 Assimp 加载模型的方法相匹配。Assimp 用一个 aiScene 对象来代表被加载的 mesh, aiScene 对象中封装了包含模型各部分的 mesh 结构体。