本页内容

QSGRenderNode Class

QSGRenderNode 类表示一组针对场景图所使用的图形 API 的自定义渲染命令。更多内容...

头文件: #include <QSGRenderNode>
CMake: find_package(Qt6 REQUIRED COMPONENTS Quick)
target_link_libraries(mytarget PRIVATE Qt6::Quick)
qmake: QT += quick
继承自: QSGNode

公共类型

struct RenderState
enum RenderingFlag { BoundedRectRendering, DepthAwareRendering, OpaqueRendering, NoExternalRendering }
flags RenderingFlags
enum StateFlag { ViewportState, ScissorState, DepthState, StencilState, ColorState, …, RenderTargetState }
flags StateFlags

公共函数

virtual ~QSGRenderNode() override
virtual QSGRenderNode::StateFlags changedStates() const
const QSGClipNode *clipList() const
(since 6.6) QRhiCommandBuffer *commandBuffer() const
virtual QSGRenderNode::RenderingFlags flags() const
qreal inheritedOpacity() const
const QMatrix4x4 *matrix() const
(since 6.0) virtual void prepare()
(since 6.5) const QMatrix4x4 *projectionMatrix() const
virtual QRectF rect() const
virtual void releaseResources()
virtual void render(const QSGRenderNode::RenderState *state) = 0
(since 6.6) QRhiRenderTarget *renderTarget() const

详细说明

QSGRenderNode 允许创建场景图节点,这些节点可通过以下方式执行自定义渲染:通过 `QRhi `(自 Qt 6.6 起采用的通用方法)、直接通过 OpenGL、Vulkan 或 Metal 等 3D 图形 API,或者在使用 `software ` 后端时,通过 `QPainter`。

QSGRenderNode 是将自定义 2D/3D 渲染集成到Qt Quick 场景中的三种方式之一的关键实现。 另外两种方案分别是:通过before 或after 执行渲染,即直接使用Qt Quick 场景自身的渲染功能;或者生成一个完全独立的渲染通道,将其目标指向专用的渲染目标(一种纹理),然后让场景中的某个对象显示该纹理。 基于 QSGRenderNode 的方法与前者类似,即不涉及额外的渲染通道或渲染目标,并且允许在Qt Quick 场景的自有渲染中“内联”注入自定义渲染命令。有关这三种方法的进一步讨论,请参阅Qt Quick Scene Graph。

另请参阅 《场景图 - 自定义 QSGRenderNode》。

成员类型文档

enum QSGRenderNode::RenderingFlag
flags QSGRenderNode::RenderingFlags

flags() 返回的位掩码可能取的值。

常量值描述
QSGRenderNode::BoundedRectRendering0x01表示render() 的实现不会在rect() 报告的区域之外(以项坐标为基准)进行渲染。此类节点实现可根据场景图后端的不同,实现更高效的渲染。例如,当场景中所有渲染节点都设置了此标志时,software 后端可以继续使用更优的部分更新路径。
QSGRenderNode::DepthAwareRendering0x02表示render() 的实现符合场景图的预期,即仅在场景坐标系中生成 Z 值为 0 的值,该值随后由从RenderState::projectionMatrix() 和matrix() 获取的矩阵进行变换,具体如render() 的注释中所述。此类节点实现可能带来更高效的渲染效果,具体取决于场景图后端。 例如,当场景中的所有渲染节点都设置了此标志时,批处理 OpenGL 渲染器可以继续使用更优的渲染路径。
QSGRenderNode::OpaqueRendering0x04表示render() 的实现会为rect() 报告的整个区域写入不透明像素。默认情况下,渲染器必须假设render() 也可以输出半透明或完全透明的像素。在某些情况下,设置此标志可以提高性能。
QSGRenderNode::NoExternalRendering0x08表示prepare() 和render() 的实现仅使用QRhi 系列 API,而非直接调用 OpenGL、Vulkan 或 Metal 等 3D API。

