0
$\begingroup$

I'm just starting to work with framebuffer objects and am having trouble trying to figure out why I can't blit my framebuffer to my viewport. I know my framebuffer has data drawn to it since I can read its pixel using glReadPixels and save it as an image. However, when I try to draw it to my back buffer so that I can see it in the window, it draws nothing at all - all I see is the color I cleared the viewport to.

What am I doing wrong?


void DocumentPanel::paintGL()
{
    QOpenGLFunctions_3_3_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();

    //Setup framebuffer
    setupFramebuffer();

    //Render to framebuffer
    f->glBindFramebuffer(GL_FRAMEBUFFER, _frameBufferID);
    f->glClearColor(0, 0, 1, 0);

    f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    drawShapes();


    //--------------------------------------------

    f->glBindFramebuffer(GL_FRAMEBUFFER, 0);

    if (!_oneShot)
    {
        dumpFramebuffer();
        _oneShot = true;
    }

    f->glClearColor(0, 0.5, .5, 0);
    f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    f->glDisable(GL_DEPTH_TEST);
    f->glDisable(GL_STENCIL_TEST);

    int w = width();
    int h = height();
    f->glBindFramebuffer(GL_READ_FRAMEBUFFER, _frameBufferID);
    f->glReadBuffer(GL_COLOR_ATTACHMENT0);
    f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    f->glDrawBuffer(GL_BACK);
    f->glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
    checkForErrors();
}


void DocumentPanel::setupFramebuffer()
{
    QOpenGLFunctions_3_3_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();

    int w = width();
    int h = height();
    int samples = 4;
    bool multisample = false;

    if (_frameBufferID == 0)
    {
        f->glGenFramebuffers(1, &_frameBufferID);
        f->glBindFramebuffer(GL_FRAMEBUFFER, _frameBufferID);
    }

    if (_renderBufferColorID == 0)
    {
        f->glGenRenderbuffers(1, &_renderBufferColorID);
        f->glBindRenderbuffer(GL_RENDERBUFFER, _renderBufferColorID);

        if (!multisample)
            f->glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, w, h);
        else
            f->glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA, w, h);
        f->glBindRenderbuffer(GL_RENDERBUFFER, 0);

        f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _renderBufferColorID);
    }

    if (_renderBufferDepthStencilID == 0)
    {
        f->glGenRenderbuffers(1, &_renderBufferDepthStencilID);
        f->glBindRenderbuffer(GL_RENDERBUFFER, _renderBufferDepthStencilID);
        if (!multisample)
            f->glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h);
        else
            f->glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, w, h);
        f->glBindRenderbuffer(GL_RENDERBUFFER, 0);

        f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _renderBufferDepthStencilID);
    }

    GLenum status = f->glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (status != GL_FRAMEBUFFER_COMPLETE)
    {
        //error
        QString err;

        switch (status)
        {
        case GL_FRAMEBUFFER_UNDEFINED:
            err = "GL_FRAMEBUFFER_UNDEFINED";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
            err = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT :
            err = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT ";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER :
            err = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER ";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER :
            err = "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER ";
        break;
        case GL_FRAMEBUFFER_UNSUPPORTED :
            err = "GL_FRAMEBUFFER_UNSUPPORTED ";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE :
            err = "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE ";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS  :
            err = "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS  ";
        break;
        }

        f->glBindFramebuffer(GL_FRAMEBUFFER, 0);

        qDebug() << "Error building frambuffer: " << err;
        return;
    }

    //Rendering to window again
    f->glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
```
$\endgroup$
1
  • $\begingroup$ maybe void QOpenGLContext::swapBuffers(QSurface *surface) $\endgroup$
    – Saleh
    Commented Jan 24, 2021 at 14:17

1 Answer 1

0
$\begingroup$

Looks like I misunderstood how my windowing system was handling rendering. It had created an offscreen buffer that was being used to update the window. When I use glBlitFramebuffer with the buffer id QOpenGLWdget gives me, my image appears.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.