OpenGL render to texture using QOpenGLFramebufferObject



  • Hi,
    I am currently restructuring some code and want to bring it from Qt 4.7.4 to Qt 5.4 with the aim to compile it for android.
    The code makes use of the QGLFramebufferObject (Qt 4.7.4) and because this no longer exists in 5.4, I am attempting to use QOpenGLFramebufferObject (which exists in Qt 5.4) for the updated code.

    The code in question works fine in 4.7.4, but I can't get it to work in 5.4. The only difference in the calls it makes is that instead of QGLFramebufferObject, the code now uses QOpenGLFramebufferObject.

    The code is supposed to render some colored rectangles to an offscreen buffer, and then copy a rectangular section from the offscreen buffer and render the section on the screen.

    in 4.7.4 and in 5.4 both the code looks identical like this:
    (the difference is that for the old code GLWidget inherits from QGLWidget, and in the new code it inherits from QOpenGLWidget).
    "fbo" is the QGLFramebufferObject / QOpenGLFramebufferObject, respectively.
    Also initialization of OpenGL, looks pretty much the same for both code instances. I am really puzzled why the new code doesn't work, just shows a black screen.

    void GLWidget::paintGL()
    {
        // Clear screen and depth buffer
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
        DrawOffScreen();
        DrawScreen();
    	glFlush();
    }
    
    void GLWidget::DrawOffScreen(){
    
        glPushAttrib(GL_ALL_ATTRIB_BITS);
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
    
        glViewport(0, 0, 512, 512);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        // 2D Ortho View
        glOrtho(0.0, 512, 0.0, 512, -1.0f, 1.0f); 
        // back to modelview mode
        glMatrixMode(GL_MODELVIEW);     
        glLoadIdentity();
    
        // render to the framebuffer object
        fbo->bind();
        // Clear screen and depth buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    
            //draw some rectangles..
            DrawRectangle(0,0,512,512, 255,0,255);
            DrawRectangle(200,0,300,510, 0,255,255);
            DrawRectangle(100,30,100,310, 200,155);
        fbo->release();
    
        // pop the projection matrix and GL state back 
        //for rendering to the actual widget
        glPopAttrib();
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
    
        // back to modelview mode
        glMatrixMode(GL_MODELVIEW);     
    }
    
    void GLWidget::DrawScreen(){
    
        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
        glBindTexture(GL_TEXTURE_2D, fbo->texture());
    
        glDisable(GL_BLEND);
        glEnable(GL_TEXTURE_2D);
        glColor4f(1.0f, 1.0f, 1.0f, 1);
        glBegin(GL_QUADS);
    
            glTexCoord2f(0,0);   glVertex2f(0, 0);
            glTexCoord2f(1, 0);   glVertex2f(512, 0);
            glTexCoord2f(1, 1);   glVertex2f(512, 512);
            glTexCoord2f(0, 1);   glVertex2f(0, 512);
    
        glEnd();
        glEnable(GL_BLEND);
    }
    
    

    Any ideas? Thanks a lot for reading this.



  • Could it be that Qt 5.4 has a bug supporting the OpenGL library, where Qt 4.7 still worked? Or what else could this be?
    I'm happy to send the sources for this in a minimal project, if that helps?


  • Lifetime Qt Champion

    Hi,

    AFAIK, QGLFramebufferObject is still available in Qt 5, what error did you get with it ?

    Your software is using the OpenGL fixed pipeline, but IIRC with the new set of OpenGL classes in Qt 5, you need to request a profile that provides support for it otherwise you'll have to refactor your code to use the new dynamic pipeline.

    Hope it helps



  • Do a makeCurrent() in GLWidget::paintGL right after drawOffScreen(). When you call fbo->release() you will end up with binding the default framebuffer (id 0) instead of the QOpenGLWidget's backing framebuffer. This has been fixed in Qt 5.5 (QTBUG-43269) so the example you posted should work there without any changes. For previous versions call makeCurrent() manually.



  • @SGaist

    what error did you get with it ?

    when I try to use #include <QGLFramebufferObject> I get a compile error:

    In file included from mainwidget.cpp:44: ./mainwidget.h:56:10: fatal error: 'QGLFramebufferObject' file not found #include <QGLFramebufferObject>

    and I'm compiling on Qt 5.4.1



  • @agocs hmmm, I tried doing that, inserting makeCurrent(), but that didn't change anything. Still get a black screen.

    btw, when I deactivate drawOffScreen(), only calling drawScreen() it gives me scrambled data (undefined) on the screen, where I would expect to see a white quad, because of glColor4f(1.0f, 1.0f, 1.0f, 1.0f); in drawScreen()



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.