QML核心渲染类说明

一 Node 节点

QSGNode:

QSGNode类是场景图中所有节点的基类。

qsnode类可以用作子容器。子节点与appendChildNode()、prependChildNode()、insertChildNodeBefore()和insertChildNodeAfter()一起添加。节点的顺序很重要,因为几何体节点是根据它们在场景图中的顺序进行渲染的。

场景图节点包含一种机制,用于描述场景的哪些部分发生了更改。这包括组合矩阵、累积不透明度、对节点层次结构的更改等。此信息可用于场景图渲染器内部的优化。为了使渲染器正确渲染节点,当节点发生更改时,用户使用正确的标志调用QSGNode::markDirty()非常重要。节点类上的大多数函数都将隐式调用markDirty()。例如,qsnode::appendChildNode()将调用markDirty(),传入qsnode::DirtyNodeAdded。

如果节点更改每一帧,则可以使用preprocess()函数为渲染的每一帧对节点应用更改。必须通过在节点上设置QSGNode::useproprocess标志来显式启用preprocess()的使用。

virtual isSubtreeBlocked()函数可用于同时禁用子树。被阻止的子树中的节点将不会被预处理(),也不会被呈现。

注意:所有带有QSG前缀的类都应该单独在场景图的渲染线程上使用。有关详细信息,请参见场景图和渲染。

QSGBasicGeometryNode: 

QSGBasicGeometryNode类用作基于几何体的节点的基类。

QSGBasicGeometryNode类不应单独使用。它只封装了QSGGeometryNode和QSGClipNode类之间的共享功能。

  QSGClipNode: 

    QSGClipNode类实现场景图中的剪辑功能。

    剪裁应用于节点的子树,并且可以嵌套。多个剪辑节点将通过相交其所有几何体来累积。累积是渲染的一部分。

    剪辑节点必须具有几何体才能添加到场景图中。

    裁剪通常是通过使用模具缓冲区来实现的。

  QSGGeometryNode:

    QSGGeometryNode由几何和材料组成。几何体定义了要绘制的网格、顶点及其结构。材质定义了形状的填充方式。

    官方有示范代码,说明如何使用QSGGeometryNode创建红线:

    在将几何体节点添加到场景图之前,它必须同时具有几何体和法线材质。将节点添加到场景图后,当几何体和材质发生更改时,用户还应使用QSGNode::markDirty()将其标记为dirty。

    “几何体”节点支持两种类型的材质:“不透明”材质和“法线”材质。当渲染时累积的场景图形不透明度为1时,将使用不透明材质。主要的用例是特例不透明渲染,以避免片段着色器中的额外操作会对嵌入式图形芯片的性能产生重大影响。不透明材料是可选的。

    QSGImageNode:

      提供QSGImageNode类是为了方便使用QML场景图轻松绘制纹理内容

    QSGRectangleNode:

      QSGRectangleNode类是一个方便的类,用于使用scenegraph绘制实心矩形。

    QSGSimpleRectNode:

      功能类似QSGRectangleNode

    QSGSimpleTextureNode:      

      提供qsgsimplettexturenode类是为了方便使用QML场景图轻松绘制纹理内容。

      警告:简单纹理节点类在添加到要渲染的场景图之前必须具有纹理。

      警告:此实用程序类仅在使用OpenGL或Qt Quick scenegraph的软件后端运行时才起作用。要获得正确的跨平台替代方案,请通过QQuickWindow::createImageNode()或QSGEngine::createImageNode()使用QSGImageNode。

QSGOpacityNode:

QSGOpacityNode类用于更改节点的不透明度。

不透明度应用于其子树并可以嵌套。多个不透明度节点将通过乘以它们的不透明度来累积。累积是渲染的一部分。

当嵌套的不透明度低于某个阈值时,子树可能被标记为blocked,从而导致isSubtreeBlocked()返回true。这样做是出于性能原因。

QSGRenderNode:

QSGRenderNode类表示一组自定义呈现命令,这些命令针对scenegraph正在使用的图形API。

QSGTransformNode:

QSGTransformNode类实现场景图中的转换。

转换应用节点的子树,并且可以嵌套。将多个变换节点的所有矩阵相交,从而累加多个变换节点。累积是渲染的一部分。

