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
qquickshadereffectmesh.cpp
Go to the documentation of this file.
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
// Qt-Security score:significant reason:default
4
5
#
include
"qquickshadereffectmesh_p.h"
6
#
include
<
QtQuick
/
qsggeometry
.
h
>
7
#
include
"qquickshadereffect_p.h"
8
#
include
"qquickscalegrid_p_p.h"
9
#
include
"qquickborderimage_p_p.h"
10
#
include
<
QtQuick
/
private
/
qsgbasicinternalimagenode_p
.
h
>
11
12
QT_BEGIN_NAMESPACE
13
14
static
const
char
qt_position_attribute_name
[] =
"qt_Vertex"
;
15
static
const
char
qt_texcoord_attribute_name
[] =
"qt_MultiTexCoord0"
;
16
17
const
char
*
qtPositionAttributeName
()
18
{
19
return
qt_position_attribute_name
;
20
}
21
22
const
char
*
qtTexCoordAttributeName
()
23
{
24
return
qt_texcoord_attribute_name
;
25
}
26
27
QQuickShaderEffectMesh::QQuickShaderEffectMesh(QObject *parent)
28
: QObject(parent)
29
{
30
}
31
32
QQuickShaderEffectMesh::QQuickShaderEffectMesh(QObjectPrivate &dd, QObject *parent)
33
: QObject(dd, parent)
34
{
35
}
36
37
/*!
38
\qmltype GridMesh
39
\nativetype QQuickGridMesh
40
\inqmlmodule QtQuick
41
\since 5.0
42
\ingroup qtquick-effects
43
\brief Defines a mesh with vertices arranged in a grid.
44
45
GridMesh defines a rectangular mesh consisting of vertices arranged in an
46
evenly spaced grid. It is used to generate \l{QSGGeometry}{geometry}.
47
The grid resolution is specified with the \l resolution property.
48
*/
49
50
QQuickGridMesh::QQuickGridMesh(QObject *parent)
51
: QQuickShaderEffectMesh(parent)
52
, m_resolution(1, 1)
53
{
54
}
55
56
bool
QQuickGridMesh::validateAttributes(
const
QList<QByteArray> &attributes,
int
*posIndex)
57
{
58
const
int
attrCount = attributes.size();
59
int
positionIndex = attributes.indexOf(qtPositionAttributeName());
60
int
texCoordIndex = attributes.indexOf(qtTexCoordAttributeName());
61
62
switch
(attrCount) {
63
case
0:
64
m_log = QLatin1String(
"Error: No attributes specified."
);
65
return
false
;
66
case
1:
67
if
(positionIndex != 0) {
68
m_log = QLatin1String(
"Error: Missing \'"
) + QLatin1String(qtPositionAttributeName())
69
+ QLatin1String(
"\' attribute.\n"
);
70
return
false
;
71
}
72
break
;
73
case
2:
74
if
(positionIndex == -1 || texCoordIndex == -1) {
75
m_log.clear();
76
if
(positionIndex == -1) {
77
m_log = QLatin1String(
"Error: Missing \'"
) + QLatin1String(qtPositionAttributeName())
78
+ QLatin1String(
"\' attribute.\n"
);
79
}
80
if
(texCoordIndex == -1) {
81
m_log += QLatin1String(
"Error: Missing \'"
) + QLatin1String(qtTexCoordAttributeName())
82
+ QLatin1String(
"\' attribute.\n"
);
83
}
84
return
false
;
85
}
86
break
;
87
default
:
88
m_log = QLatin1String(
"Error: Too many attributes specified."
);
89
return
false
;
90
}
91
92
if
(posIndex)
93
*posIndex = positionIndex;
94
95
return
true
;
96
}
97
98
QSGGeometry *QQuickGridMesh::updateGeometry(QSGGeometry *geometry,
int
attrCount,
int
posIndex,
99
const
QRectF &srcRect,
const
QRectF &dstRect)
100
{
101
int
vmesh = m_resolution.height();
102
int
hmesh = m_resolution.width();
103
104
if
(!geometry) {
105
Q_ASSERT(attrCount == 1 || attrCount == 2);
106
geometry =
new
QSGGeometry(attrCount == 1
107
? QSGGeometry::defaultAttributes_Point2D()
108
: QSGGeometry::defaultAttributes_TexturedPoint2D(),
109
(vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2),
110
QSGGeometry::UnsignedShortType);
111
112
}
else
{
113
geometry->allocate((vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2));
114
}
115
116
QSGGeometry::Point2D *vdata =
static_cast
<QSGGeometry::Point2D *>(geometry->vertexData());
117
118
for
(
int
iy = 0; iy <= vmesh; ++iy) {
119
float
fy = iy /
float
(vmesh);
120
float
y =
float
(dstRect.top()) + fy *
float
(dstRect.height());
121
float
ty =
float
(srcRect.top()) + fy *
float
(srcRect.height());
122
for
(
int
ix = 0; ix <= hmesh; ++ix) {
123
float
fx = ix /
float
(hmesh);
124
for
(
int
ia = 0; ia < attrCount; ++ia) {
125
if
(ia == posIndex) {
126
vdata->x =
float
(dstRect.left()) + fx *
float
(dstRect.width());
127
vdata->y = y;
128
++vdata;
129
}
else
{
130
vdata->x =
float
(srcRect.left()) + fx *
float
(srcRect.width());
131
vdata->y = ty;
132
++vdata;
133
}
134
}
135
}
136
}
137
138
quint16 *indices = (quint16 *)geometry->indexDataAsUShort();
139
int
i = 0;
140
for
(
int
iy = 0; iy < vmesh; ++iy) {
141
*(indices++) = i + hmesh + 1;
142
for
(
int
ix = 0; ix <= hmesh; ++ix, ++i) {
143
*(indices++) = i + hmesh + 1;
144
*(indices++) = i;
145
}
146
*(indices++) = i - 1;
147
}
148
149
return
geometry;
150
}
151
152
/*!
153
\qmlproperty size QtQuick::GridMesh::resolution
154
155
This property holds the grid resolution. The resolution's width and height
156
specify the number of cells or spacings between vertices horizontally and
157
vertically respectively. The minimum and default is 1x1, which corresponds
158
to four vertices in total, one in each corner.
159
For non-linear vertex transformations, you probably want to set the
160
resolution higher.
161
162
\table
163
\header
164
\li Result
165
\li QML code
166
\li gridmesh.vert
167
\row
168
\li \image declarative-gridmesh.png {Qt logo distorted by GridMesh
169
transformation}
170
\li \qml
171
import QtQuick 2.0
172
173
ShaderEffect {
174
width: 200
175
height: 200
176
mesh: GridMesh {
177
resolution: Qt.size(20, 20)
178
}
179
property variant source: Image {
180
source: "qt-logo.png"
181
sourceSize { width: 200; height: 200 }
182
}
183
vertexShader: "gridmesh.vert"
184
}
185
\endqml
186
\li \badcode
187
#version 440
188
layout(location = 0) in vec4 qt_Vertex;
189
layout(location = 1) in vec2 qt_MultiTexCoord0;
190
layout(location = 0) out vec2 qt_TexCoord0;
191
layout(std140, binding = 0) uniform buf {
192
mat4 qt_Matrix;
193
float qt_Opacity;
194
float width;
195
};
196
void main() {
197
vec4 pos = qt_Vertex;
198
float d = 0.5 * smoothstep(0.0, 1.0, qt_MultiTexCoord0.y);
199
pos.x = width * mix(d, 1.0 - d, qt_MultiTexCoord0.x);
200
gl_Position = qt_Matrix * pos;
201
qt_TexCoord0 = qt_MultiTexCoord0;
202
}
203
\endcode
204
\endtable
205
*/
206
207
void
QQuickGridMesh::setResolution(
const
QSize &res)
208
{
209
if
(res == m_resolution)
210
return
;
211
if
(res.width() < 1 || res.height() < 1) {
212
return
;
213
}
214
m_resolution = res;
215
emit resolutionChanged();
216
emit geometryChanged();
217
}
218
219
QSize QQuickGridMesh::resolution()
const
220
{
221
return
m_resolution;
222
}
223
224
/*!
225
\qmltype BorderImageMesh
226
\nativetype QQuickBorderImageMesh
227
\inqmlmodule QtQuick
228
\since 5.8
229
\ingroup qtquick-effects
230
\brief Defines a mesh with vertices arranged like those of a BorderImage.
231
232
BorderImageMesh provides BorderImage-like capabilities to a ShaderEffect
233
without the need for a potentially costly ShaderEffectSource.
234
235
The following are functionally equivalent:
236
\qml
237
BorderImage {
238
id: borderImage
239
border {
240
left: 10
241
right: 10
242
top: 10
243
bottom: 10
244
}
245
source: "myImage.png"
246
visible: false
247
}
248
ShaderEffectSource {
249
id: effectSource
250
sourceItem: borderImage
251
visible: false
252
}
253
ShaderEffect {
254
property var source: effectSource
255
...
256
}
257
\endqml
258
259
\qml
260
Image {
261
id: image
262
source: "myImage.png"
263
visible: false
264
}
265
ShaderEffect {
266
property var source: image
267
mesh: BorderImageMesh {
268
border {
269
left: 10
270
right: 10
271
top: 10
272
bottom: 10
273
}
274
size: image.sourceSize
275
}
276
...
277
}
278
\endqml
279
280
But the BorderImageMesh version can typically be better optimized.
281
*/
282
QQuickBorderImageMesh
::QQuickBorderImageMesh(QObject *parent)
283
: QQuickShaderEffectMesh(parent), m_border(
new
QQuickScaleGrid(
this
)),
284
m_horizontalTileMode(
QQuickBorderImageMesh
::
Stretch
),
285
m_verticalTileMode(
QQuickBorderImageMesh
::
Stretch
)
286
{
287
}
288
289
bool
QQuickBorderImageMesh
::
validateAttributes
(
const
QList<QByteArray> &attributes,
int
*posIndex)
290
{
291
Q_UNUSED(attributes);
292
Q_UNUSED(posIndex);
293
return
true
;
294
}
295
296
QSGGeometry *
QQuickBorderImageMesh
::
updateGeometry
(QSGGeometry *geometry,
int
attrCount,
int
posIndex,
297
const
QRectF &srcRect,
const
QRectF &rect)
298
{
299
Q_UNUSED(attrCount);
300
Q_UNUSED(posIndex);
301
302
QRectF innerSourceRect;
303
QRectF targetRect;
304
QRectF innerTargetRect;
305
QRectF subSourceRect;
306
307
QQuickBorderImagePrivate::calculateRects(m_border, m_size, rect.size(), m_horizontalTileMode, m_verticalTileMode,
308
1, &targetRect, &innerTargetRect, &innerSourceRect, &subSourceRect);
309
310
QRectF sourceRect = srcRect;
311
QRectF modifiedInnerSourceRect(sourceRect.x() + innerSourceRect.x() * sourceRect.width(),
312
sourceRect.y() + innerSourceRect.y() * sourceRect.height(),
313
innerSourceRect.width() * sourceRect.width(),
314
innerSourceRect.height() * sourceRect.height());
315
316
geometry = QSGBasicInternalImageNode::updateGeometry(targetRect, innerTargetRect, sourceRect,
317
modifiedInnerSourceRect, subSourceRect, geometry);
318
319
return
geometry;
320
}
321
322
/*!
323
\qmlpropertygroup QtQuick::BorderImageMesh::border
324
\qmlproperty int QtQuick::BorderImageMesh::border.left
325
\qmlproperty int QtQuick::BorderImageMesh::border.right
326
\qmlproperty int QtQuick::BorderImageMesh::border.top
327
\qmlproperty int QtQuick::BorderImageMesh::border.bottom
328
329
The 4 border lines (2 horizontal and 2 vertical) break the image into 9 sections,
330
as shown below:
331
332
\image declarative-scalegrid.png {Red rounded rectangle divided into
333
9 numbered regions by dashed border lines}
334
335
Each border line (left, right, top, and bottom) specifies an offset in pixels
336
from the respective edge of the mesh. By default, each border line has
337
a value of 0.
338
339
For example, the following definition sets the bottom line 10 pixels up from
340
the bottom of the mesh:
341
342
\qml
343
BorderImageMesh {
344
border.bottom: 10
345
// ...
346
}
347
\endqml
348
*/
349
QQuickScaleGrid *
QQuickBorderImageMesh
::
border
()
const
350
{
351
return
m_border;
352
}
353
354
/*!
355
\qmlproperty size QtQuick::BorderImageMesh::size
356
357
The base size of the mesh. This generally corresponds to the \l {Image::}{sourceSize}
358
of the image being used by the ShaderEffect.
359
*/
360
QSize
QQuickBorderImageMesh
::size()
const
361
{
362
return
m_size;
363
}
364
365
void
QQuickBorderImageMesh
::
setSize
(
const
QSize &size)
366
{
367
if
(size == m_size)
368
return
;
369
m_size = size;
370
Q_EMIT sizeChanged();
371
Q_EMIT geometryChanged();
372
}
373
374
/*!
375
\qmlproperty enumeration QtQuick::BorderImageMesh::horizontalTileMode
376
\qmlproperty enumeration QtQuick::BorderImageMesh::verticalTileMode
377
378
This property describes how to repeat or stretch the middle parts of an image.
379
380
\list
381
\li BorderImage.Stretch - Scales the image to fit to the available area.
382
\li BorderImage.Repeat - Tile the image until there is no more space. May crop the last image.
383
\li BorderImage.Round - Like Repeat, but scales the images down to ensure that the last image is not cropped.
384
\endlist
385
386
The default tile mode for each property is BorderImage.Stretch.
387
*/
388
389
QQuickBorderImageMesh
::
TileMode
QQuickBorderImageMesh
::
horizontalTileMode
()
const
390
{
391
return
m_horizontalTileMode;
392
}
393
394
void
QQuickBorderImageMesh
::
setHorizontalTileMode
(
TileMode
t)
395
{
396
if
(t == m_horizontalTileMode)
397
return
;
398
m_horizontalTileMode = t;
399
Q_EMIT horizontalTileModeChanged();
400
Q_EMIT geometryChanged();
401
}
402
403
QQuickBorderImageMesh
::
TileMode
QQuickBorderImageMesh
::
verticalTileMode
()
const
404
{
405
return
m_verticalTileMode;
406
}
407
408
void
QQuickBorderImageMesh
::
setVerticalTileMode
(
TileMode
t)
409
{
410
if
(t == m_verticalTileMode)
411
return
;
412
413
m_verticalTileMode = t;
414
Q_EMIT verticalTileModeChanged();
415
Q_EMIT geometryChanged();
416
}
417
418
QT_END_NAMESPACE
419
420
#
include
"moc_qquickshadereffectmesh_p.cpp"
QQuickBorderImageMesh
Definition
qquickshadereffectmesh_p.h:92
QQuickBorderImageMesh::validateAttributes
bool validateAttributes(const QList< QByteArray > &attributes, int *posIndex) override
Definition
qquickshadereffectmesh.cpp:289
QQuickBorderImageMesh::verticalTileMode
TileMode verticalTileMode() const
Definition
qquickshadereffectmesh.cpp:403
QQuickBorderImageMesh::setSize
void setSize(const QSize &size)
Definition
qquickshadereffectmesh.cpp:365
QQuickBorderImageMesh::border
QQuickScaleGrid * border() const
Definition
qquickshadereffectmesh.cpp:349
QQuickBorderImageMesh::setVerticalTileMode
void setVerticalTileMode(TileMode)
Definition
qquickshadereffectmesh.cpp:408
QQuickBorderImageMesh::TileMode
TileMode
Definition
qquickshadereffectmesh_p.h:112
QQuickBorderImageMesh::Stretch
@ Stretch
Definition
qquickshadereffectmesh_p.h:112
QQuickBorderImageMesh::horizontalTileMode
TileMode horizontalTileMode() const
\qmlproperty enumeration QtQuick::BorderImageMesh::horizontalTileMode \qmlproperty enumeration QtQuic...
Definition
qquickshadereffectmesh.cpp:389
QQuickBorderImageMesh::updateGeometry
QSGGeometry * updateGeometry(QSGGeometry *geometry, int attrCount, int posIndex, const QRectF &srcRect, const QRectF &rect) override
Definition
qquickshadereffectmesh.cpp:296
QQuickBorderImageMesh::setHorizontalTileMode
void setHorizontalTileMode(TileMode)
Definition
qquickshadereffectmesh.cpp:394
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qt_texcoord_attribute_name
static const char qt_texcoord_attribute_name[]
Definition
qquickshadereffectmesh.cpp:15
qtTexCoordAttributeName
const char * qtTexCoordAttributeName()
Definition
qquickshadereffectmesh.cpp:22
qt_position_attribute_name
static QT_BEGIN_NAMESPACE const char qt_position_attribute_name[]
Definition
qquickshadereffectmesh.cpp:14
qtPositionAttributeName
const char * qtPositionAttributeName()
Definition
qquickshadereffectmesh.cpp:17
qtdeclarative
src
quick
items
qquickshadereffectmesh.cpp
Generated on
for Qt by
1.18.0