Qt World Summit: Register Today!

QOpenGLContext's defaultFramebufferObject() always returns 0 in a QOpenGLWidget subclass.

  • Hi,

    I have tested Qt 5.4.0-RC1 on Windows 8.1 with MSVC2013 64bit OpenGL.

    Since I want to use QOpenGLWidget class for my OpenGL implementation,
    I moved from QWindow to QOpenGLWidget.

    As explained in the documentation, it recommends to use

    @GLuint QOpenGLWidget::defaultFramebufferObject() const@

    to get the Framebuffer ID that should be bound because rendering in QOpenGLWidget happens in QOpenGLFramebufferObject. Therefore, default framebuffer object ID is always greater than or equal to 1.

    In my implementation, multiple framebuffer objects are used, however, I cannot re-bind to the default framebuffer easily from other framebuffers as all the following calls re-bind framebuffer to 0.

    glBindFramebuffer( context()->defaultFramebufferObject() );

    The reason that I verified is because QOpenGLContext's defaultFramebufferObject() always returns 0.
    This is a bit strange compared to the explanation in the documentation.

    bq. On some platforms the default framebuffer object depends on the surface being rendered to, and might be different from 0. Thus, instead of calling glBindFramebuffer(0), you should call glBindFramebuffer(ctx->defaultFramebufferObject()) if you want your application to work across different Qt platforms. If you use the glBindFramebuffer() in QOpenGLFunctions you do not have to worry about this, as it automatically binds the current context's defaultFramebufferObject() when 0 is passed.

    My workaround solution is as follows.

    GLint prev_fbo_id;
    glGetIntegerv( GL_FRAMEBUFFER_BINDING, &prev_fbo_id );
    my_fbo->bind(); // bind to my custom framebuffer object (QOpenGLFramebufferObject).

    ... do some rendering here

    // any of following methods will bind framebuffer object to 0,
    // however, QOpenGLWidget's default is not 0

    //glBindFramebuffer( GL_FRAMEBUFFER, ctx->defaultFramebufferObject() );

    // that's why I stored previous framebuffer object ID manually before, and use it.
    glBindFramebuffer( GL_FRAMEBUFFER, prev_fbo_id );

    I don't understand why this happens. Any help?

  • I think I am running into something similar. I use offscreen FBO's to make an image, and I am trying to use a QOpenGLWidget to display the result using frameBuffer->texture(); and drawing it as a texture in the QOpenGLWidget's paint() method. But, that gives me a blank widget. I know the content of the frameBuffer is fine because I can run frameBuffer->toImage().save("something.jpg") and it looks fine. If I do frameBuffer.toImage() and draw that image as a texture in my QOpenGLViewport, I get weird broken picture in picture effects, which makes me think I am doing something wrong with regard to have the right context current and the right frameBuffer bound. Somehow I am drawing the window into the texture I am drawing into the window into...

    Here's an image of it, I'm not sure how to describe it very precisely...

  • Note that the documentation refers to QOpenGLWidget::defaultFramebufferObject(), not the identically named function in QOpenGLContext.

    That being said, it is indeed a bit annoying that QOpenGLContext's defaultFramebufferObject() does not know about QOpenGLWidgets. This could be improved in the future.

Log in to reply