RenderingFlags 类型是QFlags<RenderingFlag> 的 typedef 定义。它存储 RenderingFlag 值的按“或”运算组合。

另请参阅 render()、prepare()、rect() 以及QRhi 。

enum QSGRenderNode::StateFlag
flags QSGRenderNode::StateFlags

该枚举包含changedStates() 返回的位掩码中可能使用的值。

常量值描述
QSGRenderNode::ViewportState0x40视口
QSGRenderNode::ScissorState0x04启用剪刀测试状态,剪刀矩形
QSGRenderNode::DepthState0x01此值在 Qt 6 中无效。
QSGRenderNode::StencilState0x02该值在 Qt 6 中无效。
QSGRenderNode::ColorState0x08此值在 Qt 6 中无效。
QSGRenderNode::BlendState0x10此值在 Qt 6 中无效。
QSGRenderNode::CullState0x20此值在 Qt 6 中无效。
QSGRenderNode::RenderTargetState0x80此值在 Qt 6 中无效。

StateFlags 类型是QFlags<StateFlag> 的 typedef。它存储 StateFlag 值的按“或”运算组合。

成员函数文档

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

销毁渲染节点。派生类应在此处执行类似于releaseResources() 的清理操作。

对于QRhi 以及QRhiBuffer 、QRhiTexture 、QRhiGraphicsPipeline 等资源,通常建议使用智能指针(如 std::unique_ptr),这通常可以避免实现析构函数的必要性,并使源代码更加精简。 但请注意,实现releaseResources() 仍然非常重要,该函数很可能包含对 unique_ptr 的多次 reset() 调用。

另请参阅 releaseResources()。

[virtual] QSGRenderNode::StateFlags QSGRenderNode::changedStates() const

该函数应返回一个掩码,其中每个位代表由render()函数更改的图形状态。

注意:在 Qt 6 以及基于 `QRhi` 的渲染中,唯一相关的值是 `ViewportState ` 和 `ScissorState`。虽然可以返回其他值,但在实际应用中会被忽略。

常量描述
ViewportState视口
ScissorState剪切测试启用状态、剪切矩形
DepthState该值在 Qt 6 中无效。
StencilState此值在 Qt 6 中无效。
ColorState此值在 Qt 6 中无效。
BlendState此值在 Qt 6 中无效。
CullState此值在 Qt 6 中无效。
RenderTargetState此值在 Qt 6 中无效。

注意: software 后端会 公开其QPainter ,并在调用render()前后进行数据保存和恢复。因此,无需在此处报告任何状态变化。

默认实现返回 0,表示在render() 中未更改任何相关状态。

注意:此 函数可能在调用render() 之前被调用。

const QSGClipNode *QSGRenderNode::clipList() const

返回当前的片段列表。

[since 6.6] QRhiCommandBuffer *QSGRenderNode::commandBuffer() const

返回当前的命令缓冲区。

该函数于 Qt 6.6 中引入。

另请参阅 renderTarget()。

[virtual] QSGRenderNode::RenderingFlags QSGRenderNode::flags() const

返回描述此渲染节点行为的标志。

默认实现返回 0。

另请参阅 RenderingFlag 和rect()。

qreal QSGRenderNode::inheritedOpacity() const

返回当前的有效不透明度。

const QMatrix4x4 *QSGRenderNode::matrix() const

返回指向当前模型-视图矩阵的指针。

[virtual, since 6.0] void QSGRenderNode::prepare()

在帧准备阶段被调用。每次调用 `render()` 之前,都会调用此函数。

与render() 不同,该函数是在场景图开始在底层命令缓冲区上记录当前帧的渲染通道之前调用的。这在使用 Vulkan 等图形 API 进行渲染时非常有用,因为此类 API 中的复制操作需要在渲染通道开始之前被记录下来。

默认实现为空。

