- class QSGMaterialShader#
QSGMaterialShader
类表示一个与图形 API 无关的着色器程序。更多...摘要#
方法#
def
__init__()
def
flags()
def
setFlag()
def
setFlags()
虚方法#
注意
此文档可能包含从 C++ 自动转换到 Python 的片段。我们始终欢迎对片段翻译的贡献。如果您发现翻译有误,也可以通过在 https:/bugreports.qt.io/projects/PYSIDE 上创建工单来告知我们。
详细说明#
QSGMaterialShader
代表了一个由顶点和片段着色器组成的组合,定义了图形管线状态的变化数据,以及更新图形资源(如统一缓冲区和纹理)的逻辑。注意
应仅在场景图渲染线程中使用带有 QSG 前缀的所有类。有关更多信息,请参阅 场景图和渲染。
《QSGMaterial》和《QSGMaterialShader》之间有一个紧密的关系。对于场景图(包括嵌套图),有一个唯一的《QSGMaterialShader》实例,它封装了场景图使用该材料渲染对象所需的所有着色器和数据。每个《QSGGeometryNode》都可以有一个唯一的《QSGMaterial》,它定义了绘图节点时必须如何配置图形管线。用户不会显式创建《QSGMaterialShader》的实例,它将通过《createShader()`》方法在场景图需要时创建。场景图通过调用`createShader()`方法创建《QSGMaterialShader》的实例,确保每个着色器实现只有一个实例。
在Qt 5中,《QSGMaterialShader》与OpenGL相关联。它是直接建立在《QOpenGLShaderProgram》之上的,具有如`updateState()`这样的函数,可以发出任意的OpenGL命令。这种情况在Qt 6中已不再适用。《QSGMaterialShader》不是严格意义上的数据导向的,这意味着它提供了数据(着色器和所需的管线状态变化)以及更新统一缓冲区中数据的逻辑。不提供图形API访问。这意味着《QSGMaterialShader》不能自行执行OpenGL、Vulkan、Metal或Direct 3D调用。与统一的着色器管理相结合,这使得《QSGMaterialShader》可以一次编写,在运行时与任何支持的图形API一起工作。
通过调用受保护的`setShaderFileName()`函数设置的着色器控制了材料如何处理几何图形的顶点数据,以及如何对片段进行着色。《QSGMaterialShader》通常在构建期间设置一个顶点和一个片段着色器。之后更改着色器可能不会导致期望的效果,必须避免更改。
在Qt 6中,默认方法是将
.qsb
文件随应用程序一起分发,通常通过资源系统内嵌,并在调用setShaderFileName()
时引用。这些.qsb
文件是在线生成或最晚在应用程序构建时生成,从使用Qt Shader Tools模块中的qsb
工具生成的Vulkan风格的GLSL源代码中生成。有三个虚拟函数可以被覆盖。这些提供了数据或生成数据的逻辑,用于统一缓冲区、纹理和管线状态更改。
updateUniformData()
是在子类中最常重写的函数。该函数预期将更新一个QByteArray的内容,然后作为统一缓冲区暴露给着色器。任何在其顶点或片段着色器中具有统一块的QSGMaterialShader
都必须重写updateUniformData()
。当着色器代码采样纹理时,
updateSampledImage()
是相关的。该函数会针对每个采样器(或API中相关的组合图像采样器)调用,从而允许指定应该将哪个QSGTexture
暴露给着色器。着色器管线状态更改很少使用。一种用例是希望使用特定混合模式的材料。相关的函数是
updateGraphicsPipelineState()
。除非QSGMaterialShader
通过设置标志UpdatesGraphicsPipelineState
进行了选择,否则该函数不会调用。该函数的任务是使用所需的更改更新传递给它的GraphicsPipelineState
结构实例。目前只有混合和剔除相关的功能可用,其他状态不能由材料控制。一个包括纹理支持的最小示例可能如下。这里我们假设Material是在其
createShader()
中创建Shader实例的QSGMaterial
,并且它持有我们希望在片段着色器中采样的QSGTexture
。顶点着色器仅依赖于模型视图投影矩阵。class Shader : public QSGMaterialShader { public: Shader() { setShaderFileName(VertexStage, QLatin1String(":/materialshader.vert.qsb")); setShaderFileName(FragmentStage, QLatin1String(":/materialshader.frag.qsb")); } bool updateUniformData(RenderState &state, QSGMaterial *, QSGMaterial *) { bool changed = false; QByteArray *buf = state.uniformData(); if (state.isMatrixDirty()) { const QMatrix4x4 m = state.combinedMatrix(); memcpy(buf->data(), m.constData(), 64); changed = true; } return changed; } void updateSampledImage(RenderState &, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *) { Material *mat = static_cast<Material *>(newMaterial); if (binding == 1) *texture = mat->texture(); } };
着色器的Vulkan风格GLSL源代码可能如下所示。这些预期使用
qsb
工具脱机预处理,生成由Shader()构造函数引用的.qsb
文件。#version 440 layout(location = 0) in vec4 aVertex; layout(location = 1) in vec2 aTexCoord; layout(location = 0) out vec2 vTexCoord; layout(std140, binding = 0) uniform buf { mat4 qt_Matrix; } ubuf; out gl_PerVertex { vec4 gl_Position; }; void main() { gl_Position = ubuf.qt_Matrix * aVertex; vTexCoord = aTexCoord; }
#version 440 layout(location = 0) in vec2 vTexCoord; layout(location = 0) out vec4 fragColor; layout(binding = 1) uniform sampler2D srcTex; void main() { vec4 c = texture(srcTex, vTexCoord); fragColor = vec4(c.rgb * 0.5, 1.0); }
- 类 Flag#
(继承自
enum.Flag
) 表示特殊材质属性的 Flag 值。常量
描述
QSGMaterialShader.UpdatesGraphicsPipelineState
设置此 Flag 将启用调用
updateGraphicsPipelineState()
.
- 类 Stage#
- __init__()#
构建一个新的
QSGMaterialShader
.- combinedImageSamplerCount(binding)#
- 参数:
binding - int
- 返回类型:
int
返回在
binding
位置的复合图像采样变量中的元素数量。此值从着色器代码中内省获得。该变量可能是一个数组,并且可能有多个维度。此计数反映了变量中复合图像采样项的总数。在以下示例中,
srcA
的计数为 1,srcB
为 4,而srcC
为 6。layout (binding = 0) uniform sampler2D srcA; layout (binding = 1) uniform sampler2D srcB[4]; layout (binding = 2) uniform sampler2D srcC[2][3];
此计数是
QSGTexture
指针在updateSampledImage
的纹理参数中的数量。另请参阅
updateSampledImage
返回此材质着色器目前设置的 Flag。
另请参阅
当
on
为真时,设置此材质着色器上的flags
;否则清除指定的标志。设置此材质着色器的
flags
。另请参阅
设置特定
stage
的着色器的filename
。该文件预计包含一个序列化的 QShader。
- updateUniformData(state, newMaterial, oldMaterial)#
- 参数:
state –
RenderState
newMaterial –
QSGMaterial
oldMaterial –
QSGMaterial
- 返回类型:
布尔值
当场景图调用此函数以获取着色程序均匀缓冲区的内容更新时,该函数被调用。实现不需要执行任何真实图形操作,它仅仅负责将数据复制到从
uniformData()
返回的 QByteArray 中。场景图会确保该缓冲区在着色器中可见。当前渲染
state
从场景图传递。如果状态指示任何相关的状态是脏的,实现必须在可通过uniformData()
访问的缓冲数据中的相应区域进行更新。当一个状态,例如,矩阵或不透明度,不是脏的时候,没有必要触摸相应的区域,因为数据是持久的。如果任何均匀数据发生变化,则返回值必须为
true
。应从
newMaterial
中提取子类特定的状态,例如平面颜色材质的颜色,以相应地更新缓冲区中的相关区域。oldMaterial
可以用来在更新材质状态时最小化缓冲区更改(通常是 memcpy 调用)。当oldMaterial
为空时,表示此着色器刚刚激活。