PySide6.QtQuick.QQuickRhiItem¶
- class QQuickRhiItem¶
QQuickRhiItem类是QQuickFramebufferObject的可移植替代方案,它不依赖于 OpenGL,而是允许将渲染与 QRhi API 集成到 Qt Quick 中。更多…在版本6.7中添加。
概要¶
属性¶
方法¶
def
__init__()def
alphaBlending()def
sampleCount()def
setSampleCount()
虚拟方法¶
def
createRenderer()
信号¶
注意
本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对代码片段翻译的贡献。如果您发现翻译问题,您也可以通过在我们的https:/bugreports.qt.io/projects/PYSIDE上创建工单来告知我们。
详细描述¶
警告
本节包含从C++自动翻译到Python的代码片段,可能包含错误。
注意
QQuickRhiItem在 Qt 6.7 中处于技术预览阶段。API 正在开发中,可能会发生变化。QQuickRhiItem实际上是 Qt Quick 世界中 QRhiWidget 的对应物。这两者都意味着要被继承,并且它们都支持记录基于 QRhi 的渲染,目标是离屏颜色缓冲区。生成的 2D 图像随后与 Qt Quick 场景的其余部分进行合成。注意
虽然
QQuickRhiItem是一个公共的Qt API,但Qt Gui模块中的QRhi系列类,包括QShader和QShaderDescription,提供的兼容性保证有限。这些类没有源代码或二进制兼容性保证,意味着API仅保证与应用程序开发时使用的Qt版本兼容。然而,源代码不兼容的更改将尽量减少,并且只会在次要版本(如6.7、6.8等)中进行。qquickrhiitem.h不直接包含任何与QRhi相关的头文件。在实现QQuickRhiItem子类时使用这些类,需要链接到Qt::GuiPrivate(如果使用CMake),并包含带有rhi前缀的适当头文件,例如#include。QQuickRhiItem是旧版QQuickFramebufferObject类的替代品。后者本质上与 OpenGL / OpenGL ES 绑定,而QQuickRhiItem则与 QRhi 类一起工作,允许使用 Vulkan、Metal、Direct 3D 11/12 和 OpenGL / OpenGL ES 运行相同的渲染代码。在概念和功能上它们非常接近,从QQuickFramebufferObject迁移到QQuickRhiItem是直接的。QQuickFramebufferObject仍然可用,以确保与直接使用 OpenGL API 的现有应用程序代码的兼容性。注意
QQuickRhiItem在使用 Qt Quick 场景图的software适配时将无法正常工作。在大多数平台上,场景图渲染,以及由
QQuickRhiItem执行的渲染,将在一个专用线程上进行。因此,QQuickRhiItem类强制实施了项目实现(QQuickItem子类)和实际渲染逻辑之间的严格分离。所有项目逻辑,如暴露给QML的属性和UI相关的辅助函数,必须位于QQuickRhiItem子类中。与渲染相关的所有内容必须位于QQuickRhiItemRenderer类中。为了避免两个线程之间的竞争条件和读写问题,渲染器和项目永远不应读取或写入共享变量。项目和渲染器之间的通信应主要通过QQuickRhiItem::synchronize()函数进行。此函数将在渲染线程上调用,而GUI线程被阻塞。使用队列连接或事件进行项目和渲染器之间的通信也是可能的。应用程序必须同时继承
QQuickRhiItem和QQuickRhiItemRenderer。必须重新实现纯虚函数createRenderer(),以返回QQuickRhiItemRenderer子类的新实例。与QRhiWidget一样,
QQuickRhiItem自动管理颜色缓冲区,通常是一个2D纹理(QRhiTexture),或者在使用多重采样时是一个QRhiRenderBuffer。(一些3D API区分纹理和渲染缓冲区,而其他一些API的底层原生资源是相同的;渲染缓冲区主要用于允许在OpenGL ES 3.0中使用多重采样。)纹理的大小默认会根据项目的大小进行调整(考虑到了
device pixel ratio)。如果项目大小发生变化,纹理会以正确的大小重新创建。如果希望使用固定大小,可以将fixedColorBufferWidth和fixedColorBufferHeight设置为非零值。QQuickRhiItem是一个texture provider,可以直接用于 ShaderEffects 和其他消耗纹理提供者的类中。虽然不是主要用例,
QQuickRhiItem也允许集成直接使用3D图形API(如Vulkan、Metal、Direct 3D或OpenGL)的渲染代码。有关在QRhi渲染过程中记录原生命令的详细信息,请参见QRhiCommandBuffer::beginExternal(),以及QRhiTexture::createFrom(),该方法可以包装现有的原生纹理,然后在后续的渲染过程中与QRhi一起使用。另请参见QQuickGraphicsConfiguration,了解如何配置原生3D API环境(例如设备扩展),并注意通过尽早调用QWindow::setVulkanInstance(),可以将QQuickWindow与自定义的QVulkanInstance关联。注意
QQuickRhiItem总是使用与QQuickWindow相同的 QRhi 实例(因此也使用相同的 OpenGL 上下文、Vulkan 设备等)。要选择使用哪个底层的 3D 图形 API,请尽早调用QQuickWindow上的setGraphicsApi()。一旦场景图初始化后,就无法更改它,并且场景中的所有QQuickRhiItem实例都将使用相同的 3D API 进行渲染。一个简单的例子¶
以下是一个
QQuickRhiItem的子类。这里展示了它的完整形式。它使用透视投影渲染一个三角形,其中三角形的旋转基于自定义项的angle属性。(这意味着它可以通过例如QML中的NumberAnimation等动画驱动)class ExampleRhiItemRenderer(QQuickRhiItemRenderer): # public def initialize(cb): def synchronize(item): def render(cb): # private m_rhi = None std.unique_ptr<QRhiBuffer> m_vbuf std.unique_ptr<QRhiBuffer> m_ubuf std.unique_ptr<QRhiShaderResourceBindings> m_srb std.unique_ptr<QRhiGraphicsPipeline> m_pipeline m_viewProjection = QMatrix4x4() m_angle = 0.0f class ExampleRhiItem(QQuickRhiItem): Q_OBJECT QML_NAMED_ELEMENT(ExampleRhiItem) Q_PROPERTY(float angle READ angle WRITE setAngle NOTIFY angleChanged) # public QQuickRhiItemRenderer createRenderer() override float angle() { return m_angle; } def setAngle(a): # signals def angleChanged(): # private m_angle = 0.0f QQuickRhiItemRenderer ExampleRhiItem.createRenderer() return ExampleRhiItemRenderer() def setAngle(self, a): if m_angle == a: return m_angle = a angleChanged.emit() update() def synchronize(self, rhiItem): item = ExampleRhiItem(rhiItem) if item.angle() != m_angle: m_angle = item.angle() def getShader(name): f = QFile(name) return f.open(QIODevice.ReadOnly) if QShader.fromSerialized(f.readAll()) else QShader() vertexData = { 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, def initialize(self, cb): if m_rhi != rhi(): m_pipeline.reset() m_rhi = rhi() if not m_pipeline: m_vbuf.reset(m_rhi.newBuffer(QRhiBuffer.Immutable, QRhiBuffer.VertexBuffer, sizeof(vertexData))) m_vbuf.create() m_ubuf.reset(m_rhi.newBuffer(QRhiBuffer.Dynamic, QRhiBuffer.UniformBuffer, 64)) m_ubuf.create() m_srb.reset(m_rhi.newShaderResourceBindings()) m_srb.setBindings({ QRhiShaderResourceBinding.uniformBuffer(0, QRhiShaderResourceBinding.VertexStage, m_ubuf.get()), }) m_srb.create() m_pipeline.reset(m_rhi.newGraphicsPipeline()) m_pipeline.setShaderStages({ { QRhiShaderStage.Vertex, getShader(":/shaders/color.vert.qsb") }, { QRhiShaderStage.Fragment, getShader(":/shaders/color.frag.qsb") } }) inputLayout = QRhiVertexInputLayout() inputLayout.setBindings({ { 5 * sizeof(float) } }) inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute.Float2, 0 }, { 0, 1, QRhiVertexInputAttribute.Float3, 2 * sizeof(float) } }) m_pipeline.setVertexInputLayout(inputLayout) m_pipeline.setShaderResourceBindings(m_srb.get()) m_pipeline.setRenderPassDescriptor(renderTarget().renderPassDescriptor()) m_pipeline.create() resourceUpdates = m_rhi.nextResourceUpdateBatch() resourceUpdates.uploadStaticBuffer(m_vbuf.get(), vertexData) cb.resourceUpdate(resourceUpdates) outputSize = renderTarget().pixelSize() m_viewProjection = m_rhi.clipSpaceCorrMatrix() m_viewProjection.perspective(45.0f, outputSize.width() / (float) outputSize.height(), 0.01f, 1000.0f) m_viewProjection.translate(0, 0, -4) def render(self, cb): resourceUpdates = m_rhi.nextResourceUpdateBatch() modelViewProjection = m_viewProjection modelViewProjection.rotate(m_angle, 0, 1, 0) resourceUpdates.updateDynamicBuffer(m_ubuf.get(), 0, 64, modelViewProjection.constData()) clearColor = QColor.fromRgbF(0.4f, 0.7f, 0.0f, 1.0f) cb.beginPass(renderTarget(), clearColor, { 1.0f, 0 }, resourceUpdates) cb.setGraphicsPipeline(m_pipeline.get()) outputSize = renderTarget().pixelSize() cb.setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height())) cb.setShaderResources() QRhiCommandBuffer.VertexInput vbufBinding(m_vbuf.get(), 0) cb.setVertexInput(0, 1, vbufBinding) cb.draw(3) cb.endPass()
值得注意的是,这个简单的类几乎与QRhiWidget介绍中显示的代码完全相同。顶点和片段着色器也是相同的。这些以Vulkan风格的GLSL源代码提供,必须首先由Qt着色器基础设施处理。这可以通过手动运行
qsb命令行工具,或在CMake中使用qt_add_shaders()函数来实现。QQuickRhiItem加载这些随应用程序一起提供的预处理.qsb文件。有关Qt的着色器翻译基础设施的更多信息,请参阅Qt Shader Tools。color.vert#version 440 layout(location = 0) in vec4 position; layout(location = 1) in vec3 color; layout(location = 0) out vec3 v_color; layout(std140, binding = 0) uniform buf { mat4 mvp; }; void main() { v_color = color; gl_Position = mvp * position; }
color.frag#version 440 layout(location = 0) in vec3 v_color; layout(location = 0) out vec4 fragColor; void main() { fragColor = vec4(v_color, 1.0); }
一旦暴露给QML(注意
QML_NAMED_ELEMENT),我们的自定义项可以在任何场景中实例化。(在导入为CMake项目中的qt_add_qml_module指定的适当URI之后)ExampleRhiItem { anchors.fill: parent anchors.margins: 10 NumberAnimation on angle { from: 0; to: 360; duration: 5000; loops: Animation.Infinite } }
查看 场景图 - RHI 纹理项 以获取更复杂的示例。
另请参阅
QQuickRhiItemRenderer场景图 - RHI 纹理项 场景图和渲染- class TextureFormat¶
注意
当使用
from __feature__ import true_property时,属性可以直接使用,否则通过访问器函数使用。- property alphaBlendingᅟ: bool¶
控制在绘制由
QQuickRhiItem及其渲染器生成的内容纹理的四边形时,是否始终启用混合。默认值为
false。这是出于性能考虑:如果不涉及半透明,因为QQuickRhiItemRenderer清除为不透明颜色并且从不渲染alpha小于1的片段,那么启用混合就没有意义。如果
QQuickRhiItemRenderer子类渲染时涉及半透明,请将此属性设置为true。注意
在某些条件下,无论此属性的值如何,混合仍然会发生。例如,如果项目的
opacity(更准确地说,是从父链继承的组合不透明度)小于1,即使此属性设置为false,混合也会自动启用。注意
Qt Quick 场景图依赖于并期望预乘的 alpha。例如,如果意图是在渲染器中清除背景到 alpha 值为 0.5,那么确保将红色、绿色和蓝色的清除颜色值也乘以 0.5。否则,混合结果将不正确。
- Access functions:
- property colorBufferFormatᅟ: QQuickRhiItem.TextureFormat¶
此属性控制用作颜色缓冲区的纹理的纹理格式。默认值为TextureFormat::RGBA8。
QQuickRhiItem支持渲染到QRhiTexture支持的格式子集。只有通过QRhi::isTextureFormatSupported()报告为支持的格式才应指定,否则渲染将无法正常工作。注意
当项目及其渲染器已经初始化并渲染时,设置新的格式意味着如果由于不同的纹理格式导致关联的QRhiRenderPassDescriptor现在不兼容,则渲染器创建的所有QRhiGraphicsPipeline对象可能变得不可用。类似于动态更改
sampleCount,这意味着initialize()或render()实现必须负责释放现有的管道并创建新的管道。- Access functions:
此属性公开了底层颜色缓冲区(QRhiTexture 或 QRhiRenderBuffer)的大小(以像素为单位)。它用于在 GUI(主)线程、QML 绑定或 JavaScript 中使用。
注意
QQuickRhiItemRenderer实现,在场景图渲染线程上操作时,不应使用此属性。这些实现应该从render target中查询大小。注意
从主线程的角度来看,该值是异步可用的,这意味着当渲染线程进行渲染时,该值会发生变化。这意味着此属性主要在QML绑定中有用。应用程序代码不能假设在构造
QQuickRhiItem对象时该值已经是最新的。这是一个只读属性。
- Access functions:
- property fixedColorBufferHeightᅟ: int¶
项目关联纹理的固定高度,以像素为单位。当需要一个不依赖于项目大小的固定纹理大小时,此属性相关。此大小不会影响项目的几何形状(其在场景中的大小和位置),这意味着纹理的内容将显示为拉伸(放大)或缩小到项目的区域上。
例如,设置一个正好是项目(像素)大小两倍的尺寸,实际上执行了2倍超采样(以两倍分辨率渲染,然后在纹理化场景中与项目对应的四边形时隐式缩小)。
默认值为
0。值为0表示纹理的大小跟随项目的大小。(texture size=item size*device pixel ratio)。- Access functions:
- property fixedColorBufferWidthᅟ: int¶
项目关联纹理或渲染缓冲区的固定宽度,以像素为单位。当需要一个不依赖于项目大小的固定颜色缓冲区大小时,此属性相关。此大小对项目的几何形状(其在场景中的大小和位置)没有影响,这意味着纹理的内容将显示为拉伸(放大)或缩小到项目的区域上。
例如,设置一个正好是项目(像素)大小两倍的尺寸,实际上执行了2倍超采样(以两倍分辨率渲染,然后在纹理化场景中与项目对应的四边形时隐式缩小)。
默认值为
0。值为0表示纹理的大小跟随项目的大小。(texture size=item size*device pixel ratio)。- Access functions:
- property mirrorVerticallyᅟ: bool¶
此属性控制在绘制纹理四边形时是否翻转纹理UV。它对离屏颜色缓冲区的内容和由
QQuickRhiItemRenderer实现的渲染没有影响。默认值为
false。- Access functions:
- property sampleCountᅟ: int¶
此属性控制多重采样抗锯齿的样本计数。默认值为
1,表示MSAA已禁用。有效值为1、4、8,有时为16和32。QRhi::supportedSampleCounts() 可用于在运行时查询支持的样本计数,但通常应用程序应请求1(无MSAA)、4x(普通MSAA)或8x(高MSAA)。
注意
设置新值意味着渲染器创建的所有QRhiGraphicsPipeline对象必须从此使用相同的样本计数。使用不同样本计数创建的现有QRhiGraphicsPipeline对象不能再使用。当值发生变化时,所有颜色和深度-模板缓冲区都会被自动销毁并重新创建,并且会再次调用
initialize()。然而,当isAutoRenderTargetEnabled()为false时,应用程序需要自行管理深度-模板缓冲区或额外的颜色缓冲区。将样本计数从默认的1更改为更高的值意味着
colorTexture()变为None,而msaaColorBuffer()开始返回一个有效的对象。切换回1(或0)则意味着相反的情况:在下一次调用initialize()时,msaaColorBuffer()将返回None,而colorTexture()再次变为有效。此外,当样本计数大于1时(即使用MSAA),resolveTexture()返回一个有效的(非多重采样)QRhiTexture。- Access functions:
- __init__([parent=None])¶
- Parameters:
父级 –
QQuickItem
使用给定的
parent构造一个新的QQuickRhiItem。- alphaBlending()¶
- Return type:
布尔
另请参阅
属性
alphaBlendingᅟ的获取器。- alphaBlendingChanged()¶
属性
alphaBlendingᅟ的通知信号。- autoRenderTargetChanged()¶
- colorBufferFormat()¶
- Return type:
属性
colorBufferFormatᅟ的获取器。- colorBufferFormatChanged()¶
属性
colorBufferFormatᅟ的通知信号。- abstract createRenderer()¶
- Return type:
重新实现此函数以创建并返回
QQuickRhiItemRenderer子类的新实例。此函数将在GUI线程被阻塞时在渲染线程上调用。
属性
effectiveColorBufferSizeᅟ的获取器。- effectiveColorBufferSizeChanged()¶
属性
effectiveColorBufferSizeᅟ的通知信号。- fixedColorBufferHeight()¶
- Return type:
整数
属性
fixedColorBufferHeightᅟ的获取器。- fixedColorBufferHeightChanged()¶
属性
fixedColorBufferHeightᅟ的通知信号。- fixedColorBufferWidth()¶
- Return type:
整数
属性
fixedColorBufferWidthᅟ的获取器。- fixedColorBufferWidthChanged()¶
属性
fixedColorBufferWidthᅟ的通知信号。- isAutoRenderTargetEnabled()¶
- Return type:
布尔
返回当前的自动深度-模板缓冲区和渲染目标管理设置。
默认情况下,此值为
true。- isMirrorVerticallyEnabled()¶
- Return type:
布尔
属性
mirrorVerticallyᅟ的获取器。- mirrorVerticallyChanged()¶
属性
mirrorVerticallyᅟ的通知信号。- sampleCount()¶
- Return type:
整数
另请参阅
属性
sampleCountᅟ的获取器。- sampleCountChanged()¶
属性
sampleCountᅟ的通知信号。- setAlphaBlending(enable)¶
- Parameters:
enable – 布尔值
另请参阅
属性
alphaBlendingᅟ的设置器。- setAutoRenderTarget(enabled)¶
- Parameters:
enabled – 布尔值
控制是否由项目自动创建和维护深度模板QRhiRenderBuffer和QRhiTextureRenderTarget。默认值为
true。早期调用此函数,例如从派生类的构造函数中调用,将enabled设置为false以禁用此功能。在自动模式下,深度-模板缓冲区的大小和样本计数遵循颜色缓冲区纹理的设置。在非自动模式下,renderTarget() 和 depthStencilBuffer() 总是返回
None,然后由应用程序的 initialize() 实现来负责设置和管理这些对象。- setColorBufferFormat(format)¶
- Parameters:
格式 –
TextureFormat
另请参阅
属性
colorBufferFormatᅟ的设置器。- setFixedColorBufferHeight(height)¶
- Parameters:
height – int
属性
fixedColorBufferHeightᅟ的设置器。- setFixedColorBufferWidth(width)¶
- Parameters:
width – 整数
属性
fixedColorBufferWidthᅟ的设置器。- setMirrorVertically(enable)¶
- Parameters:
enable – 布尔值
属性
mirrorVerticallyᅟ的设置器。- setSampleCount(samples)¶
- Parameters:
样本 – int
另请参阅
属性
sampleCountᅟ的设置器。