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