Qt World Summit: Register Today!

QOpenGLFrameBuffer drawing takes a number of seconds to appear when used as a texture

  • In an attempt to circumvent the fact that each QOpenGLWidget seems to have its own context, which means I can't share VAOs between OpenGL widgets, I've set up my application to render its various scenes in a dedicated rendering context (though not in a different thread). The scenes are rendered to an intermediate QOpenGLFrameBufferObject, which is shared, and this is then used as an OpenGL texture to render a full-screen quad in any viewport that requires it.

    However, when drawing this quad in the viewport, it seems that the QOpenGLFrameBuffer texture takes many frames to actually change its contents. I've confirmed that the viewport itself is actually updating at a reasonable rate (ie. up to 60 FPS), and that the scene is being rendered to the intermediate frame buffer at this frequency, but the contents of the frame buffer's texture when it's used only seem to update at something like 20 FPS or lower.

    Once having rendered a scene into the frame buffer, I'm just drawing it like this:

    // With the QOpenGLQWidget current:
    GLuint textureId = sharedFrameBuffer->texture();
    // Bind shader program, local VAO, local buffers to draw the quad, etc...
    glBindTexture(GL_TEXTURE_2D, textureId);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    // Unbind everything again.

    The actual rendering itself, both from the scene to the frame buffer and then from the frame buffer to the widget, works OK - I can see things in the widget. It just appears like the frame buffer's texture contents are the same for many successive frames, as if it's only updating once every x frames instead of every frame that the QOpenGLWidget is drawn.

    Is there any reason why this might be happening? I'm wondering whether I'm perhaps unknowingly abusing OpenGL somehow, and that it can't keep up with this particular method of rendering.

  • Update: I've determined this is because of the fact that the QOpenGLFrameBuffer is in a separate context. If it's in the same context, or alternatively if I used takeTexture() instead of texture(), rendering happens as expected (although using takeTexture() and destroying the texture immediately afterwards feels very wasteful). Can anyone recommend the best course of action?

Log in to reply