QRhiWidget Class

QRhiWidgetクラスは、Vulkan、Metal、Direct 3Dなどのアクセラレイティド・グラフィックスAPIを介して3Dグラフィックスをレンダリングするためのウィジェットです。詳細...

Header: #include <QRhiWidget>
CMake: find_package(Qt6 REQUIRED COMPONENTS Widgets)
target_link_libraries(mytarget PRIVATE Qt6::Widgets)
qmake: QT += widgets
Since: Qt 6.7
Inherits: QWidget
Status: Preliminary

このクラスは開発中であり、変更される可能性があります。

パブリックタイプ

enum class Api { Null, OpenGL, Metal, Vulkan, Direct3D11, Direct3D12 }
enum class TextureFormat { RGBA8, RGBA16F, RGBA32F, RGB10A2 }

プロパティ

パブリック関数

QRhiWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {})
virtual ~QRhiWidget() override
QRhiWidget::Api api() const
QRhiWidget::TextureFormat colorBufferFormat() const
QSize fixedColorBufferSize() const
QImage grabFramebuffer() const
bool isDebugLayerEnabled() const
bool isMirrorVerticallyEnabled() const
int sampleCount() const
void setApi(QRhiWidget::Api api)
void setColorBufferFormat(QRhiWidget::TextureFormat format)
void setDebugLayerEnabled(bool enable)
void setFixedColorBufferSize(QSize pixelSize)
void setFixedColorBufferSize(int w, int h)
void setMirrorVertically(bool enabled)
void setSampleCount(int samples)

シグナル

void colorBufferFormatChanged(QRhiWidget::TextureFormat format)
void fixedColorBufferSizeChanged(const QSize &pixelSize)
void frameSubmitted()
void mirrorVerticallyChanged(bool enabled)
void renderFailed()
void sampleCountChanged(int samples)

保護された関数

QRhiTexture *colorTexture() const
QRhiRenderBuffer *depthStencilBuffer() const
virtual void initialize(QRhiCommandBuffer *cb)
QRhiRenderBuffer *msaaColorBuffer() const
virtual void releaseResources()
virtual void render(QRhiCommandBuffer *cb)
QRhiRenderTarget *renderTarget() const
QRhiTexture *resolveTexture() const
QRhi *rhi() const
void setAutoRenderTarget(bool enabled)

再実装された保護された関数

virtual bool event(QEvent *e) override
virtual void paintEvent(QPaintEvent *e) override
virtual void resizeEvent(QResizeEvent *e) override

詳細説明

注意: QRhiWidgetはQt 6.7の技術プレビュー版です。APIは開発中であり、変更される可能性があります。

QRhiWidgetは、QWidget ベースのアプリケーション内で、QRhi APIを通してレンダリングされた3Dコンテンツを表示する機能を提供します。多くの点でQOpenGLWidget と同等のポータブルなもので、単一の3DグラフィックスAPIに縛られることなく、QRhi がサポートするすべてのAPI(Direct 3D 11/12、Vulkan、Metal、OpenGLなど)で機能します。

QRhiWidgetはサブクラス化される予定です。QRhiWidgetによって暗黙的に作成、管理される2Dテクスチャにレンダリングするために、サブクラスは仮想関数initialize ()とrender ()を再実装する必要があります。

テクスチャのサイズは、デフォルトではウィジェットのサイズに適応します。固定サイズが望ましい場合は、setFixedColorBufferSize() を呼び出して、ピクセルで指定された固定サイズを設定します。

カラーバッファとして機能するテクスチャに加えて、深度/ステンシルバッファと、これらを結合するレンダーターゲットも暗黙的に維持されます。

ウィジェットのトップレベルウィンドウのQRhi は、デフォルトでプラットフォーム固有のバックエンドとグラフィック API を使用するように設定されています:macOSとiOSではMetal、WindowsではDirect 3D 11、それ以外ではOpenGLです。これをオーバーライドするには、setApi() を呼び出します。

注意: 1つのウィジェットウィンドウは、1つのQRhi バックエンド、つまり1つの3DグラフィックスAPIしか使用できません。ウィンドウのウィジェット階層にある2つのQRhiWidgetまたはQQuickWidget ウィジェットが異なるAPIを要求した場合、そのうちの1つだけが正しく機能します。

