Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qsgcurvestrokenode.cpp
Go to the documentation of this file.
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
// Qt-Security score:significant reason:default
4
5
#
include
"qsgcurvestrokenode_p.h"
6
#
include
"qsgcurvestrokenode_p_p.h"
7
8
QT_BEGIN_NAMESPACE
9
10
/*!
11
\class QSGCurveStrokeNode
12
\inmodule QtQuick
13
\internal
14
*/
15
QSGCurveStrokeNode::QSGCurveStrokeNode()
16
{
17
setFlag(OwnsGeometry,
true
);
18
qsgnode_set_description(
this
, QLatin1StringView(
"curve stroke"
));
19
setGeometry(
new
QSGGeometry(attributes(), 0, 0));
20
// defer updateMaterial() until later
21
}
22
23
void
QSGCurveStrokeNode::QSGCurveStrokeNode::updateMaterial()
24
{
25
const
bool
expandingInVertexShader = m_cosmetic || expandingStrokeEnabled();
26
m_material.reset(
new
QSGCurveStrokeMaterial(
this
, expandingInVertexShader));
27
setMaterial(m_material.data());
28
}
29
30
// Take the start, control and end point of a curve and return the points A, B, C
31
// representing the curve as Q(s) = A*s*s + B*s + C
32
std::array<QVector2D, 3> QSGCurveStrokeNode::curveABC(
const
std::array<QVector2D, 3> &p)
33
{
34
QVector2D a = p[0] - 2*p[1] + p[2];
35
QVector2D b = 2*p[1] - 2*p[0];
36
QVector2D c = p[0];
37
38
return
{a, b, c};
39
}
40
41
/*!
42
Append a triangle with \a vtx corners within which the fragment shader will
43
draw the visible part of a quadratic curve from ctl[0] to ctl[2] with
44
control point ctl[1] (AKA a quadratic Bézier curve with 3 control points).
45
The \a normal vectors are used in the vertex shader to expand the triangle
46
according to its stroke width: therefore, it's ok for the triangle to be
47
degenerate, and get expanded to size in the vertex shader. Normals are
48
usually unit vectors, but it's also ok for some to have larger magnitudes,
49
to handle the case when miter corners need to be extended proportionally
50
farther as stroke width increases.
51
*/
52
void
QSGCurveStrokeNode::appendTriangle(
const
std::array<QVector2D, 3> &vtx,
53
const
std::array<QVector2D, 3> &ctl,
54
const
std::array<QVector2D, 3> &normal,
55
const
std::array<
float
, 3> &extrusions)
56
{
57
auto
abc = curveABC(ctl);
58
59
int
currentVertex = m_uncookedVertexes.count();
60
61
for
(
int
i = 0; i < 3; ++i) {
62
m_uncookedVertexes.append( { vtx[i].x(), vtx[i].y(),
63
abc[0].x(), abc[0].y(), abc[1].x(), abc[1].y(), abc[2].x(), abc[2].y(),
64
normal[i].x(), normal[i].y(), extrusions[i] } );
65
}
66
m_uncookedIndexes << currentVertex << currentVertex + 1 << currentVertex + 2;
67
}
68
69
/*!
70
Append a triangle with \a vtx corners within which the fragment shader will
71
draw the visible part of a line from ctl[0] to ctl[2].
72
The \a normal vectors are used in the vertex shader to expand the triangle
73
according to its stroke width: therefore, it's ok for the triangle to be
74
degenerate, and get expanded to size in the vertex shader. Normals are
75
usually unit vectors, but it's also ok for some to have larger magnitudes,
76
to handle the case when miter corners need to be extended proportionally
77
farther as stroke width increases.
78
*/
79
void
QSGCurveStrokeNode::appendTriangle(
const
std::array<QVector2D, 3> &vtx,
80
const
std::array<QVector2D, 2> &ctl,
81
const
std::array<QVector2D, 3> &normal,
82
const
std::array<
float
, 3> &extrusions)
83
{
84
// We could reduce this to a linear equation by setting A to (0,0).
85
// However, then we cannot use the cubic solution and need an additional
86
// code path in the shader. The following formulation looks more complicated
87
// but allows to always use the cubic solution.
88
auto
A = ctl[1] - ctl[0];
89
auto
B = QVector2D(0., 0.);
90
auto
C = ctl[0];
91
92
int
currentVertex = m_uncookedVertexes.count();
93
94
for
(
int
i = 0; i < 3; ++i) {
95
m_uncookedVertexes.append( { vtx[i].x(), vtx[i].y(),
96
A.x(), A.y(), B.x(), B.y(), C.x(), C.y(),
97
normal[i].x(), normal[i].y(), extrusions[i] } );
98
}
99
m_uncookedIndexes << currentVertex << currentVertex + 1 << currentVertex + 2;
100
}
101
102
void
QSGCurveStrokeNode::cookGeometry()
103
{
104
updateMaterial();
// by now, setCosmeticStroke has been called if necessary
105
QSGGeometry *g = geometry();
106
if
(g->indexType() != QSGGeometry::UnsignedIntType) {
107
g =
new
QSGGeometry(attributes(),
108
m_uncookedVertexes.size(),
109
m_uncookedIndexes.size(),
110
QSGGeometry::UnsignedIntType);
111
setGeometry(g);
112
}
else
{
113
g->allocate(m_uncookedVertexes.size(), m_uncookedIndexes.size());
114
}
115
116
g->setDrawingMode(QSGGeometry::DrawTriangles);
117
memcpy(g->vertexData(),
118
m_uncookedVertexes.constData(),
119
g->vertexCount() * g->sizeOfVertex());
120
memcpy(g->indexData(),
121
m_uncookedIndexes.constData(),
122
g->indexCount() * g->sizeOfIndex());
123
124
m_uncookedIndexes.clear();
125
m_uncookedIndexes.squeeze();
126
m_uncookedVertexes.clear();
127
m_uncookedVertexes.squeeze();
128
}
129
130
const
QSGGeometry::AttributeSet &QSGCurveStrokeNode::attributes()
131
{
132
static
QSGGeometry::Attribute data[] = {
133
QSGGeometry::Attribute::createWithAttributeType(0, 2, QSGGeometry::FloatType, QSGGeometry::PositionAttribute),
//vertexCoord
134
QSGGeometry::Attribute::createWithAttributeType(1, 2, QSGGeometry::FloatType, QSGGeometry::UnknownAttribute),
//A
135
QSGGeometry::Attribute::createWithAttributeType(2, 2, QSGGeometry::FloatType, QSGGeometry::UnknownAttribute),
//B
136
QSGGeometry::Attribute::createWithAttributeType(3, 2, QSGGeometry::FloatType, QSGGeometry::UnknownAttribute),
//C
137
QSGGeometry::Attribute::createWithAttributeType(4, 3, QSGGeometry::FloatType, QSGGeometry::UnknownAttribute),
//normalExt
138
};
139
static
QSGGeometry::AttributeSet attrs = { 5,
sizeof
(StrokeVertex), data };
140
return
attrs;
141
}
142
143
// TODO remove when we consider the expanding-stroke shader to be stable for full-time use
144
bool
QSGCurveStrokeNode::expandingStrokeEnabled()
145
{
146
static
const
bool
ret = qEnvironmentVariableIntValue(
"QT_QUICKSHAPES_STROKE_EXPANDING"
);
147
return
ret;
148
}
149
150
QT_END_NAMESPACE
qtdeclarative
src
quick
scenegraph
qsgcurvestrokenode.cpp
Generated on
for Qt by
1.18.0