2016-08-23 38 views
2

我有以下問題:僅獲得一個QOpenGLContext不同的QT部件

我想它從不同的角度,光照渲染一個共同的OpenGL場景很多人認爲組成一個應用程序,以及其他選項。

基本上,我的問題是用qt做這件事的最好方法是什麼?

我的第一次嘗試是創建多個QOpenGLWidget並獲取一個常見的QOpenGLContext,其中存儲了紋理,但也存儲了網格和着色器。 但它不適用於網格,因爲頂點數組對象似乎不可共享。 經過大量嘗試後,可能的解決方案是爲每個需要網格的小部件存儲一個VAO,但這看起來非常糟糕。

所以,我想知道這種問題是否有一個好的選擇,或者是一個很好的文檔來理解這些QOpenGLContext是如何工作的。

我想象的最簡單的想法是隻創建一個QOpenGLContext並在不同的小部件中使用它。但我不知道如何僅僅創建一個QOpenGLContext,也不知道什麼樣的QWidgets能夠顯示這些渲染。

這是我的第一篇文章,所以我不知道它是否足夠清楚,或者如果我需要描述我的整個架構。

+1

'QOpenGLContext'封裝了OpenGL上下文。它的侷限性與OpenGL上下文的工作方式有關。 Qt與它沒有太大的關係。你需要的文檔是OpenGL文檔和教程,而不是'QOpenGLContext'文檔。 –

+0

我知道OpenGL上下文的限制,爲什麼我只想使用一個用於我的整個應用程序,但重點是要知道如何用qt來做到這一點。 –

回答

-1

你已經嘗試過了,所以我傳遞了有關共享上下文的單詞。

OpenGL上下文綁定到一個窗口:如果你只想要一個上下文,直接的答案是隻有一個窗口。

使用窗口小部件模塊,可以在同一個QOpenGLWidget中使用多個視口使用同一場景的多個視圖。例如:

void myWidget::paintGL() { 
    //... 

    glViewport(
     0, 0, 
     this->width()/2, this->height()/2 
    ); 

    // draw scene from one point of view 

    glViewport(
     this->width()/2, this->height()/2, 
     this->width()/2, this->height()/2 
    ); 

    // draw scene from an other point of view 

    //... 
} 

您應該設計一個視口類來存儲和管理每個視口的渲染參數。

缺點是您必須檢測用戶在哪個視口中單擊以處理交互:某種if event.pos.x is between 0 and this->width()/2 ...


的另一種方式可能是失望的部件模塊,並使用Qt快速和QML:一個快速的窗口聲明瞭一個獨特的OpenGL上下文,其中每個快速項目就像是一個視口,但在其自己的對象封裝起來,你不必考慮用戶在哪裏進行交互。

繼承QQuickItem而不是QOpenGLWidget,並使用qmlRegisterType()宏將您的類導出到QML。然後,您可以在程序中創建一個QQuickView,以在聲明物品的地方加載QML代碼。來自Qt文檔here的一個例子。

+0

我從來沒有考慮過這個解決方案,因爲我認爲最好不要重新發明輪子。但實際上它可能是保持我的資源和渲染控制的最簡單的解決方案。 –

+0

我想通過重新發明輪子,你會提到多視口解決方案。你應該考慮使用QML解決方案:這與已經發明的車輪相同 – wasthishelpful

+0

好吧,我已經看過一些快速的東西,看起來比舊的方法更容易使用。 儘管如此,在我的文檔步驟中再進一步之前,您能否告訴我qml是否允許我動態更改視口的大小或數量? –

-1

我認爲,因爲多個視圖/ surfces可以獨立更新,不幸的是它不可能有一個單獨的QOpenGLContext來完成這項工作。分享上下文有你已經在你的問題中指出的限制。

QOpenGLContext可以通過moveToThread()移動到不同的線程。 不要從QOpenGLContext對象所屬的不同線程調用makeCurrent()到 。上下文一次只能在一個線程和一個表面上當前 ,並且線程一次只有一個上下文 。

鏈接:http://doc.qt.io/qt-5/qopenglcontext.html

所以,你可以得到它的工作方法之一是擁有自主更新您的觀點。順序,並通過一個使上下文當前和移動到下一個視圖之前渲染。這將保證在任何給定時間上下文僅在一個視圖中是最新的。也許使用QMutex來序列化更新。

或者,您也可以在線程之間傳遞上下文並序列化它們的更新,但這是一種糟糕的方法。

+0

如果更新是連續的,使用線程有什麼意義? – wasthishelpful

+0

如果有一些cpu端的東西需要完成渲染前該部分可以是並行的,只有渲染需要同步。 – Harish

+0

僅供參考,我使用經典的SIGNAL/SLOT組合刷新我的顯示。我不知道它是否連續。 –