[英]Assimp opengl loading problems
我正在尝试加载和渲染我从搅拌机导出为 3ds 格式的 3D 模型。
我使用 Assimp 加载模型和 OpenGL (GLEW) 来渲染它。 出于某种原因一些。 在某些模型中,仅渲染模型的一部分。 对于某些人来说,这可以通过选择搅拌机中的所有对象并单击加入来解决。 但对于其他人来说,这并不能解决问题。
这是我用来加载模型的代码:(这里的所有“数组”都是 std::vector)
void Mesh::recursiveProcess(aiNode* node,const aiScene* scene) {
for(int i=0;i<node->mNumMeshes;i++) {
aiMesh* mesh=scene->mMeshes[node->mMeshes[i]];
processMesh(mesh, scene);
}
for(int i=0;i<node->mNumChildren;i++) {
recursiveProcess(node->mChildren[i], scene);
}
}
void Mesh::processMesh(aiMesh* m,const aiScene* scene) {
for(int i=0;i<m->mNumVertices;i++) {
vertexArray.push_back(m->mVertices[i].x);
vertexArray.push_back(m->mVertices[i].y);
vertexArray.push_back(m->mVertices[i].z);
if(m->mNormals!=NULL) {
normalArray.push_back(m->mNormals[i].x);
normalArray.push_back(m->mNormals[i].y);
normalArray.push_back(m->mNormals[i].z);
}
if(m->mTextureCoords[0]!=NULL) {
uvArray.push_back(m->mTextureCoords[0][i].x);
uvArray.push_back(m->mTextureCoords[0][i].y);
}
if(m->mTangents!=NULL) {
tangentArray.push_back(m->mTangents[i].x);
tangentArray.push_back(m->mTangents[i].y);
tangentArray.push_back(m->mTangents[i].z);
}
}
for(int i=0;i<m->mNumFaces;i++) {
aiFace face=m->mFaces[i];
for(int j=0;j<face.mNumIndices;j++) {
indexArray.push_back(face.mIndices[j]);
}
}
}
void Mesh::Load(string path) {
vertexArray.clear();
indexArray.clear();
normalArray.clear();
uvArray.clear();
tangentArray.clear();
const aiScene* scene=aiImportFile(path.c_str(),
aiProcess_GenSmoothNormals |
aiProcess_CalcTangentSpace |
aiProcess_Triangulate |
aiProcess_FindInvalidData);
const char* err = aiGetErrorString();
if(err!=NULL&&sizeof(err) > 4 && scene==NULL) {
cout << "The file wasn't successfuly opened " << path << " Because " << err;
return;
}
recursiveProcess(scene->mRootNode,scene);
if(uvArray.size()==0) uvArray.push_back(0);
if(normalArray.size()==0) normalArray.push_back(0);
if(tangentArray.size()==0) tangentArray.push_back(0);
}
这是我渲染它们的方式; 首先我创建缓冲区。 我这样做一次
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertexArray.size() * sizeof(float), vertexArray.data(), GL_STATIC_DRAW);
glGenBuffers(1, &indexbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexArray.size() * sizeof(unsigned int), indexArray.data(), GL_STATIC_DRAW);
glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, uvArray.size() * sizeof(float), uvArray.data(), GL_STATIC_DRAW);
然后我在主渲染循环中执行这个
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0);
camera.Update();
mvp = camera.getProjection() * camera.getView() * Model;
shader.SetUniformLocationMatrix4fv("MVP", &mvp[0][0]);
glBindTexture(GL_TEXTURE_2D, akm_tex);
glUseProgram(shader);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexbuffer);
glDrawElements(
GL_TRIANGLES, // mode
indexArray.size(), // count
GL_UNSIGNED_INT, // type
(void*)0 // element array buffer offset
);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
这是模型在我的程序中的样子:
您错过了将节点的变换应用于您正在渲染的顶点缓冲区。 每个 assimp 节点都存储一个本地变换,需要将其应用于所有分配的网格。
您可以在着色器中引入一个统一变量来表示顶点的全局变换。 在渲染过程中,您需要将局部变换与全局变换相乘,并通过这个统一矩阵应用它。
或者您可以只使用 glPushMAtrix 和 glPopMatrix 并应用当前节点的本地转换,如您所见(recursive_render)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.