QPainterPaths的高效屏幕外渲染(需要OpenGL和非OpenGL解决scheme)
- 在我的应用程序中,我使用
QPainter
在widget
上绘制街道地图- 由
QPainterPaths
,包含预先绘制的path - 该
widget
目前是一个QWidget
,而不是一个QGLWidget
,但这可能会改变。
- 由
- 我正试图将这幅画移出屏幕,并将其分割成大块的作业
- 我想绘制每个块到
QImage
,最后将所有图像绘制到widget
-
QPainterPaths
已经分块,所以这不是问题 - 问题是,在
QImages
上绘图比在QWidget
绘图慢大约5倍
- 我想绘制每个块到
- 我做了一些基准testing
- 时间值在多次运行中取平均值
- testing块包含100个
QPainterPaths
,每个QPainterPaths
具有大约150个线性线段 - 用
QPainter::Antialiasing
渲染提示绘制了大约15k条path,QPen
使用圆顶和圆形连接
- 请记住,我的源代码是
QPainterPaths
(线宽+颜色;一些绘制 ,一些填充 )- 我不需要
QPainter
支持的所有其他types的绘图 -
QPainterPaths
可以转换成其他可以在OpenGL buffer
上绘制的东西,这将是一个很好的解决scheme。 - 我不熟悉
OpenGL
离屏渲染,我知道有不同types的OpenGL缓冲区,其中大部分不是用于2D图像渲染,而是用于顶点数据。
- 我不需要
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!
如果你能告诉我一个非基于OpenGL的解决scheme ,那就太好了,因为我想编译两个版本的应用程序: OpenGL
和non-OpenGL
版本。
另外,我希望解决scheme能够在非GUI线程中呈现。
有没有一个很好的方法来有效地画出块?
QGLWidget
(一个OpenGL
的屏幕外缓冲区)有一个离屏计数器部分,可以用作QPainter
的绘图设备吗?
Qt-interest档案,2008年8月QGLContext :: create()
说:
一个QGLContext只能用一个有效的GL绘图设备来创build,这意味着当你创build它的时候,它需要被绑定到一个QGLWidget,QGLPixelBuffer或者QPixmap。 如果你使用QPixmap,它会给你只有软件的渲染,而你不需要它。 QGLFramebufferObject本身不是一个有效的GL绘图设备,它只能在QGLWidget或QGLPixelBuffer的上下文中创build 。 这意味着你需要一个QGLWidget或QGLPixelBuffer作为你的QGLFramebufferObject的基础。
正如文档所指出的那样,如果你想使用opengl在一个离屏的缓冲区中渲染,你需要QGLPixelBuffer。 下面的代码是一个非常简单的例子,演示了如何在OpenGL中使用QGLPixelBuffer:
#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(); }
该程序的结果是一个PNG图像文件为:
对于使用QPixmap的非opengl版本,代码可能采用以下forms:
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(); }
上面的程序的结果是一个PNG文件,如下所示:
虽然代码很简单,但它的工作原理,也许你可以做一些改变,使其适合你。