C++ 使用同一着色器绘制多个VAO,但不具有相同纹理或颜色的最佳方法是什么

C++ 使用同一着色器绘制多个VAO,但不具有相同纹理或颜色的最佳方法是什么,c++,opengl,C++,Opengl,我想知道如果我想画画,最好做什么 使用同一着色器的VAO超过6000个 现在我绑定我的着色器,然后给它所有需要的信息(统一),然后通过每个VAO循环绑定并绘制它们 这段代码使我的计算机以每秒200帧的速度下降,而不是3000或4000帧。 据介绍,使用GLDrawerElementsInstanced可以让我处理大量相同的VAO,但由于我有约6000个不同的VAO,似乎我无法使用它 有人能给我证实一下吗?你们这些家伙会做什么来吸引这么多的VAO,并尽可能多地节省性能 GLDrawerElemen

我想知道如果我想画画,最好做什么 使用同一着色器的VAO超过6000个

现在我绑定我的着色器,然后给它所有需要的信息(统一),然后通过每个VAO循环绑定并绘制它们

这段代码使我的计算机以每秒200帧的速度下降,而不是3000或4000帧。 据介绍,使用GLDrawerElementsInstanced可以让我处理大量相同的VAO,但由于我有约6000个不同的VAO,似乎我无法使用它

有人能给我证实一下吗?你们这些家伙会做什么来吸引这么多的VAO,并尽可能多地节省性能

GLDrawerElementsInstanced可以让我处理大量相同的VAO,但由于我有约6000个不同的VAO,似乎我无法使用它

因此,您应该做的是将对象合并到同一个VAO中。然后使用
glmultidrawArrayIndirect
glMultiDrawElementsIndirect
对同一VAO内的所有不同对象进行绘制。这就是答案


为了处理不同的纹理,您可以构建纹理图集,将纹理打包到纹理数组中,或者使用扩展(如果可用)。

步骤1:不要有6000个不同的VAO

毫无疑问,您将每个VAO视为一个单独的网格。停止这样做。相反,应将每个VAO视为单独的顶点格式。也就是说,如果要传递不同类型的顶点数据,则只需要一个新的VAO。属性的数量和每个属性的格式构成格式信息

理想情况下,您只需要4到10组单独的顶点格式。鉴于您在多个VAO上使用相同的着色器,您可能已经了解了这一点

那么,如何对多个网格使用相同的VAO?理想情况下,可以通过将特定类型网格(即:顶点格式)的所有网格数据放在同一缓冲区对象中来实现这一点。您可以通过一些技巧(如
glDrawerElementsBaseVertex
的baseVertex参数)为特定渲染操作选择要检索的数据,或者仅通过为特定绘制命令选择要从哪个索引数据范围进行绘制。其他备选方案包括渲染函数的“多重绘制”系列

如果由于某种原因无法将所有数据放在同一缓冲区中,则应该这样做。这样,您可以使用
glVertexAttribFormat
调用设置顶点格式数据,并且可以根据需要使用
glBindVertexBuffers
更改缓冲区,而无需触摸顶点格式本身。这比改变VAO要快


老实说,你无论如何都应该采用
glvertexattributeformat
,因为它是一个更好的API,不像
glvertexattributepointer
那样愚蠢。

谢谢,这是一个好主意,但它意味着我不能以不同的方式绘制VAO(就像在GL\u line\u循环中绘制所有东西,但在GL\u draw中只绘制一个)不包括在另一个VAO中。我想不是那样的importante@Xemuth你画的是什么?例如,如果你想将GL_线与GL_三角形结合起来,那么是的,在普通OpenGL中,没有办法在一次调用中组合不同类型的原语。谢谢Nicol,但要重述一下:因为我所有的数据都具有相同的顶点格式,所以我应该只使用一个VAO。要做到这一点,我必须将所有数据放在一个缓冲区中。设置“如何读取它(使用GLVertexAttributePointer?”,然后在我想要绘制其中一个时使用GLDrawerElementsBaseVertex来选择我想要绘制的数据部分。