PySide6.QtQuick.QSGRenderNode

class QSGRenderNode

QSGRenderNode 类表示一组针对场景图正在使用的图形API的自定义渲染命令。More_

PySide6.QtQuick.QSGRenderNode 的继承图

概要

方法

虚拟方法

注意

本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对代码片段翻译的贡献。如果您发现翻译问题,您也可以通过在我们的https:/bugreports.qt.io/projects/PYSIDE上创建工单来告知我们。

详细描述

QSGRenderNode 允许创建场景图节点,这些节点可以通过 QRhi(从 Qt 6.6 开始的常见方法)、直接通过 3D 图形 API(如 OpenGL、Vulkan 或 Metal)或在使用 software 后端时通过 QPainter 执行自己的自定义渲染。

QSGRenderNode 是将自定义2D/3D渲染集成到Qt Quick场景中的三种方式之一。其他两种选择是在Qt Quick场景自己的渲染之前之后执行渲染,或者生成一个完全独立的渲染过程,目标是专用的渲染目标(纹理),然后让场景中的一个项目显示该纹理。基于QSGRenderNode的方法与前者类似,因为它不涉及额外的渲染过程或渲染目标,并且允许“内联”注入自定义渲染命令与Qt Quick场景自己的渲染一起进行。

另请参阅

场景图 - 自定义 QSGRenderNode

class StateFlag

(继承自 enum.Flag) 这个枚举是一个位掩码,用于标识多个状态。

常量

描述

QSGRenderNode.DepthState

深度

QSGRenderNode.StencilState

模板

QSGRenderNode.ScissorState

剪刀

QSGRenderNode.ColorState

颜色

QSGRenderNode.BlendState

混合

QSGRenderNode.CullState

剔除

QSGRenderNode.ViewportState

视口状态

QSGRenderNode.RenderTargetState

渲染目标

class RenderingFlag

(继承自 enum.Flag) 从 flags() 返回的位掩码的可能值。

常量

描述

QSGRenderNode.BoundedRectRendering

表示render()的实现不会在rect()报告的区域内渲染。这样的节点实现可以带来更高效的渲染,具体取决于场景图后端。例如,当场景中的所有渲染节点都设置了此标志时,software后端可以继续使用更优化的部分更新路径。

QSGRenderNode.DepthAwareRendering

表示render()的实现符合场景图的期望,仅在场景坐标中生成Z值为0,然后通过从RenderState::projectionMatrix()和matrix()获取的矩阵进行转换,如render()的注释中所述。此类节点实现可以带来更高效的渲染,具体取决于场景图后端。例如,当场景中的所有渲染节点都设置了此标志时,批处理OpenGL渲染器可以继续使用更优化的路径。

QSGRenderNode.OpaqueRendering

表示render()的实现为从rect()报告的整个区域写入不透明像素。默认情况下,渲染器必须假设render()也可能输出半透明或完全透明的像素。在某些情况下,设置此标志可以提高性能。

QSGRenderNode.NoExternalRendering

表示prepare()render()的实现使用QRhi系列的API,而不是直接调用如OpenGL、Vulkan或Metal等3D API。

另请参阅

render() prepare() rect() QRhi

__init__()
changedStates()
Return type:

StateFlag的组合

当底层渲染API是OpenGL时,此函数应返回一个掩码,其中每个位表示由render()函数更改的图形状态:

  • 深度状态

  • 深度写入掩码,深度测试启用,深度比较函数

对于非OpenGL的API,唯一相关的值是那些对应于记录在命令列表/缓冲区上的动态状态更改的值。例如,在D3D11的情况下是RSSetViewports、RSSetScissorRects、OMSetBlendState、OMSetDepthStencilState,或者在Vulkan的情况下是vkCmdSetViewport、vkCmdSetScissor、vkCmdSetBlendConstants、vkCmdSetStencilRef,并且只有当这些命令被添加到通过QSGRendererInterface::CommandList资源枚举查询的场景图的命令列表中时。在管道状态对象中设置的状态不需要在这里报告。同样,与绘制调用相关的设置(管道状态、描述符集、顶点或索引缓冲区绑定、根签名、描述符堆等)总是由场景图再次设置,因此render()可以自由更改它们。

RenderTargetState 不再支持像 Vulkan 这样的 API。这是由本质决定的。render() 在 Qt Quick 场景图的主命令缓冲区正在记录渲染通道时被调用,因此无法更改目标并启动另一个渲染通道(至少在该命令缓冲区上)。因此,返回一个设置了 RenderTargetState 的值是没有意义的。

注意

software 后端暴露了它的 QPainter,并在调用 render() 之前和之后进行保存和恢复。因此,从这里报告任何更改的状态是不必要的。

该函数由渲染器调用,以便在渲染此节点后重置状态。这使得render()的实现更简单,因为它不必查询和恢复这些状态。

默认实现返回0,意味着在render()中没有相关的状态被改变。

注意

此函数可以在render()之前调用。

注意

使用 Qt 6 和基于 QRhi 的渲染时,唯一相关的值是 ViewportStateScissorState。其他值可能会返回,但在实践中会被忽略。

