在qt中显示gl计算的进度
我有一个进程正在使用 gl 而不是 cpu 进行一些繁重的数学运算(到目前为止,gl/gpu 的速度大约比 cpu 快 100 倍),但通常的问题大小仍然需要大约一分钟才能准备好,所以我想要一个好的进度条以了解需要多长时间。
因此,我将我的类设置为从 QObject
继承,并每隔一段时间发出一个信号 currentProgress(int)
。 不幸的是,我的程序在计算过程中冻结,因此看不到任何进展。 我在调用 QCoreApplication::processEvents() 中找到了解决方案,这给了我另一个问题。 在此调用期间,会触发整个窗口的重新绘制,这会导致我的计算在无限递归中被调用,因为它本身是由绘制事件触发的。
现在所有这些问题都是信号,告诉我的编程直觉槽,我可能设计错误了一些东西,所以我问你在qt中拥有刷新进度条的默认方式是什么?
另请注意:当我想将计算推入另一个线程时,我可能需要创建一个新的 GL 上下文,或者至少将现有的上下文移过来。因此,如果这是要走的路,有人可以向我解释如何在 qt 中实现这一点吗?
编辑
为了让事情更清楚,我没有绘制到 QGLWidget 而是使用了 FBO。 也许最好使用自己的上下文进行计算,但我不知道这是否是正确的方法。
新信息
因此,我尝试遵循您的建议,但偶然发现了一个问题。 QGLContext
似乎必须已连接到屏幕/gui 对象,因此我无法在屏幕外创建一个。
此外,我无法使 QGLWidget
在其他线程中处于当前状态。它返回错误 QGLContext::makeCurrent(): Failed.
此外,我读到的所有条目都是像我一样遇到同样问题的人:他们想在另一个线程中进行渲染,但没有找到解决方案。
I have a process that is doing some heavy maths with gl rather than the cpu (gl/gpu is so far doing approximatly 100x faster than cpu) but still it is about a minute for usual problem sizes to be ready, so I wanted a nice progress bar to know how long it will take.
So I set up my classes to inherit from QObject
and have a signal currentProgress(int)
that is emitted every once in a while.
Unfortunately my program freezes during the calculation so no progress is visible.
I found the solution in calling QCoreApplication::processEvents()
which gave me another problem.
During this call a repaint of the whole window is triggered which results in my calculation being called in an infinite recursion, because it is itself triggered by the paint event.
Now all this problems are signals that tell my programming intuition slot that I probably misdesigned something, so I ask you what is the default way to have a refreshing progress bar in qt?
Also note: When I want to push the calculation into another thread I probably need to create a new GL context or at least move the existing one over. So if that is the way to go, might someone explain to me how to achieve this in qt?
EDIT
To make things more clear I am not drawing to the QGLWidget but using a FBO.
Probably it is the best to use an own context for the calculations but I don't know if it is the right way to go.
New Information
So I tried to follow your advice but stumbled upon a problem.
A QGLContext
seems to must have been connected to a screen/gui object so I cannot create one offscreen.
Further I cannot make the QGLWidget
current in the other threads. It returns the error QGLContext::makeCurrent(): Failed.
Further all entries I read about that were people with the same problem like me: They wanted to do renderings in another thread and did not find a solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
那么你不应该在绘制事件中触发你的计算。如果窗口是 OpenGL 窗口(即:GPGPU 内容渲染到窗口),那么您应该在计算期间隐藏它。如果它不是 OpenGL 窗口,则刷新它不应引发计算。
除非您使用 OpenGL 实际绘制某些内容,否则您应该使用离屏渲染目标。基本上,您创建一个 GL 窗口,然后使用 创建一个与其共享对象的新上下文WGL_ARB_pbuffers(或 GLX 等效项,具体取决于您的 GUI 系统)。这是一个离屏渲染目标。然后你摧毁原来的窗户。
至于线程,不要忘记:即使你有两个 GL 上下文,你也只有一个 GPU。因此,如果您使用 OpenGL 绘制到窗口,并使用 OpenGL 进行一些计算,则这可能无法全部解决。
Then you should not be triggering your calculations in the paint event. If the window is the OpenGL window (ie: the GPGPU stuff renders to the window), then you should hide it for the duration of the computations. If it's not the OpenGL window, then refreshing it should not be provoking the computations.
Unless you are using OpenGL to actually draw something, you should be using an off-screen render target. Basically, you create a GL window, then create a new context that shares objects with that using WGL_ARB_pbuffers (or the GLX equivalent, depending on your GUI system). This is an off-screen render target. Then you destroy the original window.
As for threading, don't forget: even if you have two GL contexts, you only have one GPU. So if you're using OpenGL to draw to a window, and OpenGL to do some computations, this may not all work out.
绘画小部件上的 setUpdatesEnabled(false); 可能会有所帮助。
A setUpdatesEnabled(false); on the painting widget may help.
是的,将其放入自己的线程中是正确的方法。 QGLWidget 提供了以下成员函数:
从处理线程中适当地调用它们。
setUpdatesEnables(false);
防止通常的信号处理触发重绘。顺便说一句:我在新闻组 comp.graphics.api.opengl 中认识你吗?那里也有一个“无人”活动。查看我的用户个人资料,了解我是谁。
Yes putting this into a own thread is the way to go. QGLWidget provides the following member functions:
Call them from the processing thread apropriately.
setUpdatesEnables(false);
prevents usual signal processing to trigger a redraw.BTW: Do I know you from the newsgroup comp.graphics.api.opengl? There's a "Nobody" active there, too. Take a look at my user profile to know who I am there.