openGL 索引渲染问题

Posted

技术标签:

【中文标题】openGL 索引渲染问题【英文标题】:openGL indices rendering issues 【发布时间】:2021-07-24 23:22:22 【问题描述】:

我希望有人可以帮助我了解我缺少什么或做错了什么。我正在尝试制作一个简单的金字塔,但由于某种原因,金字塔的底部不会呈现(构成底部的两个三角形)。

GLfloat verts[] = 

        // Vertex Positions    // Colors (r,g,b,a)

        //front triangle
         0.0f,  1.0f, 0.0f,   1.0f, 0.0f, 0.0f, 1.0f, // Top Right Vertex 0
        -1.0f, -1.0f, 1.0f,   0.0f, 1.0f, 0.0f, 1.0f, // Bottom Right Vertex 1
         1.0f, -1.0f, 1.0f,   0.0f, 0.0f, 1.0f, 1.0f, // Bottom Left Vertex 2

        //right triangle
         0.0f,  1.0f, 0.0f,   1.0f, 0.0f, 1.0f, 1.0f, // Top Right vertex 3
         1.0f, -1.0f, 1.0f,   0.5f, 0.5f, 1.0f, 1.0f, // 4 
         1.0f,  -1.0f, -1.0f,  1.0f, 1.0f, 0.5f, 1.0f, //  5 

         //back triangle
         0.0f,  1.0f, 0.0f,   0.2f, 0.2f, 0.5f, 1.0f, //  6  
         1.0f, -1.0f, -1.0f,  1.0f, 0.0f, 1.0f, 1.0f, //  7 
        -1.0f, -1.0f, -1.0f,  1.0f, 0.0f, 1.0f, 1.0f, // 8

        //left triangle
        0.0f,  1.0f,  0.0f,  1.0f, 0.0f, 1.0f, 0.5f, // 9
       -1.0f, -1.0f, -1.0f,  0.0f, 0.0f, 1.0f, 1.0f, // 10
       -1.0f, -1.0f,  1.0f,  0.5f, 0.5f, 1.0f, 1.0f // 11

       //bottom triangle
       - 1.0f, -1.0f,  1.0f,  0.0f, 0.0f, 0.0f, 0.0f, //12
        1.0f, -1.0f,  1.0f,  0.0f, 0.0f, 0.0f, 0.0f, //13
       -1.0f, -1.0f, -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, //14

        //bottom triangle right
       -1.0f, -1.0f, -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, //15
        1.0f, -1.0f, -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, //16 
        1.0f, -1.0f, -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, //17

    ;

以下是为每个三角形列出的索引

GLushort indices[] = 
        0, 1, 2,     // Triangle 1
        3, 4, 5,     // Triangle 2
        6, 7, 8,     // Triangle 3
        9, 10, 11,   // Triangle 4
        12, 13, 14,  // Triangle 5
        15, 16, 17,  // Triangle 6
    

您可以在下面看到我在哪里根据索引的大小定义顶点数并创建 VBO 和缓冲区

 const GLuint floatsPerVertex = 3;
    const GLuint floatsPerColor = 4;

    //mesh.nVertices = sizeof(verts) / (sizeof(verts[0]) * (floatsPerVertex + floatsPerColor));
    mesh.nVertices = sizeof(indices) / (sizeof(indices[0]));
    glGenVertexArrays(1, &mesh.vao); // we can also generate multiple VAOs or buffers at the same time
    glBindVertexArray(mesh.vao);

    // Create VBO
    glGenBuffers(2, mesh.vbo);
    glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo[0]); // Activates the buffer
    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); // Sends vertex or coordinate data to the GPU

    //buffer for indices
    //mesh.nVertices = sizeof(indices) / sizeof(indices[0]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vbo[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // Strides between vertex coordinates
    GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor);

    // Create Vertex Attribute Pointers
    glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
    glEnableVertexAttribArray(1);

在下面我激活网格来绘制元素

// Activate the VBOs contained within the mesh's VAO
    glBindVertexArray(gMesh.vao);

    glDrawElements(GL_TRIANGLES, gMesh.nVertices, GL_UNSIGNED_SHORT, NULL); // draws the triangle for pyramids
    glBindVertexArray(0);

【问题讨论】:

您检查过它们的朝向是否正确吗? @Neil 我相信我有,我不知道是否有更好的方法,但我尝试通过使三角形的顶点更长并在不同的位置来调整三角形的顶点,看看它是否会扭曲我的金字塔,但没有任何改变......我想我在尝试渲染底部的两个三角形时做错了,但我看不到什么。 (我基本上是自学openGL) 【参考方案1】:

发现错误:


        //bottom triangle right
       -1.0f, -1.0f, -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, //15
        1.0f, -1.0f, -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, //16 
        1.0f, -1.0f, -1.0f,  0.0f, 0.0f, 0.0f, 0.0f, //17

编号为 16 和 17 的顶点具有相同的值。您确定要为三角形打印相同的顶点吗?

【讨论】:

我错误地替换了那里的值,之前我已经将这些值更改为非常大的值,以查看它是否会严重扭曲金字塔的任何一侧,因此我可以直观地看到它是否正在渲染这些顶点但是不正确。我没有发现任何变化。我想知道我是否没有正确生成 VBO? 尝试将 glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex)); 中的类型更改为 glVertexAttribPointer(1, floatsPerColor, GL_UNSIGNED_SHORT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex)); 不知道是否有帮助,但由于您使用无符号短裤作为索引,您可以尝试将类型设置为无符号短裤 还可以尝试将glVertexAttribPointer() 中的最后一个参数从(char*) 更改为(void*),因为最后一个参数的类型是const void*。不知道这是否也有帮助,但试试吧。 感谢所有提示!我发现了问题,最终是我在三角形 11 的末尾错过了一个逗号,哈哈。它总是导致问题的最简单的事情,而不会弹出任何类型的错误 哦,没想到会这样^-^。

以上是关于openGL 索引渲染问题的主要内容,如果未能解决你的问题,请参考以下文章

使用索引在 OpenGL 中渲染四边形的问题

索引顺序影响 OPENGL 中的立方体结构

在 OpenGL 中渲染 .ply 文件

glDrawElement 的 OpenGL 渲染问题

opengl vbo 纹理

使用 OpenGL 和顶点数组对象渲染两个对象