Assimp opengl加载问题

时间:2018-02-12 22:07:20

标签: c++ opengl 3d assimp

我正在尝试加载并渲染我从blender导出为3ds格式的3D模型。

我正在使用Assimp加载模型和OpenGL(GLEW)来渲染它。由于某种原因。在某些模型中,只有部分模型会被渲染。 对于某些人来说,这可以通过选择搅拌机中的所有对象并单击连接来解决。但对于其他人来说,这并没有解决问题。

以下是用于加载模型的代码: (这里的所有“数组”都是std :: vector)

import PrflSrvcs from './ProfileServices'
console.log(PrflSrvcs.getName('1253'));

以下是我如何渲染它们; 首先我创建缓冲区。我这样做了一次

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);

这是模型在我的程序中的样子:

enter image description here

这是它在搅拌机中的样子 enter image description here

1 个答案:

答案 0 :(得分:1)

您错过了将节点转换应用于要渲染的顶点缓冲区。每个assimp节点都存储一个局部变换,需要将其应用于所有已分配的网格。

您可以在着色器中引入一个统一变量来表示顶点的全局变换。在渲染过程中,您需要将局部变换与全局变换相乘,并通过此统一矩阵应用它。

或者您可以使用glPushMAtrix和glPopMatrix并应用当前节点的本地转换,如您所见here (recursive_render)