Joh*_*Cox 4 c++ opengl qt multithreading
我正在试验Qt的工作中的仪器模拟程序的新布局.我们当前的sim在一个窗口中运行所有内容(我们使用过剩(旧)和fltk),它使用glViewport(...)
并将glScissor(...)
仪器读数分成他们自己的视图,然后它使用某种形式的"ortho2D"调用来创建他们的拥有虚拟像素空间.模拟器当前更新仪器,然后逐个在各自的视口中绘制每个仪器,所有这些都在同一个线程中.
我们想找到一个更好的方法,我们选择了Qt.我在一些很大的限制下工作:
paintEvent(...)
方法的开头更新自己是可行的,所以我希望模拟更新在单独的线程中运行.glBegin()
和glEnd()
之间的所有东西,并且仪器绘制了一堆垃圾变量符号,因此绘图需要花费大量时间,我想将绘图拆分为它自己的线程.我还不知道OpenGL 3是否在桌面上,这对于渲染到屏幕外缓冲区是必要的(我认为).问题: QOpenGLWidget没有可重写的"更新"方法,它只在窗口小部件paintEvent(...)
和paintGL(...)
调用期间绘制.
暂定解决方案:将模拟器拆分为三个线程:
paintEvent(...)
,和paintGL(...)
.在这个设计中,跨线程说话是循环的,单向的,GUI线程提供输入,模拟器线程在下一个循环中考虑该输入,绘图线程读取最新的符号系统并将其呈现给FBO并设置"下一帧可用"标志为true(或者可能发出信号),然后该paintGL(...)
方法将该FBO并将其吐出到小部件,从而保持事件处理能力下降和GUI响应能力提高.继续这个循环.
底线问题:我在这里读到GUI操作无法在单独的线程中完成,所以我的方法是否可行?
如果可行,任何其他谨慎或建议将不胜感激.
每个OpenGL小部件都有自己的OpenGL上下文,这些上下文是QObject
s,因此可以移动到其他线程.与任何其他非线程安全对象一样,您应该只从它们访问它们thread()
.
另外 - 这也可以移植到QML - 您可以使用工作器函数来计算显示列表,然后将其提交到渲染线程以转换为绘制调用.渲染线程不做任何逻辑并且不计算任何东西:它接受数据(顶点数组等)并提交它以进行绘制.工作仿函数将使用提交在线程池上执行QtConcurrent::run
.
因此,您可以拥有一个主线程,一个渲染线程(可能每个小部件一个,但不一定),以及运行模拟步骤的仿函数.
无论如何,卷积逻辑和渲染是一个非常糟糕的主意.无论您是在QPainter
栅格窗口小部件上进行绘图,还是使用QPainter
on QOpenGLWidget
或使用直接OpenGL调用,执行绘图的线程都不应该计算要绘制的内容.
如果你不想惹OpenGL调用,你可以代表大部分工作基于阵列的QPainter
呼叫(例如drawRects
,drawPolygons
),这些几乎可以直接转换成OpenGL绘图调用和OpenGL的后端将一样快,仿佛使它们翻译你手工编写了绘制调用.QPainter
如果你在它上面使用它,你会做到这一切QOpenGLWidget
!
归档时间: |
|
查看次数: |
722 次 |
最近记录: |