强制 OpenGL 渲染始终在 Qt 中的相同 (Q) 线程上运行

Posted

技术标签:

【中文标题】强制 OpenGL 渲染始终在 Qt 中的相同 (Q) 线程上运行【英文标题】:Force OpenGL rendering to run always on same (Q)Thread in Qt 【发布时间】:2014-08-08 13:41:17 【问题描述】:

我创建了一个带有 Qt GUI 的应用程序来进行图像处理。对于一部分计算,OpenGL 用于渲染转换后的图像(离屏)。一切正常。但是,当在 GUI 线程中单击按钮时,我做了所有繁重的处理。由于计算需要几秒钟,因此 GUI 变得无响应。

幸运的是,Qt 已经包含一个线程库(QThreadQtConcurrent 等)。现在我只使用QtConcurrent::run()QFutureWatcher<cv::Mat> 通过回调函数异步进行计算。问题是在计算过程中,OpenGL 函数被多次调用,现在可以在不同的线程上运行连续的按钮点击。如果渲染是在与初始化 OpenGL 的线程不同的线程上完成的,则 OpenGL 不会渲染任何内容(黑屏)。当然这取决于 Qt 的线程处理。

所以我的问题是:是否有一个简单的解决方案使用当前设置(Qt 线程和 OpenGL)而不需要额外的库等来强制渲染始终在同一个线程上运行。

我知道有一个方法QObject::moveToThread(),但我不知道在这种情况下如何使用它。 OpenGL 的东西根本不包含任何与 Qt 相关的代码或函数。那么我该如何解决这个问题呢?

我也不知道某个QThread 是否总是使用相同的底层本地线程。是这样吗?

【问题讨论】:

【参考方案1】:

这是一个approach。您创建了一个线程,只要您需要,它就会一直存在,并向其中添加作业。您可以替换 QThread 或使用 std::thread。

【讨论】:

谢谢,我已经考虑过类似的解决方案。我可以通过将 OpenGL 作为任务添加到工作人员来初始化 OpenGL,然后始终将渲染任务添加到该工作人员。我只是不知道将这个解决方案与 QThreads 混合是否是个好主意......在示例中仅用 QThread 替换线程的问题可能是 QThread 只是本机线程的包装器(据我所知,也可能是它选择了 GUI 线程作为底层线程)。但是如果没有其他答案,我会尝试这个并将问题标记为已接受:) 你也可以看看这里描述的更多方法——github.com/troyane/lambdaConcurrent

以上是关于强制 OpenGL 渲染始终在 Qt 中的相同 (Q) 线程上运行的主要内容,如果未能解决你的问题,请参考以下文章

强制OpenGL将内容保存在内存中?

如何使用 OpenGL 在 Qt 界面上显示 IPLImage 流进行渲染?

Qt & OpenGL:如何强制使用 OpenGL 2.1?

OpenGL + QT:渲染到纹理并显示回来

Qt/OpenGL - 渲染的图元被扭曲

Qt & OpenGL:如何尽可能频繁地渲染?