[英]Lazy rendering of Qt on OpenGL
我遇到了這個問題,並且知道可以做得更好。
當用Qt小部件覆蓋QGLWidget(Qt OpenGL上下文視圖)時,Qt會在每個Qt幀之后重繪這些小部件。
Qt不是為了不斷重新繪制整個窗口> 60fps,所以速度非常慢。
讓Qt使用其他東西來繪制:透明紋理。 使OpenGL在重繪時使用此紋理,並將其繪制在其他所有內容之上。 使Qt將與OpenGL上下文視圖的所有交互重定向到繪制到紋理上的小部件。
優點是Qt只需要重新繪制(例如,懸停或點擊小部件,或文本字段中的文本光標閃爍),並且可以進行更快的部分重繪。
怎么解決這個問題? 我怎么能告訴Qt繪制紋理? 我如何將與窗口小部件的交互重定向到另一個窗口小部件(例如,如果我將鼠標移動到上下文視圖中區域上方,其中復選框位於繪制到紋理窗口小部件中,Qt應將此事件注冊到復選框並重新繪制以反映它的國家)
出於同樣的原因,我將2D和3D渲染分離為類似CAD的應用程序,盡管在我的情況下我的2D東西不是小部件 - 但它不應該有所作為。 這是如何處理問題:
QGLFramebufferObject
,請通過在QGLWidget::paintEvent(..)
使用FBO作為QPaintDevice
來調用QPainter
並調用myWidget->render( myQPainter, ...)
。 對於你有多少小部件重復此操作,但只對同一個FBO重復 - 不要為每個小部件創建一個FBO ...請記住先清除它,就像一個'普通'幀緩沖區。 QGLFramebufferObject
,方式相同。 QGLWidget::paintEvent(..)
的末尾,激活着色器程序,將幀緩沖區綁定為紋理( myFBO->texture()
獲取句柄),並渲染單位四元組。 因為您的相機是單位正方形,並且視口大小定義了FBO大小,所以它將完美填充視口像素。 然而,這是最簡單的部分......困難的部分是小部件交互。 因為您實際上是在渲染“代理”,所以您必須在“真實”和“代理”小部件之間傳遞交互,同時保持“真實”小部件不可見。 我將如何開始:
我應該聲明我還必須創建一個“標記”系統來很好地處理重繪。 您不希望每個窗口小部件事件觸發窗口小部件FBO重繪,因為可能有許多同時發生的事件(不要只考慮鼠標) - 但您只需要重繪一次。 所以我創建了一個系統,如果應用程序中的任何內容可以在視口中更改視口中的任何內容,那么它會將視口標記為“臟”。 然后為你想要的許多fps設置一個QTimer
(在我的情況下,場景會變得非常沉重,所以我也計算了一個幀花了多長時間然后使用該值+ 10%作為下一次檢查的定時器延遲,這個當渲染變得遲鈍時系統不被轟炸的方式)。 然后檢查臟狀態:如果臟了,重繪; 否則不要。 我發現生活變得更容易有兩個臟標志,一個用於3D東西,一個用於2D - 但是如果你需要保持OpenGL繪圖的恆定繪制率,則可能不需要兩個。
我想我所做的並不是最簡單的方法,但它為調整和分析提供了充足的空間 - 從長遠來看,這使得生活更加輕松。 所有的答案絕對不是在這篇文章中,但希望它會讓你走上戰略的道路。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.