OpenGL VBO更新数据

17

我需要绘制一个包含数千个顶点的缓冲区。我使用VBO来存储数据。

我知道我需要多次更新VBO,但每次只更新一小部分。

因此,我想知道最好的方法是什么:

  1. 将VBO分成较小的VBO(每个VBO包含大约300个顶点),然后使用1个调用更新单个VBO?
  2. 使用一个大的VBO,并使用大量glBufferSubData()调用?
  3. 使用glMapBuffer()和一个大的VBO?
2个回答

10

还有另一种选择,有点像选项3 - 使用一个大的VBO(可能使用GL_STREAM_DRAW模式),每帧重置一次(通过调用glBufferData并传入NULL缓冲指针和相同的大小)。然后立即使用glMapBuffer将其映射。缓冲区在填充时保持映射状态,然后在绘制之前取消映射。重复此过程。

glBufferData的调用告诉OpenGL旧的缓冲区内容不再需要,因此glMapBuffer不必等待GPU完成。

这种方法似乎是由vertex_buffer_object扩展官方认可的。请参考“使用映射缓冲对象的顶点数组”示例:

http://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt

这表明OpenGL(或驱动程序?)将会监视这种行为,并在发现时安排事情以使其高效执行。

2
  1. 听起来不是一个好主意:它会强制你在多个调用中绘制它,同时在每次绘制调用之间更改绑定缓冲区。
  2. 如果您的缓冲区非常大,这可能行得通。
  3. 整个缓冲区肯定会上传到GPU。这肯定和一个glBufferData一样有效,但您可以异步执行它。

如果您的缓冲区很小,则认为glBufferData或glMapBuffer是更好的解决方案。100000 * sizeof(float) * 3 ~= 1MB。那应该没有问题。


附注:我已经知道我必须分几次绘制它 - 无论我是否使用许多VBO。 我也知道我每次只会绘制部分顶点。 更改绑定的VBO缓冲区是否有很多开销? 另外,mapBuffer比bufferdata慢吗? - Pubby
mapBuffer 的优点在于,当 GL 在执行其他操作时,你可以在缓冲区内复制数据。另一方面,缓冲区映射的性能实际上非常依赖于具体实现。如果你可以避免多次更改 VBO,则建议这样做。 - tibur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接