注意: QRhiWidgetはQtのパブリックAPIですが、QRhiQShaderQShaderDescription を含むQt GuiモジュールのQRhi クラスファミリーは、限定的な互換性保証を提供します。これらのクラスにはソース互換性もバイナリ互換性も保証されていません。つまり、APIはアプリケーションが開発されたQtバージョンでのみ動作することが保証されています。しかし、ソース互換性のない変更は最小限にとどめることを目的としており、マイナーリリース(6.7、6.8など)でのみ行われる予定です。qrhiwidget.h は、QRhi 関連のヘッダを直接含みません。QRhiWidgetのサブクラスを実装する際にこれらのクラスを使用するには、Qt::GuiPrivate (CMakeを使用している場合)にリンクし、rhi のプレフィックスで適切なヘッダーをインクルードしてください(例:#include <rhi/qrhi.h> )。

三角形をレンダリングするシンプルなQRhiWidgetサブクラスの例を以下に示します:

class ExampleRhiWidget : public QRhiWidget
{
public:
    ExampleRhiWidget(QWidget *parent = nullptr) : QRhiWidget(parent) { }
    void initialize(QRhiCommandBuffer *cb) override;
    void render(QRhiCommandBuffer *cb) override;
private:
    QRhi *m_rhi = nullptr;
    std::unique_ptr<QRhiBuffer> m_vbuf;
    std::unique_ptr<QRhiBuffer> m_ubuf;
    std::unique_ptr<QRhiShaderResourceBindings> m_srb;
    std::unique_ptr<QRhiGraphicsPipeline> m_pipeline;
    QMatrix4x4 m_viewProjection;
    float m_rotation = 0.0f;
};

float vertexData[] = {
     0.0f,   0.5f,     1.0f, 0.0f, 0.0f,
    -0.5f,  -0.5f,     0.0f, 1.0f, 0.0f,
     0.5f,  -0.5f,     0.0f, 0.0f, 1.0f,
};

QShader getShader(const QString &name)
{
    QFile f(name);
    return f.open(QIODevice::ReadOnly) ? QShader::fromSerialized(f.readAll()) : QShader();
}

void ExampleRhiWidget::initialize(QRhiCommandBuffer *cb)
{
    if (m_rhi != rhi()) {
        m_pipeline.reset();
        m_rhi = rhi();
    }

    if (!m_pipeline) {
        m_vbuf.reset(m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData)));
        m_vbuf->create();

        m_ubuf.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64));
        m_ubuf->create();

        m_srb.reset(m_rhi->newShaderResourceBindings());
        m_srb->setBindings({
            QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, m_ubuf.get()),
        });
        m_srb->create();

        m_pipeline.reset(m_rhi->newGraphicsPipeline());
        m_pipeline->setShaderStages({
            { QRhiShaderStage::Vertex, getShader(QLatin1String(":/shader_assets/color.vert.qsb")) },
            { QRhiShaderStage::Fragment, getShader(QLatin1String(":/shader_assets/color.frag.qsb")) }
        });
        QRhiVertexInputLayout inputLayout;
        inputLayout.setBindings({
            { 5 * sizeof(float) }
        });
        inputLayout.setAttributes({
            { 0, 0, QRhiVertexInputAttribute::Float2, 0 },
            { 0, 1, QRhiVertexInputAttribute::Float3, 2 * sizeof(float) }
        });
        m_pipeline->setVertexInputLayout(inputLayout);
        m_pipeline->setShaderResourceBindings(m_srb.get());
        m_pipeline->setRenderPassDescriptor(renderTarget()->renderPassDescriptor());
        m_pipeline->create();

        QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch();
        resourceUpdates->uploadStaticBuffer(m_vbuf.get(), vertexData);
        cb->resourceUpdate(resourceUpdates);
    }

    const QSize outputSize = colorTexture()->pixelSize();
    m_viewProjection = m_rhi->clipSpaceCorrMatrix();
    m_viewProjection.perspective(45.0f, outputSize.width() / (float) outputSize.height(), 0.01f, 1000.0f);
    m_viewProjection.translate(0, 0, -4);
}

void ExampleRhiWidget::render(QRhiCommandBuffer *cb)
{
    QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch();
    m_rotation += 1.0f;
    QMatrix4x4 modelViewProjection = m_viewProjection;
    modelViewProjection.rotate(m_rotation, 0, 1, 0);
    resourceUpdates->updateDynamicBuffer(m_ubuf.get(), 0, 64, modelViewProjection.constData());

    const QColor clearColor = QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f);
    cb->beginPass(renderTarget(), clearColor, { 1.0f, 0 }, resourceUpdates);

    cb->setGraphicsPipeline(m_pipeline.get());
    const QSize outputSize = colorTexture()->pixelSize();
    cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height()));
    cb->setShaderResources();
    const QRhiCommandBuffer::VertexInput vbufBinding(m_vbuf.get(), 0);
    cb->setVertexInput(0, 1, &vbufBinding);
    cb->draw(3);

    cb->endPass();

    update();
}

