使用Assimp在QT和OpenGL中加载模型
最编程
2024-08-04 10:32:22
...
#include "model.h"
#include "assimp/Importer.hpp"
#include <iostream>
using namespace std;
Model::Model(QOpenGLFunctions_4_5_Core *glFn, const std::string &path)
{
gl_fn_ = glFn;
loadModel(path);
}
Model::~Model()
{
}
void Model::loadModel(const std::string &path)
{
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(path.c_str(), aiProcess_Triangulate | aiProcess_FlipUVs);
if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
{
cout << "ERROR::ASSIMP::" << importer.GetErrorString() <<endl;
return;
}
directory_ = path.substr(0, path.find_last_of('/'));
processNode(scene->mRootNode, scene);
}
void Model::processNode(aiNode *node, const aiScene *scene)
{
for(unsigned int i = 0; i < node->mNumMeshes; i++)
{
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
meshes_.push_back(processMesh(mesh, scene));
}
for(unsigned int i = 0; i < node->mNumChildren; i++)
{
processNode(node->mChildren[i], scene);
}
}
Mesh Model::processMesh(aiMesh *mesh, const aiScene *scene)
{
QVector<Vertex> vertices;
QVector<unsigned int> indices;
QVector<Texture> textures;
// 顶点数据
for(unsigned int i = 0; i < mesh->mNumVertices; i++)
{
Vertex vertex;
QVector3D vector;
vector.setX(mesh->mVertices[i].x);
vector.setY(mesh->mVertices[i].y);
vector.setZ(mesh->mVertices[i].z);
vertex.position = vector;
vector.setX(mesh->mNormals[i].x);
vector.setY(mesh->mNormals[i].y);
vector.setZ(mesh->mNormals[i].z);
vertex.normal = vector;
if(mesh->mTextureCoords[0])
{
QVector2D tex;
tex.setX(mesh->mTextureCoords[0][i].x);
tex.setY(mesh->mTextureCoords[0][i].y);
vertex.tex_coords = tex;
}
else
{
vertex.tex_coords = QVector2D(0.0, 0.0);
}
vertices.push_back(vertex);
}
// 索引数据
for(unsigned int i = 0; i < mesh->mNumFaces; i++)
{
aiFace face = mesh->mFaces[i];
for(unsigned int j = 0; j < face.mNumIndices; j++)
{
indices.push_back(face.mIndices[j]);
}
}
// 纹理数据
if(mesh->mMaterialIndex >= 0)
{
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
QVector<Texture> diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, "diffuse");
textures.append(diffuseMaps);
QVector<Texture> specularMaps = loadMaterialTextures(material, aiTextureType_SPECULAR, "specular");
textures.append(specularMaps);
}
return Mesh(gl_fn_, vertices, indices, textures);
}
QVector<Texture> Model::loadMaterialTextures(aiMaterial *mat, aiTextureType type, std::string typeName)
{
QVector<Texture> textures;
for(unsigned int i = 0; i < mat->GetTextureCount(type); i++)
{
aiString str;
mat->GetTexture(type, i, &str);
bool skip = false;
for(int j = 0; j < texture_loaded_.size(); j++)
{
if(std::strcmp(texture_loaded_[j].path.data(), str.C_Str()) == 0)
{
textures.push_back(texture_loaded_[j]);
skip = true;
break;
}
}
if(!skip)
{
Texture texture;
texture.texture = textureFromFile(directory_ + "/" + str.C_Str());
texture.type = typeName;
texture.path = str.C_Str();
textures.push_back(texture);
texture_loaded_.push_back(texture);
}
}
return textures;
}
QOpenGLTexture *Model::textureFromFile(const std::string &file)
{
QOpenGLTexture *texture = new QOpenGLTexture(QImage(file.c_str()).mirrored());
if(!texture->isCreated())
{
cout << "texture load failed!" << endl;
}
return texture;
}
推荐阅读
-
在Qt中获取实时日期和时间:QDateTime、QTime和QDate的使用教程
-
在Mac上使用Assimp编译OpenGL模型加载教程
-
简易教程:在iOS上使用Assimp库进行OpenGL重学和编译
-
全面指南:在VS2015中安装、编译和使用Assimp(特别适合新手)
-
在VS 2022中使用OpenGL加载ASSIMP模型的步骤
-
使用Assimp在QT和OpenGL中加载模型
-
用OpenGL和assimp加载FBX 3D模型
-
准备模型:在QT和OpenGL中第八步
-
使用assimp库在OpenGL中导入模型
-
在Unreal Engine 4的Runtime中,使用Assimp库导入各类3D文件(如fbx、obj和gltf)到UStaticMesh