【发布时间】:2013-08-28 10:28:30
【问题描述】:
我正在编写一个 OpenGL3+ 应用程序,但对 VAO 的使用有些困惑。现在我只有一个 VAO,一个围绕原点的标准化四边形集。这个单一的 VAO 包含 3 个 VBO;一个用于位置,一个用于表面法线,一个 GL_ELEMENT_ARRAY_BUFFER 用于索引(所以我只能存储 4 个顶点,而不是 6 个)。
我已经设置了一些辅助方法来将对象绘制到场景中,例如drawCube(),它采用位置和旋转值并遵循程序;
- 绑定quad VAO。
- 每个立方体面:
- 创建一个代表这张脸的模型矩阵。
- 将模型矩阵上传到
uniform mat4 model顶点着色器变量。 - 调用
glDrawElements()将四边形绘制到该面的位置。
我刚刚开始添加每个立方体颜色的任务,并意识到我不能将我的颜色 VBO 添加到单个 VAO,因为它会随着每个立方体而变化,这感觉不对。
我刚刚阅读了这个问题; OpenGL VAO best practices,它告诉我我的方法是错误的,我应该使用更多的 VAO 来节省每次设置整个场景的工作。
应该使用多少个 VAO? 显然我使用 1 个的方法不是最优的,场景中的每个静态表面是否应该有一个 VAO?那些会动的呢?
我正在为每个顶点写入一个统一变量,对吗? 我读到 uniform 着色器变量不应该在帧中更改,如果我能够将不同的值写入我的uniform 变量,制服与顶点着色器中的简单 in 变量有何不同?
【问题讨论】:
-
VAO 不包含任何 VBO。这是关于 VAO 如何工作以及它们的状态向量实际包含什么的常见误解。您可以完全初始化 VAO,而无需绑定 VBO。它不会让您将单个顶点推入管道,但这是可能的。话虽如此,在您的情况下,术语“VBO”是模棱两可的。通常,您将绑定到 GL_ARRAY_BUFFER 的缓冲区对象称为 VBO。这样的缓冲区对象与绑定到 GL_ELEMENT_ARRAY_BUFFER 的缓冲区对象具有不同的语义。后者的绑定实际上是 VAO 状态。但是,它们仍然只是缓冲区对象。
-
"我正在为每个顶点写入一个统一变量,对吗?" 这不仅不正确,而且不可能。要么你混淆了你的条款,要么你正在做一些你没有意识到你正在做的事情。
-
@NicolBolas 我将调用
glDrawElements与调用glUniformMatrix4交错,通过更新模型矩阵(声明为uniform mat4 model)将相同的VAO 绘制到不同的位置。我只能假设这是可行的,因为我的立方体出现在预期的位置,并且没有对这些位置进行其他用途。 -
@thokra 谢谢,我觉得 ELEMENT 缓冲区不同,但没有意识到将 is 称为 VBO 是不正确的。我应该为我的世界中的每个多边形使用 VAO 吗?或者一个 VAO 用于所有具有相同纹理的表面,等等...我试图弄清楚应该使用什么粒度的 VAO。
-
@lynks:Nicol Bolas 的意思是,您无法更改单个绘图调用提交的每个顶点的统一变量的值。您只能在两次绘图调用之间更改制服,但不能为每个顶点更改制服,除非您为每个顶点发出绘图调用,这通常是愚蠢的,甚至不适用于除 POINTS 之外的任何基本类型。