これは、プレゼンテーション・レート(画面のリフレッシュ・レートに応じてvsync)によってスロットルされ、継続的に更新を要求するウィジェットです。継続的なレンダリングを望まない場合は、render() のupdate() 呼び出しを削除し、レンダリングされたコンテンツの更新が必要な場合にのみ発行します。たとえば、立方体の回転をQSlider の値に関連付ける必要がある場合は、スライダの値変更シグナルを、新しい値を転送してupdate() を呼び出すスロットまたはラムダに接続すれば十分です。

頂点シェーダとフラグメントシェーダは、Vulkan スタイルの GLSL として提供されるため、Qt シェーダインフラストラクチャで最初に処理する必要があります。これは、qsb コマンドラインツールを手動で実行するか、CMake のqt_add_shaders()関数を使用することで実現できます。QRhiWidgetの実装では、アプリケーションに同梱されているこれらの前処理済みの.qsb 。Qtのシェーダ変換インフラストラクチャの詳細については、Qt Shader Toolsを参照してください。

これらのシェーダのソースコードは次のようになります:

color.vert

#version 440
layout(location = 0) in vec4 position;
layout(location = 1) in vec3 color;
layout(location = 0) out vec3 v_color;
layout(std140, binding = 0) uniform buf {
    mat4 mvp;
};

void main()
{
    v_color = color;
    gl_Position = mvp * position;
}

color.frag

#version 440
layout(location = 0) in vec3 v_color;
layout(location = 0) out vec4 fragColor;

void main()
{
    fragColor = vec4(v_color, 1.0);
}

結果は以下のようなウィジェットになります:

完全で最小限の入門的な例については、Simple RHI Widget Exampleをチェックしてください。

より多くの機能を持つ例とさらなるコンセプトのデモについては、Cube RHI Widget Exampleをご覧ください。

QRhiWidgetは常に、ウィンドウ(ネイティブウィンドウのウィンドウシステムによって提供されるサーフェスまたはレイヤー)に直接レンダリングするのではなく、バッキングテクスチャにレンダリングします。これにより、コンテンツをウィジェットベースのUIの残りの部分と適切に合成し、シンプルでコンパクトなAPIを提供することができ、簡単に始めることができます。これらはすべて、追加リソースとパフォーマンスへの潜在的な影響を犠牲にしています。これは実際には完全に受け入れられることが多いですが、上級ユーザーは異なるアプローチの長所と短所を覚えておく必要があります。2つのアプローチの詳細については、RHI Window Exampleを参照し、Simple RHI Widget Exampleと比較してください。

QRhiWidgetを別のウィンドウ(トップレベルのウィジェット)に属するウィジェット階層に再ペアレントする、またはQRhiWidget自体を(親をnullptr に設定することで)トップレベルにすることは、QRhiWidgetが健在であり続ける一方で、関連するQRhi (そして潜在的に古いものを破壊する)を変更することを伴います。これをサポートするために、堅牢なQRhiWidget実装は、releaseResources()仮想関数も再実装し、デストラクタで行うように、QRhi リソースを削除することが期待されます。Cube RHI Widget Exampleは、これを実際に示しています。

主な使用例ではありませんが、QRhiWidgetは、Vulkan、Metal、Direct 3D、OpenGLなどの3DグラフィックスAPIを直接使用するレンダリングコードを組み込むこともできます。QRhi レンダーパスのネイティブコマンドの記録についてはQRhiCommandBuffer::beginExternal()を、既存のネイティブテクスチャをラップし、後続のレンダーパスのQRhi で使用する方法についてはQRhiTexture::createFrom() を参照してください。しかし、QRhiWidgetの主な目的は、QRhi-ベースのレンダリングコードに適した環境を提供することであり、任意の、潜在的に複雑な、外国のレンダリングエンジンを有効にすることではないため、基礎となるグラフィックスAPI(そのデバイスまたはコンテキスト機能、レイヤー、拡張機能など)の設定可能性は制限されることに注意してください。

QRhi,QShader,QOpenGLWidget,Simple RHI Widget Example, andCube RHI Widget Exampleも参照

メンバ型ドキュメント

enum class QRhiWidget::Api

使用する 3D API およびQRhi バックエンドを指定します。

定数
QRhiWidget::Api::Null0
QRhiWidget::Api::OpenGL1
QRhiWidget::Api::Metal2
QRhiWidget::Api::Vulkan3
QRhiWidget::Api::Direct3D114
QRhiWidget::Api::Direct3D125

QRhiも参照してください

enum class QRhiWidget::TextureFormat

QRhiWidget がレンダリングするテクスチャのフォーマットを指定します。

