[英]Is it feasible to split Qt GUI into multiple threads for GUI, simulation, and OpenGL?
我正在試驗Qt的工作中的儀器模擬程序的新布局。 我們當前的sim在一個窗口中運行所有內容(我們使用了glut(舊)和fltk),它使用glViewport(...)
和glScissor(...)
將儀器讀數分成他們自己的視圖,然后它使用某種形式的“ortho2D”調用來創建自己的虛擬像素空間。 模擬器當前更新儀器,然后逐個在各自的視口中繪制每個儀器,所有這些都在同一個線程中。
我們想找到一個更好的方法,我們選擇了Qt。 我正在一些很大的限制下工作:
paintEvent(...)
方法的開頭更新自己是可行的,所以我希望模擬更新在單獨的線程中運行。 glBegin()
和glEnd()
以及介於兩者之間的所有東西,並且儀器繪制了一堆垃圾變量符號,因此繪制需要花費大量時間,我想將繪制分割成它自己的線程。 我還不知道OpenGL 3是否在桌面上,這對於渲染到屏幕外緩沖區是必要的(我認為)。 問題: QOpenGLWidget沒有可重寫的“update”方法,它只在窗口小部件的paintEvent(...)
和paintGL(...)
調用期間繪制。
暫定解決方案 :將模擬器拆分為三個線程:
paintEvent(...)
和paintGL(...)
。 在這個設計中,跨線程說話是循環的,單向的,GUI線程提供輸入,模擬器線程在下一個循環中考慮該輸入,繪圖線程讀取最新的符號系統並將其呈現給FBO並設置“下一幀可用”標志為true(或者可能發出信號),然后paintGL(...)
方法將該FBO並將其吐出到小部件,從而保持事件處理能力下降和GUI響應能力提高。 繼續這個循環。
底線問題 :我在這里讀到GUI操作無法在單獨的線程中完成,所以我的方法是否可行?
如果可行,任何其他謹慎或建議將不勝感激。
每個OpenGL小部件都有自己的OpenGL上下文 ,這些上下文是QObject
,因此可以移動到其他線程。 與任何其他非線程安全對象一樣,您只應從其thread()
訪問它們。
另外 - 這也可以移植到QML - 您可以使用工作器函數來計算顯示列表,然后將其提交到渲染線程以轉換為繪制調用。 渲染線程不做任何邏輯並且不計算任何東西:它接受數據(頂點數組等)並提交它以進行繪制。 工作QtConcurrent::run
函數將使用QtConcurrent::run
提交在線程池上QtConcurrent::run
。
因此,您可以擁有一個主線程,一個渲染線程(可能每個小部件一個,但不一定),以及運行模擬步驟的仿函數。
無論如何,卷積邏輯和渲染是一個非常糟糕的主意 。 無論您是在柵格小部件上使用QPainter
進行繪制,還是在QOpenGLWidget
上使用QPainter
,或者使用直接OpenGL調用,執行繪圖的線程都不應該計算要繪制的內容。
如果您不想搞亂OpenGL調用,並且您可以將大部分工作表示為基於數組的QPainter
調用(例如drawRects
, drawPolygons
),則這些調用幾乎直接轉換為OpenGL繪制調用,而OpenGL后端將使它們呈現為很快,好像你手動編寫了繪制調用。 如果你在QOpenGLWidget
上使用它, QPainter
會為你做這QOpenGLWidget
!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.