【问题标题】:OpenTK MultiThreading: How to "unbind" a GraphicsContextOpenTK 多线程:如何“取消绑定”GraphicsContext
【发布时间】:2018-09-03 13:49:54
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: multithreading opengl opentk wgl


    【解决方案1】:

    简答

    使用 OpenTK 功能:

    mycontext.MakeCurrent(null);
    

    长答案

    今天的wglMakeCurrent doc 删掉了这条旧评论:

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

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

    更好的方法

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

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

    【讨论】:

    • 在与 Media Foundation 相同的线程中加载将使管理缓冲区更容易,因为我只需要管理 OpenGL 纹理缓冲区,而不是管理纹理上传的 RAM 缓冲区。感谢您的回复,我明天会检查一下,(如果我得到许可,(上帝感觉就像一个必须升级的 RPG)将您的答案标记为正确。
    • 我没有尝试在线程中映射/取消映射缓冲区,而是将其填充到另一个线程中。它可能是后缀。另外,请阅读OGL wiki streaming
    • GraphicsContext.MakeCurrent(null) 就像一个魅力。谢谢!如果你愿意,我可以报告我的纹理加载工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    相关资源
    最近更新 更多