シーングラフ - QML下のVulkan
Qt Quick シーン下で Vulkan を直接レンダリングする方法を示します。
注: この例をコンパイルするには、SDK が必要です。インストール方法については、Vulkan Integrationを参照してください。
概要
この例では、QQuickWindow::beforeRendering() とQQuickWindow::beforeRenderPassRecording() シグナルを使用して、Qt Quick シーン下でカスタム Vulkan コンテンツを描画します。QMLは、上にテキストラベルをレンダリングするために使用されます。
この例は、OpenGL Under QML、Direct3D 11 Under QML、Metal Under QMLの例とほとんどの点で同じです。
QMLを利用することの詳細は、カスタムVulkanレンダリングの詳細を掘り下げることなく、このドキュメントでカバーされます。
QMLからのVulkanレンダリングへの影響
この例では、Vulkanレンダリングを制御するためにQMLに公開されている値を使用する方法を示しています。
しきい値t
を QML に公開するために、VulkanSquircle
の定義で、Q_OBJECT 、Q_PROPERTY 、QML_ELEMENT のようにマクロを使用しています:
class VulkanSquircle : public QQuickItem { Q_OBJECT Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged) QML_ELEMENT
次に、publicとprivateの項目を宣言します:
public: VulkanSquircle(); qreal t() const { return m_t; } void setT(qreal t); signals: void tChanged(); public slots: void sync(); void cleanup(); private slots: void handleWindowChanged(QQuickWindow *win); private: void releaseResources() override; qreal m_t = 0; SquircleRenderer *m_renderer = nullptr;
そして、main.qml
で、NumberAnimation を使って閾値をアニメートします。
VulkanSquircle { SequentialAnimation on t { NumberAnimation { to: 1; duration: 2500; easing.type: Easing.InQuad } NumberAnimation { to: 0; duration: 2500; easing.type: Easing.OutQuad } loops: Animation.Infinite
t
変数は、最終的にスクサークルを描画するSPIR-Vシェーダプログラムによって使用されます。
カスタムVulkanコンテンツをレンダリングするためのシグナルの使用
QQuickWindow::beforeRendering() とQQuickWindow::beforeRenderPassRecording() シグナルが使用されます。
QQuickWindow::beforeRendering() シグナルは、シーングラフがレンダリングを開始する前に、各フレームの開始時に発行されます。これは、このシグナルへの応答として行われるすべてのVulkan描画コールが、Qt Quick 項目の下でスタックされることを意味します。カスタムVulkanコマンドは、シーングラフによって使用される同じコマンドバッファに記録されるため、2つのシグナルがあります。
beforeRendering()関数は、vkCmdBeginRenderPassを使用してrenderpass
インスタンスの開始を記録する前に、フレームの開始時に発行されるため、これだけでは十分ではありません。
解決策:beforeRenderPassRecording()に接続することで、アプリケーション自身のコマンドとシーングラフの足場が正しい順序で終了します。
シグナルの接続は、sync()
関数によって行われます:
void VulkanSquircle::sync() { if (!m_renderer) { m_renderer = new SquircleRenderer; // Initializing resources is done before starting to record the // renderpass, regardless of wanting an underlay or overlay. connect(window(), &QQuickWindow::beforeRendering, m_renderer, &SquircleRenderer::frameStart, Qt::DirectConnection); // Here we want an underlay and therefore connect to // beforeRenderPassRecording. Changing to afterRenderPassRecording // would render the squircle on top (overlay). connect(window(), &QQuickWindow::beforeRenderPassRecording, m_renderer, &SquircleRenderer::mainPassRecordingStart, Qt::DirectConnection); } m_renderer->setViewportSize(window()->size() * window()->devicePixelRatio()); m_renderer->setT(m_t);
Qt Quick シーンの上にVulkanコンテンツをレンダリングするもう1つの方法は、QQuickWindow::afterRendering() とQQuickWindow::afterRenderPassRecording() シグナルに接続することです。
© 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.