45
  1. 私のアプリケーションではQPainterwidget
    • によって作成されQPainterPaths、描画される事前計算されたパスが含まれています
    • widget現在、QWidgetではなくQGLWidgetですが、これは変更される可能性があります。
  2. 絵を画面外に移動して、チャンクジョブに分割しようとしています
    • 各チャンクをにペイントしQImage、最後にすべての画像をに描画したいwidget
    • QPainterPathsすでにチャンク化されているため、これは問題ではありません
    • 問題は、描画が描画よりもQImages5 倍遅いことです。QWidget
  3. 私が行ったいくつかのベンチマークテスト
    • 時間の値は、複数回の実行の丸め平均です
    • テスト チャンクにはQPainterPaths、それぞれ約 150 の直線セグメントを持つ100 が含まれます
    • 約 15,000 のパスがQPainter::Antialiasingレンダー ヒントで描画され、QPenラウンド キャップとラウンド ジョインが使用されます
  4. QPainterPaths私のソースは(および線幅+色;一部は描画され、一部は塗りつぶされていることを覚えておいてください)
    • QPainter他のすべての種類の描画サポートは必要ありません
    • QPainterPathsに描画できる別のものに変換できます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!

アプリケーションを 2 つのバージョンでコンパイルしたいので、OpenGL ベース以外のソリューションも教えていただければ幸いです。また、ソリューションを非 GUI スレッド でレンダリングできるようにしたいと考えています。OpenGLnon-OpenGL


チャンクを画面外に効率的に描画する良い方法はありますか? のペイント デバイスとして使用できる(オフスクリーン バッファー) のオフ
スクリーン カウンター部分はありますか?QGLWidgetOpenGLQPainter

4

1 に答える 1

5

Qt-interest Archiveのドキュメント、2008 年 8 月 QGLContext::create()

言います:

QGLContext は、有効な GL ペイント デバイスでのみ作成できます。つまり、作成時に QGLWidget、QGLPixelBuffer、または QPixmap のいずれかにバインドする必要があります。QPixmap を使用すると、ソフトウェアのみのレンダリングが提供されますが、それは望ましくありません。QGLFramebufferObject は、それ自体では有効な GL ペイント デバイスではなく、 QGLWidget または QGLPixelBuffer のコンテキスト内でのみ作成できます。これは、QGLFramebufferObject のベースとして QGLWidget または QGLPixelBufferが必要であることを意味します。

ドキュメントが示すように、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 に答える