opengl 为什么要用 VAO 绑定索引缓冲区来绘制元素?

n7taea2i  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(145)

我使用下面的代码来渲染一个使用顶点数组和索引缓冲区的简单四边形。
在Vertex规范中,我看到
索引缓冲区绑定存储在 VAO 中。
但在我的代码中,在渲染循环中,我需要绑定索引缓冲区才能看到四元数组。
数据:

float mesh[24] = {
        // pos           // color
          0, 0,  0,      1, 1, 0,
        -.5, 0,  0,      0, 1, 1,
        -.5, 0, .5,      1, 0, 1,
          0, 0, .5,      1, 1, 1
};
int indices[6] = {0, 1, 2, 0, 2, 3};

缓冲区的初始化:

GLuint vao{};
GLuint buffers[2]{};

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glGenBuffers(2, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(float), mesh, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(int), indices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

在主循环中,我用途:

glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); // Why this line is necessary ?
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
glBindVertexArray(0);

为什么要在渲染循环中使用glBindBuffer()GL_ELEMENT_ARRAY_BUFFER

a14dhokn

a14dhokn1#

为什么这条线是必要的?
这不是必须的。但是,元素缓冲区引用存储在 VAO 中。只需删除glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);。这一行打破了索引缓冲区与VAO的绑定。
索引缓冲区(ELEMENT_ARRAY_BUFFER)绑定存储在顶点数组对象中。当调用glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO)时,元素缓冲区对象ID存储在当前绑定的顶点数组对象中。因此, VAO 必须在使用glBindVertexArray(VAO)绑定元素缓冲区之前绑定。
与索引缓冲区不同,顶点缓冲区绑定(ARRAY_BUFFER)是一个全局状态。
在VAO状态向量中陈述的每个属性可以指不同的ARRAY_BUFFER,当glVertexAttribPointer被调用时,当前绑定到目标ARRAY_BUFFER的缓冲器被关联到指定的属性索引,并且对象的ID被存储在当前绑定的VAO的状态向量中。

相关问题