Search code examples
c++qtqt6qtopengl

How do I display a QOpenGLFramebufferObject in a QOpenGLWidget using textures?


I'm trying to play with QOpenGLFramebufferObject to see how could it affect the performance of an app I'm working on.

I have a QOpenGLFramebufferObject fbo that I use like this to draw a simple line:

void Example::drawLine() {
    fbo->bind();
    glBegin(GL_LINES);
    glVertex2f(0, 0);
    glVertex2f(100, 100);
    glEnd();
    fbo->release();
}

If I convert the framebuffer object to an image and display this image in the widget, the line is displayed correctly:

void Example::paintGL() {  // This implementation works.
    drawLine();

    QPainter painter(this);
    painter.beginNativePainting();
    auto im = fbo->toImage();
    painter.drawImage(QPoint(0, 0), im);
    painter.endNativePainting();
}

However, if I try to use textures (and from my understanding, I should use textures if performance matters), then the widget doesn't display anything:

void Example::paintGL() {  // This one doesn't display anything.
    drawLine();

    fbo->bind();
    glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle());
    glBindTexture(GL_TEXTURE_2D, fbo->texture());

    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    fbo->release();
}

What am I missing?

(Note: I simplified the piece of code to be easier to read; in the actual code, I do extra checks for glGetError, and I do verify that bind and release return true.)


Solution

  • When you work with an additional framebuffer, the line:

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    

    is surely wrong.

    All rendering happens into an OpenGL framebuffer object. makeCurrent() ensure that it is bound in the context. Keep this in mind when creating and binding additional framebuffer objects in the rendering code in paintGL(). Never re-bind the framebuffer with ID 0. Instead, call defaultFramebufferObject() to get the ID that should be bound.

    according to QOpenGLWidget reference.