QPainterPaths的高效离屏渲染(需要OpenGL和非OpenGL解决方案) [英] Efficient off-screen rendering of QPainterPaths (OpenGL and non-OpenGL solution required)

查看:885
本文介绍了QPainterPaths的高效离屏渲染(需要OpenGL和非OpenGL解决方案)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 在我的应用程序中,我使用 QPainter 小部件上绘制街道地图

    • QPainterPaths 制作,包含要绘制的预先计算的路径

    • code> widget 目前是 QWidget ,而不是 QGLWidget 可能会改变。

  1. In my application, I paint a street map using QPainter on a widget
    • made by QPainterPaths that contain precalculated paths to be drawn
    • the widget is currently a QWidget, not a QGLWidget, but this might change.

  • 我要将每个块绘制到 QImage ,最后将所有图像绘制到小部件

  • QPainterPaths 已经分块,所以这不是问题

  • 绘制 QImages 比绘制 QWidget
  • 大约慢5倍 b $ b
  • I want to paint each chunk onto a QImage and finally draw all images onto the widget
  • QPainterPaths are already chunked, so this is not the problem
  • problem is, that drawing on QImages is about 5 times slower than drawing on QWidget

  • 时间值是多次运行的舍入平均值

  • 测试区块包含100个 QPainterPaths ,每个

  • 有大约150个线性线段用 QPainter :: Antialiasing 渲染提示, QPen 使用圆帽和圆形连接绘制

  • time values are rounded averages over multiple runs
  • test chunk contains 100 QPainterPaths that have about 150 linear line segments each
  • the roughly 15k paths are drawn with QPainter::Antialiasing render hint, QPen uses round cap and round join

  • 不需要所有其他类型的绘图 QPainter 支持

  • 可以 QPainterPaths 转换为可以在 OpenGL缓冲区上绘制的其他东西,这将是一个很好的解决方案。

  • 我不熟悉使用 OpenGL 离屏渲染,我知道有不同类型的OpenGL缓冲区,其中大多数不是2D图像渲染,而是顶点数据。 li>
  • I don't need all the other types of drawing QPainter supports
  • Can QPainterPaths be converted to something else which can be drawn on a OpenGL buffer, this would be a good solution.
  • I'm not familiar with 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
----------------------------------------------------+--------------------------

(*)这两行已经添加,并且是问题的解决方案!

如果你可以告诉我一个非基于OpenGL的解决方案,这将是很好,因为我想编译我的应用程序的两个版本: OpenGL 非OpenGL 版本。

此外,我希望解决方案能够在非GUI线程

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.

off-screen?

QGLWidget (一个 OpenGL QPainter

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?

推荐答案

Qt-兴趣档案,2008年8月QGLContext :: create()

说:


QGLContext只能使用有效的GL绘图设备创建,
意味着在创建它时需要绑定到QGLWidget,QGLPixelBuffer或
QPixmap。如果你使用QPixmap它会给你
纯软件渲染,你不想要的。 QGLFramebufferObject
本身不是有效的GL绘图设备,它只能在QGLWidget或QGLPixelBuffer
的上下文中的
中创建。这意味着
你需要一个QGLWidget或QGLPixelBuffer作为你的
QGLFramebufferObject的基础。

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.

如文档所示,如果要使用opengl在屏幕外缓冲区中呈现,则需要QGLPixelBuffer。下面的代码是一个非常简单的例子,演示了如何使用QGLPixelBuffer与OpenGL:

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();
}

程序的结果是一个png图像文件:

The result of the program is a png image file as:

>

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

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();
}

上面的程序的结果是一个png文件看起来像:

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.

这篇关于QPainterPaths的高效离屏渲染(需要OpenGL和非OpenGL解决方案)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