clipList()
Return type:

QSGClipNode

返回当前的剪辑列表。

commandBuffer()
Return type:

QRhiCommandBuffer

返回当前命令缓冲区。

另请参阅

renderTarget()

inheritedOpacity()
Return type:

浮点数

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

matrix()
Return type:

QMatrix4x4

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

prepare()

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

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

默认实现为空。

当实现一个使用QRhi进行渲染的QSGRenderNode时,通过rhi()QQuickWindow查询QRhi对象。要获取用于提交工作的QRhiCommandBuffer,请调用commandBuffer()。要查询有关活动渲染目标的信息,请调用renderTarget()。有关详细信息,请参阅{Scene Graph - Custom QSGRenderNode}示例。

projectionMatrix()
Return type:

QMatrix4x4

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

render()中,这是与RenderState::projectionMatrix()返回的相同矩阵。这个getter的存在是为了让prepare()也有一种查询投影矩阵的方式。

在使用现代图形API或Qt自己的图形抽象层时,很可能会希望将*projectionMatrix() * *matrix()加载到统一缓冲区中。然而,这需要在prepare()中完成,即在渲染通道的记录之外。这就是为什么这两个矩阵可以直接从QSGRenderNode中查询,无论是在prepare()还是render()中。

projectionMatrix(index)
Parameters:

索引 – int

Return type:

QMatrix4x4

rect()
Return type:

QRectF

返回render()所触及区域的边界矩形,单位为项目坐标。该值仅在flags()包含BoundedRectRendering时使用,否则忽略。

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

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

注意

节点也可以自由地在项目宽度和高度指定的边界之外渲染,因为场景图节点不受QQuickItem几何形状的限制,只要此函数正确报告了这一点。

另请参阅

flags()

releaseResources()

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

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

注意

一些场景图后端可能选择不调用此函数。因此,期望QSGRenderNode的实现在其析构函数和releaseResources()中都执行清理操作。

与析构函数不同,预计在调用releaseResources()之后调用render()时,它可以重新初始化所需的所有资源。

使用OpenGL时,场景图的OpenGL上下文在调用析构函数和此函数时都将处于当前状态。

abstract render(state)
Parameters:

状态RenderState

此函数由渲染器调用,应使用当前使用的图形API(OpenGL、Direct3D等)中的直接调用命令绘制此节点。

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

投影矩阵可以通过state获取,而模型视图矩阵可以通过matrix()获取。组合矩阵则是投影矩阵乘以模型视图矩阵。投影矩阵确保了场景中项目的正确堆叠。

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

注意

QSGRenderNode 提供了一种实现自定义2D或2.5D Qt Quick项目的方法。它不适用于将真正的3D内容集成到Qt Quick场景中。对于这种用例,QQuickFramebufferObjectbeforeRendering() 或OpenGL以外的API的等效功能提供了更好的支持。

注意

QSGRenderNode 可以比基于纹理的方法(例如,QQuickFramebufferObject)表现得更好,特别是在片段处理能力有限的系统上。这是因为它避免了渲染到纹理然后再绘制纹理四边形。相反,QSGRenderNode 允许记录与场景图的其他命令一致的绘制调用,避免了额外的渲染目标和潜在的高成本纹理和混合。

在调用函数之前计算剪辑信息。希望考虑剪辑的实现可以根据state中的信息设置剪裁或模板。模板缓冲区填充了必要的剪辑形状,但启用模板测试取决于实现。

一些场景图后端,特别是软件,不使用剪刀或模板。在那里,裁剪区域被提供为一个普通的QRegion。

当实现一个使用QRhi进行渲染的QSGRenderNode时,通过rhi()QQuickWindow查询QRhi对象。要获取用于提交工作的QRhiCommandBuffer,请调用commandBuffer()。要查询有关活动渲染目标的信息,请调用renderTarget()。有关详细信息,请参阅{Scene Graph - Custom QSGRenderNode}示例。

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

注意

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

注意

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

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

renderTarget()
Return type:

QRhiRenderTarget

返回当前的渲染目标。

这主要是为了启用使用QRhi访问QRhiRenderTarget的renderPassDescriptor或像素大小的prepare()render()实现。

要构建一个QRhiGraphicsPipeline,这意味着必须提供一个QRhiRenderPassDescriptor,可以从渲染目标中查询renderPassDescriptor。但请注意,在自定义QQuickItemQSGRenderNode的生命周期内,渲染目标可能会发生变化。例如,考虑在项目或其祖先上动态设置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();
}

另请参阅

commandBuffer()

class RenderState

概要

虚拟方法

注意

本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对代码片段翻译的贡献。如果您发现翻译问题,您也可以通过在我们的https:/bugreports.qt.io/projects/PYSIDE上创建工单来告知我们。

详细描述

abstract clipRegion()
Return type:

QRegion

get(state)
Parameters:

state – str

Return type:

void

abstract projectionMatrix()
Return type:

QMatrix4x4

abstract scissorEnabled()
Return type:

布尔

abstract scissorRect()
Return type:

QRect

abstract stencilEnabled()
Return type:

布尔

abstract stencilValue()
Return type:

整数