0

我可以得到更全面/一般的描述吗?

我整个星期都在尝试研究这些东西,但我只涉及到超级技术的解释或示例。

有人可以解释这些 VAO 的整体过程或目标吗?也许概述了在 OpenGL 中设置 VAO 的“逐步”流程图?

我从来都不是通过例子学习的人......所以到目前为止我在网上找到的所有东西都真的没有帮助。

4

4 回答 4

4

您的顶点缓冲区对象 (VBO) 包含顶点数据。您设置属性指针,指定应如何访问和解释数据以绘制顶点 - 每个顶点有多少组件,它们如何存储(例如 GL_FLOAT)等。

顶点数组对象 (VAO) 保存了所有这些属性。它们的目的是允许您设置这些属性一次,然后在需要使用它们时通过一次状态更改来恢复它们。

这样做的好处是您可以轻松设置多个状态并恢复它们——如果我想绘制一个立方体和一个三角形,这是两种不同的状态——我为每个状态创建一个 VAO,VAO 为每个状态保存状态。当我想绘制立方体时,我只恢复立方体的状态。

设置

设置有四个步骤:

  1. 创建 VAO
  2. 绑定 VAO
  3. 设置状态
  4. 解除绑定 VAO

创建 VAO 非常简单:

GLuint vao_name;
glGenVertexArrays(1, &vao_name);

这将生成一个顶点数组,并将其名称存储在 vao_name 中。

创建 VAO 后,您需要绑定它:

glBindVertexArray(vao_name);

现在,您对属性指针或到元素数组缓冲区的绑定所做的任何更改都将被保存。这是对以下任何一项的调用:

  1. glVertexAttribPointer(...)
  2. glEnableVertexAttribArray(...)
  3. glDisableVertexAttribArray(...)
  4. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)

每当您进行这些调用之一时,相应的状态都会保存在当前绑定的 VAO 中。当您稍后再次绑定 VAO 时,状态将恢复。

设置状态后,您可以取消绑定 VAO。通过绑定 VAO 0 来做到这一点:

glBindVertexArrays(0);

您还可以绑定不同的 VAO 并为此设置不同的状态。发生这种情况时,可以安全地更改属性指针,而不会破坏您之前的状态。

绘画

当你想画一些东西时,你所要做的就是恢复 VAO:

glBindVertexArray(cube_vao)
glDrawArrays(GL_TRIANGLES, 0, 36);

glBindVertexArray(triangle_vao);
glDrawArrays(GL_TRIANGLES, 0, 3);

glBindVertexArray(0);                //Unbind the VAO

编辑:

这些是我试图理解 VAO 时帮助我的一些答案: glVertexAttribPointer overwriteglVertexAttribPointer clarification什么时候应该调用 glVertexAttribPointer?

此外,一旦您了解了基础知识,OpenGL 规范就会很好地解释它:https ://www.opengl.org/registry/

于 2015-02-02T22:22:00.157 回答
1

VAO 包含有关如何从 VBO 读取属性的所有信息。

这包括每个属性,它所在的 VBO;偏移量、步幅、编码方式(int、float、规范化与否)、每个属性有多少值。换句话说,glVertexAttribPointer(以及调用时绑定的 GL_ARRAY_BUFFER 的参数。

它还保存保存索引的元素数组缓冲区。

于 2015-02-02T07:58:06.783 回答
0

对于 VAO 是什么,请参阅@ratchet-freak 的回答。

至于VAO 的目标,它是通过允许单个状态更改来设置所有顶点属性绑定来提高性能的问题,这不仅意味着更少的函数调用,而且为 OpenGL 实现提供了更多机会来优化这个状态作为一个整体。

于 2015-02-02T10:44:12.130 回答
0

对于 VAO,了解 VBO 和着色器是先决条件。VAO 提供了一种“预定义”顶点数据及其属性的方法。

一种理解方法是使用 VBO 绘制,然后使用 VAO 绘制相同的内容。您会注意到它类似于使用 VBO 进行绘图,只是它首先“保存”在 VAO 中供以后使用。随后,激活 VAO 以实际绘制保存的状态。

请参阅VBO、Shader、VAO以获得相当好的示例。

于 2016-05-18T13:34:38.777 回答