使用 Assimp 和 OpenGL ES 绘制的骨架网格不正确

Incorrect skeleton mesh drawn using Assimp and OpenGL ES

我正在尝试使用 ASSIMP 绘制骨架动画网格(模型 boblampclean.md5mesh),但网格绘制不正确。网格已正确加载 我正在按照 ogld 教程加载和绘制网格。下面是我的一些代码和输出:

这是填充缓冲区以及最初生成 VAO、VBO 和 EBO 的方式:

    GLCall(glBufferData(GL_ARRAY_BUFFER, m_Positions.size() * sizeof(m_Positions[0]),&m_Positions[0],GL_STATIC_DRAW))
    GLCall(glEnableVertexAttribArray(POSITION_LOCATION))
    GLCall(glVertexAttribPointer(POSITION_LOCATION, 3, GL_FLOAT, GL_FALSE, 0,nullptr))

    GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[TEXCOORD_VB]))
    GLCall(glBufferData(GL_ARRAY_BUFFER, m_TexCoords.size() * sizeof(m_TexCoords[0]),&m_TexCoords[0],GL_STATIC_DRAW))
    GLCall(glEnableVertexAttribArray(TEX_COORD_LOCATION))
    GLCall(glVertexAttribPointer(TEX_COORD_LOCATION, 2, GL_FLOAT, GL_FALSE, 0, nullptr))

    GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[NORMAL_VB]))
    GLCall(glBufferData(GL_ARRAY_BUFFER, m_Normals.size() * sizeof(m_Normals[0]), &m_Normals[0], GL_STATIC_DRAW))
    GLCall(glEnableVertexAttribArray(NORMAL_LOCATION))
    GLCall(glVertexAttribPointer(NORMAL_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, nullptr))

    GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[BONE_VB]))
    GLCall(glBufferData(GL_ARRAY_BUFFER, m_Bones.size() * sizeof(m_Bones[0]), &m_Bones[0],GL_STATIC_DRAW))

    GLCall(glEnableVertexAttribArray(BONE_ID_LOCATION))
    GLCall(glVertexAttribIPointer(BONE_ID_LOCATION, MAX_NUM_BONES_PER_VERTEX, GL_INT,sizeof(VertexBoneData), nullptr))

    GLCall(glEnableVertexAttribArray(BONE_WEIGHT_LOCATION))
    GLCall(glVertexAttribPointer(BONE_WEIGHT_LOCATION, MAX_NUM_BONES_PER_VERTEX, GL_FLOAT, GL_FALSE,sizeof(VertexBoneData),(const GLvoid *) (MAX_NUM_BONES_PER_VERTEX * sizeof(int32_t))))

    GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Buffers[INDEX_BUFFER]))
    GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Indices.size() * sizeof(m_Indices[0]), &m_Indices[0],GL_STATIC_DRAW))

绘图调用:

    GLCall(glUseProgram(meshProgram))
        glm::mat4 projection = glm::perspective(45.0f,
                                                (float) windowWidth / (float) windowHeight,
                                                0.1f,
                                                100.0f);
        glm::mat4 translate = glm::translate(glm::mat4(1.0), glm::vec3(0.0f, 0.0f, 50.0f));
        glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(120.0f),
                                         glm::vec3(0.0f, 1.0f, 1.0f));
        glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(0.2, 0.2, 0.2));
        glm::mat4 model = translate * rotation * scale;
        GLCall(GLuint projectionLocation = meshShader->getUniformLocation("projection"))
        GLCall(GLuint modelLocation = meshShader->getUniformLocation("model"))
        meshCamera->useCamera();

        std::vector<Matrix4f> boneMatrix;
        mesh->GetBoneTransforms(mesh->getAnimationSecond(), boneMatrix);

        GLuint mBoneLocation[100];
        for (unsigned int i = 0; i < ARRAY_SIZE_IN_ELEMENTS(mBoneLocation); i++) {
            char Name[128];
            memset(Name, 0, sizeof(Name));
            snprintf(Name, sizeof(Name), "gBones[%d]", i);
            GLCall(mBoneLocation[i] = meshShader->getUniformLocation(Name))
        }

        for (int i = 0; i < boneMatrix.size(); ++i) {
            if (i >= 100) {
                break;
            }
            Matrix4f matrix = boneMatrix[i];
            GLCall(glUniformMatrix4fv(mBoneLocation[i], 1, GL_TRUE, (const GLfloat *) matrix))
        }

        // GLCall(GLuint meshTextureLocation = meshShader->getUniformLocation("texture"))
        GLCall(meshShader->setUniformMatrix4fv(projectionLocation, 1, glm::value_ptr(projection)))
        GLCall(meshShader->setUniformMatrix4fv(modelLocation, 1, glm::value_ptr(model)))

        Vector3f localPos = mesh->GetWorldTransform().WorldPosToLocalPos(meshCamera->getCameraPos());
        GLCall(GLuint localCameraPosLocation = meshShader->getUniformLocation("gCameraLocalPos"))
        GLCall(glUniform3f(localCameraPosLocation, localPos.x, localPos.y, localPos.z))[![enter image description here][1]][1]

        GLCall(glBindVertexArray(m_VAO))

        for (auto &m_Meshe : m_Meshes) {

            unsigned int MaterialIndex = m_Meshe.MaterialIndex;

            if (m_Materials[MaterialIndex].pDiffuse) {
                Texture *texture = m_Materials[MaterialIndex].pDiffuse;
                GLCall(texture->bind())
                GLCall(GLuint diffuseLocation = glGetUniformLocation(program, "gSampler"))
                GLCall(glUniform1i(diffuseLocation, texture->getSlot()))
            }
            if (m_Materials[MaterialIndex].pSpecularExponent) {
                Texture *texture = m_Materials[MaterialIndex].pSpecularExponent;
                GLCall(GLuint specularLocation = glGetUniformLocation(program,
                               "gSamplerSpecularExponent"))
                GLCall(texture->bind())
                GLCall(glUniform1i(specularLocation, texture->getSlot()))
            }

            GLCall(glDrawElementsBaseVertex(GL_TRIANGLES, m_Meshe.NumIndices, GL_UNSIGNED_INT,
                                            (GLvoid *) (sizeof(unsigned int) * m_Meshe.BaseIndex),
                                            m_Meshe.BaseVertex))

        }
        GLCall(glBindVertexArray(0))

输出:

我设法通过正确存储法线、顶点和 Texchord 来修复它。