Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QOpenGLFrameBuffer toImage(): text with too big font size displayed as black bar



  • I have a QOpenGLWidget in which I draw text with a QPainter. I would like to implement a snapshot feature by rendering the widget content into a QOpenGLFrameBuffer and converting the frame buffer into a QImage.

    Unfortunately, if I set the font's point size too high (> 46), the text appears as a black bar in the snapshot, while in the widget it is displayed correctly. See below an example snapshot where the block over the line is supposed to be text with font size > 46.
    The block over the black line is supposed to be some text

    Here is the simplified code to render the image (it should work, because it is correctly displayed in the QOpenGLWidget):

    void renderSomething(const int x, const int y, const QString & str, const int fontSize) {
        // 1. draw the line
        // (calculate min_x, max_x, y and z values)
        glLineWidth(3);
        glColor3f(0., 0., 0.);
        glBegin(GL_LINES);
        glVertex3f(min_x, y, z);
        glVertex3f(max_x, y, z);
        glEnd();
    
        // 2. draw the text
        GLint gl_viewport[4];
        glGetIntegerv(GL_VIEWPORT, gl_viewport);
        backup_gl_state();
        QOpenGLPaintDevice paintDevice(gl_viewport[2], gl_viewport[3]);
        QPainter painter(&paintDevice);
        painter.setFont(QFont(painter.font().family(), fontSize);
        painter.setPen(Qt::black);
        painter.drawText(x, y, str);
        painter.end();
        restore_gl_state();
    }
    

    Here is the code for storing a snapshot:

    void Viewport::takeSnapshot(const QString & path, const int size) {
        glPushAttrib(GL_VIEWPORT_BIT);
        glViewport(0, 0, size, size); // since size varies I want the text to scale with it
        QOpenGLFramebufferObject fbo(size, size, QOpenGLFramebufferObject::Depth);
        fbo.bind();
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        renderer.renderSomething(100, 100, "Test", 50); // Here is the render call!
    
        QImage fboImage(fbo.toImage());
        QImage image(fboImage.constBits(), fboImage.width(), fboImage.height(), QImage::Format_RGB32);
        image.save(path);
        glPopAttrib();
        fbo.bindDefault();
        fbo.release();
    }