变换节点实现4x4矩阵,理论上支持全三维变换。但是,由于渲染器针对2D用例而不是3D用例进行优化,因此需要谨慎地使用完整的3D变换渲染场景。

注意:所有带有QSG前缀的类都应该单独在场景图的渲染线程上使用。有关详细信息,请参见场景图和渲染。

 

二 材质

QSGMaterial:

封装了着色器程序的渲染状态,非常低级,一般渲染会采用QSGSimpleMaterialShader类,它提供了一个更加方便的的API

QSGMaterial和QSGMaterialShader子类形成了紧密的关系。对于一个场景图(包括嵌套图),有一个唯一的QSGMaterialShader实例,它封装了场景图用于渲染该材质的QOpenGLShaderProgram,例如将着色器渲染为几何体的平面着色。每个QSGGeometryNode都可以有一个唯一的QSGMaterial,其中包含绘制节点时应如何配置着色器,例如用于渲染几何体的实际颜色。
QSGMaterial有两个需要实现的虚拟函数。函数type()应该为特定子类的所有实例返回一个唯一的实例。createShader()函数应返回QSGMaterialShader的新实例,该实例特定于QSGMaterial的子类。

QSGFlatColorMaterial:

QSGFlatColorMaterial类提供了一种在场景图中渲染纯色几何体的方便方法,

平面颜色材质将使用纯色填充几何体中的每个像素。颜色可以包含透明度。

要使用平面颜色材质渲染的几何体需要QSGGeometry对象中属性位置0的顶点才能正确渲染。QSGGeometry::defaultAttributes\u Point2D()返回与此材质兼容的属性集。

在更新其渲染状态时,平面颜色材质将同时考虑当前不透明度和当前矩阵。

QSGOpaqueTextureMaterial:

QSGOpaqueTextureMaterial类提供了一种在场景图中渲染纹理几何体的方便方法。

不透明纹理材质将使用提供的纹理填充几何体中的每个像素。该材质不考虑QSGMaterialShader::RenderState的不透明度,因此使用该材质的节点父链中的不透明度节点没有任何效果。

要使用不透明纹理材质渲染的几何体需要属性位置0中的顶点和属性位置1中的纹理坐标。纹理坐标是一个二维浮点元组。QSGGeometry::defaultAttributes\u TexturedPoint2D返回与此材质兼容的属性集。

可以使用setTexture()设置要渲染的纹理。可以使用setMipmapFiltering()、setFiltering()、setHorizontalWrapMode()和setVerticalWrapMode()指定如何渲染纹理。渲染状态是在绑定纹理实例之前设置的。

不透明纹理材质尊重当前矩阵和纹理的alpha通道。它将忽略场景图中累积的不透明度。

纹理材质在用作场景图形中的材质之前必须具有纹理集。

QSGSimpleMaterial

QSGSimpleMaterial类是一个模板生成的类,用于存储qsgsimplematerialshader使用的状态。

可以通过模板生成的state()函数访问材质的状态。

注意:所有带有QSG前缀的类都应该单独在场景图的渲染线程上使用。有关详细信息,请参见场景图和渲染。

QSGVertexColorMaterial

提供了一种在场景图中渲染逐顶点着色几何体的方便方法。 

“顶点颜色”材质将为几何体中的每个顶点提供一种颜色。顶点之间的像素将进行线性插值。颜色可以包含透明度。

要使用顶点颜色渲染的几何体必须具有以下布局。属性位置0必须包含顶点。属性位置1必须包含颜色,一个由4个值组成的元组,带有RGBA布局。0到1范围内的浮动和0到255范围内的无符号字节都对颜色值有效。

注意:渲染管道需要具有预乘alpha的像素。

QSGGeometry::defaultAttributes\u ColoredPoint2D()可用于构造与此材质兼容的属性集。

顶点颜色材质在更新其渲染状态时同时考虑当前不透明度和当前矩阵。

 

三 着色器

QSGMaterialShader:

QSGMaterialShader类表示渲染器中的OpenGL着色器程序。

QSGMaterialShader API是非常低级的。QSGSimpleMaterialShader提供了一个更方便的API,它提供了几乎所有相同的特性。

