QPainterPaths的高效离屏渲染(需要OpenGL和非OpenGL解决方案)

时间:2012-07-13 15:59:56

标签: c++ qt opengl qpainter

  1. 在我的应用程序中,我使用QPainter上的widget绘制街道地图
      QPainterPaths制作的
    • 包含预先绘制的路径
    • widget目前是QWidget,而不是QGLWidget,但这可能会发生变化。
  2. 我正试图将这幅画移出屏幕并将其分成多块作业
    • 我想将每个块绘制到QImage上,最后将所有图像绘制到widget
    • QPainterPaths已经分块了,所以这不是问题
    • 问题是,QImages上的绘图比<{1}}
    • 上的绘图慢5倍
  3. 我做过一些基准测试
    • 时间值是多次运行的四舍五入平均值
    • 测试块包含100个QWidget,每个<{li>有大约150个线性线段
    • 使用QPainterPaths渲染提示绘制大约15k路径,QPainter::Antialiasing使用圆顶和圆形连接
  4. 请记住,我的来源为QPen(线宽+颜色;部分 绘制 ,部分 已填充 < /强>)
    • 我不需要所有其他类型的图纸QPainterPaths支持
    • 可以将QPainter转换为可以在QPainterPaths上绘制的其他内容,这将是一个很好的解决方案。
    • 我不熟悉OpenGL buffer离屏渲染,我知道有不同类型的OpenGL缓冲区,其中大多数不是用于2D图像渲染,而是用于顶点数据。
  5. OpenGL

    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 ----------------------------------------------------+--------------------------

    如果你能告诉我一个非基于OpenGL的解决方案那就太好了,因为我想用两个版本编译我的应用程序:(*) These 2 lines have been added afterwards and are solutions to the problem!和{{1} }版 此外,我希望解决方案能够在非GUI线程中呈现。


    有没有一种好方法可以在屏幕外有效地绘制块?
    是否有OpenGLnon-OpenGL屏幕外缓冲区)的屏幕外计数器部分,可用作QGLWidget的绘图设备?

1 个答案:

答案 0 :(得分:5)

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

的文件

表示:

  

只能使用有效的GL绘图设备创建QGLContext   意味着它需要绑定到QGLWidget,QGLPixelBuffer或   创建时的QPixmap。如果你使用QPixmap,它会给你   纯软件渲染,你不希望这样。 一个QGLFramebufferObject   它本身不是一个有效的GL绘图设备,它只能在其中创建   QGLWidget或QGLPixelBuffer 的上下文。这意味着什么   你需要一个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图像文件:

enter image description here

对于使用QPixmap的非opengl版本,代码可能采用以下形式:

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文件,如下所示:

enter image description here

虽然代码很简单,但它有效但也许您可以做一些更改以使其适合您。