Agg painting

From qtnode

Jump to: navigation, search

Painting to QWidget's with libagg

There are some outstanding issues with Qt4's painting system that make it too slow for many applications (eg mapping, CAD, etc). An alternative to using Qt's built-in QPainter, is to use libagg (www.antigrain.com) which is orders of magnitude faster for vector painting.

In order to do this, in the QWidget's paintEvent(), you must create a QImage of the correct size and width. You can then retrieve the location of the pixel buffer using QImage::bits() and attach it to an agg render buffer. You can the use agg to draw onto the QImage, and finally draw the QImage onto the widget using QPainter::drawImage(). This is apparently a fairly slow step (~20 fps fullscreen not alpha-blended), but should be adequate for many purposes.

... code, links to follow ...

<Ahigerd>: My thought here is that you should maintain a QImage in memory and reuse the buffer rather than instantiating a new object every time. If the image doesn't change very often, it might be preferable to maintain a QPixmap as well, converting the QImage to a QPixmap after painting is complete; QPainter::drawPixmap() is much faster than QPainter::drawImage(), but QPixmap::fromImage() is a little expensive so it's only worthwhile if you're not updating the image with every paint event.

<Ahigerd>: Maintaining a static QImage also means updates will be buffered, allowing you to make incremental changes if you desire. If you don't want buffering, I would wager that QImage::fill() is faster than instantiating a new QImage, but I haven't benchmarked this.

<Ahigerd>: One last possibility I've considered is to use QWidget::getDC() to allow third-party paint routines to draw directly to the widget. This may or may not be ideal but it sidesteps the inefficiency of painting QImage.

<Ahigerd>: Anyway, any third-party painting library should be able to be integrated into Qt using one of these two procedures (paint to a buffer in a QImage or getDC() and paint directly); which method you use depends on what options the library provides. Keep in mind that getDC() isn't necessarily portable.

Personal tools