运用assimp库进行OpenGL模型的加载与转换

这篇文章将介绍运用assimp库进行实际的模型加载与转换的代码。

#include "assimp\Importer.hpp"
#include "assimp\scene.h"
#include "assimp\postprocess.h"
首先导入assimp库的头文件。

Assimp::Importer importer;
		const aiScene* scene = importer.ReadFile(file, 
			aiProcess_Triangulate | 
			aiProcess_JoinIdenticalVertices | 
			aiProcess_GenSmoothNormals);
		if (!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
			std::cout << "Model could not be imported: " << std::endl;
			std::cout << importer.GetErrorString() << std::endl;
			return false;
		}

首先创建一个在assimp空间的Importer对象,然后调用它的ReadFile方法。其中,方法的第一个参数file就是模型的存储地址,第二个参数为后处理说明,我们可以通过对这个参数的设置来强制对导入的模型进行一些额外的操作。通过设置aiProcess_Triangulate,我们告诉Assimp如果模型不是(全部)由三角形组成,应该转换所有的模型的原始几何形状为三角形。通过设置aiProcess_GenNormals 表示模型没有包含法线向量,就为每个顶点创建法线。

在加载模型的操作结束后,我们通过检验模型的根节点是否为空来检验模型的加载是否成功。我们通过Import对象自带的GetErrorString函数来返回我们检测到的错误。


for (unsigned i = 0; i < scene->mNumMeshes; i++) {
			aiMesh* ai_mesh = scene->mMeshes[i];

			VertexFormat vertex_format;
			vertex_format.AddAttribute(Semantic::POSITION, 3);
			if (ai_mesh->mNormals != NULL)
				vertex_format.AddAttribute(Semantic::NORMAL, 3);
			if (ai_mesh->mTextureCoords[0] != NULL)
				vertex_format.AddAttribute(Semantic::TEXCOORD, 2);

			std::shared_ptr vertex_buffer = std::make_shared(ai_mesh->mNumVertices,
				vertex_format, nullptr, BufferUsage::STATIC_DRAW);

			float* vertex_data = static_cast(vertex_buffer->Map());

			for (unsigned i = 0; i < ai_mesh->mNumVertices; i++) {
				aiVector3D vertex = ai_mesh->mVertices[i];

				*vertex_data++ = vertex.x;
				*vertex_data++ = vertex.y;
				*vertex_data++ = vertex.z;

				if (ai_mesh->mNormals != NULL) {
					aiVector3D normal = ai_mesh->mNormals[i];

					*vertex_data++ = normal.x;
					*vertex_data++ = normal.y;
					*vertex_data++ = normal.z;
				}

				if (ai_mesh->mTextureCoords[0] != NULL) {
					aiVector3D texcoord = ai_mesh->mTextureCoords[0][i];

					*vertex_data++ = texcoord.x;
					*vertex_data++ = texcoord.y;
				}
			}

之前的博客中介绍了我们组关于SubMesh类的定义,SubMesh中只定义了定点数据和面片索引的存储。所以在对模型进行操作前,我们先要检测Mesh对象是否有存储有模型定点的法线向量信息和纹理坐标信息,如果有的话,我们需要添加存储这些信息的属性。


你可能感兴趣的:(运用assimp库进行OpenGL模型的加载与转换)