QQuickRenderControl 类
The QQuickRenderControl class provides a mechanism for rendering the Qt Quick scenegraph onto an offscreen render target in a fully application-controlled manner. 更多...
头文件 | #include <QQuickRenderControl> |
CMake | find_package(Qt6 REQUIRED COMPONENTS Quick) target_link_libraries(mytarget PRIVATE Qt6::Quick) |
qmake | QT += quick |
继承 | QObject |
公开函数
QQuickRenderControl(QObject *parent = nullptr) | |
虚拟 | ~QQuickRenderControl() override |
(since 6.0) void | beginFrame() |
(since 6.6) QRhiCommandBuffer * | commandBuffer() const |
(since 6.0) void | endFrame() |
(since 6.0) bool | initialize() |
void | invalidate() |
void | polishItems() |
void | prepareThread(QThread *targetThread) |
void | render() |
virtual QWindow * | renderWindow(QPoint *offset) |
(since 6.6) QRhi * | rhi() const |
(since 6.0) int | samples() const |
(since 6.0) void | setSamples(int sampleCount) |
bool | sync() |
(since 6.0) QQuickWindow * | window() const |
信号
void | renderRequested() |
void | sceneChanged() |
静态公开成员
QWindow * | renderWindowFor(QQuickWindow *win, QPoint *offset = nullptr) |
详细描述
QQuickWindow 和 QQuickView 及其相关的内部渲染循环将 Qt Quick 场景渲染到原生窗口。在一些情况下,例如与第三方 OpenGL、Vulkan、Metal 或 Direct 3D 渲染器集成时,将场景获取到纹理中,然后由外部渲染引擎以任意方式使用是很有用的。这种机制在与 VR 框架集成时同样必不可少。QQuickRenderControl 通过硬件加速的方式实现这一点,与使用 QQuickWindow::grabWindow() 在性能上有限的替代方案不同。
在使用 QQuickRenderControl 时,不应该显示 QQuickWindow(它不会在屏幕上可见)且不会为其提供底层本地窗口。相反,使用 QQuickWindow 构造函数的超载实例将 QQuickWindow 与渲染控制对象关联,并通过 QQuickWindow::setRenderTarget() 指定纹理或图像对象。尽管如此,由于它表示 Qt Quick 场景并提供大部分场景管理和事件传递机制,因此 QQuickWindow 对象仍然至关重要。但从视窗系统的角度来看,它并不充当真正的屏幕窗口。
图形设备、上下文、图像和纹理对象的管理由应用程序负责。在调用 initialize() 之前必须创建将被 Qt Quick 使用的设备或上下文。纹理对象的创建可以延迟,详情见下文。Qt 5.4 引入了 QOpenGLContext 采用现有本地上下文的能力。与 QQuickRenderControl 结合,这可以使创建与外部渲染引擎现有上下文共享的 QOpenGLContext 成为可能。然后,可以使用新的 QOpenGLContext 将 Qt Quick 场景渲染到其他引擎的上下文可访问的纹理中。对于 Vulkan、Metal 和 Direct 3D,由于没有提供设备对象的 Qt 包装器,因此可以通过 QQuickWindow::setGraphicsDevice() 直接传递现有的。
使用 QQmlEngine 通过加载和实例化 QML 组件发生。一旦创建了根对象,它将需要连接到 QQuickWindow 的内容项上。
应用程序通常会连接到 4 个重要的信号
- QQuickWindow::sceneGraphInitialized() 在调用 QQuickRenderControl::initialize() 一段时间后发出。在此信号发生时,应用程序应创建其帧缓冲区对象并将其关联到 QQuickWindow。
- QQuickWindow::sceneGraphInvalidated() 当场景图资源被释放时,也可以销毁帧缓冲区对象。
- QQuickRenderControl::renderRequested() 表示必须通过调用 render() 来渲染场景。在使上下文成为当前后,应用程序应调用 render()。
- QQuickRenderControl::sceneChanged() 表示场景已更改,这意味着在渲染之前还需要进行抛光和同步。
要向场景发送事件,例如鼠标或键盘事件,请使用带有 QQuickWindow 实例作为接收者的 QCoreApplication::sendEvent()。
对于键盘事件,可能还需要手动设置所需的项目的焦点。实际上,这涉及在项目关联到场景(即 QQuickWindow)时,在所需的项目上(例如场景的根项)调用 forceActiveFocus()。
注意: 通常,所有 Qt Quick 后端都支持 QQuickRenderControl。但是,某些功能(特别是 grab())可能并不总是在所有情况下都可用。
成员函数文档
[显示}
QQuickRenderControl::QQuickRenderControl(QObject *parent = nullptr)
构造一个带有父对象 parent 的 QQuickRenderControl 对象。
[覆盖虚函数 noexcept]
QQuickRenderControl::~QQuickRenderControl()
销毁实例。释放所有场景图资源。
另请参阅invalidate。
[自 6.0]
void QQuickRenderControl::beginFrame()
指定图形帧的开始。调用 sync() 或 render() 必须在调用 beginFrame() 和 endFrame() 之间进行。
与 Qt 5 早期的仅 OpenGL 世界不同,使用其他图形 API 进行渲染需要更明确的开始和结束帧的点。在通过 QQuickRenderControl 手动驱动渲染循环时,现在需要 QQuickRenderControl 的用户指定这些点。
一个典型的更新步骤,包括将渲染初始化到现有纹理中,可能如下所示。此示例代码片段假设 Direct3D 11,但相同的概念也适用于其他图形 API。
if (!m_quickInitialized) { m_quickWindow->setGraphicsDevice(QQuickGraphicsDevice::fromDeviceAndContext(m_engine->device(), m_engine->context())); if (!m_renderControl->initialize()) qWarning("Failed to initialize redirected Qt Quick rendering"); m_quickWindow->setRenderTarget(QQuickRenderTarget::fromNativeTexture({ quint64(m_res.texture), 0 }, QSize(QML_WIDTH, QML_HEIGHT), SAMPLE_COUNT)); m_quickInitialized = true; } m_renderControl->polishItems(); m_renderControl->beginFrame(); m_renderControl->sync(); m_renderControl->render(); m_renderControl->endFrame(); // Qt Quick's rendering commands are submitted to the device context here
注意:在使用 Qt Quick 的 软件
适配时,不必也不应调用此函数。
注意:内部 beginFrame() 和 endFrame() 调用 beginOffscreenFrame() 和 endOffscreenFrame(),分别。这意味着在调用此函数时,不得在 QRhi 上有任何帧(无论是离屏帧还是基于交换链的帧)正在记录。
此函数是在 Qt 6.0 中引入的。
另请参阅endFrame,initialize,sync,render,QQuickGraphicsDevice 和 QQuickRenderTarget。
[自 6.6]
QRhiCommandBuffer *QQuickRenderControl::commandBuffer() const
返回当前命令缓冲区。
一旦调用 beginFrame(),就会自动设置一个 QRhiCommandBuffer。这就是 Qt Quick 场景图使用的命令缓冲区,但在某些情况下,应用程序可能还想查询它,例如,发布资源更新(例如,纹理读取回)。
返回的命令缓冲区引用仅在 beginFrame() 和 endFrame() 之间使用。存在特定的例外,例如在 endFrame() 之后以及下一个 beginFrame() 之前调用命令缓冲区上的 lastCompletedGpuTime() 是有效的。
注意:使用 Qt Quick 的 软件
适配时,此函数不适用,并将返回 null。
此函数是在 Qt 6.6 中引入的。
另请参阅rhi,beginFrame 和 endFrame。
[自 6.0]
void QQuickRenderControl::endFrame()
指定图形帧的结束。调用 sync 或 render 必须在调用 beginFrame() 和 endFrame() 之间进行。
当调用此函数时,场景图排队等待的任何图形命令都会提交到上下文或命令队列,具体取决于情况。
注意:在使用 Qt Quick 的 软件
适配时,不必也不应调用此函数。
此函数是在 Qt 6.0 中引入的。
另请参阅 beginFrame(),initialize(),sync(),render(),QQuickGraphicsDevice和QQuickRenderTarget。
[自6.0以来]
bool QQuickRenderControl::initialize()
初始化场景图资源。在为Qt Quick渲染使用如Vulkan、Metal、OpenGL或Direct3D等图形API时,当调用此函数时,QQuickRenderControl将设置适当的渲染引擎。只要存在QQuickRenderControl,此渲染基础设施就存在。
要控制Qt Quick使用的图形API,使用QQuickWindow::setGraphicsApi()并传入QSGRendererInterface:GraphicsApi常量之一进行操作。必须在调用此函数之前完成此操作。
要防止场景图创建其自己的设备和上下文对象,通过调用QQuickWindow::setGraphicsDevice()指定适当的QQuickGraphicsDevice并将现有图形对象包装在内。
要配置要启用的设备扩展(例如,对于Vulkan),在调用此函数之前调用QQuickWindow::setGraphicsConfiguration()。
注意:当使用Vulkan时,QQuickRenderControl不会自动创建QVulkanInstance。相反,创建适当的QVulkanInstance并将其与QQuickWindow关联是应用程序的责任。在初始化QVulkanInstance之前,强烈建议通过调用静态函数QQuickGraphicsConfiguration::preferredInstanceExtensions()查询Qt Quick希望设置的实例扩展列表,并将返回的列表传递给QVulkanInstance::setExtensions。
成功时返回true
,否则返回false
。
注意:在使用 Qt Quick 的 软件
适配时,不必也不应调用此函数。
使用默认的Qt Quick适配器,此函数创建一个新的QRhi对象,类似于在没有使用QQuickRenderControl时,带屏幕QQuickWindow将产生的情况。要使此新QRhi对象采用某些现有的设备或上下文资源(例如,使用现有的QOpenGLContext而不是创建一个新的),使用上面提到的QQuickWindow::setGraphicsDevice()。当应用程序想使Qt Quick渲染使用已存在的QRhi对象时,也可以通过QQuickGraphicsDevice::fromRhi实现。当设置了此类引用已存在的QRhi的QQuickGraphicsDevice后,在initialize()中将不会创建新的QRhi对象。
此函数是在 Qt 6.0 中引入的。
另请参阅 QQuickRenderTarget,QQuickGraphicsDevice和QQuickGraphicsConfiguration::preferredInstanceExtensions。
void QQuickRenderControl::invalidate()
停止渲染并释放资源。
这等同于在窗口变为隐藏时,真实QQuickWindow发生的清理操作。
此函数在析构函数中被调用。因此通常不需要直接调用它。
调用invalidate()之后,可以通过再次调用initialize()来重用QQuickRenderControl实例。
注意:此函数不考虑QQuickWindow::persistentSceneGraph()或QQuickWindow::persistentGraphics()。这意味着上下文特定的资源总是会释放。
void QQuickRenderControl::polishItems()
在调用sync之前尽可能晚地调用此函数。在多线程场景中,渲染可以与此函数并行发生。
void QQuickRenderControl::prepareThread(QThread *targetThread)
准备在GUI线程外部渲染Qt Quick场景。
targetThread指定同步和渲染将发生的线程。在单线程场景中不需要调用此函数。
void QQuickRenderControl::render()
使用当前上下文渲染场景图。
[信号]
void QQuickRenderControl::renderRequested()
当场景图需要渲染时,会发出此信号。不需要调用sync。
注意:避免在发出此信号时直接触发渲染。相反,最好通过使用计时器等方式将其延迟。这将提高性能。
[虚函数]
QWindow *QQuickRenderControl::renderWindow(QPoint *offset)
在子类中重新实现以返回渲染控制实际渲染到的真实窗口。
如果offset非空,它将被设置为控制在其窗口内的偏移。
注意:虽然不是强制的,但在支持具有不同设备像素比的多屏幕以及正确定位从QML打开的弹出窗口的情况下重新实现此函数变得至关重要。因此,在子类中提供它是非常推荐的。
[静态]
QWindow *QQuickRenderControl::renderWindowFor(QQuickWindow *win, QPoint *offset = nullptr)
返回正在渲染到win的实际窗口(如果有)。
如果offset非空,它将被设置为渲染在其窗口内的偏移。
[自6.6起]
QRhi *QQuickRenderControl::rhi() const
返回与QQuickRenderControl关联的QRhi。
注意:只有在initialize成功完成后,QRhi才会存在。在此之前,返回值是null。
注意:使用 Qt Quick 的 软件
适配时,此函数不适用,并将返回 null。
此函数是在 Qt 6.6 中引入的。
另请参阅commandBuffer()、beginFrame()和endFrame()。
[自6.0起]
int QQuickRenderControl::samples() const
返回当前的样本数。1或0表示没有多重采样。
此函数是在 Qt 6.0 中引入的。
另请参阅setSamples()。
[信号]
void QQuickRenderControl::sceneChanged()
当场景图更新时,会发出此信号,这意味着需要调用 polishItems() 和 sync()。如果 sync() 返回 true,则需要调用 render()。
注意:当此信号发出时,应避免直接触发精炼、同步和渲染。相反,最好通过使用定时器等方式进行延迟。这将提高性能。
[自6.0起]
void QQuickRenderControl::setSamples(int sampleCount)
设置用于多重采样的样本数量。当 sampleCount 为 0 或 1 时,禁用多重采样。
注意:此函数始终与多重采样渲染目标一起使用,这意味着 sampleCount 必须与传递给 QQuickRenderTarget::fromNativeTexture() 的样本数量匹配,该数量必须与原生纹理的样本数量匹配。
此函数是在 Qt 6.0 中引入的。
另请参阅:samples(),initialize(),以及 QQuickRenderTarget。
bool QQuickRenderControl::sync()
此函数用于同步 QML 场景与渲染场景图。
如果使用专用的渲染线程,则 GUI 线程在此调用期间应该被阻塞。
如果同步更改了场景图,则返回 true。
[自6.0起]
QQuickWindow *QQuickRenderControl::window() const
返回与 QQuickWindow 关联的 QQuickRenderControl。
注意:在构造 QQuickWindow 时,QQuickRenderControl 将与 QQuickWindow 关联。在此函数返回值之前,此函数的返回值为 null。
此函数是在 Qt 6.0 中引入的。
© 2024 The Qt Company Ltd. 包含在此处的文档贡献分别是其各自所有者的版权。提供的文档根据自由软件基金会发布的条款,在 GNU 自由文档许可的第1.3版 下授权。Qt 及其相关徽标是 The Qt Company Ltd. 在芬兰和/或全球其他国家的商标。所有其他商标均为其各自所有者的财产。