在两个独立窗口中渲染相同的场景

时间:2017-03-27 11:18:40

标签: qt opengl

我正在尝试在两个不同的QOpenGLWindow中渲染相同的场景。我不想复制内存,因此我尝试使用共享上下文,但我不确定它是如何工作的。

我使用属性Qt::AA_ShareOpenGLContexts,因为文档说它会使每个着色器上下文在它们之间共享。

但是,我在一个上下文中生成VBO并在每个上下文中生成VAO和着色器程序(因为它无法共享),但第二个小部件不会绘制任何内容。

我认为我的问题出现是因为上下文之间没有共享VBO。 Qt::AA_ShareOpenGLContexts还不够?也许我必须使用QOpenGLContext::globalShareContext(),我怎么能用它?

以下文字解释了我在做什么......

使用以下方法,我生成Object,其中包含有关我想在场景中绘制的对象的信息:

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和VAO,每个上下文一个:

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中被复制。

1 个答案:

答案 0 :(得分:0)

Qt :: AA_ShareOpenGLContexts工作正常,我可以使用此属性。我有两个主要问题:

  • 首先,您必须知道QOpenGLWidgets第一次绘制时会生成上下文。这非常重要,因为必须在共享上下文中创建VBO。首先执行QOpenGLWidget :: show()然后生成VBO。

  • 第二个问题是关于状态管理,我绑定了QOpenGLVertexArrayObject并启用了属性数组并设置了QOpenGLShaderProgram的属性缓冲区,但为了做到这一点,你必须绑定VBO ......我没有这样做。

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

感谢。