【问题标题】:OpenGL. Updating vertex buffer with glBufferDataOpenGL。使用 glBufferData 更新顶点缓冲区
【发布时间】:2013-03-05 20:05:27
【问题描述】:

我正在使用OpenGL 来实现某种批量绘图。为此,我创建了一个 vertex buffer 来存储数据。

注意:这个缓冲区通常会在每一帧更新,但永远不会减小大小(但仍然可以增加)。

我的问题是:使用glBufferData(带有streaming write-only mode)来更新它(而不是例如glMapBuffer)在技术上是否正确?我想没有必要映射它,因为完整的数据已经更新,所以我一次发送一个完整的包。如果当前缓冲区大小小于我发送的大小,它会自动增加,不是吗?我现在才确定它的实际工作方式(也许它会在每次调用时重新创建缓冲区,不是吗?)。

【问题讨论】:

    标签: opengl streaming vertex-buffer


    【解决方案1】:

    最好有固定大小的缓冲区,不要每帧都重新创建。

    您可以通过以下方式实现:

    • 创建最大大小的缓冲区,例如 1000 个顶点的空间
    • 只用新数据更新缓冲区的开头。因此,如果您更改了 500 个顶点的数据,则使用 glMapBuffer 填充缓冲区的前半部分
    • 绘制时更改绘制顶点的计数。例如,您可以仅使用整个 1000 个顶点缓冲区中的某个顶点范围(例如,从 200 到 500)。使用 glDrawArrays(mode, first, count)

    来自 cmets 的想法:

    • glMapBufferRange 和 glBufferSubData 也有帮助
    • 还要考虑缓冲区的双缓冲

    链接:http://hacksoflife.blogspot.com/2010/02/double-buffering-vbos.html

    希望对你有帮助

    【讨论】:

    • 感谢您的回复!但这有点不同:不可能创建最大大小的缓冲区。但是改变它的大小的可能性非常低,所以现在这是一个问题。至于绘图范围 - 这就是我现在所做的。但是我可以问一个关于您的第二个选项的问题(仅更新一系列顶点):在这种情况下,我总是将我的数据存储在一个连续的块中(在 CPU 上),这样我就可以使用相同的 glBufferData 更新缓冲区,但指定的尺寸更小 - 结果相同?它不会破坏缓冲区或重新创建它吗?谢谢
    • 通过每帧删除一个缓冲区并创建一个新缓冲区,您肯定会在 GPU/CPU 之间获得更好的性能吗?如果 GPU 当前正在使用缓冲区,更新可能正在使用的缓冲区会不会导致一些潜在的阻塞?
    • 这里有一些有趣的链接:hacksoflife.blogspot.com/2010/02/double-buffering-vbos.html,还有一个 glMapBufferRange 函数可以提供帮助。
    • @Celestis:是的,就像所有内存分配一样,glBufferData 是一个缓慢的操作。但是 glBufferSubData 非常快,glMapBuffer[Range] 和 glUnmapBuffer 也是如此。顺便说一句,在客户端/CPU 端分配内存也很慢;如果你告诉 OpenGL 分配一些内存,它必须在 GPU 和 CPU 端都这样做。所以最好避免。预分配一个只使用一个子集的大缓冲区是可行的方法。
    • @Celestis:是的,这就是一般的想法。但是,如果您不断更新数据,则应使用 2 或 3 个缓冲区,在其中循环更新数据。例如,仅在过去 2 天里,我编写了一个小型“示波器”来可视化实验中 DAQ 系统提供的波形……以 1.5GSamples/sec 的速率;即我必须以 1.5GByte/s 的速率更新 VBO。
    【解决方案2】:

    除了fen和datenwolf所说的,见Chapter 22 of OpenGL Insights;特别是,它包括各种硬件和技术的时序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-11
      • 1970-01-01
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-31
      相关资源
      最近更新 更多