QQuickRhiItem Class

QQuickRhiItemクラスは、QQuickFramebufferObject のポータブルな代替クラスで、OpenGLに縛られることなく、QRhi APIとQt Quick を使ってレンダリングを統合することができます。さらに...

ヘッダー #include <QQuickRhiItem>
CMake: find_package(Qt6 REQUIRED COMPONENTS Quick)
target_link_libraries(mytarget PRIVATE Qt6::Quick)
qmake: QT += quick
以来:Qt 6.7
継承: QQuickItem
ステータス予備

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

プロパティ

パブリック関数

QQuickRhiItem(QQuickItem *parent = nullptr)
virtual ~QQuickRhiItem() override
bool alphaBlending() const
QQuickRhiItem::TextureFormat colorBufferFormat() const
QSize effectiveColorBufferSize() const
int fixedColorBufferHeight() const
int fixedColorBufferWidth() const
bool isMirrorVerticallyEnabled() const
int sampleCount() const
void setAlphaBlending(bool enable)
void setColorBufferFormat(QQuickRhiItem::TextureFormat format)
void setFixedColorBufferHeight(int height)
void setFixedColorBufferWidth(int width)
void setMirrorVertically(bool enable)
void setSampleCount(int samples)

再実装パブリック関数

virtual bool isTextureProvider() const override
virtual QSGTextureProvider *textureProvider() const override

シグナル

保護された関数

virtual QQuickRhiItemRenderer *createRenderer() = 0
bool isAutoRenderTargetEnabled() const
void setAutoRenderTarget(bool enabled)

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

virtual bool event(QEvent *e) override
virtual void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override
virtual void releaseResources() override

詳細説明

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

QQuickRhiItem は事実上、Qt Quick の世界におけるQRhiWidget と対になるものです。これらはどちらもサブクラス化されることを意図しており、QRhi- ベースのレンダリングで、画面外のカラーバッファをターゲットにしたレコーディングを可能にします。結果として得られる2D画像は、Qt Quick シーンの残りの部分と合成されます。

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

QQuickRhiItemは、従来のQQuickFramebufferObject 。後者は本質的にOpenGL / OpenGL ESと結びついていますが、QQuickRhiItemはQRhi クラスと連携し、Vulkan、Metal、Direct 3D 11/12、OpenGL / OpenGL ESで同じレンダリングコードを実行できます。概念的にも機能的にも非常に近く、QQuickFramebufferObject から QQuickRhiItem への移行は簡単です。QQuickFramebufferObject は、OpenGL API で直接動作する既存のアプリケーションコードの互換性を確保するために引き続き使用できます。

注意: QQuickRhiItemは、Qt Quick シーングラフのsoftware を使用している場合は機能しません。

ほとんどのプラットフォームでは、シーングラフのレンダリング、したがってQQuickRhiItemによって実行されるレンダリングは、専用のスレッド上で発生します。このため、QQuickRhiItemクラスでは、アイテムの実装(QQuickItem サブクラス)と実際のレンダリングロジックを厳密に分離しています。QMLに公開されるプロパティやUI関連ヘルパー関数などのアイテムロジックは、すべてQQuickRhiItemサブクラスに配置する必要があります。レンダリングに関連するものはすべて、QQuickRhiItemRenderer クラスに配置する必要があります。レースコンディションや2つのスレッドからの読み書きの問題を避けるために、レンダラーとアイテムは共有変数を決して読み書きしないことが重要です。アイテムとレンダラー間の通信は、主に QQuickRhiItem::synchronize() 関数で行います。この関数は、GUI スレッドがブロックされている間にレンダリング スレッドで呼び出されます。アイテムとレンダラー間の通信にキュー接続またはイベントを使用することも可能です。

アプリケーションはQQuickRhiItemとQQuickRhiItemRenderer の両方をサブクラス化する必要があります。純粋仮想のcreateRenderer() 関数は、QQuickRhiItemRenderer サブクラスの新しいインスタンスを返すように再実装する必要があります。

