1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qsgflatcolormaterial.h" |
5 | #include <private/qsgmaterialshader_p.h> |
6 | |
7 | QT_BEGIN_NAMESPACE |
8 | |
9 | class FlatColorMaterialRhiShader : public QSGMaterialShader |
10 | { |
11 | public: |
12 | FlatColorMaterialRhiShader(int viewCount); |
13 | |
14 | bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; |
15 | |
16 | static QSGMaterialType type; |
17 | }; |
18 | |
19 | QSGMaterialType FlatColorMaterialRhiShader::type; |
20 | |
21 | FlatColorMaterialRhiShader::FlatColorMaterialRhiShader(int viewCount) |
22 | { |
23 | setShaderFileName(stage: VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/flatcolor.vert.qsb" ), viewCount); |
24 | setShaderFileName(stage: FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/flatcolor.frag.qsb" ), viewCount); |
25 | } |
26 | |
27 | bool FlatColorMaterialRhiShader::updateUniformData(RenderState &state, |
28 | QSGMaterial *newMaterial, |
29 | QSGMaterial *oldMaterial) |
30 | { |
31 | Q_ASSERT(!oldMaterial || newMaterial->type() == oldMaterial->type()); |
32 | QSGFlatColorMaterial *oldMat = static_cast<QSGFlatColorMaterial *>(oldMaterial); |
33 | QSGFlatColorMaterial *mat = static_cast<QSGFlatColorMaterial *>(newMaterial); |
34 | bool changed = false; |
35 | QByteArray *buf = state.uniformData(); |
36 | const int shaderMatrixCount = newMaterial->viewCount(); |
37 | const int matrixCount = qMin(a: state.projectionMatrixCount(), b: shaderMatrixCount); |
38 | |
39 | for (int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) { |
40 | if (state.isMatrixDirty()) { |
41 | const QMatrix4x4 m = state.combinedMatrix(index: viewIndex); |
42 | memcpy(dest: buf->data() + 64 * viewIndex, src: m.constData(), n: 64); |
43 | changed = true; |
44 | } |
45 | } |
46 | |
47 | const QColor &c = mat->color(); |
48 | if (!oldMat || c != oldMat->color() || state.isOpacityDirty()) { |
49 | float r, g, b, a; |
50 | c.getRgbF(r: &r, g: &g, b: &b, a: &a); |
51 | const float opacity = state.opacity() * a; |
52 | QVector4D v(r * opacity, g * opacity, b * opacity, opacity); |
53 | Q_ASSERT(sizeof(v) == 16); |
54 | memcpy(dest: buf->data() + 64 * shaderMatrixCount, src: &v, n: 16); |
55 | changed = true; |
56 | } |
57 | |
58 | return changed; |
59 | } |
60 | |
61 | |
62 | /*! |
63 | \class QSGFlatColorMaterial |
64 | |
65 | \brief The QSGFlatColorMaterial class provides a convenient way of rendering |
66 | solid colored geometry in the scene graph. |
67 | |
68 | \inmodule QtQuick |
69 | \ingroup qtquick-scenegraph-materials |
70 | |
71 | \warning This utility class is only functional when running with the default |
72 | backend of the Qt Quick scenegraph. |
73 | |
74 | The flat color material will fill every pixel in a geometry using |
75 | a solid color. The color can contain transparency. |
76 | |
77 | The geometry to be rendered with a flat color material requires |
78 | vertices in attribute location 0 in the QSGGeometry object to render |
79 | correctly. The QSGGeometry::defaultAttributes_Point2D() returns an attribute |
80 | set compatible with this material. |
81 | |
82 | The flat color material respects both current opacity and current matrix |
83 | when updating its rendering state. |
84 | */ |
85 | |
86 | |
87 | /*! |
88 | Constructs a new flat color material. |
89 | |
90 | The default color is white. |
91 | */ |
92 | |
93 | QSGFlatColorMaterial::QSGFlatColorMaterial() : m_color(QColor(255, 255, 255)) |
94 | { |
95 | } |
96 | |
97 | /*! |
98 | \fn const QColor &QSGFlatColorMaterial::color() const |
99 | |
100 | Returns this flat color material's color. |
101 | |
102 | The default color is white. |
103 | */ |
104 | |
105 | |
106 | |
107 | /*! |
108 | Sets this flat color material's color to \a color. |
109 | */ |
110 | |
111 | void QSGFlatColorMaterial::setColor(const QColor &color) |
112 | { |
113 | m_color = color; |
114 | setFlag(flags: Blending, on: m_color.alpha() != 0xff); |
115 | } |
116 | |
117 | |
118 | |
119 | /*! |
120 | \internal |
121 | */ |
122 | |
123 | QSGMaterialType *QSGFlatColorMaterial::type() const |
124 | { |
125 | return &FlatColorMaterialRhiShader::type; |
126 | } |
127 | |
128 | |
129 | |
130 | /*! |
131 | \internal |
132 | */ |
133 | |
134 | QSGMaterialShader *QSGFlatColorMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const |
135 | { |
136 | Q_UNUSED(renderMode); |
137 | return new FlatColorMaterialRhiShader(viewCount()); |
138 | } |
139 | |
140 | |
141 | /*! |
142 | \internal |
143 | */ |
144 | |
145 | int QSGFlatColorMaterial::compare(const QSGMaterial *other) const |
146 | { |
147 | const QSGFlatColorMaterial *flat = static_cast<const QSGFlatColorMaterial *>(other); |
148 | return m_color.rgba() - flat->color().rgba(); |
149 | |
150 | } |
151 | |
152 | QT_END_NAMESPACE |
153 | |