使用缓冲区对象传输顶点数据有什么好处?

时间:2014-10-22 00:41:32

标签: opengl gpu

使用带有GL_STREAM_DRAW数据的缓冲区对象的优势是什么,只需使用指向客户端内存的指针就可以为每次使用实际更新?

正如我想象的那样,每次都必须将数据从RAM上传到GPU,那么为什么使用缓冲区对象会有优势呢?

我想象一下,使用客户端内存的一个缺点可能是驱动程序必须将内存内容复制到一边以确保它不会被再次修改或在GPU被使用之前解除分配;但是,在调用glBufferData时,这不会将数据转移到缓冲区对象中吗?如果glBufferData在调用返回之前从系统内存中上传数据,那么指定客户端内存的glVertexAttribPointer调用是否可以执行相同的操作?

2 个答案:

答案 0 :(得分:2)

使用客户端侧顶点阵列的一个主要缺点是Core Profile中不再支持它们。因此,如果您想使用核心配置文件,则无法做出选择。

对于频繁更改的顶点数据,在每次绘制调用的极端情况下,您可能还需要考虑缓冲区映射。使用glMapBufferRange()glUnmapBuffer(),您可以将数据直接写入VBO,这可以保存一个数据副本。缺点是你必须要小心,不要在CPU和GPU之间引入同步点,这会损害性能。您可以使用循环遍历多个缓冲区的方案来减少不需要的同步。

在尝试有效使用VBO时,非常动态的数据确实是最棘手的情况。我在很久以前写的一个爱好项目中有一些代码,当时使用立即模式。在这种情况下,所有坐标都是动态计算的,并且只使用一次。虽然几乎所有人都同意立即模式效率非常低(除了被弃用),但我最初尝试将VBO用于同一目的导致整个事情变得更慢!它需要一些调整,并尝试各种选项,直到我的运行速度至少与原始速度一样快。

答案 1 :(得分:1)

不,指向客户端内存的glVertexAttribPointer调用不会做同样的事情。

这只是设置一个指针。当发出绘制命令时,服务器实际上只读取该场景中的客户端内存;增加绘制调用的开销。使用VBO的真正好处来自于服务器管理内存的事实,这为驱动程序提供了一些更智能的选项,以避免在上传新数据或不必要地复制 每个<上的客户端内存时停止渲染管道/ em> 画来电。

我建议您浏览一下"buffer orphaning",以便对此问题进行更详细的讨论。缓冲孤儿是优化此特定任务的最简单策略,但如果您的目标是更新版本的OpenGL,那么还有一些其他更复杂的策略。