场景图 - QML 下的 Vulkan
展示了如何在 Qt Quick 场景下直接使用 Vulkan 进行渲染。
注意:编译此示例需要 SDK。有关要安装内容的详细信息,请参阅Vulkan 集成。
概述
此示例使用QQuickWindow::beforeRendering() 和QQuickWindow::beforeRenderPassRecording() 信号,在 Qt Quick 场景下绘制自定义 Vulkan 内容。QML 用于渲染顶部的文本标签。
在大多数方式上,此示例与OpenGL Under QML、Direct3D 11 Under QML 和Metal Under QML 示例等价,它们都渲染相同自定义内容,只是通过不同的本地 API。
此文档将涵盖 QML 的具体使用,而不会深入到自定义 Vulkan 渲染的细节。
从 QML 影响Vulkan渲染
此示例展示了如何使用暴露给 QML 的值来控制 Vulkan 渲染。
要将在 VulkanSquircle
的定义中暴露给 QML 的阈值值 t
,我们使用 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: 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
变量最终用于绘制 squircles 的 SPIR-V 着色器程序。
使用信号渲染自定义Vulkan内容
使用QQuickWindow::beforeRendering() 和QQuickWindow::beforeRenderPassRecording() 信号。
QQuickWindow::beforeRendering() 信号在每个帧的开始时发射,在场景图开始渲染之前。这意味着对响应此信号所发出的任何 Vulkan 绘制调用,将堆叠在 Qt Quick 项之下。有两个信号,因为自定义 Vulkan 命令被记录在场景图使用的相同命令缓冲区上。
仅仅使用 beforeRendering() 函数是不够的,因为它在帧的开始时发射,在记录 renderpass
实例的开始之前使用vkCmdBeginRenderPass。
解决方案:通过连接到 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);
您还可以通过连接到QQuickWindow::afterRendering() 和 QQuickWindow::afterRenderPassRecording() 信号来在 Qt Quick 场景上渲染 Vulkan 内容。
© 2024 Qt 公司。本文件中的文档贡献归其各自的版权所有者所有。本提供的文档是根据自由软件基金会发布的GNU 自由文档许可协议版本 1.3许可的。Qt 和相应的商标是芬兰 Qt 公司的商标,也是全球其他国家的商标。所有其他商标均为其各自所有者的财产。