定数説明
QRhiWidget::TextureFormat::RGBA80QRhiTexture::RGBA8 を参照してください。
QRhiWidget::TextureFormat::RGBA16F1QRhiTexture::RGBA16F を参照してください。
QRhiWidget::TextureFormat::RGBA32F2QRhiTexture::RGBA32F を参照。
QRhiWidget::TextureFormat::RGB10A23QRhiTexture::RGB10A2 を参照。

QRhiTextureも参照。

プロパティ ドキュメント

autoRenderTarget : const bool

深度ステンシルバッファとレンダーターゲットの自動メンテナンスの現在の設定。

デフォルト値はtrue です。

colorBufferFormat : TextureFormat

このプロパティは、カラーバッファとして使用されるテクスチャ(またはレンダーバッファ)のテクスチャフォーマットを制御します。デフォルト値はTextureFormat::RGBA8 です。QRhiWidget は、QRhiTexture でサポートされているフォーマットのサブセットへのレンダリングをサポートします。QRhi::isTextureFormatSupported() からサポートされていると報告されたフォーマットのみを指定する必要があります。そうでない場合、レンダリングは機能しません。

注意: ウィジェットがすでに初期化され、レンダリングされているときに新しいフォー マットを設定すると、関連するQRhiRenderPassDescriptor のテクスチャフォーマットが異なるた めに互換性がない場合、レンダラーによって作成されたすべてのQRhiGraphicsPipeline オブジェクト が使用できなくなる可能性があります。これは、sampleCount を動的に変更するのと同様に、initialize() またはrender() の実装が、既存のパイプラインを解放し、新しいパイプラインを作成する必要があることを意味します。

アクセス関数

QRhiWidget::TextureFormat colorBufferFormat() const
void setColorBufferFormat(QRhiWidget::TextureFormat format)

通知シグナル:

void colorBufferFormatChanged(QRhiWidget::TextureFormat format)

fixedColorBufferSize : QSize

QRhiWidget の関連テクスチャの固定サイズ(ピクセル単位)。ウィジェットのサイズに依存しない固定テクスチャサイズが必要な場合に関連します。このサイズは、ウィジェットのジオメトリ(そのサイズとトップレベルウィンドウ内の配置)に影響しないので、テクスチャのコンテンツは、ウィジェットの領域上に引き伸ばされて(拡大されて)表示されるか、縮小されて表示されます。

例えば、ウィジェットの(ピクセル)サイズのちょうど2倍のサイズを設定すると、効果的に2倍のスーパーサンプリング(2倍の解像度でレンダリングし、ウィンドウ内のウィジェットに対応するクワッドをテクスチャリングするときに暗黙的にスケールダウンする)を実行します。

デフォルトでは、値は nullQSize です。null または空のQSize は、テクスチャのサイズがQRhiWidget のサイズに従うことを意味します。(texture size =widget size *device pixel ratio)。

アクセス関数:

QSize fixedColorBufferSize() const
void setFixedColorBufferSize(QSize pixelSize)
void setFixedColorBufferSize(int w, int h)

通知シグナル:

void fixedColorBufferSizeChanged(const QSize &pixelSize)

mirrorVertically : bool

有効にすると、QRhiWidget'のバッキングテクスチャをトップレベルウィンドウのウィジェットコンテンツの残りの部分と合成するときに、X軸を中心に画像を反転します。

デフォルト値はfalse です。

アクセス関数:

bool isMirrorVerticallyEnabled() const
void setMirrorVertically(bool enabled)

Notifier シグナル:

void mirrorVerticallyChanged(bool enabled)

sampleCount : int

このプロパティは、マルチサンプル・アンチエイリアシングのサンプルカウントを制御します。デフォルト値は1 、MSAAが無効であることを意味する。

有効な値は1、4、8、場合によっては16と32です。QRhi::supportedSampleCounts()を使用すると、実行時にサポートされているサンプル数を問い合わせることができますが、通常、アプリケーションは1(MSAAなし)、4x(通常のMSAA)、または8x(高MSAA)を要求する必要があります。

注: 新しい値を設定すると、レンダラーによって作成されたすべてのQRhiGraphicsPipeline オブジェクトは、それ以降同じサンプル カウントを使用する必要があります。異なるサンプルカウントで作成された既存のQRhiGraphicsPipeline オブジェクトは、これ以上使用してはなりません。値が変更されると、すべてのカラーおよびデプス-ステンシル-バッファが自動的に破棄され、再作成され、initialize ()が再度呼び出されます。ただし、autoRenderTargetfalse の場合、デプス・ステ ン・バッファや追加カラー・バッファの管理はアプリケーション次第となる。

