Efficient off-screen rendering of QPainterPaths (OpenGL and non-OpenGL solution required)

The document of Qt-interest Archive, August 2008 QGLContext::create()

says:

A QGLContext can only be created with a valid GL paint device, which
means it needs to be bound to either a QGLWidget, QGLPixelBuffer or
QPixmap when you create it. If you use a QPixmap it will give you
software-only rendering, and you don’t want that. A QGLFramebufferObject
is not in itself a valid GL paint device, it can only be created within
the context of a QGLWidget or a QGLPixelBuffer
. What this means is that
you need a QGLWidget or QGLPixelBuffer as the base for your
QGLFramebufferObject.

As the document indicated, if you want to render in an off-screen buffer using opengl, you need QGLPixelBuffer. The code below is a very simple example which demonstrates how to use QGLPixelBuffer with OpenGL:

#include <QtGui/QApplication>
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <QtOpenGL/QGLFormat>
#include <QtOpenGL/QGLPixelBuffer>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // Construct an OpenGL pixel buffer.
    QGLPixelBuffer glPixBuf(100, 100); 
    // Make the QGLContext object bound to pixel buffer the current context
    glPixBuf.makeCurrent();
    // The opengl commands 
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glViewport(0, 0, 100, 100);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, 100, 0, 100);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 0.0, 0.0);
    glPointSize(4.0);
    glBegin(GL_TRIANGLES);
    glVertex2i(10, 10);
    glVertex2i(50, 50);
    glVertex2i(25, 75);
    glEnd();
    // At last, the pixel buffer was saved as an image
    QImage &pImage = glPixBuf.toImage();
    pImage.save(QString::fromLocal8Bit("gl.png"));

    return a.exec();
}

The result of the program is a png image file as:

enter image description here

For non-opengl version using QPixmap, the code maybe in forms of below:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QPixmap pixmap(100, 100);
    QPainter painter;
    painter.begin(&pixmap);
    painter.drawText(10, 45, QString::fromLocal8Bit("I love American."));
    painter.end();
    pixmap.save(QString::fromLocal8Bit("pixmap.png"));

    return a.exec();
}

The result of the program above is a png file looks like:

enter image description here

Though the code is simple, but it works, maybe you can do some changes to make it suitable for you.

Leave a Comment