在实现使用QRhi 进行渲染的QSGRenderNode 时,请通过QQuickWindow::rhi()从QQuickWindow 中查询QRhi 对象。要获取用于提交工作的QRhiCommandBuffer ,请调用commandBuffer()。要查询活动渲染目标的相关信息,请调用renderTarget()。详情请参阅{场景图 - 自定义QSGRenderNode}示例。

该函数于 Qt 6.0 中引入。

[since 6.5] const QMatrix4x4 *QSGRenderNode::projectionMatrix() const

返回指向当前投影矩阵的指针。

在render()中,此矩阵与RenderState::projectionMatrix()返回的矩阵相同。设置此获取器是为了让prepare()也能查询投影矩阵。

在使用现代图形 API 或 Qt 自身的图形抽象层时,开发者极有可能希望将 `*projectionMatrix() * *matrix() ` 加载到统一缓冲区中。但这必须在 `prepare()` 中完成,即在渲染通道录制之外进行。 正因如此,无论是prepare() 还是render(),均可直接从QSGRenderNode 中查询这两个矩阵。

该函数在 Qt 6.5 中引入。

[virtual] QRectF QSGRenderNode::rect() const

返回由render()触及的区域在项目坐标系中的边界矩形。该值仅在flags()包含BoundedRectRendering 时才被使用,否则将被忽略。

在software 后端中,结合BoundedRectRendering 报告该矩形尤为重要,因为否则场景中存在渲染节点会触发全屏更新,从而跳过所有部分更新的优化。

对于覆盖相应QQuickItem 整个区域的渲染节点,返回值将为 (0, 0, item->width(), item->height())。

注意:节点 也可以在项目宽度和高度指定的边界之外进行渲染,因为场景图节点不受QQuickItem 几何体的限制,只要该函数正确报告了这些信息即可。

另请参阅 flags()。

[virtual] void QSGRenderNode::releaseResources()

当需要立即释放该节点分配的所有自定义图形资源时,将调用此函数。如果该节点未通过所使用的图形 API 直接分配图形资源(缓冲区、纹理、渲染目标、栅栏等),则此处无需执行任何操作。

若未能释放所有自定义资源,在某些系统中可能会导致图形设备丢失时出现异常行为,因为后续对图形系统的重新初始化可能会失败。

注意:某些 场景图后端可能会选择不调用此函数。因此,预计QSGRenderNode 的实现会在其析构函数和 releaseResources() 中都执行清理工作。

与析构函数不同,预期在调用 releaseResources() 之后,render() 能够重新初始化其所需的所有资源。

在 OpenGL 中,无论是在调用析构函数还是调用此函数时,场景图的 OpenGL 上下文均处于活动状态。

[pure virtual] void QSGRenderNode::render(const QSGRenderNode::RenderState *state)

该函数由渲染器调用,应通过QRhi 直接调用命令,或直接通过底层图形API(如OpenGL、Direct3D等)对该节点进行绘制。

可通过inheritedOpacity() 获取有效不透明度。

可以通过state 获取投影矩阵,而模型视图矩阵可通过matrix() 获取。组合矩阵即为投影矩阵与模型视图矩阵的乘积。投影矩阵确保了场景中各元素的正确堆叠顺序。

使用提供的矩阵时,顶点数据的坐标系遵循常规的QQuickItem 约定:左上角为 (0, 0),右下角为对应的QQuickItem 的 width() 和 height() 值减去 1。 例如,假设每个顶点采用两个浮点数 (x-y) 的坐标布局,则覆盖该对象一半面积的三角形可使用逆时针方向指定为 (width - 1, height - 1), (0, 0), (0, height - 1)。

注意: QSGRenderNode 提供了一种实现自定义 2D 或 2.5DQt Quick 项的方法。它并非用于将真正的 3D 内容集成到Qt Quick 场景中。对于这种用例,其他用于集成自定义渲染的方法支持得更好。

