我有一个进程用gl而不是cpu进行一些繁重的数学运算(gl / gpu到目前为止比cpu快大约100倍)但是通常问题大小准备好了大约一分钟,所以我想要一个很好的进度条,知道它需要多长时间。
所以我将我的类设置为继承自QObject
并且每隔一段时间发出一个信号currentProgress(int)
。
不幸的是,我的程序在计算期间冻结,因此无法看到进度。
我在调用QCoreApplication::processEvents()
时找到了解决方案,这给了我另一个问题。
在此调用期间,将触发整个窗口的重绘,这会导致我的计算在无限递归中被调用,因为它本身是由paint事件触发的。
现在所有这些问题都是告诉我编程直觉插槽的信号,我可能错误地设计了一些东西,所以我问你在qt中有一个刷新进度条的默认方法是什么?
另请注意:当我想将计算推送到另一个线程时,我可能需要创建一个新的GL上下文或者至少移动现有的上下文。所以如果这是要走的路,有人可以向我解释如何在qt中实现这个目标吗?
修改
为了使事情更清楚,我没有使用QGLWidget而是使用FBO。 可能最好使用自己的上下文进行计算,但我不知道这是否是正确的方法。
新信息
所以我试着听从你的建议,但偶然发现了一个问题。
QGLContext
似乎必须连接到屏幕/ gui对象,因此我无法创建一个屏幕外。
此外,我无法在其他线程中使QGLWidget
当前。它返回错误QGLContext::makeCurrent(): Failed.
此外,我读到的所有条目都是像我一样有问题的人:他们想在另一个线程中做渲染但没找到解决方案。
答案 0 :(得分:3)
在此调用期间,将触发整个窗口的重绘,这会导致我的计算在无限递归中被调用,因为它本身是由paint事件触发的。
然后你不应该在paint事件中触发你的计算。如果窗口是OpenGL窗口(即:GPGPU东西渲染到窗口),那么您应该在计算期间隐藏它。如果它不是OpenGL窗口,那么刷新它不应该激发计算。
除非您使用OpenGL实际绘制某些内容,否则您应该使用屏幕外渲染目标。基本上,您创建一个GL窗口,然后创建一个新的上下文,使用WGL_ARB_pbuffers(或GLX等效,取决于您的GUI系统)与对象共享对象。这是一个离屏渲染目标。然后你破坏了原来的窗口。
至于线程,不要忘记:即使你有两个GL上下文,你也只有一个GPU。因此,如果您使用OpenGL绘制到窗口,并使用OpenGL进行一些计算,则可能并非都有效。
答案 1 :(得分:2)
绘画小部件上的setUpdatesEnabled(false);可能会有所帮助。
答案 2 :(得分:2)
是的,将它放入自己的线程是可行的方法。 QGLWidget提供以下成员函数:
void QGLWidget::makeCurrent()
void QGLWidget::doneCurrent()
恰当地从处理线程中调用它们。 setUpdatesEnables(false);
阻止通常的信号处理触发重绘。
顺便说一句:我是否从新闻组 comp.graphics.api.opengl 中认识你?那里也有一个“没人”活跃。看看我的用户档案,了解我在那里。