我可以在 OpenGL 中将 VAO 设置在 VBO 之前吗?

Can I set VAO before VBO in OpenGL?

我有一个 Sphere class 可以生成用于创建给定输入半径和更多参数的 VBO。

每个 Sphere VBO 共享相同的内存布局(假设顶点索引 0 = 顶点,1 = 颜色)。

我可能理解错了,但如果理解正确的话,状态就是 VAO 存储的内容。但是不知道是VAO提示绑定了哪个VBO还是使用当前绑定的VBO。但我认为它在修改它时使用了 VBO 绑定(因此这意味着为每个 Sphere 渲染重新配置 VAO)

问题 #1

是否可以将所有球体存储在 VAO 上?多个VBO共享一个VAO。

问题 #2

我们可以独立于 VBO 设置 VAO 吗?我想说,甚至在创建 VBO 之前并且没有 VBO 绑定,例如在创建 Spheres 之前的静态函数中。

问题 #3

这个问题可能没有意义并且是针对具体情况的,但是我应该为每个 Sphere 使用一个 VAO 和一个 VBO 还是为所有 Sphere 共享一个 VAO(如果可能的话)?

使用没有缓冲对象的 API, it is easy to set up a VAO independently from any particular set of source buffer objects. The vertex format information (component type, count, etc) can all be established via glVertexAttribFormat。您甚至可以设置属性索引和缓冲区绑定点之间的关系,以便您可以从单个缓冲区绑定中读取交错的属性。所有这些都没有绑定缓冲区对象。

现在在数据结束时,您必须在渲染时将缓冲区对象附加到 VAO(通过 glBindVertexBuffer(s))。 VAO 将存储上次设置的缓冲区。但你基本上应该忽略这一点。将 VAO 视为顶点格式状态,缓冲区绑定是您在使用它进行渲染之前所做的事情。

是的,有一个 VAO 和多个以该顶点格式读取的潜在缓冲区(或者更好的是,只有一个缓冲区,其中包含多个网格数据,它们都共享相同的顶点格式,网格选择是通过the baseVertex parameter of glDrawElementsBaseVertex) 是正确的方法。


综上所述,您还应该记住,所有球体都是相同的网格。它们可能以不同的大小出现在不同的位置,但这只是提供单位球体的不同变换的问题。使用多个球体网格的唯一原因是如果您需要不同的 分辨率 球体(更多多边形与更少)。