注意: QSGRenderNode 的 性能可能远优于基于纹理的方法(例如QQuickRhiItem ),特别是在片段处理能力受限的系统上。 这是因为它避免了先渲染到纹理,再绘制带纹理的四边形的过程。相反,QSGRenderNode 允许将绘制调用与场景图中的其他命令直接结合,从而避免了额外的渲染目标以及可能耗费资源的纹理贴图和混合操作。

裁剪信息在调用该函数之前即已计算完成。希望考虑裁剪因素的实现可以基于state 中的信息设置剪切或模板。模板缓冲区将填充必要的裁剪形状,但是否启用模板测试由具体实现决定。

某些场景图后端(尤其是软件后端)不使用剪切或模板。在这种情况下,剪裁区域将作为普通的QRegion 提供。

在实现使用 `QRhi ` 进行渲染的 `QSGRenderNode ` 时,应通过 `QQuickWindow::rhi()` 从 `QQuickWindow ` 查询 `QRhi ` 对象。若要获取用于提交渲染任务的 `QRhiCommandBuffer `,请调用 `commandBuffer()`。若要查询当前活动渲染目标的信息,请调用 `renderTarget()`。详情请参阅{场景图 - 自定义 QSGRenderNode}示例。

在 Qt 6 及其基于QRhi 的场景图渲染器中,调用此函数时不应针对活动(OpenGL)状态做出任何假设,即使正在使用 OpenGL 也是如此。调用此函数时,请勿对命令列表/缓冲区中绑定的管道和动态状态做出任何假设。

注意:深度 写入预计已被禁用。启用深度写入可能会导致意外结果,具体取决于所使用的场景图后端以及场景中的内容,因此请谨慎操作。

注意:在 Qt 6 中,changedStates() 的用途有限。有关更多信息,请参阅changedStates() 的文档。

对于某些图形 API(包括直接使用QRhi 时),可能还需要额外重写prepare() 函数,或者连接到QQuickWindow::beforeRendering() 信号。 这些操作是在命令缓冲区上记录渲染通道开始之前调用的(Vulkan 中为 vkCmdBeginRenderPass,Metal 中为通过 MTLRenderCommandEncoder 开始编码)。 使用此类 API 时,无法在 render() 内部执行复制操作。相反,应在prepare() 中执行此类操作,或者连接到 beforeRendering 的插槽(使用 DirectConnection)。

另请参阅 QSGRendererInterface 和QQuickWindow::rendererInterface()。

[since 6.6] QRhiRenderTarget *QSGRenderNode::renderTarget() const

返回当前的渲染目标。

此方法主要为支持prepare()和render()的实现而提供,这些实现会通过QRhi 访问QRhiRenderTarget 的renderPassDescriptor 或pixel size 。

要构建一个QRhiGraphicsPipeline (这意味着必须提供一个QRhiRenderPassDescriptor ),请从渲染目标中查询renderPassDescriptor。 但请注意,在自定义QQuickItem 和QSGRenderNode 的生命周期内,渲染目标可能会发生变化。例如,考虑在项(item)或其祖先上动态设置layer.enabled: true 时会发生什么:这会触发渲染到纹理中,而不是直接渲染到窗口,这意味着从那时起,QSGRenderNode 将与不同的渲染目标配合工作。 新的渲染目标可能具有不同的像素格式,这会导致已构建的图形管道出现兼容性问题。可通过如下逻辑来处理此情况:

if (m_pipeline && renderTarget()->renderPassDescriptor()->serializedFormat() != m_renderPassFormat) {
    delete m_pipeline;
    m_pipeline = nullptr;
}
if (!m_pipeline) {
    // Build a new QRhiGraphicsPipeline.
    // ...
    // Store the serialized format for fast and simple comparisons later on.
    m_renderPassFormat = renderTarget()->renderPassDescriptor()->serializedFormat();
}

该函数在 Qt 6.6 中引入。

另请参阅 commandBuffer()。

© 2026 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.