将QGLWdiget内容绘制到FBO

时间:2013-10-04 12:57:43

标签: c++ qt opengl fbo

我有一个QGraphicsScene + QGraphicsView设置,使用QGLWidget来绘制内容。

我还制作了一些片段着色器,为场景添加置换贴图和绽放效果。如果我使用QPainter作为设备创建QFramebufferObject对象并调用QPainter对象上的图形场景的渲染功能,则场景将呈现给FBO,然后我可以使用它进行合成。然而,这样做的缺点是它使用软件渲染并且占用了大量资源。

不幸的是,当我尝试将FBO设置为当前渲染目标并让QGLWidget在FBO上绘制时,FBO显示为空白(并且空白我的意思是glClearColor的颜色调用)

所以我的问题基本上是,有没有办法在FBO上获取QGLWidget的内容,或者是否有其他方法可以在QGLWidget

中实现后期处理着色器

以下是我当前代码的相关部分

void MyWindow::SwitchRenderContext(RenderType type)
{
    m_renderType = type;
    m_renderArea->SetRenderType(type);
    switch(type)
    {
    case RenderType_Software:
        m_view.setViewport(NULL);
        layout()->removeWidget(&m_view);
        layout()->addWidget(m_renderArea);
        m_view.m_renderWidget = NULL;
        break;
    case RenderType_OpenGL:
        m_view.setViewport(m_renderArea);
        m_view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
        layout()->addWidget(m_renderArea);
        m_view.m_renderWidget = m_renderArea;
        break;
    }
}

void MyGlWidget::initializeGL()
{
    m_initialized = true;
    if(m_dispFbo == NULL)
        m_dispFbo = new QGLFramebufferObject(width(), height());
    if(m_bufFbo == NULL)
        m_bufFbo = new QGLFramebufferObject(width(), height());
    if(m_fbo == NULL)
        m_fbo = new QGLFramebufferObject(width(), height());

    static const float vertex[] = {
        -1.0f,  1.0f, 0.0f, 1.0f,
        1.0f,  1.0f, 0.0f, 1.0f,
        -1.0f, -1.0f, 0.0f, 1.0f,
        1.0f, 1.0f, 0.0f, 1.0f,
        1.0f, -1.0f, 0.0f, 1.0f,
        -1.0f, -1.0f, 0.0f, 1.0f,
    };

    //initialize vbo
    if(!m_vbo.isCreated())
    {
        m_vboEnabled = m_vbo.create();
        if(m_vboEnabled)
        {
            m_vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
            m_vbo.bind();
            m_vbo.allocate(vertex, sizeof(vertex) );
            m_vbo.release();
        }
        glEnable(GL_TEXTURE_2D);
    }
    glViewport(0, 0, width(), height());
    m_shadersEnabled = initializeShaders();
}

void MyGlWidget::SetRenderType(RenderType type)
{
    m_renderType = type;
}

void MyGlWidget::DoHardwarePaint()
{
    m_fbo->release();
    QPainter dispPainter(m_dispFbo);
    m_dispScene->RenderScene(&dispPainter);
    dispPainter.end();

    DrawShaders();

    m_fbo->bind();
}

void MyGlWidget::DoSoftwarePaint()
{
    if(!m_shadersEnabled || !m_vboEnabled)
    {
        QPainter painter(this);
        m_scene->render(&painter);
        return;
    }

    QPainter dispPainter(m_dispFbo);
    m_dispScene->RenderScene(&dispPainter);
    dispPainter.end();

    QPainter painter(m_fbo);
    m_scene->render(&painter);
    painter.end();

    DrawShaders();
    update();

}

void MyGlWidget::DrawShaders()
{
    m_vbo.bind();
    m_bufFbo->bind();
    glDisable(GL_DEPTH_TEST);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, m_dispFbo->texture());

    m_displaceShader.bind();
    m_displaceShader.enableAttributeArray("in_verts");
    m_displaceShader.setAttributeBuffer( "in_verts", GL_FLOAT, 0, 4);
    m_displaceShader.setUniformValue("inCol", 0);
    m_displaceShader.setUniformValue("inDisplace", 1);
    glDrawArrays(GL_TRIANGLES, 0, m_vbo.size());

    m_bufFbo->release();

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, m_bufFbo->texture());

    m_bloomShader.bind();
    m_bloomShader.enableAttributeArray("in_verts");
    m_bloomShader.setAttributeBuffer( "in_verts", GL_FLOAT, 0, 4);
    m_bloomShader.setUniformValue("inCol", 0);
    m_bloomShader.setUniformValueArray("offsets", offsets, 8, 2);
    glDrawArrays(GL_TRIANGLES, 0, m_vbo.size());

    m_bloomShader.disableAttributeArray("in_verts");
    m_bloomShader.release();

    m_vbo.release();
    glEnable(GL_DEPTH_TEST);
}

void MyGlWidget::paintGL()
{
    if(!m_vboEnabled && m_renderType == RenderType_OpenGL)
        return;

    if(m_renderType == RenderType_Software)
    {
        DoSoftwarePaint();
        return;
    }

    DoHardwarePaint();
}

0 个答案:

没有答案