OpenGL。使用glBufferData更新顶点缓冲区

OpenGL。使用glBufferData更新顶点缓冲区,opengl,streaming,vertex-buffer,Opengl,Streaming,Vertex Buffer,我正在使用OpenGL实现某种批处理绘图。为此,我创建了一个顶点缓冲区来存储数据 注意:此缓冲区通常会在每一帧上更新,但不会减小大小(但仍可能增大) 我的问题是:使用glBufferData(使用streaming write-only mode)来更新它(而不是例如glMapBuffer)在技术上是否正确?我想没有必要映射它,因为完整的数据是更新的,所以我只需立即发送一个完整的包。如果当前缓冲区的大小小于我发送的大小,它将自动增加,不是吗?我刚刚确定了它的工作方式(可能每次调用时都会重新创建缓

我正在使用
OpenGL
实现某种批处理绘图。为此,我创建了一个
顶点缓冲区来存储数据

注意:此缓冲区通常会在每一帧上更新,但不会减小大小(但仍可能增大)


我的问题是:使用
glBufferData
(使用s
treaming write-only mode
)来更新它(而不是例如
glMapBuffer
)在技术上是否正确?我想没有必要映射它,因为完整的数据是更新的,所以我只需立即发送一个完整的包。如果当前缓冲区的大小小于我发送的大小,它将自动增加,不是吗?我刚刚确定了它的工作方式(可能每次调用时都会重新创建缓冲区,不是吗?)

最好是使用固定大小的缓冲区,而不要在每一帧都重新创建缓冲区

您可以通过以下方式实现此目的:

  • 创建最大大小的缓冲区,例如1000个顶点的空间
  • 仅使用新数据更新缓冲区的开头。所以,如果您更改了500个顶点的数据,则使用glMapBuffer填充缓冲区的上半部分
  • 绘制时更改绘制顶点的计数。例如,您可以仅使用整个1000个顶点缓冲区中的一些顶点范围(例如,从200到500)。使用gldrawArray(模式,第一,计数)
评论中的想法:

  • glMapBufferRange和glBufferSubData也有帮助
  • 还考虑缓冲区
  • 的双重缓冲
链接:


希望这有助于

除了fen和datenwolf所说的,请参见;特别是,它包括各种硬件和技术的时间安排。

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