【问题标题】:OpenGL (core profile) model's triangles wrong renderingOpenGL(核心配置文件)模型的三角形错误渲染
【发布时间】:2016-07-14 22:46:16
【问题描述】:

这是我项目的一个issue,请看截图:

  1. problems
  2. original(correct)

我的对象是以错误的方式构建的。顶点未正确连接。 我怀疑它与模型的索引有关。无论如何,这是为我构建网格的代码:

mesh model::processMesh(aiMesh * mesh_, const aiScene * scene)
{
    std::vector<vertex> vertices;
    std::vector<GLuint> indices;
    std::vector<texture> textures;

    //vertices
    for (GLuint i = 0; i < mesh_->mNumVertices; i++)
    {
        vertex vert;
        glm::vec3 vector;

        //positions
        vector.x = mesh_->mVertices[i].x;
        vector.y = mesh_->mVertices[i].y;
        vector.z = mesh_->mVertices[i].z;
        vert.position = vector;

        //normals
        vector.x = mesh_->mNormals[i].x;
        vector.y = mesh_->mNormals[i].y;
        vector.z = mesh_->mNormals[i].z;
        vert.normal = vector;

        //texture coords
        if (mesh_->mTextureCoords[0])
        {
            glm::vec2 vector_;
            vector_.x = mesh_->mTextureCoords[0][i].x;
            vector_.y = mesh_->mTextureCoords[0][i].y;
            vert.texCoords = vector_;
        }
        else vert.texCoords = glm::vec2(0.0f, 0.0f);

        vertices.push_back(vert);
    }

    //indices
    for (GLuint i = 0; i < mesh_->mNumFaces; i++)
    {
        aiFace face = mesh_->mFaces[i];
        for (GLuint j = 0; j < mesh_->mNumFaces; j++) indices.push_back(face.mIndices[j]);
    }

    //textures
    if (mesh_->mMaterialIndex >= 0)
    {
        aiMaterial* material = scene->mMaterials[mesh_->mMaterialIndex];

        //diffuse
        std::vector<texture> diffuseMaps = this->loadMaterialTextures(material, aiTextureType_DIFFUSE, TEX_DIFF_NAME);
        textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
        //specular
        std::vector<texture> specularMaps = this->loadMaterialTextures(material, aiTextureType_SPECULAR, TEX_SPEC_NAME);
        textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());
    }

    return mesh(vertices, indices, textures);
}

在这个函数中我设置了所有对象:

void mesh::setupMesh()
{
    //buffers
    glGenVertexArrays(1, &this->vao);
    glGenBuffers(1, &this->vbo);
    glGenBuffers(1, &this->ebo);

    glBindVertexArray(this->vao);

    glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
    glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(vertex), &this->vertices[0], GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint), &this->indices[0], GL_STATIC_DRAW);

    //attributes
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)offsetof(vertex, normal));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)offsetof(vertex, texCoords));

    //unbind
    glBindVertexArray(0);
}

这是渲染

void mesh::draw(shader* shader)
{
    GLuint tex_diffNumber = 1;
    GLuint tex_specNumber = 1;

    for (GLuint i = 0; i < this->textures.size() ; i++)
    {
        //load target texture
        glActiveTexture(GL_TEXTURE0 + i);

        std::stringstream sstream;
        std::string number;
        std::string name = this->textures[i].type;

        if (name == TEX_DIFF_NAME) 
            sstream << tex_diffNumber++;
        else if (name == TEX_SPEC_NAME) 
            sstream << tex_specNumber++;

        number = sstream.str();

        glBindTexture(GL_TEXTURE_2D, this->textures[i].id);
        glUniform1i(glGetUniformLocation(shader->shaderProgID, (name + number).c_str()), i);

    }

    //set shininess
    //glUniform1f(glGetUniformLocation(shader->shaderProgID, "material.shininess"), 16.0f);

    //draw
    glBindVertexArray(this->vao);
    glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

    //release
    for (GLuint i = 0; i < this->textures.size(); i++)
    {
        glActiveTexture(GL_TEXTURE0 + i);
        glBindTexture(GL_TEXTURE_2D, 0);
    }
}

问题是为什么我的模型有错误的三角形? 询问任何其他信息。 提前感谢您的帮助,伙计们!

【问题讨论】:

    标签: opengl rendering


    【解决方案1】:
    for (GLuint i = 0; i < mesh_->mNumFaces; i++)
    {
        aiFace face = mesh_->mFaces[i];
        for (GLuint j = 0; j < mesh_->mNumFaces; j++)
            indices.push_back(face.mIndices[j]);
    }
    

    这在我看来是错误的。我不认为内循环应该再次遍历所有面孔。相反,它应该遍历面部的所有索引:

    for (GLuint i = 0; i < mesh_->mNumFaces; i++)
    {
        aiFace face = mesh_->mFaces[i];
        for (GLuint j = 0; j < face->mNumIndices; j++)
            indices.push_back(face.mIndices[j]);
    }
    

    请注意,原始版本是在可用内存之外读取的,因为循环很可能会持续到 j = 5(六个面),但只有最多四个索引的面。如果有人会附加一个调试器并单步执行它,这应该很容易看到。

    【讨论】:

    • 谢谢大师!它解决了这个问题。完全有道理。我经常复制粘贴 for 循环,结果有些东西被遗忘了。
    猜你喜欢
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 2017-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多