4

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

在此处输入图像描述

程序流程如下:

 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();
4

1 回答 1

3

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

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

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

于 2013-08-13T13:51:53.630 回答