2

私は次の問題を抱えています:

さまざまな視点、照明、およびその他のオプションから共通の OpenGL シーンをレンダリングする多くのビューで構成されるアプリケーションを取得したいと考えています。

基本的に、私の質問は qt でそれを行う最良の方法は何ですか?

私の最初の試みは、複数の QOpenGLWidget を作成し、テクスチャだけでなくメッシュとシェーダーも格納する共通の QOpenGLContext を取得することでした。しかし、頂点配列オブジェクトは共有できないように見えるため、メッシュでは機能しませんでした。何度も試行錯誤した結果、メッシュを必要とするウィジェットごとに 1 つの VAO を保存することが解決策として考えられますが、これは非常に見栄えが悪くなります。

ですから、この種の問題に対する適切な代替手段や、これらの QOpenGLContext がどのように機能するかを理解するための適切なドキュメントがあるのではないかと思います。

私が想像した最も単純なアイデアは、QOpenGLContext を 1 つだけ作成し、それをさまざまなウィジェットで使用することです。しかし、QOpenGLContext を単独で作成する方法も、これらのレンダリングを表示できる QWidget の種類もわかりません。

これは私の最初の投稿なので、十分に明確であるかどうか、またはアーキテクチャ全体を説明する必要があるかどうかはわかりません。

4

2 に答える 2

-1

すでに試したので、共有コンテキストについて説明します。

OpenGL コンテキストはウィンドウにバインドされます。コンテキストが 1 つだけ必要な場合は、ウィンドウを 1 つだけにするのが正解です。

ウィジェット モジュールを使用すると、同じ QOpenGLWidget 内の複数のビューポートを使用して、同じシーンの複数のビューを持つことができます。何かのようなもの:

void myWidget::paintGL() {
    //...

    glViewport(
        0, 0,
        this->width()/2, this->height()/2
    );

    // draw scene from one point of view

    glViewport(
        this->width()/2, this->height()/2,
        this->width()/2, this->height()/2
    );

    // draw scene from an other point of view

    //...
}

おそらく、各ビューポートのレンダリング パラメータを格納および管理するためのビューポート クラスを設計する必要があります。

欠点は、ユーザーがインタラクションを処理するためにクリックしているビューポートを検出する必要があることですif event.pos.x is between 0 and this->width()/2 ...


別の方法として、ウィジェット モジュールを放棄して Qt Quick と QML を使用することもできます。クイック ウィンドウは一意の OpenGL コンテキストを宣言します。各クイック アイテムはビューポートに似ていますが、独自のオブジェクトにカプセル化されているため、考える必要はありません。ユーザーが対話している場所について。

QOpenGLWidget の代わりに QQuickItem を継承し、qmlRegisterType() マクロを使用してクラスを QML にエクスポートします。次に、プログラムで QQuickView を作成して、項目を宣言する QML コードをロードできます。Qt のドキュメントの例はこちらです。

于 2016-08-23T14:02:21.587 に答える
-1

複数のビュー/サーフェスを個別に更新できるため、残念ながら、その仕事を行う単一の QOpenGLContext を持つことはできません。また、共有コンテキストには、質問ですでに指摘した制限があります。

QOpenGLContext は、moveToThread() を使用して別のスレッドに移動できます。QOpenGLContext オブジェクトが属するスレッドとは異なるスレッドから makeCurrent() を呼び出さないでください。コンテキストは、一度に 1 つのスレッド内で 1 つのサーフェスに対してのみ現在の状態にすることができ、スレッドは一度に 1 つのコンテキストのみを現在の状態にすることができます。

リンク: http://doc.qt.io/qt-5/qopenglcontext.html

したがって、それを機能させる方法の 1 つは、ビューを順番に独立して更新し、コンテキストを 1 つずつ最新にして、次のビューに移動する前にレンダリングすることです。これにより、常に 1 つのビューでのみコンテキストが最新であることが保証されます。おそらく、QMutex を使用して更新をシリアル化します。

別の方法として、スレッド間でコンテキストを渡し、それらの更新をシリアル化することもできますが、これは悪い方法です。

于 2016-08-23T14:22:23.217 に答える