1// Copyright (C) 2023 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#ifndef QSGCURVEFILLNODE_P_H
5#define QSGCURVEFILLNODE_P_H
6
7#include <QtGui/qbrush.h>
8
9#include <QtQuick/qtquickexports.h>
10#include <QtQuick/private/qsggradientcache_p.h>
11#include <QtQuick/private/qsgtransform_p.h>
12#include <QtQuick/qsgnode.h>
13#include <QtQuick/qsgtextureprovider.h>
14
15#include "qsgcurveabstractnode_p.h"
16
17//
18// W A R N I N G
19// -------------
20//
21// This file is not part of the Qt API. It exists for the convenience
22// of a number of Qt sources files. This header file may change from
23// version to version without notice, or even be removed.
24//
25// We mean it.
26//
27
28QT_BEGIN_NAMESPACE
29
30class QSGTextureProvider;
31
32class Q_QUICK_EXPORT QSGCurveFillNode : public QObject, public QSGCurveAbstractNode
33{
34 Q_OBJECT
35public:
36 QSGCurveFillNode();
37
38 void setColor(QColor col) override
39 {
40 m_color = col;
41 markDirty(bits: DirtyMaterial);
42 }
43
44 QColor color() const
45 {
46 return m_color;
47 }
48
49 void setFillTextureProvider(QSGTextureProvider *provider)
50 {
51 if (provider == m_textureProvider)
52 return;
53
54 if (m_textureProvider != nullptr) {
55 disconnect(sender: m_textureProvider, signal: &QSGTextureProvider::textureChanged,
56 receiver: this, slot: &QSGCurveFillNode::handleTextureChanged);
57 disconnect(sender: m_textureProvider, signal: &QSGTextureProvider::destroyed,
58 receiver: this, slot: &QSGCurveFillNode::handleTextureProviderDestroyed);
59 }
60
61 m_textureProvider = provider;
62 markDirty(bits: DirtyMaterial);
63
64 if (m_textureProvider != nullptr) {
65 connect(sender: m_textureProvider, signal: &QSGTextureProvider::textureChanged,
66 context: this, slot: &QSGCurveFillNode::handleTextureChanged);
67 connect(sender: m_textureProvider, signal: &QSGTextureProvider::destroyed,
68 context: this, slot: &QSGCurveFillNode::handleTextureProviderDestroyed);
69 }
70 }
71
72
73 QSGTextureProvider *fillTextureProvider() const
74 {
75 return m_textureProvider;
76 }
77
78 void setFillGradient(const QSGGradientCache::GradientDesc &fillGradient)
79 {
80 m_fillGradient = fillGradient;
81 markDirty(bits: DirtyMaterial);
82 }
83
84 const QSGGradientCache::GradientDesc *fillGradient() const
85 {
86 return &m_fillGradient;
87 }
88
89 void setGradientType(QGradient::Type type)
90 {
91 m_gradientType = type;
92 markDirty(bits: DirtyMaterial);
93 }
94
95 QGradient::Type gradientType() const
96 {
97 return m_gradientType;
98 }
99
100 void setFillTransform(const QSGTransform &transform)
101 {
102 m_fillTransform = transform;
103 markDirty(bits: DirtyMaterial);
104 }
105
106 const QSGTransform *fillTransform() const
107 {
108 return &m_fillTransform;
109 }
110
111 float debug() const
112 {
113 return m_debug;
114 }
115
116 void setDebug(float newDebug)
117 {
118 m_debug = newDebug;
119 }
120
121 void appendTriangle(const std::array<QVector2D, 3> &v, // triangle vertices
122 const std::array<QVector2D, 3> &n, // vertex normals
123 std::function<QVector3D(QVector2D)> uvForPoint
124 )
125 {
126 QVector3D uv1 = uvForPoint(v[0]);
127 QVector3D uv2 = uvForPoint(v[1]);
128 QVector3D uv3 = uvForPoint(v[2]);
129
130 QVector2D duvdx = QVector2D(uvForPoint(v[0] + QVector2D(1, 0))) - QVector2D(uv1);
131 QVector2D duvdy = QVector2D(uvForPoint(v[0] + QVector2D(0, 1))) - QVector2D(uv1);
132
133 m_uncookedIndexes.append(t: m_uncookedVertexes.size());
134 m_uncookedVertexes.append( t: { .x: v[0].x(), .y: v[0].y(),
135 .u: uv1.x(), .v: uv1.y(), .w: uv1.z(),
136 .dudx: duvdx.x(), .dvdx: duvdx.y(),
137 .dudy: duvdy.x(), .dvdy: duvdy.y(),
138 .nx: n[0].x(), .ny: n[0].y()
139 });
140
141 m_uncookedIndexes.append(t: m_uncookedVertexes.size());
142 m_uncookedVertexes.append( t: { .x: v[1].x(), .y: v[1].y(),
143 .u: uv2.x(), .v: uv2.y(), .w: uv2.z(),
144 .dudx: duvdx.x(), .dvdx: duvdx.y(),
145 .dudy: duvdy.x(), .dvdy: duvdy.y(),
146 .nx: n[1].x(), .ny: n[1].y()
147 });
148
149 m_uncookedIndexes.append(t: m_uncookedVertexes.size());
150 m_uncookedVertexes.append( t: { .x: v[2].x(), .y: v[2].y(),
151 .u: uv3.x(), .v: uv3.y(), .w: uv3.z(),
152 .dudx: duvdx.x(), .dvdx: duvdx.y(),
153 .dudy: duvdy.x(), .dvdy: duvdy.y(),
154 .nx: n[2].x(), .ny: n[2].y()
155 });
156 }
157
158 void appendTriangle(const QVector2D &v1,
159 const QVector2D &v2,
160 const QVector2D &v3,
161 const QVector3D &uv1,
162 const QVector3D &uv2,
163 const QVector3D &uv3,
164 const QVector2D &n1,
165 const QVector2D &n2,
166 const QVector2D &n3,
167 const QVector2D &duvdx,
168 const QVector2D &duvdy)
169 {
170 m_uncookedIndexes.append(t: m_uncookedVertexes.size());
171 m_uncookedVertexes.append( t: { .x: v1.x(), .y: v1.y(),
172 .u: uv1.x(), .v: uv1.y(), .w: uv1.z(),
173 .dudx: duvdx.x(), .dvdx: duvdx.y(),
174 .dudy: duvdy.x(), .dvdy: duvdy.y(),
175 .nx: n1.x(), .ny: n1.y()
176 });
177
178 m_uncookedIndexes.append(t: m_uncookedVertexes.size());
179 m_uncookedVertexes.append( t: { .x: v2.x(), .y: v2.y(),
180 .u: uv2.x(), .v: uv2.y(), .w: uv2.z(),
181 .dudx: duvdx.x(), .dvdx: duvdx.y(),
182 .dudy: duvdy.x(), .dvdy: duvdy.y(),
183 .nx: n2.x(), .ny: n2.y()
184 });
185
186 m_uncookedIndexes.append(t: m_uncookedVertexes.size());
187 m_uncookedVertexes.append( t: { .x: v3.x(), .y: v3.y(),
188 .u: uv3.x(), .v: uv3.y(), .w: uv3.z(),
189 .dudx: duvdx.x(), .dvdx: duvdx.y(),
190 .dudy: duvdy.x(), .dvdy: duvdy.y(),
191 .nx: n3.x(), .ny: n3.y()
192 });
193 }
194
195 void appendTriangle(const QVector2D &v1,
196 const QVector2D &v2,
197 const QVector2D &v3,
198 std::function<QVector3D(QVector2D)> uvForPoint)
199 {
200 appendTriangle(v: {v1, v2, v3}, n: {}, uvForPoint);
201 }
202
203 QVector<quint32> uncookedIndexes() const
204 {
205 return m_uncookedIndexes;
206 }
207
208 void cookGeometry() override;
209
210 void reserve(qsizetype size)
211 {
212 m_uncookedIndexes.reserve(asize: size);
213 m_uncookedVertexes.reserve(asize: size);
214 }
215
216 void preprocess() override
217 {
218 if (m_textureProvider != nullptr) {
219 if (QSGDynamicTexture *texture = qobject_cast<QSGDynamicTexture *>(object: m_textureProvider->texture()))
220 texture->updateTexture();
221 }
222 }
223
224 QVector2D boundsSize() const
225 {
226 return m_boundsSize;
227 }
228
229 void setBoundsSize(const QVector2D &boundsSize)
230 {
231 m_boundsSize = boundsSize;
232 }
233
234private Q_SLOTS:
235 void handleTextureChanged()
236 {
237 markDirty(bits: DirtyMaterial);
238 }
239
240 void handleTextureProviderDestroyed()
241 {
242 m_textureProvider = nullptr;
243 markDirty(bits: DirtyMaterial);
244 }
245
246private:
247 struct CurveNodeVertex
248 {
249 float x, y, u, v, w;
250 float dudx, dvdx, dudy, dvdy; // Size of pixel in curve space (must be same for all vertices in triangle)
251 float nx, ny; // normal vector describing the direction to shift the vertex for AA
252 };
253
254 void updateMaterial();
255 static const QSGGeometry::AttributeSet &attributes();
256
257 QScopedPointer<QSGMaterial> m_material;
258
259 QVector<CurveNodeVertex> m_uncookedVertexes;
260 QVector<quint32> m_uncookedIndexes;
261
262 QSGGradientCache::GradientDesc m_fillGradient;
263 QSGTextureProvider *m_textureProvider = nullptr;
264 QVector2D m_boundsSize;
265 QSGTransform m_fillTransform;
266 QColor m_color = Qt::white;
267 QGradient::Type m_gradientType = QGradient::NoGradient;
268 float m_debug = 0.0f;
269};
270
271QT_END_NAMESPACE
272
273#endif // QSGCURVEFILLNODE_P_H
274

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtdeclarative/src/quick/scenegraph/qsgcurvefillnode_p.h