Important: Please read the Qt Code of Conduct -

Bare minimal QOpenGLFramebufferObject render to texture: Rendered triangle contains "noise"

  • Hello,
    I am trying to make a minimal example that renders the famous red triangle to a texture. I tried this using the following code:

    void GLWidget::initializeGL()
        glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
        m_vao = new QOpenGLVertexArrayObject(this);
        static const GLfloat g_vertex_buffer_data[] = {
           -1.0f, -1.0f, 0.0f,
           1.0f, -1.0f, 0.0f,
           0.0f,  1.0f, 0.0f,
        m_vertexBuffer.allocate(g_vertex_buffer_data, sizeof(g_vertex_buffer_data));
        m_program = new QOpenGLShaderProgram(this);
        m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertexshader.glsl");
        m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fragmentshader.glsl");
        m_program->setAttributeBuffer(0, GL_FLOAT,0,3,0);
        m_framebuffer = new QOpenGLFramebufferObject(QSize(512,512), GL_TEXTURE_2D);
        m_filename = "C:/Users/Axel/Desktop/phased-array/trunk/testcases/build-rendertotexture-Desktop_Qt_5_8_0_MinGW_32bit2-Debug/test.png";
    void GLWidget::paintGL()
        m_framebuffer->bind(); // <= uncomment this one to draw on screen, which works perfectly
        glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
        QImage fbo_img(m_framebuffer->toImage());

    When I uncomment the first two lines of my drawing routine, e.g. m_framebuffer->bind(); and glViewport(0,0,512,512); I get my red triangle as expected on the screen. When I render to the FBO and look into the resulting file, only about maybe half of the pixels are red, the others stay black. The black and red pixel follow a noise-like pattern and on each drawing calls, different pixels belonging to the triangle are red or black.

    I see two possible explainations:

    1. There is some kind of uninitialized buffer involved. Do you have any idea which one?
    2. The graphics card is still busy drawing all the fragments while I save the image. I tried fixing this by calling glFinish, but was not successfull.

    Do you have any idea what might went wrong in my case?

    Best regards


  • Just a shot in the dark, in case the problem is number 2) maybe you should try to save to the file outside the paintGL()

  • Just to be clear, are you using QGLWidget?

    I might be wrong, but I have a feeling that the FBO isn't fully updated at the time of m_framebuffer->toImage().
    If that's the case, you need to find a way to execute that at a point where the rendering (paintGL) is done. Maybe updateGL()?

    Ps. I just saw johngod pointing in the same direction. Maybe this answer give some more value. Ds.

  • Any way, if all you want to do is create a image file from the window and if you using QOpenGLWidget I just remember I have done it before, check the following snipet that you can adatp to your needs:

    void XXXXX::SaveImageAs()
        QString filename;
        filename = QFileDialog::getSaveFileName( this,
                                                tr("Save File"),
                                                getenv( "HOME" ), tr(" Image (*.png)") );
                                                //getenv( "HOME" ), fileformat );
        if( !filename.endsWith( ".png" ) )
            filename.append( ".png" );
        QPixmap pixmap( size() );
        render( &pixmap );
        QImage image = grabFramebuffer();
        QImageWriter imageWriter( filename, "png" );
        if( imageWriter.canWrite() )
            QMessageBox::warning( this, tr("Save Image"), tr("Error saving image.") );

Log in to reply