サンプル・カウントをデフォルトの 1 から高い値に変更すると、colorTexture() がnullptr になり、msaaColorBuffer() が有効なオブジェクトを返すようになります。1(または0)に戻した場合は、その逆を意味する。initialize () の次の呼び出しでは、msaaColorBuffer ()はnullptr を返すが、colorTexture ()は再び 有効になる。さらに、resolveTexture ()は、サンプル数が1より大きい(つまりMSAAが使用されている)とき はいつでも、有効な(非マルチサンプル)QRhiTexture を返す。

アクセス関数:

int sampleCount() const
void setSampleCount(int samples)

ノーティファイア・シグナル:

void sampleCountChanged(int samples)

msaaColorBuffer() およびresolveTexture()も参照のこと

メンバ関数ドキュメント

[explicit] QRhiWidget::QRhiWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {})

ウィジェットフラグがf に設定されたparent の子ウィジェットを構築する。

[override virtual noexcept] QRhiWidget::~QRhiWidget()

デストラクタ。

QRhiWidget::Api QRhiWidget::api() const

現在設定されているグラフィックス API (QRhi backend) を返します。

setApi()も参照してください

[protected] QRhiTexture *QRhiWidget::colorTexture() const

ウィジェットのカラーバッファとして機能するテクスチャを返します。

initialize() とrender() からのみ呼び出す必要があります。

深度ステンシルバッファやQRhiRenderTarget とは異なり、このテクスチャは常に利用可能で、autoRenderTarget の値とは無関係にQRhiWidget によって管理されます。

注: sampleCount が 1 より大きく、マルチサンプル・アンチエイリアスが有効になっている場合、返り値はnullptr になります。代わりに、msaaColorBuffer() を呼び出してQRhiRenderBuffer を照会します。

注: バッキングテクスチャサイズとサンプルカウントは、renderTarget ()から返されるQRhiRenderTarget 。これは、マルチサンプリングが使用されているかどうかに関係なく動作するため、QRhiTexture またはQRhiRenderBuffer からクエリするよりも便利でコンパクトになります。

msaaColorBuffer()、depthStencilBuffer()、renderTarget()、resolveTexture()も参照

[protected] QRhiRenderBuffer *QRhiWidget::depthStencilBuffer() const

ウィジェットのレンダリングで使用される深度ステンシルバッファを返します。

initialize() とrender() からのみ呼び出す必要があります。

autoRenderTargettrue の場合のみ利用可能。それ以外の場合、返される値はnullptr であり、深度ステンシルバッファとQRhiTextureRenderTarget を作成し管理するのはinitialize() の再実装次第です。

colorTexture() およびrenderTarget()も参照してください

[override virtual protected] bool QRhiWidget::event(QEvent *e)

再実装:QWidget::event(QEvent *event)。

[signal] void QRhiWidget::frameSubmitted()

このシグナルは、ウィジェットのトップレベルウィンドウがコンポジションを終了し、submitted a frame

QImage QRhiWidget::grabFramebuffer() const

新しいフレームをレンダリングし、テクスチャの内容を読み返して、QImage として返します。

エラーが発生すると、NULLQImage が返されます。

返されるQImage のフォーマットは、colorBufferFormat() に応じて、QImage::Format_RGBA8888QImage::Format_RGBA16FPx4QImage::Format_RGBA32FPx4 、またはQImage::Format_BGR30 のいずれかです。

QRhiWidget は、レンダラーのブレンドと合成のアプローチを知らないため、出力に RGB カラー値にアルファが事前乗算されているかどうかを知ることができません。したがって、 形式が適切な場合でも、返される 形式に使用されることはない。結果のデータを適切なように解釈するかどうかは、呼び出し側次第である。_Premultiplied QImage QImage

注意: この関数は、QRhiWidget が画面上のトップレベルウィンドウに属するウィジェット階層に追加されていない場合にも呼び出すことができる。これにより、画面外の3Dレンダリングから画像を生成することができます。

この関数は、QOpenGLWidgetQQuickWidget との一貫性を保つため、grabFramebuffer() という名前になっています。QRhiWidget のコンテンツから CPU 側の画像データを取得する唯一の方法ではありません。QRhiWidget やその祖先に対してQWidget::grab() を呼び出すことも機能します(QPixmap を返します)。QImage で直接動作することに加えて、grabFramebuffer() のもう1つの利点は、QWidget の残りのインフラを通過する必要がなく、新しいフレームのレンダリングをすぐにトリガしてリードバックを実行できるため、若干パフォーマンスが高くなる可能性があることです。

setColorBufferFormat()も参照してください

[virtual protected] void QRhiWidget::initialize(QRhiCommandBuffer *cb)

