QPainter on a widget QPainterPaths that contain precalculated paths to be drawnwidget is currently a QWidget, not a QGLWidget, but this might change.QImage and finally draw all images onto the widget QPainterPaths are already chunked, so this is not the problemQImages is about 5 times slower than drawing on QWidget QPainterPaths that have about 150 linear line segments eachQPainter::Antialiasing render hint, QPen uses round cap and round joinQPainterPaths (and line width + color; some drawn, some filled) QPainter supportsQPainterPaths be converted to something else which can be drawn on a OpenGL buffer, this would be a good solution.OpenGL off-screen rendering and I know that there are different types of OpenGL buffers, of which most of them aren't for 2D image rendering but for vertex data.Paint Device for chunk | Rendering the chunk itself | Painting chunk on QWidget -----------------------+----------------------------+-------------------------- QImage | 2000 ms | < 10 ms QPixmap (*) | 250 ms | < 10 ms QGLFramebufferObj. (*) | 50 ms | < 10 ms QPicture | 50 ms | 400 ms -----------------------+----------------------------+-------------------------- none (directly on a QWidget in paintEvent) | 400 ms ----------------------------------------------------+-------------------------- (*) These 2 lines have been added afterwards and are solutions to the problem!
It would be nice if you can tell me a non-OpenGL-based solution, too, as I want to compile my application in two versions: OpenGL and non-OpenGL version.
Also, I want the solution to be able to render in a non-GUI thread.
Is there a good way to efficiently draw the chunks off-screen?
Is there an off-screen counter part of QGLWidget (an OpenGL off-screen buffer) which can be used as a paint device for QPainter?
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:

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:

Though the code is simple, but it works, maybe you can do some changes to make it suitable for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With