使用VBO的最佳方式

Qua*_*hey 13 opengl vbo

什么是最快和最灵活(适用于大多数情况下)使用VBO的方法?

我正在开发一个openGL应用程序,我希望它能达到最佳性能,所以我需要有人来回答这些问题.我读了很多问题和答案,但我想有很多我不需要的信息弄乱了我的大脑......

  • 我应该使用多少个vbos?
  • 我该如何创建vbos?
  • 如果数据大小不固定,我应该如何更新vbos数据?
  • 我该如何渲染vbos?
  • 我应该如何处理我不想再渲染的vbos中的数据?

dat*_*olf 18

  • 我应该使用多少个vbos?

尽量少.切换VBO需要很小但可测量的成本.通常,您会尝试将类似的数据分组到VBO中.例如,在FPS游戏中,位于街道上的所有不同种类的垃圾,小道具等通常将位于相同或仅少量的VBO中.

它还归结为绘制批量大小.glDraw…渲染少于约100个原语的调用是次优的(即使是15年前也是如此).所以你想在可能的情况下批量至少100个原语.但是,如果单个网格只有20个三角形(用于实例化的低多元数道具等),则每个网格都在自己的VBO中,您不能再批量更多.

  • 我该如何创建vbos?

glGenBuffers→glBindBuffer→glBufferData

更新您可以将空指针传递给dataglBufferData 的参数,以初始化缓冲区对象而无需设置数据.

  • 如果数据大小不固定,我应该如何更新vbos数据?

使用比数据大小更粗的粒度创建VBO.无论如何,您的操作系统正在为您的主机端数据执行此操作,它称为分页.此外,如果你想使用glMapBuffer使缓冲对象成为主机页面大小的倍数对整个系统来说非常好.

当前系统的常用页面大小为4kiB.这就是我选择的VBO大小粒度.更新:您可以BTW询问您的操作系统正在使用的页面大小.那是OS依赖的,我会问另一个问题.

使用glBufferSubData更新数据或使用glMapBuffer在主机端映射内存中修改映射,然后使用glUnmapBuffer.

如果数据超出缓冲区对象,则创建一个新的,更大的数据并使用glCopyBufferSubData进行复制.参见lase段落.

  • 我该如何渲染vbos?

glBindBuffer→glDraw ...

  • 我应该如何处理我不想再渲染的vbos中的数据?

如果数据只消耗VBO的一部分并与其他数据共享,那么你就没有内存不足,那么就是不要访问它.理想情况下,您可以保留一些索引,在该索引中,您可以跟踪哪个VBO具有哪些部分可用于执行何种任务.这非常类似于内存管理,特别是称为对象堆栈(obstacks)的方案.

但是最终可能有必要使现有的缓冲区对象变得紧凑.为此,您将创建一个新的缓冲区对象,将其绑定为写入目标,并选择旧的缓冲区对象作为读取目标.然后使用glCopyBufferSubData将内容复制到一个新的,收紧的缓冲区对象中.当然,您必须更新对缓冲区对象名称(= OpenGL ID)和偏移的所有引用.

因此,在OpenGL缓冲区对象之上编写一个精简抽象层是有意义的,它可以跟踪OpenGL缓冲区对象中无结构blob中的实际类型化数据.