VertexArrayObjects是否在实践中使用?

时间:2014-01-03 16:58:33

标签: opengl vao

我目前正在学习OpenGL,而VAO让我感到困惑。据我所知,VAO只是封装了VBO的状态。

Bind VAO
load buffer data
Disable VAO

然后你可以像

一样画画
activate VAO
DrawArray ...
deactivate VAO

但我不确定这在实践中是否真的有用。假设我有一个非常大的场景,我想渲染。也许10平方公里,我显然不希望一次将每个对象加载到GPU上,我可能想将场景分成不同的块。

现在我正在四处走动,有一点我必须将另一块物体加载到GPU上吗?但据我所知,我不能改变VAO,每当我的场景发生变化时,我都必须创建一个新的VAO。

那么在我的场景中会有什么样的VAO?整个场景都是VAO吗?或者每个对象都是VAO?

对于我来说,有多个VAO没有太多意义,因为我无法将VAO组合在一起我只能将它们画在彼此之上

activate VAO1
DrawArray ...
deactivate VAO1

activate VAO2
DrawArray ...
deactivate VAO2

2 个答案:

答案 0 :(得分:2)

您无法启用或禁用VAO,它们是OpenGL中的一类对象,称为容器(与FBO相同)。它们为顶点数组绘制操作和描述它们所需的状态提供上下文。您肯定可以更改VAO,它们只是状态容器...绑定它然后更改它存储的其中一个状态。无论您是在整个场景中使用一个VAO还是多个VAO都取决于您,但请记住在核心OpenGL 3.2上下文中,您无法发出 任何 顶点绘制命令至少有一些VAO受约束。

此外,VAO与 当前绑定的 缓冲区对象本身无关,但元素数组缓冲区除外。 VAO存储顶点数组指针,可能直接或间接(参见:GL_ARB_vertex_attrib_binding)绑定到VBO,但VAO根本不关心VBO当前绑定的内容{{ 1}}。正如我所提到的,元素数组缓冲区不同,VAO 执行跟踪当前绑定的元素数组缓冲区,以便对GL_ARRAY_BUFFER的调用仅具有一致的行为通过绑定VAO。如果没有此属性,则必须先绑定VAO,然后再绑定元素数组缓冲区,然后才能发出索引绘制操作。

答案 1 :(得分:0)

您的第一个声明:

  

据我所知,VAO只是封装了VBO的状态。

大多是正确的,因为VBO是VAO中存储最多的缓冲区,但是与顶点处理相关的任何类型的缓冲区(即元素数组,间接绘制缓冲区等,取决于您支持哪些缓冲区)版本的OpenGL也包含在VAO中。

将VAO添加到API的原因是减少了为不同对象交换数据所需的函数调用次数。在具有需要不同顶点属性集的多个对象的应用程序中,在VAO之前,您需要为呈现该对象所需的每个VBO(包括元素数组缓冲区)调用glBindBuffer(顶点属性的关联)位置和缓冲区是该缓冲区的属性,而不是VAO的属性,以防您遇到该问题)。正如您所提到的,VAO允许将所有这些绑定封装到单个对象中,只需对glBindVertexArray进行一次调用即可绑定。

你也在VAO之间交换正确的轨道。在应用程序的初始化中(或者当您需要添加更多对象时),您可以根据需要创建和初始化任意数量的VAO,并为每个VAO绑定它,并使用其所有相关缓冲区填充它。当你想使用它时,你只需绑定它。还值得注意的是,您始终可以使用glBufferData或类似调用更新VBO中的数据,并且该操作不会对与该缓冲区关联的VAO所包含的绑定产生任何影响。