ウィジェットが初めて初期化されたとき、関連するテクスチャのサイズ、フォーマット、サンプルカウントが変更されたとき、またはQRhi とテクスチャが何らかの理由で変更されたときに呼び出されます。この関数は、render() のレンダリングコードで使用されるグラフィックリソースを維持(未作成の場合は作成、サイズが変更された場合は調整と再構築)することが期待されます。

QRhiQRhiTexture 、およびその他の関連オブジェクトに問い合わせるには、rhi ()、colorTexture ()、depthStencilBuffer ()、renderTarget ()を呼び出す。

size ウィジェットサイズが変更されると、QRhi オブジェクト、カラーバッファテクスチャ、および深度ステンシルバッファオブジェクトは、すべて以前と同じインスタンスになります(したがって、ゲッターは同じポインタを返します)。

再実装はまた、QRhi オブジェクトとカラーバッファのテクスチャがこの関数の呼び出しの間に変更されるかもしれないことを準備する必要があります。オブジェクトが異なる特別なケースとして、まだ表示されていないウィジェットでgrabFramebuffer ()を実行し、トップレベルのウィジェット内でウィジェットを画面上に表示する場合があります。この場合、グラブは専用のQRhi 、その後のinitialize()とrender()呼び出しでトップレベル・ウィンドウの関連QRhi に置き換えられます。もう1つの、より一般的なケースは、ウィジェットが新しいトップレベル・ウィンドウに属するように再レンタリングされる場合です。この場合、QRhi と、QRhiWidget によって管理されるすべての関連リソースは、この関数の後続の呼び出しにおいて、以前とは異なるインスタンスになります。そして、サブクラスによって以前に作成されたすべての既存のQRhi リソースは、ウィジェットによってもう使用されるべきではない以前のQRhi に属しているため、破棄されることが重要です。

デフォルトであるautoRenderTargettrue の場合、colorTexture() (またはmsaaColorBuffer()) とデプスステンシル・バッファに関連付けられたデプスステンシルQRhiRenderBufferQRhiTextureRenderTarget が自動的に作成され、管理されます。initialize()およびrender()の再実装は、depthStencilBuffer()およびrenderTarget()を介して、これらのオブジェクトに問い合わせることができます。autoRenderTargetfalse に設定されると、これらのオブジェクトは自動的に作成され管理されなくなります。むしろ、initialize() の実装が、適切と思われるようにバッファを作成し、レンダー・ターゲットを設定することになります。レンダー・ターゲットの追加のカラー・アタッチメントやデプス・スタ ン・アタッチメントを手動で管理する場合、それらのサイズとサンプル数は、常にcolorTexture() /msaaColorBuffer() のサイズとサンプル数に従わなければなりません。

サブクラスで作成されたグラフィックリソースは、サブクラスのデストラクタ実装で解放されることが期待されます。

cb は、ウィジェットの現在のフレームに対する です。この関数は、フレームが記録されている状態で呼び出されますが、アクティブなレンダーパスはありません。コマンドバッファは主に、 () に延期することなく をエンキューできるようにするために提供されます。QRhiCommandBuffer render resource updates

render()も参照してください

bool QRhiWidget::isDebugLayerEnabled() const

使用中のグラフィックスAPIに適用可能な場合、デバッグまたは検証レイヤが要求される場合はtrueを返します。

setDebugLayerEnabled()も参照

[protected] QRhiRenderBuffer *QRhiWidget::msaaColorBuffer() const

ウィジェットのマルチサンプルカラーバッファとして機能する renderbuffer を返します。

initialize() とrender() からのみ呼び出されなければならない。

sampleCount が 1 より大きく、マルチサンプル アンチエイリアライズが有効な場合、返されるQRhiRenderBuffer は一致するサンプルカウントを持ち、カラーバッファとして機能します。このバッファへのレンダリングに使用されるグラフィックパイプラインは、同じサンプルカウントで作成されなければならず、デプスステンシルバッファのサンプルカウントも一致しなければなりません。マルチサンプルのコンテンツは、resolveTexture ()から返されるテクスチャに解決されることが期待されます。autoRenderTargettrue の場合、renderTarget() は、カラーアタッチメント 0 のrenderbuffer として msaaColorBuffer() を設定し、そのresolveTexture としてresolveTexture() を設定することで、これを行うように自動的に設定されます。

MSAAが使用されていない場合、戻り値はnullptr 。代わりにcolorTexture() を使用してください。

基礎となる 3D グラフィックス API によっては、サンプル数が 1 より大きいマルチサンプルテクスチャとカラーレンダーバッファの間に実用的な違いがない場合があります(QRhi は、両方を同じネイティブリソースタイプにマッピングするだけかもしれません)。しかし、古い API の中には、テクスチャとレンダーバッファを区別するものもあります。マルチサンプルレンダーバッファは利用できるが、マルチサンプルテクスチャは利用できないOpenGL ES 3.0をサポートするために、QRhiWidget 、常にマルチサンプルQRhiRenderBuffer をカラーアタッチメントとして使用してMSAAを実行します(決してマルチサンプルQRhiTexture )。

