在 .net 对象的终结器中调用 glDeleteTextures 的正确方法

Nic*_*uet 5 .net opengl multithreading garbage-collection finalizer

我即将围绕 OpenGL 纹理实现一个托管包装类,并且我希望对象终结器调用glDeleteTextures.

因此,调用终结器的线程(GC线程?)必须通过调用绑定到纹理所属的OpenGL渲染上下文wglMakeCurrent

wglMakeCurrent文档明确指出,一个OpenGL渲染上下文不能同时是多个线程的当前渲染上下文。

如果GC可以随时触发,我不能保证发生时没有其他线程正在使用上下文。

glDeleteTextures调用 .net 对象的终结器的正确方法是什么?

编辑

该包装类将用于“按需加载”场景图的复杂系统,并通过WeakReference等等实现缓存策略。因此,“手动处置”不是我想要考虑的选项:我真的希望 GC 能够处理这个问题。

Ste*_*nke 5

你不知道。

使用该IDisposable接口使释放具有确定性。当释放纹理对象时,调用该dispose方法。在里面,删除纹理。

这适用于分配非托管资源的所有对象;在本例中,由 OpenGL 处理。


编辑: Dispose 模式似乎不适用于此处。资源需要在其创建线程上完成,而执行此操作的标准方法不能处理这种情况。

  • 你不能让 GC 处理 OpenGL 对象(线程、fbo、vbo,...)。您必须在创建 OpenGL 对象的线程中手动调用删除它们。简单的方法是在 IDisposable 对象上使用“using”构造。 (3认同)

Nic*_*uet 1

好的,这就是我所做的。

我实施了IDisposable我在资源对象(纹理、顶点数组、着色器等的基类)上

处置时(或者如果未手动处置则最终确定),资源将其 id 和类型添加到其 OpenGL 上下文包装类拥有的同步列表中,并最终通过设置事件唤醒主线程。

我已经更改了我的应用程序消息泵(我现在使用MsgWaitForMultipleObjects而不是GetMessage),并且在循环中,一旦获取了 OpenGL 上下文,线程首先“释放”未使用的资源,然后再处理消息(如果有)。

到目前为止,它就像一个魅力。

感谢 Stefan Hanke 对此的提示!