QRhiWidget と同様に、QQuickRhiItem は自動的にカラーバッファを管理します。通常は 2D テクスチャ (QRhiTexture) で、マルチサンプリングが使用されている場合はQRhiRenderBuffer です。(レンダーバッファは主にOpenGL ES 3.0でマルチサンプリングを可能にするために使用されます)。

テクスチャのサイズは、デフォルトでアイテムのサイズに適応します(device pixel ratio を考慮)。アイテムのサイズが変更されると、テクスチャは正しいサイズで再作成されます。固定サイズが望ましい場合は、fixedColorBufferWidthfixedColorBufferHeight をゼロ以外の値に設定してください。

QQuickRhiItemはtexture providerShaderEffects 、テクスチャプロバイダを消費する他のクラスで直接使用できます。

主な使用例ではありませんが、QQuickRhiItemは、Vulkan、Metal、Direct 3D、OpenGLなどの3DグラフィックスAPIを直接使用するレンダリングコードを組み込むこともできます。QRhi レンダーパスのネイティブコマンドを記録する方法についてはQRhiCommandBuffer::beginExternal() を、既存のネイティブテクスチャをラップし、後続のレンダーパスでQRhi を使用して使用する方法についてはQRhiTexture::createFrom() を参照してください。ネイティブ3D API環境の設定(デバイス拡張など)については、QQuickGraphicsConfiguration も参照してください。また、QWindow::setVulkanInstance ()を十分に早い段階で呼び出すことで、QQuickWindow をカスタムQVulkanInstance に関連付けることができます。

注意: QQuickRhiItemは常に、QQuickWindow が使用するのと同じQRhi インスタンスを使用します(ひいては、同じOpenGLコンテキスト、Vulkanデバイスなど)。どの3DグラフィックスAPIを使用するかを選択するには、QQuickWindowsetGraphicsApi() を十分に早い段階で呼び出します。シーングラフが初期化されると、それを変更することはできません。シーン内のすべてのQQuickRhiItemインスタンスは、同じ3D APIを使用してレンダリングされます。

簡単な例

次のQQuickRhiItemのサブクラスを見てください。これは完全な形でここに示されています。これは、透視投影で1つの三角形をレンダリングします。この三角形は、カスタムアイテムのangle プロパティに基づいて回転します。(つまり、例えばQMLのNumberAnimation のようなアニメーションで動かすことができます)

class ExampleRhiItemRenderer : public QQuickRhiItemRenderer
{
public:
    void initialize(QRhiCommandBuffer *cb) override;
    void synchronize(QQuickRhiItem *item) 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_angle = 0.0f;
};

class ExampleRhiItem : public QQuickRhiItem
{
    Q_OBJECT
    QML_NAMED_ELEMENT(ExampleRhiItem)
    Q_PROPERTY(float angle READ angle WRITE setAngle NOTIFY angleChanged)

public:
    QQuickRhiItemRenderer *createRenderer() override;

    float angle() const { return m_angle; }
    void setAngle(float a);

signals:
    void angleChanged();

private:
    float m_angle = 0.0f;
};

QQuickRhiItemRenderer *ExampleRhiItem::createRenderer()
{
    return new ExampleRhiItemRenderer;
}

void ExampleRhiItem::setAngle(float a)
{
    if (m_angle == a)
        return;

    m_angle = a;
    emit angleChanged();
    update();
}

void ExampleRhiItemRenderer::synchronize(QQuickRhiItem *rhiItem)
{
    ExampleRhiItem *item = static_cast<ExampleRhiItem *>(rhiItem);
    if (item->angle() != m_angle)
        m_angle = item->angle();
}

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

static 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,
};

