0

我正在使用 OpenTK 3 和 WinForms 开发多线程 OpenGL 应用程序。我有 2 个共享的 GraphicsContexts:

  • 一个“主”渲染上下文,用于场景绘制和同步加载操作。
  • “辅助”资源加载器上下文,用于在绘制期间加载资源。

此辅助上下文用于加载来自 Windows Media Foundation 会话(使用自定义媒体接收器)的视频帧。但是,我无法控制此媒体接收器在哪个线程上运行,因此我需要一种方法,在每次加载操作后,“取消绑定”辅助 GraphicsContext,以便它可以绑定到下一个需要它的线程中.

我是否必须 P/Invoke wglMakeCurrent(NULL, NULL) 或者是否有适当的 OpenTK 方法来执行此操作?

4

1 回答 1

1

简短的回答

使用 OpenTK 功能:

mycontext.MakeCurrent(null);

长答案

今天的wglMakeCurrent 文档删除了这个旧评论:

如果 hglrc 为 NULL,该函数使调用线程的当前渲染上下文不再是当前的,并释放渲染上下文使用的设备上下文。在这种情况下,hdc 被忽略。

我相信该评论仍然有效,因为有很多代码依赖它。
注意“释放设备上下文”。也许 OpenTK 做了一些与设备上下文相关的操作。也许hdc是私有的(通过使用窗口样式标志CS_OWNDC)所以,让 OpenTK 处理这种“NULL”情况。

更好的方法

请注意,即使您使用多个共享上下文,也是由 GPU(通常是一张唯一的卡)执行加载,并且在执行其他工作时允许加载的卡并不多。因此,不能保证您获得更好的性能。但不知何故,为此目的存在共享上下文。

为什么要在不同的线程中使用相同的上下文?
我会使用不同的线程来加载视频帧(没有任何 gl 调用)并将它们上传到 GPU。最后一个线程是永久的,并且有自己的 gl-context,所以它不需要在每次工作时都设置为当前线程。它休眠或等待,直到另一个线程完成加载数据,并在该任务完成后将该数据上传到 GPU。

于 2018-09-03T17:03:03.113 回答