OpenGL 缓冲区与 VAO 有何关系?

How do OpenGL buffers relate to the VAO?

我目前正在学习 OpenGL,但我在理解不同缓冲区与 VAO 的关系时遇到了一些问题。在下面的代码中,我创建了一个 VAO 和两个缓冲区(VBO 用于顶点位置,EBO 用于顶点顺序)。至此,如果我没有理解错的话,VAO、VBO、EBO之间并没有什么联系。我基本上只创建了一个 VAO 和两个缓冲区。现在使用 glBindVertexArrayglBindBuffer 我告诉 OpenGL 状态机我当前使用的 VAO 并将我创建的缓冲区分配给特定的缓冲区类型。使用 glBufferData 然后我将数据加载到缓冲区中。据我了解,此时 VAO 仍然是空的,只能使用 glVertexAttribPointer 函数加载数据。现在,OpenGL 解释来自 GL_ELEMENT_ARRAY_BUFFER 的数据并将它们加载到索引 0 处的 VAO 中。然后使用 glEnableVertexAttribArray(0) 我指定我的 VAO 中索引 0 处的数据(顶点位置)应该用于渲染进程。

unsigned int VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

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

在我的主循环中,我为我的三角形指定一个着色器,绑定一个 VAO 进行渲染,然后绘制元素,然后交换前后缓冲区。

glUseProgram(shader);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);

但是 OpenGL 究竟是如何知道顶点的顺序的呢?我只将顶点位置数据上传到我的 VAO,但没有上传订单(元素)数据。在将数据加载到 VAO 中时,glVertexAttribPointer 是否考虑了来自 GL_ELEMENT_ARRAY_BUFFER 的当前绑定数据?我在这里错过了什么?

Now, OpenGL interprets the Data from GL_ELEMENT_ARRAY_BUFFER and loads them into the VAO at index 0.

没有。有点像,但不像你描述的那样。

大多数缓冲区绑定点将缓冲区绑定到 OpenGL 上下文。 GL_ELEMENT_ARRAY_BUFFER 绑定点不同。它将缓冲区附加到本身绑定到上下文的 VAO。也就是说,调用 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER) 本身 的行为是在 VAO 和索引缓冲区之间创建关联的。本协会与glVertexAttribPointer.

无关

这也意味着,如果您没有绑定到上下文的 VAO,则无法将任何内容绑定到 GL_ELEMENT_ARRAY_BUFFER