注意: バッキングテクスチャのサイズとサンプル数は、renderTarget() から返されるQRhiRenderTarget を介してクエリすることもできます。これは、マルチサンプリングが使用されているかどうかに関係なく動作するため、QRhiTexture またはQRhiRenderBuffer からクエリするよりも便利でコンパクトです。

colorTexture()、depthStencilBuffer()、renderTarget()、resolveTexture()も参照の こと。

[override virtual protected] void QRhiWidget::paintEvent(QPaintEvent *e)

再実装:QWidget::paintEvent(QPaintEvent *event)。

ペイントイベントを処理します。

QWidget::update() を呼び出すと、ペイント・イベントe が送信され、この関数が呼び出されます。イベントの送信は非同期で、update() から戻った後のある時点で行われます。この関数は、いくつかの準備の後、仮想render ()を呼び出して、QRhiWidget の関連テクスチャの内容を更新します。その後、ウィジェットのトップレベルウィンドウは、テクスチャをウィンドウの残りの部分と合成します。

[virtual protected] void QRhiWidget::releaseResources()

グラフィックスリソースを早期解放する必要が生じたときに呼び出されます。

これは通常、トップレベルウィジェットの子階層に追加されたQRhiWidget では発生しません。したがって、多くの場合、この関数を再実装する必要はありません。例えば、アプリケーションは単一のトップレベル・ウィジェット(ネイティブ・ウィンドウ)しか持たないからです。しかし、ウィジェット(またはその祖先)の再ペアレントが関係する場合、この関数の再実装は、堅牢でよく書かれたQRhiWidget サブクラスで必要になります。

この関数が呼び出されたとき、実装は、デストラクタでこれを行うことが期待される方法と同様に、すべてのQRhi リソース(QRhiBufferQRhiTexture などのオブジェクト)を破棄することが期待されます。initialize ()は最終的にその後に呼び出されるため、ナルアウト、スマートポインタの使用、resources-invalid フラグの設定も必要になります。ただし、リソースの解放をその後のinitialize() に先送りするのは間違いであることに注意してください。この関数が呼ばれた場合、リターンする前にリソースを削除しなければならない。また、この関数を実装しても、クラスのデストラクタ(またはスマート・ポインタ)を置き換えることはできません。

この関数の動作例については、Cube RHI Widget Exampleを参照してください。そこでは、QRhiWidget を(親ウィジェットを持つことによる)子ウィジェットと(親ウィジェットを持たないことによる)トップレベル・ウィジェットの間で切り替えるボタンが、この関数を呼び出すトリガーとなります。これは、関連するトップレベル・ウィジェット、ネイティブ・ウィンドウ、QRhi がすべて、QRhiWidget のライフタイム中に変更されるためで、以前使用されていたQRhi が破棄されると、まだ生きているQRhiWidget によって管理されている関連リソースが早期に解放されることになります。

この関数が呼び出されるもう1つのケースは、grabFramebuffer ( )が、可視ウィンドウに追加されていないQRhiWidget 、つまりレンダリングがオフスクリーンで実行されるときに使用される場合である。後でこのQRhiWidget が可視化されたり、可視ウィジェット階層に追加されたりすると、関連するQRhi は、オフスクリーンレンダリングに使用される一時的なものから、ウィンドウ専用のものに変更され、この関数もトリガされます。

initialize()も参照してください

[virtual protected] void QRhiWidget::render(QRhiCommandBuffer *cb)

ウィジェットの内容(テクスチャの内容)の更新が必要なときに呼び出されます。

この関数が呼び出される前に、常にinitialize() が少なくとも 1 回呼び出される。

更新を要求するには、QWidget::update ()を呼び出します。render() 内からupdate() を呼び出すと、vsync によって減速されながら連続的に更新されます。

cb は、ウィジェットの現在のフレームに対する です。この関数は、フレームが記録されている状態で呼び出されますが、アクティブなレンダーパスはありません。QRhiCommandBuffer

initialize()も参照してください

[signal] void QRhiWidget::renderFailed()

QRhi このシグナルは、ウィジェットがそのバッキングテクスチャにレンダリングするはずのとき(widget update またはgrabFramebuffer() の呼び出しによる)、いつでも発行されます。

このシグナルは、問題が発生したときに複数回発せられることがあります。このシグナルは1回しか発せられないと思わないでください。エラー処理コードに一度だけ通知する場合は、Qt::SingleShotConnection に接続してください。

[protected] QRhiRenderTarget *QRhiWidget::renderTarget() const

render() の再実装においてQRhiCommandBuffer::beginPass() と共に使用しなければならないレンダーターゲットオブジェクトを返す。

initialize() およびrender() からのみ呼び出されなければならない。

autoRenderTargettrue の場合のみ利用可能。それ以外の場合、返される値はnullptr であり、デプスステンシル・バッファとQRhiTextureRenderTarget を作成し管理するのはinitialize() の再実装に任されている。

graphics pipelines を作成する際には、QRhiRenderPassDescriptor が必要である。これは、renderPassDescriptor() を呼び出すことで、返されたQRhiTextureRenderTarget から問い合わせることができる。

colorTexture() およびdepthStencilBuffer()も参照

[override virtual protected] void QRhiWidget::resizeEvent(QResizeEvent *e)

再実装:QWidget::resizeEvent(QResizeEvent *event)。

e event パラメータで渡されるリサイズイベントを処理します。仮想関数initialize() を呼び出します。

注意: 派生クラスでこの関数をオーバーライドすることは避けてください。それが不可能な場合は、QRhiWidget の実装も呼び出されるようにしてください。そうしないと、基礎となるテクスチャオブジェクトと関連リソースが適切にリサイズされず、不正なレンダリングにつながります。

[protected] QRhiTexture *QRhiWidget::resolveTexture() const

マルチサンプルコンテンツが解決される非マルチサンプルテクスチャを返します。

マルチサンプルアンチエイリアスが有効でない場合、結果はnullptr になります。

initialize() およびrender() からのみ呼び出す必要があります。

MSAA が有効な場合、これは画面上のQWidget コンテンツの残りと合成されるテクスチャです。ただし、QRhiWidget のレンダリングは、msaaColorBuffer ()から返される(マルチサンプルの)QRhiRenderBuffer をターゲットにする必要があります。autoRenderTargettrue の場合、これはrenderTarget() から返されるQRhiRenderTarget によって処理される。そうでない場合、カラーバッファと resolve テクスチャの両方を持つレンダーターゲットオブジェクトを正しく設定するのは、サブクラスのコード次第です。

colorTexture()も参照してください

[protected] QRhi *QRhiWidget::rhi() const

現在のQRhi オブジェクトを返します。

initialize() およびrender() からのみ呼び出す必要があります。

void QRhiWidget::setApi(QRhiWidget::Api api)

使用するグラフィックス API およびQRhi バックエンドをapi に設定します。

警告: この関数は、ウィジェットがウィジェット階層に追加され、画面に表示される前に、十分に早い段階で呼び出す必要があります。例えば、サブクラスのコンストラクタでこの関数を呼び出すようにします。この関数を呼び出すのが遅すぎると、何の効果もありません。

デフォルト値はプラットフォームによって異なります:macOSとiOSではMetal、WindowsではDirect 3D 11、それ以外ではOpenGLです。

api は、ウィジェットとそのトップレベルウィンドウに対して一度だけ設定できます。一旦設定され、有効になると、ウィンドウはそのAPIとQRhi バックエンドのみを使用してレンダリングできます。別の値を設定しようとしたり、別のapi で別のQRhiWidget を追加しようとしても、期待通りに機能しません。

setColorBufferFormat()、setDebugLayerEnabled()、api()も参照して ください。

[protected] void QRhiWidget::setAutoRenderTarget(bool enabled)

深度ステンシルQRhiRenderBufferQRhiTextureRenderTarget がウィジェットによって自動的に作成され、維持されるかどうかを制御します。デフォルト値はtrue です。

自動モードでは、深度ステンシルバッファのサイズとサンプルカウントは、カラーバッファテクスチャの設定に従います。非自動モードでは、renderTarget() とdepthStencilBuffer() は常にnullptr を返し、これらのオブジェクトの設定と管理はinitialize() のアプリケーションの実装に任されます。

自動モードを無効にするには、派生クラスのコンストラクタなど、早い段階でenabledfalse に設定してこの関数を呼び出します。

void QRhiWidget::setDebugLayerEnabled(bool enable)

enable が true の場合、基礎となるグラフィックス API のデバッグまたは検証レイヤーを要求します。

警告 この関数は、ウィジェットがウィジェット階層に追加され、画面に表示される前に、十分に早い段階で呼び出されなければなりません。例えば、サブクラスのコンストラクタのためにこの関数を呼び出すことを目標にしてください。この関数を呼び出すのが遅すぎると、何の効果もありません。

VulkanとDirect 3Dに適用できます。

デフォルトでは無効になっています。

setApi() およびisDebugLayerEnabled()も参照してください

©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。