2017-03-27 152 views
0

我想渲染兩個不同的QOpenGLWindow s中的相同場景。我不想重複記憶,爲此我嘗試使用共享上下文,但我不確定它是如何工作的。在兩個獨立的窗口中渲染相同的場景

我使用的屬性Qt::AA_ShareOpenGLContexts,因爲文檔說它使得每個着色器上下文都將在它們之間共享。但是,我在一個上下文中生成VBO,並在每個上下文中生成VAO和Shader程序(因爲它不能共享),但第二個小部件不繪製任何內容。

我想我的問題出現是因爲VBO沒有在上下文之間共享。 Qt::AA_ShareOpenGLContexts是不夠的?也許我必須使用QOpenGLContext::globalShareContext(),我該如何使用它?


下面的文字說明我在做什麼...

白衣下面的方法,我產生看過那部我要在現場作畫,其中包含有關對象的信息對象:

void AEOpenGLViewer::setVertices(std::vector<Vertex> vertices, GLenum primitive) { 
    makeCurrent(); 
    GLObject *theObject = new GLObject(vertices, primitive); 
    testingObjects.push_back(theObject); 
    doneCurrent(); 
} 

在構造函數中我生成VBO:

GLObject::GLObject(std::vector<Vertex> vertices, GLenum primitiveType){ 
    this->vertices = vertices; 
    this->primitiveType = primitiveType; 

    vbo.create(); 
    vbo.bind(); 
    vbo.setUsagePattern(QOpenGLBuffer::StaticDraw); 
    vbo.allocate(vertices.data(), vertices.size() * sizeof(Vertex)); 
    vbo.release(); 
} 

關於VAO和Shader程序,我產生他們時,我要畫的GLObject:

void GLObject::draw(QOpenGLContext* context, const QMatrix4x4& view, const QMatrix4x4& proj){ 
    if (!shaderProgram.contains(context)) 
     setupShader(context); 

    if (!shaderProgram[context]->isLinked()) 
     shaderProgram[context]->link(); 

    shaderProgram[context]->bind(); 
    { 
     shaderProgram[context]->setUniformValue(uniformWorldToCamera, view); 
     shaderProgram[context]->setUniformValue(uniformCameraToView, proj); 

     //If vao does not exists, create it. 
     if (!this->vao.contains(context)) 
      setupVAO(context); 

     QOpenGLVertexArrayObject *vao = this->vao[context]; 
     vao->bind(); 

     shaderProgram[context]->setUniformValue(uniformModelToWorld, transform.toMatrix()); 
     glDrawArrays(primitiveType, 0, vertices.size()); 

     vao->release(); 
    } 
    shaderProgram[context]->release(); 
} 

每個GLObject包含,使用QMAP,​​多shaderPrograms和維羅,每一個情境:

class GLObject 
{ 
public: 

    ... 

private: 

    ... 

    QMap<QOpenGLContext*, QOpenGLVertexArrayObject*> vao; //VAO cannot be shared, for this reason I will create a VAO per Widget (represent by QUuid) 
    QMap<QOpenGLContext*, QOpenGLShaderProgram*> shaderProgram; 

    //Private helpers 
    void setupVAO(QOpenGLContext* context); 
    void setupShader(QOpenGLContext* context); 
}; 

最後,QOpenGLWidgets有一個std :: vector,它被複制到不同的Widgets中。

+0

請至少顯示你正在做的一些代碼。不可能說出什麼是錯的。 – peppe

+0

我添加了我的部分代碼。最好的祝福。 – SolidusAbi

+0

我不明白VBOs是如何實際共享的。每個GLObject似乎都帶有VBO,VAO和程序。 – peppe

回答

0

Qt :: AA_ShareOpenGLContexts完美的工作,我得到它與這個屬性一起工作。我有兩個主要問題:

  • 首先,你必須知道當QOpenGLWidgets第一次繪製時會產生上下文。這非常重要,因爲VBO必須在共享上下文中創建。所以先做一個QOpenGLWidget :: show(),然後生成VBO。

  • 第二個問題是關於狀態管理,我綁定了QOpenGLVertexArrayObject並啓用了屬性數組並設置了QOpenGLShaderProgram的屬性緩衝區,但要做到這一點,您還必須綁定VBO ......我沒有這樣做。

最後,我根據上下文生成着色器程序和VAO。

感謝。