void ExampleRhiItemRenderer::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(":/shaders/color.vert.qsb")) },
            { QRhiShaderStage::Fragment, getShader(QLatin1String(":/shaders/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 = renderTarget()->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 ExampleRhiItemRenderer::render(QRhiCommandBuffer *cb)
{
    QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch();
    QMatrix4x4 modelViewProjection = m_viewProjection;
    modelViewProjection.rotate(m_angle, 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 = renderTarget()->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();
}

この単純なクラスが、QRhiWidget の紹介で示したコードとほとんど同じであることは注目に値する。頂点シェーダーとフラグメントシェーダーも同じです。これらはVulkanスタイルのGLSLソースコードとして提供され、最初にQtシェーダーインフラストラクチャで処理する必要があります。これは、qsb コマンドラインツールを手動で実行するか、CMake のqt_add_shaders()関数を使用することで実現できます。QQuickRhiItemは、アプリケーションに同梱されているこれらの事前処理された.qsb ファイルをロードします。Qt のシェーダ変換インフラストラクチャの詳細についてはQtShader 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);
}

一旦QMLに公開されれば(QML_NAMED_ELEMENT に注意してください)、カスタムアイテムはどのシーンでもインスタンス化することができます。(CMakeプロジェクトのqt_add_qml_moduleで指定された適切なURI をインポートした後に)

ExampleRhiItem {
    anchors.fill: parent
    anchors.margins: 10
    NumberAnimation on angle { from: 0; to: 360; duration: 5000; loops: Animation.Infinite }
}

より複雑な例についてはScene Graph - RHI Texture Itemを参照してください。

QQuickRhiItemRendererScene Graph - RHI Texture ItemQRhiScene Graph and Renderingも参照して ください。

プロパティ ドキュメント

alphaBlending : bool

QQuickRhiItem とそのレンダラーによって生成されたコンテンツでテクスチャ化された四角形を描画するときに、ブレンディングを常に有効にするかどうかを制御します。

デフォルト値はfalse です。これはパフォーマンス上の理由からです。QQuickRhiItemRenderer が不透明な色にクリアされ、アルファが 1 より小さいフラグメントをレンダリングすることがないため、半透明が関係ない場合は、ブレンドを有効にする意味がありません。

QQuickRhiItemRenderer サブクラスが半透明を使用してレンダリングする場合は、このプロパティを true に設定します。

注意: 特定の条件下では、このプロパティの値に関係なく、ブレンドが行われます。例えば、アイテムのopacity (正確には、親チェーンから継承された合成不透明度)が1より小さい場合、このプロパティがfalseに設定されていても、ブレンドは自動的に有効になります。

注意: Qt Quick シーングラフは、あらかじめ乗算されたアルファに依存し、それを期待しています。たとえば、レンダラーで背景を0.5のアルファ値でクリアする場合は、赤、緑、青のクリアカラー値にも0.5を掛けてください。そうしないと、ブレンド結果が不正確になります。

アクセス関数

bool alphaBlending() const
void setAlphaBlending(bool enable)

通知シグナル

void alphaBlendingChanged()

colorBufferFormat : TextureFormat

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

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

アクセス関数

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

通知シグナル:

void colorBufferFormatChanged()

[read-only] effectiveColorBufferSize : const QSize

このプロパティは、基本となるカラーバッファ(QRhiTexture またはQRhiRenderBuffer )のサイズをピクセル単位で公開します。このプロパティは、GUI(メイン)スレッド、QMLバインディング、またはJavaScriptで使用するために提供されます。

注意: シーングラフのレンダースレッドで動作するQQuickRhiItemRenderer の実装では、このプロパティを使用しないでください。それらはむしろ、render target からサイズを問い合わせるべきです。

: レンダリングスレッドでレンダリングが行われるときに値が変更されるという意味で、メインスレッドから見て非同期に値が利用可能になります。つまり、このプロパティは主にQMLバインディングにおいて有用です。アプリケーションコードは、QQuickRhiItem オブジェクトが構築された時点で、すでに値が最新であると仮定してはいけません。

このプロパティは読み取り専用です。

アクセス関数です:

QSize effectiveColorBufferSize() const

通知シグナル:

void effectiveColorBufferSizeChanged()

fixedColorBufferHeight : int

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

たとえば、アイテムの (ピクセル) サイズのちょうど 2 倍のサイズを設定すると、効果的に 2 倍のスーパーサンプリング (2 倍の解像度でレンダリングし、シーン内のアイテムに対応するクワッドをテクスチャリングするときに暗黙的に縮小する) が実行されます。

デフォルト値は0 です。0の値は、テクスチャのサイズがアイテムのサイズに従うことを意味します。(texture size =item size *device pixel ratio) です。

アクセス関数

int fixedColorBufferHeight() const
void setFixedColorBufferHeight(int height)

通知シグナル:

void fixedColorBufferHeightChanged()

fixedColorBufferWidth : int

アイテムの関連テクスチャまたはレンダーバッファの固定幅をピクセル単位で指定します。アイテムのサイズに依存しない固定カラーバッファサイズが必要な場合に関連します。このサイズは、アイテムのジオメトリ(シーン内のサイズと配置)には影響しないので、テクスチャのコンテンツは、アイテムの領域に引き伸ばされて(拡大縮小されて)表示されます。

たとえば、アイテムの (ピクセル) サイズのちょうど 2 倍のサイズを設定すると、効果的に 2 倍のスーパーサンプリング (2 倍の解像度でレンダリングし、シーン内のアイテムに対応するクワッドをテクスチャリングするときに暗黙的に縮小する) が実行されます。

デフォルト値は0 です。0の値は、テクスチャのサイズがアイテムのサイズに従うことを意味します。(texture size =item size *device pixel ratio) です。

アクセス関数

int fixedColorBufferWidth() const
void setFixedColorBufferWidth(int width)

通知シグナル:

void fixedColorBufferWidthChanged()

mirrorVertically : bool

このプロパティは、テクスチャ付きクワッドを描画するときにテクスチャ UV を反転させるかどうかを制御します。オフスクリーンのカラーバッファの内容や、QQuickRhiItemRenderer によって実装されるレンダリングには影響しません。

デフォルト値はfalse です。

アクセス関数

bool isMirrorVerticallyEnabled() const
void setMirrorVertically(bool enable)

通知シグナル:

void mirrorVerticallyChanged()

sampleCount : int

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

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

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

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

アクセス関数:

int sampleCount() const
void setSampleCount(int samples)

通知シグナル:

void sampleCountChanged()

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

メンバー関数ドキュメント

[explicit] QQuickRhiItem::QQuickRhiItem(QQuickItem *parent = nullptr)

与えられたparent で新しい QQuickRhiItem を構築します。

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

破壊者。

[pure virtual protected] QQuickRhiItemRenderer *QQuickRhiItem::createRenderer()

この関数を再実装して、QQuickRhiItemRenderer サブクラスの新しいインスタンスを作成し、返します。

この関数は、GUIスレッドがブロックされている間にレンダリングスレッドで呼び出されます。

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

再インプリメント:QQuickItem::event(QEvent *ev).

[override virtual protected] void QQuickRhiItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)

再実装:QQuickItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry).

[protected] bool QQuickRhiItem::isAutoRenderTargetEnabled() const

現在の自動深度ステンシルバッファとレンダーターゲットの管理設定を返します。

デフォルトでは、この値はtrue です。

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

[override virtual] bool QQuickRhiItem::isTextureProvider() const

再実装:QQuickItem::isTextureProvider() const.

[override virtual protected] void QQuickRhiItem::releaseResources()

再インプリメント:QQuickItem::releaseResources().

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

デプ ス ・ ス テ ン シ ルQRhiRenderBufferQRhiTextureRenderTarget が、 ア イ テ ムに よ っ て自動的に作成 ・ 管理 さ れ る か ど う か を制御 し ます。デフォルト値はtrue です。これを無効にするには、enabledfalse に設定して、派生クラスのコンストラクタなどからこの関数を早い段階で呼び出します。

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

[override virtual] QSGTextureProvider *QQuickRhiItem::textureProvider() const

再実装:QQuickItem::textureProvider() const.

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.