繁体   English   中英

assimp opengl加载问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM