OpenGL索引缓冲区对象元素顺序绘制不正确

Posted

技术标签:

【中文标题】OpenGL索引缓冲区对象元素顺序绘制不正确【英文标题】:OpenGL Index Buffer Object element order incorrectly drawn 【发布时间】:2019-09-28 16:31:45 【问题描述】:

请注意我的程序是如何绘制一个三角形的,但我试图在代码中表达的是绘制一个正方形。我的tri_indicies 索引缓冲区对象我相信正确地对这些元素进行排序,以便绘制一个正方形,但是在执行程序时,我在tri_indicies 中定义的绘制顺序不会反映在窗口中。不确定错误是否源于tri_indicies,尽管我对元素顺序的更改不会影响我的渲染输出,但我想相信它在这里,但它很可能在其他地方。

我的程序使用抽象来特别是 VertexBuffer、VertexArray 和 IndexBuffer,所有这些都在下面详述。

const int buffer_object_size = 8;
const int index_buffer_object_size = 6;
float tri_verticies[buffer_object_size] = 
    -0.7f, -0.7f, // 0
     0.7f, -0.7f, // 1
     0.7f,  0.7f, // 2
    -0.7f,  0.7f  // 3
;
unsigned int tri_indicies[index_buffer_object_size] = 
    0, 1, 2,
    2, 3, 0
;

VertexArray vertexArray;                
VertexBuffer vertexBuffer(tri_verticies, buffer_object_size * sizeof(float)); // no call vertexBuffer.bind() constructor does it    

VertexBufferLayout vertexBufferLayout;
vertexBufferLayout.push<float>(3);
vertexArray.add_buffer(vertexBuffer, vertexBufferLayout);

IndexBuffer indexBuffer(tri_indicies, index_buffer_object_size);        

ShaderManager shaderManager;
ShaderSource shaderSource = shaderManager.parse_shader("BasicUniform.shader");  // ensure debug working dir is relative to $(ProjectDir)
unsigned int shader = shaderManager.create_shader(shaderSource.vertex_source, shaderSource.fragment_source);
MyGLCall(glUseProgram(shader));

稍后在 main 中,我有一个循环,应该将我的正方形绘制到屏幕上并淡化 1.0f0.0f 之间的蓝色值。

while (!glfwWindowShouldClose(window))

    MyGLCall(glClear(GL_COLOR_BUFFER_BIT));

    vertexArray.bind();
    indexBuffer.bind();

    MyGLCall(glDrawElements(GL_TRIANGLES, index_buffer_object_size, GL_UNSIGNED_INT, nullptr)); // nullptr since we bind buffers using glGenBuffers

    if (blue > 1.0f) 
        increment_color = -0.05f;
    
    else if (blue < 0.0f) 
        increment_color = 0.05f;
    

    blue += increment_color;

    glfwSwapBuffers(window);
    glfwPollEvents();

【问题讨论】:

【参考方案1】:

数组tri_verticies 由顶点坐标和两个分量(x, y) 组成。因此,用于规范通用顶点属性数据数组的元组大小必须是 2 而不是 3:

vertexBufferLayout.push&lt;float&gt;(3);vertexBufferLayout.push&lt;float&gt;(2);

你实际上做的是指定一个具有以下坐标的数组:

-0.7, -0.7,  0.7 // 0
-0.7,  0.7,  0.7 // 1
 ???,  ???,  ??? // 2
 ???,  ???,  ??? // 3

通常,对缓冲区对象的越界访问会产生未定义的结果。 见OpenGL 4.6 API Core Profile Specification - 6.4 Effects of Accessing Outside Buffer Bounds, page 79

【讨论】:

已修复,谢谢!我明白了,我是否有坐标为 (x, y, z) 的组件,在这种情况下它将是 3。

以上是关于OpenGL索引缓冲区对象元素顺序绘制不正确的主要内容,如果未能解决你的问题,请参考以下文章

初识OpenGL (-)EBO元素缓冲对象

Opengl_8_索引绘制

为啥 OpenGL 缓冲区解除绑定顺序很重要? [复制]

我的OpenGL学习进阶之旅介绍顶点缓冲区对象VBO和元素数组缓冲区对象EBO,并对比使用VBO和不使用VBO绘制三角形的效果

OpenGL:如何在一次调用中绘制多条线带?

无法使用 VAO 和 EBO (openGL) 绘制多个对象