使用VBO的最快和最灵活(适用于大多数情况)的方式是什么?
我正在开发一个OpenGL应用程序,并希望它能达到最佳性能,所以我需要有人回答这些问题。我读了许多问题和答案,但我觉得有太多我不需要的信息,这让我的脑子混乱了...
- 我应该使用多少个VBO?
- 我应该如何创建VBO?
- 如果数据大小不固定,我应该如何更新VBO的数据?
- 我应该如何渲染VBO?
- 对于我不想再渲染的VBO中的数据,我应该如何处理?
- 我应该使用多少个vbo?
尽量少。切换VBO会带来一些小的但可测量的成本。通常,您将尝试将相似的数据分组到VBO中。例如,在FPS游戏中,所有不同种类的垃圾、小道具等通常位于同一个或仅有少量的VBO中。
这也取决于绘制批次的大小。渲染少于约100个基元的glDraw...
调用是次优的(即使15年前也是如此)。因此,您应尽可能对至少100个基元进行批处理。但是,如果单个网格仅具有,比如20个三角形(低多边形计数道具的实例化或类似),每个三角形都在自己的VBO中,则无法再进行更多批处理。
- 我应该如何创建vbos?
glGenBuffers → glBindBuffer → glBufferData
更新:您可以将null指针传递给glBufferData
的data
参数,以初始化缓冲对象而不设置数据。
- 如果数据大小不固定,我应该如何更新vbos数据?
创建VBO的粒度比数据大小更粗。您的操作系统对主机侧数据已经这样做了,它被称为分页。此外,如果要使用glMapBuffer,使缓冲对象成为主机页大小的倍数非常适合整个系统。
当前系统上的常规页面大小为4kiB。因此,我会选择VBO大小粒度。 更新:顺便说一句,您可以询问操作系统正在使用哪个页面大小。尽管如此,我会就此提出另一个问题。
使用glBufferSubData
更新数据或使用glMapBuffer
在主机侧映射内存中修改,然后glUnmapBuffer
。
sysconf(_SC_PAGESIZE);
进行查询。http://linux.die.net/man/3/sysconf - 在Windows中有函数GetSystemInfo
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724423(v=vs.85).aspx - datenwolf我应该使用多少个VBO?
需要多少就用多少,听起来很傻,但事实就是这样。
如果数据大小不固定,我该如何更新VBO的数据?
使用不同的数据和长度覆盖并渲染相同的VBO。
我应该如何创建VBO?
我应该如何渲染VBO?
请参见VBO教程。
我应该如何处理不想再渲染的VBO中的数据?
创建一个新的VBO并将数据复制到其中,或者仅渲染内存中的那部分VBO。
要仅渲染部分,请参见glVertexBufferglTexCoordPointer(根据偏移量计算新指针和新大小)。
编辑1:
使用单个VBO来处理所有内容感觉不太对,因为您必须自己管理新顶点位置/纹理坐标的分配,这会变得非常混乱。
最好将小道具分组到VBO中,并批量处理绘图命令。
我可以使用glBufferSubData向缓冲区添加数据(向大小为x的缓冲区添加100个元素)吗?
不行,因为描述中说更新缓冲对象数据存储的子集
,而子集是集合内的较小集合。
编辑2
一个很好的教程是学习现代3D图形编程,但它不是特定于VBO的。