45
  1. 在我的应用程序中,我QPainter使用widget
    • QPainterPaths包含要绘制的预先计算的路径制成
    • 当前widget是 a QWidget,而不是 a QGLWidget,但这可能会改变。
  2. 我正在尝试将绘画移出屏幕并将其拆分为分块作业
    • 我想将每个块绘制到 a 上QImage,最后将所有图像绘制到widget
    • QPainterPaths已经分块,所以这不是问题
    • 问题是,绘图QImages比绘图慢 5 倍QWidget
  3. 我做过的一些基准测试
    • 时间值是多次运行的四舍五入平均值
    • 测试块包含 100 个QPainterPaths,每个块有大约 150 个线性线段
    • QPainter::Antialiasing使用渲染提示绘制大约 15k 条路径,QPen使用圆帽和圆连接
  4. 请记住,我的来源是QPainterPaths(和线宽+颜色;一些绘制,一些填充
    • 我不需要所有其他类型的绘图QPainter支持
    • 可以QPainterPaths转换为可以在 a 上绘制的其他东西OpenGL buffer,这将是一个很好的解决方案。
    • 我不熟悉OpenGL离屏渲染,我知道有不同类型的 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 的解决方案,那就太好了,因为我想在两个版本中编译我的应用程序:OpenGLnon-OpenGLversion.
另外,我希望解决方案能够在非 GUI 线程中呈现。


有没有一种有效地在屏幕外绘制块的好方法?
是否有QGLWidgetOpenGL屏幕外缓冲区)的屏幕外计数器部分可以用作绘画设备QPainter

4

1 回答 1

5

Qt-interest Archive的文档,2008 年 8 月 QGLContext::create()

说:

QGLContext 只能使用有效的 GL 绘制设备创建,这意味着它需要在创建时绑定到 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 图像文件,如下所示:

在此处输入图像描述

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

在此处输入图像描述

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

于 2012-10-08T11:31:28.550 回答