【问题标题】:MFC: how to draw opengl from a different thread?MFC:如何从不同的线程绘制opengl?
【发布时间】:2014-10-09 08:01:19
【问题描述】:

我正在尝试在 CWnd 窗口中以 60 fps 的速度制作一些 opengl 1.0 动画。我创建了一个 CWnd 的子类:

类 COpenGLControl:公共 CWnd { ... }

我发现如果我使用内置计时器“setTimer()”并将其设置为每 1000/60 毫秒触发一次,所有 opengl 命令都能够正确呈现。但是,如果我使用单独的线程实现自己的计时器,则不会绘制任何内容。我得到的只是黑屏。

有没有办法从不同的线程发出 opengl 命令?

【问题讨论】:

  • 感谢您的回复。读完帖子后,似乎我在做的事情有点不同。我不是想多线程我的渲染器。我只想在 CWnd 线程以外的单个线程中进行所有 opengl 调用,并且是跨平台的。这就是为什么我要自己做计时器
  • 也许错误代码可能有助于调查。上下文必须绑定在您从中调用命令的线程中。
  • 如何获取错误码?我在 OnCreate() 函数中创建了上下文,并且 GL 调用是从我的计时器线程进行的。也许这就是问题所在。如果我也在计时器线程中创建上下文会起作用吗?
  • GetLastError 将给出错误代码。 @derhass 给了你一个正确的答案。

标签: multithreading opengl mfc


【解决方案1】:

即使您不打算从多个线程发出 GL 调用,您也必须考虑 OpenGL 的线程规则:一次最多只能由一个线程使用 OpenGL 上下文。 (并且,每个线程在任何时候最多可以有一个活动的 GL 上下文)。这并不意味着您不能在多个线程中使用相同的上下文,或者在一个线程中创建它并在另一个线程中使用它,您只需要明确地将上下文从一个线程“移交”到另一个线程。

我不知道您是否使用了一些进一步的库来处理 GL 上下文,所以我假设您使用的是操作系统的本机 API - 在本例中为 wgl。相关函数为wglMakeCurrent()。因此,要将线程 A 中的“当前”上下文移交给线程 B,线程 A 必须首先调用 wglMakeCurrent(NULL,NULL),然后线程 B 才能通过 wglMakeCurrent(someDC, myGLCtx) 获取上下文。当然,您可以随意切换 GL 上下文,但这会带来巨大的同步开销,应该避免。

来自您的 cmets:

如果我也在计时器线程中创建上下文会起作用吗?

是的,会的。

只是附注:创建 根本不是这里的问题,因为创建 GL 上下文不会自动使其成为线程的“当前” - 所以你可以在线程 A 中创建它然后直接使其成为线程 B 的当前线程。

【讨论】:

  • 非常感谢。这解决了我的问题。至于性能,所有的绘图都将在定时器线程上完成。只会在 UI 线程上完成一些初始设置,这将在计时器被触发之前。所以我相信这应该没问题。
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
相关资源
最近更新 更多