QSGMaterial和QSGMaterialShader形成了紧密的关系。对于一个场景图(包括嵌套图),有一个唯一的QSGMaterialShader实例,它封装了场景图用于渲染该材质的QOpenGLShaderProgram,例如将着色器渲染为几何体的平面着色。每个QSGGeometryNode都可以具有唯一的QSGMaterial,其中包含绘制该节点时应如何配置着色器,例如用于渲染几何体的实际颜色。

QSGMaterialShader的实例从来不是由用户显式创建的,它将由场景图通过QSGMaterial::createShader()根据需要创建。场景图将确保通过场景图的每个着色器实现只有一个实例。

vertexShader()返回的源代码用于控制材质对几何体中的Vertex数据执行的操作。fragmentShader()返回的源代码用于控制材质应如何填充几何体中的每个像素。顶点和片段源代码在初始化过程中只查询一次,以后更改这些函数返回的内容将不会产生任何影响。

当着色器开始使用时,场景图将调用activate()函数。当不再使用着色器时,场景图将调用deactivate函数。激活时,场景图可能会对updateState()进行一个或多个调用,该调用将更新要渲染的每个单独几何体的着色器状态。

attributeName()返回vertexShader()中使用的属性的名称。它们在activate()和deactivate()的默认实现中用于确定启用了哪些顶点寄存器。

在程序创建期间调用initialize()函数,以允许子类准备使用,例如解析vertexShader()和fragmentShader()中的统一名称。

 

QSGSimpleMaterialShader:

QSGSimpleMaterialShader类提供了一种为场景图构建基于OpenGL的自定义材质的方便方法。

警告:此实用程序类仅在与Qt Quick scenegraph的OpenGL后端一起运行时才起作用。

当QSGMaterial和QSGMaterialShader API需要一些样板代码来创建一个功能强大的材质时,QSGSimpleMaterialShader试图通过使用模板来隐藏其中的一些内容。

QSGSimpleMaterialShader::vertexShader()和QSGSimpleMaterialShader::fragmentShader()用于指定实际的着色器源代码。顶点属性的名称应该列在QSGSimpleMaterialShader::attributes()中

QSGSimpleMaterialShader::updateState()用于将材质状态推送到OpenGL着色器程序。

实际的OpenGL着色器程序可以通过QSGSimpleMaterialShader::program()函数访问。

每个QSGSimpleMaterialShader实现都在一个唯一的状态结构上运行,必须使用QSG_DECLARE_SIMPLE_SHADER宏声明

 

四 几何形状

 

QSGGeometry类提供了一种为节点构建几何形状的方便方法,你可以根据自己的喜好构建圆形 方形 样条曲线等等几何体

绘制复杂的图形时,一般是指定定点,几何形状一般是由三角形组成,参考文档:https://blog.csdn.net/xiajun07061225/article/details/7455283

 

测试

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QLoggingCategory>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QLoggingCategory::setFilterRules(QStringLiteral("qt.scenegraph.general=true"));
    qSetMessagePattern("%{category}: %{message}");

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

运行结果:
qt.scenegraph.general: threaded render loop
qt.scenegraph.general: Using sg animation driver
qt.scenegraph.general: Animation Driver: using vsync: 16.67 ms
qt.scenegraph.general: Using sg animation driver
qt.scenegraph.general: Animation Driver: using vsync: 16.67 ms
qt.scenegraph.general: texture atlas dimensions: 1024x512
qt.scenegraph.general: R/G/B/A Buffers:   8 8 8 8
qt.scenegraph.general: Depth Buffer:      24
qt.scenegraph.general: Stencil Buffer:    8
qt.scenegraph.general: Samples:           0
qt.scenegraph.general: GL_VENDOR:         Intel
qt.scenegraph.general: GL_RENDERER:       Intel(R) UHD Graphics 630
qt.scenegraph.general: GL_VERSION:        4.5.0 - Build 24.20.100.6345
qt.scenegraph.general: GL_EXTENSIONS:       略
qt.scenegraph.general: Max Texture Size: 16384
qt.scenegraph.general: Debug context:    false

 

posted @ 2021-03-14 22:00  つContent  阅读(1668)  评论(0)    收藏  举报