我创建了一个顶点缓冲对象类来管理我的应用程序中的许多顶点。用户调用构造函数创建glBuffer并调用glBufferData来分配指定的空间量。
有一个名为resize的类函数,允许用户通过再次调用glBufferData来更改VBO的容量。我的问题是,如何解除分配先前的分配?或者它是自动完成的吗?
根据opengl文档,glDeleteBuffer只删除了缓冲区本身而没有提到用glBufferData分配的实际内存。 我可以继续在同一个绑定缓冲区上调用glBufferData而没有内存泄漏吗?答案 0 :(得分:5)
您不能通过为同一个缓冲区对象重复调用glBufferData()
来创建内存泄漏。新的分配取代旧分配。
有一个微妙的方面,大部分时间你不需要担心,但可能仍然有用的理解:有可能为同一个缓冲区对象进行多次活动分配暂时。这是因为OpenGL的异步特性。为了便于说明,请按照以下方式绘制一个呼叫序列:
glBufferData(dataA)
glDraw()
glBufferData(dataB)
glDraw()
当你按照这个顺序对第3项进行API调用时,GPU可能还没有完成来自调用2的绘制调用。它实际上可能仍然在驱动程序的某个地方排队,而不是移交给GPU尚未。由于调用2取决于dataA
,因此在GPU完成执行绘制调用2之前无法删除该数据。在这种情况下,dataA
和dataB
的分配暂时存在于同一时间时间。
如果确实删除了dataA
,取决于实施方式。它不能早于GPU完成绘制调用2的时间。之后它可以立即,基于一些垃圾收集计时器,当内存不足时,或许多其他选项。
glDeleteBuffer()
也会删除缓冲区内存。与上述内容非常相似,可能不会立即发生。同样,它只能在GPU完成执行所有使用缓冲存储器的挂起操作后删除。
如果您不打算再使用缓冲区对象,则调用glDeleteBuffer()
是最佳选择。
答案 1 :(得分:0)
10分钟后,我阅读了glBufferData页面的文档。
glBufferData为当前绑定的缓冲区对象创建一个新的数据存储 目标。任何预先存在的数据存储都将被删除。
,这解决了我的问题。我确实可以继续调用它来增加或减少我的VBO的大小。
答案 2 :(得分:0)
glDeleteBuffer
删除缓冲区句柄,系统很快就会收集/释放相关资源(如果有的话)。
如果缓冲区当前已绑定,则驱动程序将解除绑定(绑定为零),尽管删除绑定缓冲区很难。