1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQuick module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40
41#include "qsgsimpletexturenode.h"
42#include <private/qsgnode_p.h>
43
44QT_BEGIN_NAMESPACE
45
46class QSGSimpleTextureNodePrivate : public QSGGeometryNodePrivate
47{
48public:
49 QSGSimpleTextureNodePrivate()
50 : texCoordMode(QSGSimpleTextureNode::NoTransform)
51 , isAtlasTexture(false)
52 , ownsTexture(false)
53 {}
54
55 QRectF sourceRect;
56 QSGSimpleTextureNode::TextureCoordinatesTransformMode texCoordMode;
57 uint isAtlasTexture : 1;
58 uint ownsTexture : 1;
59};
60
61static void qsgsimpletexturenode_update(QSGGeometry *g,
62 QSGTexture *texture,
63 const QRectF &rect,
64 QRectF sourceRect,
65 QSGSimpleTextureNode::TextureCoordinatesTransformMode texCoordMode)
66{
67 if (!texture)
68 return;
69
70 if (!sourceRect.width() || !sourceRect.height()) {
71 QSize ts = texture->textureSize();
72 sourceRect = QRectF(0, 0, ts.width(), ts.height());
73 }
74
75 // Maybe transform the texture coordinates
76 if (texCoordMode.testFlag(flag: QSGSimpleTextureNode::MirrorHorizontally)) {
77 float tmp = sourceRect.left();
78 sourceRect.setLeft(sourceRect.right());
79 sourceRect.setRight(tmp);
80 }
81 if (texCoordMode.testFlag(flag: QSGSimpleTextureNode::MirrorVertically)) {
82 float tmp = sourceRect.top();
83 sourceRect.setTop(sourceRect.bottom());
84 sourceRect.setBottom(tmp);
85 }
86
87 QSGGeometry::updateTexturedRectGeometry(g, rect, sourceRect: texture->convertToNormalizedSourceRect(rect: sourceRect));
88}
89
90/*!
91 \class QSGSimpleTextureNode
92 \brief The QSGSimpleTextureNode class is provided for convenience to easily draw
93 textured content using the QML scene graph.
94
95 \inmodule QtQuick
96
97 \warning The simple texture node class must have a texture before being
98 added to the scene graph to be rendered.
99
100 \warning This utility class is only functional when running with the default
101 or software backends of the Qt Quick scenegraph. As an alternative, prefer
102 using QSGImageNode via QQuickWindow::createImageNode() or
103 QSGEngine::createImageNode().
104
105 \deprecated
106*/
107
108/*!
109 Constructs a new simple texture node
110 */
111QSGSimpleTextureNode::QSGSimpleTextureNode()
112 : QSGGeometryNode(*new QSGSimpleTextureNodePrivate)
113 , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
114{
115 setGeometry(&m_geometry);
116 setMaterial(&m_material);
117 setOpaqueMaterial(&m_opaque_material);
118 m_material.setMipmapFiltering(QSGTexture::None);
119 m_opaque_material.setMipmapFiltering(QSGTexture::None);
120#ifdef QSG_RUNTIME_DESCRIPTION
121 qsgnode_set_description(node: this, description: QLatin1String("simpletexture"));
122#endif
123}
124
125/*!
126 Destroys the texture node
127 */
128QSGSimpleTextureNode::~QSGSimpleTextureNode()
129{
130 Q_D(QSGSimpleTextureNode);
131 if (d->ownsTexture)
132 delete m_material.texture();
133}
134
135/*!
136 Sets the filtering to be used for this texture node to \a filtering.
137
138 For smooth scaling, use QSGTexture::Linear; for normal scaling, use
139 QSGTexture::Nearest.
140 */
141void QSGSimpleTextureNode::setFiltering(QSGTexture::Filtering filtering)
142{
143 if (m_material.filtering() == filtering)
144 return;
145
146 m_material.setFiltering(filtering);
147 m_opaque_material.setFiltering(filtering);
148 markDirty(bits: DirtyMaterial);
149}
150
151
152/*!
153 Returns the filtering currently set on this texture node
154 */
155QSGTexture::Filtering QSGSimpleTextureNode::filtering() const
156{
157 return m_material.filtering();
158}
159
160
161/*!
162 Sets the target rect of this texture node to \a r.
163 */
164void QSGSimpleTextureNode::setRect(const QRectF &r)
165{
166 if (m_rect == r)
167 return;
168 m_rect = r;
169 Q_D(QSGSimpleTextureNode);
170 qsgsimpletexturenode_update(g: &m_geometry, texture: texture(), rect: m_rect, sourceRect: d->sourceRect, texCoordMode: d->texCoordMode);
171 markDirty(bits: DirtyGeometry);
172}
173
174/*!
175 \fn void QSGSimpleTextureNode::setRect(qreal x, qreal y, qreal w, qreal h)
176 \overload
177
178 Sets the rectangle of this texture node to begin at (\a x, \a y) and have
179 width \a w and height \a h.
180 */
181
182/*!
183 Returns the target rect of this texture node.
184 */
185QRectF QSGSimpleTextureNode::rect() const
186{
187 return m_rect;
188}
189
190/*!
191 Sets the source rect of this texture node to \a r.
192
193 \since 5.5
194 */
195void QSGSimpleTextureNode::setSourceRect(const QRectF &r)
196{
197 Q_D(QSGSimpleTextureNode);
198 if (d->sourceRect == r)
199 return;
200 d->sourceRect = r;
201 qsgsimpletexturenode_update(g: &m_geometry, texture: texture(), rect: m_rect, sourceRect: d->sourceRect, texCoordMode: d->texCoordMode);
202 markDirty(bits: DirtyGeometry);
203}
204
205/*!
206 \fn void QSGSimpleTextureNode::setSourceRect(qreal x, qreal y, qreal w, qreal h)
207 \overload
208 \since 5.5
209
210 Sets the rectangle of this texture node to show its texture from (\a x, \a y) and
211 have width \a w and height \a h relatively to the QSGTexture::textureSize.
212 */
213
214/*!
215 Returns the source rect of this texture node.
216
217 \since 5.5
218 */
219QRectF QSGSimpleTextureNode::sourceRect() const
220{
221 Q_D(const QSGSimpleTextureNode);
222 return d->sourceRect;
223}
224
225/*!
226 Sets the texture of this texture node to \a texture.
227
228 Use setOwnsTexture() to set whether the node should take
229 ownership of the texture. By default, the node does not
230 take ownership.
231
232 \warning A texture node must have a texture before being added
233 to the scenegraph to be rendered.
234 */
235void QSGSimpleTextureNode::setTexture(QSGTexture *texture)
236{
237 Q_ASSERT(texture);
238 Q_D(QSGSimpleTextureNode);
239 if (d->ownsTexture)
240 delete m_material.texture();
241 m_material.setTexture(texture);
242 m_opaque_material.setTexture(texture);
243 qsgsimpletexturenode_update(g: &m_geometry, texture, rect: m_rect, sourceRect: d->sourceRect, texCoordMode: d->texCoordMode);
244
245 DirtyState dirty = DirtyMaterial;
246 // It would be tempting to skip the extra bit here and instead use
247 // m_material.texture to get the old state, but that texture could
248 // have been deleted in the mean time.
249 bool wasAtlas = d->isAtlasTexture;
250 d->isAtlasTexture = texture->isAtlasTexture();
251 if (wasAtlas || d->isAtlasTexture)
252 dirty |= DirtyGeometry;
253 markDirty(bits: dirty);
254}
255
256
257
258/*!
259 Returns the texture for this texture node
260 */
261QSGTexture *QSGSimpleTextureNode::texture() const
262{
263 return m_material.texture();
264}
265
266/*!
267 \enum QSGSimpleTextureNode::TextureCoordinatesTransformFlag
268
269 The TextureCoordinatesTransformFlag enum is used to specify the
270 mode used to generate texture coordinates for a textured quad.
271
272 \value NoTransform Texture coordinates are oriented with window coordinates
273 i.e. with origin at top-left.
274
275 \value MirrorHorizontally Texture coordinates are inverted in the horizontal axis with
276 respect to window coordinates
277
278 \value MirrorVertically Texture coordinates are inverted in the vertical axis with
279 respect to window coordinates
280 */
281
282/*!
283 Sets the method used to generate texture coordinates to \a mode. This can be used to obtain
284 correct orientation of the texture. This is commonly needed when using a third party OpenGL
285 library to render to texture as OpenGL has an inverted y-axis relative to Qt Quick.
286
287 \sa textureCoordinatesTransform()
288 */
289void QSGSimpleTextureNode::setTextureCoordinatesTransform(QSGSimpleTextureNode::TextureCoordinatesTransformMode mode)
290{
291 Q_D(QSGSimpleTextureNode);
292 if (d->texCoordMode == mode)
293 return;
294 d->texCoordMode = mode;
295 qsgsimpletexturenode_update(g: &m_geometry, texture: texture(), rect: m_rect, sourceRect: d->sourceRect, texCoordMode: d->texCoordMode);
296 markDirty(bits: DirtyMaterial);
297}
298
299/*!
300 Returns the mode used to generate texture coordinates for this node.
301
302 \sa setTextureCoordinatesTransform()
303 */
304QSGSimpleTextureNode::TextureCoordinatesTransformMode QSGSimpleTextureNode::textureCoordinatesTransform() const
305{
306 Q_D(const QSGSimpleTextureNode);
307 return d->texCoordMode;
308}
309
310/*!
311 Sets whether the node takes ownership of the texture to \a owns.
312
313 By default, the node does not take ownership of the texture.
314
315 \sa setTexture()
316
317 \since 5.4
318 */
319void QSGSimpleTextureNode::setOwnsTexture(bool owns)
320{
321 Q_D(QSGSimpleTextureNode);
322 d->ownsTexture = owns;
323}
324
325/*!
326 Returns \c true if the node takes ownership of the texture; otherwise returns \c false.
327
328 \since 5.4
329 */
330bool QSGSimpleTextureNode::ownsTexture() const
331{
332 Q_D(const QSGSimpleTextureNode);
333 return d->ownsTexture;
334}
335
336QT_END_NAMESPACE
337

source code of qtdeclarative/src/quick/scenegraph/util/qsgsimpletexturenode.cpp