OpenGL:如何正确解绑和删除缓冲区

时间:2013-08-13 13:25:45

标签: opengl memory-management opentk

我正在学习opengl并写了一个简单的程序,它使用缓冲对象(颜色,位置,法线,元素索引)来绘制如下形状。即使删除和解除绑定,GPU监视程序也会在每次单击按钮后显示内存使用量增加。内存仅在我关闭应用程序时发布。如果我多次单击按钮,GPU ram将填充到2GB并开始溢出来托管ram。如何正确释放资源/缓冲区?

enter image description here

程序流程如下:

 When I click a button, the below program is executed:

 glControl1.MakeCurrent();
 GL.GenBuffers(4,buf)
 GL.BindBuffer(BufferTarget.ArrayBuffer,buf[0])
 GL.BufferData(BufferTarget.ArrayBuffer,......)

 same for buf[1]   buf[2] and buf[3](this one ElementArrayBuffer)
 Console.WriteLine(GL.GetError()); // no error 
 GL.Finish();

 [iteration loop]
 glControl1.MakeCurrent();
 GL.BindBuffer(BufferTarget.ArrayBuffer,buf[0])
 GL.ColorBuffer(....)

 GL.BindBuffer(BufferTarget.ArrayBuffer,buf[1])
 GL.VertexBuffer(....)

 GL.BindBuffer(BufferTarget.ArrayBuffer,buf[2])
 GL.NormalBuffer(....)

 GL.BindBuffer(BufferTarget.ElementArrayBuffer,buf[3])

 GL.EnableClientStates(.....)
 GL.DrawElements(.....) //draws the thing
 GL.DisableClientStates(.....)

 GL.BindBuffer(BufferTarget.ElementArrayBuffer,0) //is this unbinding?
 GL.BindBuffer(BufferTarget.ArrayBuffer,0)
 GL.BindBuffer(BufferTarget.ArrayBuffer,0)
 GL.BindBuffer(BufferTarget.ArrayBuffer,0) 
 GL.Finish();
 [loop end]

 //deleting buffers
 glControl1.MakeCurrent()
 GL.DeleteBuffers(4,buf)
 Console.WriteLine(GL.GetError()); // no error comes
 GL.Finish();

1 个答案:

答案 0 :(得分:2)

据我所知,您在单击时生成并填充新缓冲区,而不是删除它们。最后,您只删除最后创建的4个缓冲区。

当你调用glGenBuffers时,它只是生成一个新的缓冲区并返回句柄,它不会检测给定的句柄是否已被使用或类似。因此,当您提供与之前使用的相同的句柄时,它会生成新的句柄,覆盖您当前正在跟踪的句柄,从而有效地删除对旧缓冲区的任何引用。但它并没有释放那些缓冲区。因此,您不断填充更多内存。

现在,如果您只想将新数据写入现有缓冲区,只需调用glBufferSubData即可。如果您还要调整缓冲区的大小,请调用glBufferData,它会删除以前的数据。但是你不必生成新的缓冲区,因为你已经拥有了缓冲区的句柄。

希望这有帮助。