1/****************************************************************************
2**
3** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D 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#include "qabstracttexture.h"
41#include "qabstracttexture_p.h"
42#include <Qt3DRender/qabstracttextureimage.h>
43#include <Qt3DCore/qpropertyupdatedchange.h>
44#include <Qt3DCore/qpropertynodeaddedchange.h>
45#include <Qt3DCore/qpropertynoderemovedchange.h>
46
47QT_BEGIN_NAMESPACE
48
49using namespace Qt3DCore;
50
51namespace Qt3DRender {
52
53QAbstractTexturePrivate::QAbstractTexturePrivate()
54 : QNodePrivate()
55 , m_target(QAbstractTexture::Target2D)
56 , m_format(QAbstractTexture::Automatic)
57 , m_width(1)
58 , m_height(1)
59 , m_depth(1)
60 , m_autoMipMap(false)
61 , m_minFilter(QAbstractTexture::Nearest)
62 , m_magFilter(QAbstractTexture::Nearest)
63 , m_status(QAbstractTexture::None)
64 , m_maximumAnisotropy(1.0f)
65 , m_comparisonFunction(QAbstractTexture::CompareLessEqual)
66 , m_comparisonMode(QAbstractTexture::CompareNone)
67 , m_layers(1)
68 , m_samples(1)
69 , m_mipmapLevels(1)
70 , m_sharedTextureId(-1)
71 , m_handleType(QAbstractTexture::NoHandle)
72 , m_handle(QVariant())
73{
74}
75
76QTextureGeneratorPtr QAbstractTexturePrivate::dataFunctor() const
77{
78 return m_dataFunctor;
79}
80
81void QAbstractTexturePrivate::setDataFunctor(const QTextureGeneratorPtr &generator)
82{
83 if (generator != m_dataFunctor) {
84 m_dataFunctor = generator;
85 update();
86 }
87}
88
89void QAbstractTexturePrivate::setStatus(QAbstractTexture::Status status)
90{
91 Q_Q(QAbstractTexture);
92 if (m_status != status) {
93 m_status = status;
94 const bool blocked = q->blockNotifications(block: true);
95 q->statusChanged(status);
96 q->blockNotifications(block: blocked);
97 }
98}
99
100void QAbstractTexturePrivate::setHandle(const QVariant &handle)
101{
102 Q_Q(QAbstractTexture);
103 if (m_handle != handle) {
104 m_handle = handle;
105 const bool blocked = q->blockNotifications(block: true);
106 emit q->handleChanged(handle);
107 q->blockNotifications(block: blocked);
108 }
109}
110
111void QAbstractTexturePrivate::setHandleType(QAbstractTexture::HandleType type)
112{
113 Q_Q(QAbstractTexture);
114 if (m_handleType != type) {
115 m_handleType = type;
116 const bool blocked = q->blockNotifications(block: true);
117 emit q->handleTypeChanged(handleType: type);
118 q->blockNotifications(block: blocked);
119 }
120}
121
122/*!
123 \class Qt3DRender::QAbstractTexture
124 \inmodule Qt3DRender
125 \since 5.5
126 \brief A base class to be used to provide textures.
127
128 The QAbstractTexture class shouldn't be used directly but rather through
129 one of its subclasses. Each subclass implements a given texture target (2D,
130 2DArray, 3D, CubeMap ...) Each subclass provides a set of functors for each
131 layer, cube map face and mipmap level. In turn the backend uses those
132 functor to properly fill a corresponding OpenGL texture with data. It is
133 expected the functor does as minimal processing as possible so as not
134 to slow down textures generation and upload. If the content of a texture is
135 the result of a slow procedural generation process, it is recommended not
136 to implement this directly in a functor.
137
138 All textures are unique. If you instantiate twice the same texture this
139 will create 2 identical textures on the GPU, no sharing will take place.
140 */
141
142/*!
143 \qmltype AbstractTexture
144 \instantiates Qt3DRender::QAbstractTexture
145 \inqmlmodule Qt3D.Render
146 \since 5.5
147 \brief A base class to be used to provide textures.
148
149 The AbstractTexture class shouldn't be used directly but rather through one
150 of its subclasses. Each subclass implements a given texture target (2D,
151 2DArray, 3D, CubeMap ...) Each subclass provides a set of functors for each
152 layer, cube map face and mipmap level. In turn the backend uses those
153 functor to properly fill a corresponding OpenGL texture with data. It is
154 expected the functor does as minimal processing as possible so as not to
155 slow down textures generation and upload. If the content of a texture is
156 the result of a slow procedural generation process, it is recommended not
157 to implement this directly in a functor.
158
159 All textures are unique. If you instantiate twice the same texture this
160 will create 2 identical textures on the GPU, no sharing will take place.
161 */
162
163/*!
164 \enum Qt3DRender::QAbstractTexture::CubeMapFace
165
166 This enum identifies the faces of a cube map texture
167 \value CubeMapPositiveX Specify the positive X face of a cube map
168 \value CubeMapNegativeX Specify the negative X face of a cube map
169 \value CubeMapPositiveY Specify the positive Y face of a cube map
170 \value CubeMapNegativeY Specify the negative Y face of a cube map
171 \value CubeMapPositiveZ Specify the positive Z face of a cube map
172 \value CubeMapNegativeZ Specify the negative Z face of a cube map
173 \value AllFaces Specify all the faces of a cube map
174
175 \note AllFaces should only be used when a behavior needs to be applied to
176 all the faces of a cubemap. This is the case for example when using a cube
177 map as a texture attachment. Using AllFaces in the attachment specfication
178 would result in all faces being bound to the attachment point. On the other
179 hand, if a specific face is specified, the attachment would only be using
180 the specified face.
181*/
182
183/*!
184 \enum Qt3DRender::QAbstractTexture::TextureFormat
185
186 This list describes all possible texture formats
187
188 \value NoFormat
189 GL_NONE
190 \value Automatic
191 automatically_determines_format
192 \value R8_UNorm
193 GL_R8
194 \value RG8_UNorm
195 GL_RG8
196 \value RGB8_UNorm
197 GL_RGB8
198 \value RGBA8_UNorm
199 GL_RGBA8
200 \value R16_UNorm
201 GL_R16
202 \value RG16_UNorm
203 GL_RG16
204 \value RGB16_UNorm
205 GL_RGB16
206 \value RGBA16_UNorm
207 GL_RGBA16
208 \value R8_SNorm
209 GL_R8_SNORM
210 \value RG8_SNorm
211 GL_RG8_SNORM
212 \value RGB8_SNorm
213 GL_RGB8_SNORM
214 \value RGBA8_SNorm
215 GL_RGBA8_SNORM
216 \value R16_SNorm
217 GL_R16_SNORM
218 \value RG16_SNorm
219 GL_RG16_SNORM
220 \value RGB16_SNorm
221 GL_RGB16_SNORM
222 \value RGBA16_SNorm
223 GL_RGBA16_SNORM
224 \value R8U
225 GL_R8UI
226 \value RG8U
227 GL_RG8UI
228 \value RGB8U
229 GL_RGB8UI
230 \value RGBA8U
231 GL_RGBA8UI
232 \value R16U
233 GL_R16UI
234 \value RG16U
235 GL_RG16UI
236 \value RGB16U
237 GL_RGB16UI
238 \value RGBA16U
239 GL_RGBA16UI
240 \value R32U
241 GL_R32UI
242 \value RG32U
243 GL_RG32UI
244 \value RGB32U
245 GL_RGB32UI
246 \value RGBA32U
247 GL_RGBA32UI
248 \value R8I
249 GL_R8I
250 \value RG8I
251 GL_RG8I
252 \value RGB8I
253 GL_RGB8I
254 \value RGBA8I
255 GL_RGBA8I
256 \value R16I
257 GL_R16I
258 \value RG16I
259 GL_RG16I
260 \value RGB16I
261 GL_RGB16I
262 \value RGBA16I
263 GL_RGBA16I
264 \value R32I
265 GL_R32I
266 \value RG32I
267 GL_RG32I
268 \value RGB32I
269 GL_RGB32I
270 \value RGBA32I
271 GL_RGBA32I
272 \value R16F
273 GL_R16F
274 \value RG16F
275 GL_RG16F
276 \value RGB16F
277 GL_RGB16F
278 \value RGBA16F
279 GL_RGBA16F
280 \value R32F
281 GL_R32F
282 \value RG32F
283 GL_RG32F
284 \value RGB32F
285 GL_RGB32F
286 \value RGBA32F
287 GL_RGBA32F
288 \value RGB9E5
289 GL_RGB9_E5
290 \value RG11B10F
291 GL_R11F_G11F_B10F
292 \value RG3B2
293 GL_R3_G3_B2
294 \value R5G6B5
295 GL_RGB565
296 \value RGB5A1
297 GL_RGB5_A1
298 \value RGBA4
299 GL_RGBA4
300 \value RGB10A2
301 GL_RGB10_A2
302 \value RGB10A2U
303 GL_RGB10_A2UI
304 \value D16
305 GL_DEPTH_COMPONENT16
306 \value D24
307 GL_DEPTH_COMPONENT24
308 \value D24S8
309 GL_DEPTH24_STENCIL8
310 \value D32
311 GL_DEPTH_COMPONENT32
312 \value D32F
313 GL_DEPTH_COMPONENT32F
314 \value D32FS8X24
315 GL_DEPTH32F_STENCIL8
316 \value RGB_DXT1
317 GL_COMPRESSED_RGB_S3TC_DXT1_EXT
318 \value RGBA_DXT1
319 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
320 \value RGBA_DXT3
321 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
322 \value RGBA_DXT5
323 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
324 \value R_ATI1N_UNorm
325 GL_COMPRESSED_RED_RGTC1
326 \value R_ATI1N_SNorm
327 GL_COMPRESSED_SIGNED_RED_RGTC1
328 \value RG_ATI2N_UNorm
329 GL_COMPRESSED_RG_RGTC2
330 \value RG_ATI2N_SNorm
331 GL_COMPRESSED_SIGNED_RG_RGTC2
332 \value RGB_BP_UNSIGNED_FLOAT
333 GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB
334 \value RGB_BP_SIGNED_FLOAT
335 GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB
336 \value RGB_BP_UNorm
337 GL_COMPRESSED_RGBA_BPTC_UNORM_ARB
338 \value R11_EAC_UNorm
339 GL_COMPRESSED_R11_EAC
340 \value R11_EAC_SNorm
341 GL_COMPRESSED_SIGNED_R11_EAC
342 \value RG11_EAC_UNorm
343 GL_COMPRESSED_RG11_EAC
344 \value RG11_EAC_SNorm
345 GL_COMPRESSED_SIGNED_RG11_EAC
346 \value RGB8_ETC2
347 GL_COMPRESSED_RGB8_ETC2
348 \value SRGB8_ETC2
349 GL_COMPRESSED_SRGB8_ETC2
350 \value RGB8_PunchThrough_Alpha1_ETC2
351 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
352 \value SRGB8_PunchThrough_Alpha1_ETC2
353 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
354 \value RGBA8_ETC2_EAC
355 GL_COMPRESSED_RGBA8_ETC2_EAC
356 \value SRGB8_Alpha8_ETC2_EAC
357 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
358 \value RGB8_ETC1
359 GL_ETC1_RGB8_OES
360 \value SRGB8
361 GL_SRGB8
362 \value SRGB8_Alpha8
363 GL_SRGB8_ALPHA8
364 \value SRGB_DXT1
365 GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
366 \value SRGB_Alpha_DXT1
367 GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
368 \value SRGB_Alpha_DXT3
369 GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
370 \value SRGB_Alpha_DXT5
371 GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
372 \value SRGB_BP_UNorm
373 GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB
374 \value DepthFormat
375 GL_DEPTH_COMPONENT
376 \value AlphaFormat
377 GL_ALPHA
378 \value RGBFormat
379 GL_RGB
380 \value RGBAFormat
381 GL_RGBA
382 \value LuminanceFormat
383 GL_LUMINANCE
384 \value LuminanceAlphaFormat
385 0x190A
386*/
387
388/*!
389 * The constructor creates a new QAbstractTexture::QAbstractTexture
390 * instance with the specified \a parent.
391 */
392QAbstractTexture::QAbstractTexture(QNode *parent)
393 : QNode(*new QAbstractTexturePrivate, parent)
394{
395}
396
397/*!
398 * The constructor creates a new QAbstractTexture::QAbstractTexture
399 * instance with the specified \a target and \a parent.
400 */
401QAbstractTexture::QAbstractTexture(Target target, QNode *parent)
402 : QNode(*new QAbstractTexturePrivate, parent)
403{
404 d_func()->m_target = target;
405}
406
407/*! \internal */
408QAbstractTexture::~QAbstractTexture()
409{
410}
411
412/*! \internal */
413QAbstractTexture::QAbstractTexture(QAbstractTexturePrivate &dd, QNode *parent)
414 : QNode(dd, parent)
415{
416}
417
418/*!
419 Sets the size of the texture provider to width \a w, height \a h and depth \a d.
420 */
421void QAbstractTexture::setSize(int w, int h, int d)
422{
423 setWidth(w);
424 setHeight(h);
425 setDepth(d);
426}
427
428/*!
429 \property Qt3DRender::QAbstractTexture::width
430
431 Holds the width of the texture provider.
432 */
433/*!
434 \qmlproperty int Qt3DRender::QAbstractTexture::width
435
436 Holds the width of the texture provider.
437 */
438
439/*!
440 Set the width of the texture provider to \a width.
441*/
442void QAbstractTexture::setWidth(int width)
443{
444 Q_D(QAbstractTexture);
445 if (d->m_width != width) {
446 d->m_width = width;
447 emit widthChanged(width);
448 }
449}
450
451/*!
452 \property Qt3DRender::QAbstractTexture::height
453
454 Holds the height of the texture provider.
455 */
456/*!
457 \qmlproperty int Qt3DRender::QAbstractTexture::height
458
459 Holds the height of the texture provider.
460 */
461/*!
462 Set the height to \a height.
463*/
464void QAbstractTexture::setHeight(int height)
465{
466 Q_D(QAbstractTexture);
467 if (d->m_height != height) {
468 d->m_height = height;
469 emit heightChanged(height);
470 }
471}
472
473/*!
474 \property Qt3DRender::QAbstractTexture::depth
475
476 Holds the depth of the texture provider.
477 */
478/*!
479 \qmlproperty int Qt3DRender::QAbstractTexture::depth
480
481 Holds the depth of the texture provider.
482 */
483/*!
484 Set the depth of the texture to \a depth.
485*/
486void QAbstractTexture::setDepth(int depth)
487{
488 Q_D(QAbstractTexture);
489 if (d->m_depth != depth) {
490 d->m_depth = depth;
491 emit depthChanged(depth);
492 }
493}
494
495/*!
496 * Returns the width of the texture
497 */
498int QAbstractTexture::width() const
499{
500 Q_D(const QAbstractTexture);
501 return d->m_width;
502}
503
504/*!
505 * Returns the height of the texture
506 */
507int QAbstractTexture::height() const
508{
509 Q_D(const QAbstractTexture);
510 return d->m_height;
511}
512
513/*!
514 * Returns the depth of the texture
515 */
516int QAbstractTexture::depth() const
517{
518 Q_D(const QAbstractTexture);
519 return d->m_depth;
520}
521
522/*!
523 \property Qt3DRender::QAbstractTexture::layers
524
525 Holds the maximum layer count of the texture provider. By default, the
526 maximum layer count is 1.
527
528 \note this has a meaning only for texture providers that have 3D or
529 array target formats.
530 */
531/*!
532 \qmlproperty int Qt3DRender::QAbstractTexture::layers
533
534 Holds the maximum layer count of the texture provider. By default, the
535 maximum layer count is 1.
536
537 \note this has a meaning only for texture providers that have 3D or
538 array target formats.
539 */
540/*!
541 Set the maximum layer count to \a layers.
542*/
543void QAbstractTexture::setLayers(int layers)
544{
545 Q_D(QAbstractTexture);
546 if (d->m_layers != layers) {
547 d->m_layers = layers;
548 emit layersChanged(layers);
549 }
550}
551
552/*!
553 Returns the maximum number of layers for the texture provider.
554
555 \note this has a meaning only for texture providers that have 3D or
556 array target formats.
557 */
558int QAbstractTexture::layers() const
559{
560 Q_D(const QAbstractTexture);
561 return d->m_layers;
562}
563
564/*!
565 \property Qt3DRender::QAbstractTexture::samples
566
567 Holds the number of samples per texel for the texture provider.
568 By default, the number of samples is 1.
569
570 \note this has a meaning only for texture providers that have multisample
571 formats.
572 */
573/*!
574 \qmlproperty int Qt3DRender::QAbstractTexture::samples
575
576 Holds the number of samples per texel for the texture provider.
577 By default, the number of samples is 1.
578
579 \note this has a meaning only for texture providers that have multisample
580 formats.
581 */
582/*!
583 Set the number of samples per texel to \a samples.
584*/
585void QAbstractTexture::setSamples(int samples)
586{
587 Q_D(QAbstractTexture);
588 if (d->m_samples != samples) {
589 d->m_samples = samples;
590 emit samplesChanged(samples);
591 }
592}
593
594/*!
595 Returns the number of samples per texel for the texture provider.
596
597 \note this has a meaning only for texture providers that have multisample
598 formats.
599 */
600int QAbstractTexture::samples() const
601{
602 Q_D(const QAbstractTexture);
603 return d->m_samples;
604}
605
606/*!
607 \property Qt3DRender::QAbstractTexture::format
608
609 Holds the format of the texture provider.
610 */
611/*!
612 \qmlproperty TextureFormat Qt3DRender::QAbstractTexture::format
613
614 Holds the format of the texture provider.
615 */
616/*!
617 Set the texture format to \a format.
618*/
619void QAbstractTexture::setFormat(TextureFormat format)
620{
621 Q_D(QAbstractTexture);
622 if (d->m_format != format) {
623 d->m_format = format;
624 emit formatChanged(format);
625 }
626}
627
628/*!
629 Returns the texture provider's format.
630 */
631QAbstractTexture::TextureFormat QAbstractTexture::format() const
632{
633 Q_D(const QAbstractTexture);
634 return d->m_format;
635}
636
637/*!
638 \property Qt3DRender::QAbstractTexture::status readonly
639
640 Holds the current status of the texture provider.
641 */
642/*!
643 \qmlproperty Status Qt3DRender::QAbstractTexture::status readonly
644
645 Holds the current status of the texture provider.
646 */
647
648/*!
649 \enum Qt3DRender::QAbstractTexture::Status
650
651 Contains the status of the texture provider.
652
653 \value None
654 \value Loading
655 \value Ready
656 \value Error
657*/
658/*!
659 Set the status of the texture provider to the specified \a status.
660*/
661void QAbstractTexture::setStatus(Status status)
662{
663 Q_D(QAbstractTexture);
664 if (status != d->m_status) {
665 d->m_status = status;
666 const bool blocked = blockNotifications(block: true);
667 emit statusChanged(status);
668 blockNotifications(block: blocked);
669 }
670}
671
672/*!
673 * \internal
674 */
675void QAbstractTexture::setHandle(const QVariant &handle)
676{
677 Q_D(QAbstractTexture);
678 if (d->m_handle != handle) {
679 d->m_handle = handle;
680 const bool blocked = blockNotifications(block: true);
681 emit handleChanged(handle);
682 blockNotifications(block: blocked);
683 }
684}
685
686/*!
687 * \internal
688 */
689void QAbstractTexture::setHandleType(QAbstractTexture::HandleType type)
690{
691 Q_D(QAbstractTexture);
692 if (d->m_handleType != type) {
693 d->m_handleType = type;
694 const bool blocked = blockNotifications(block: true);
695 emit handleTypeChanged(handleType: type);
696 blockNotifications(block: blocked);
697 }
698}
699
700/*!
701 * Returns the current status of the texture provider.
702 */
703QAbstractTexture::Status QAbstractTexture::status() const
704{
705 Q_D(const QAbstractTexture);
706 return d->m_status;
707}
708
709/*!
710 \property Qt3DRender::QAbstractTexture::target readonly
711
712 Holds the target format of the texture provider.
713
714 \note The target format can only be set once.
715 */
716/*!
717 \qmlproperty Target Qt3DRender::QAbstractTexture::target readonly
718
719 Holds the target format of the texture provider.
720
721 \note The target format can only be set once.
722 */
723/*!
724 \enum Qt3DRender::QAbstractTexture::Target
725
726 \value TargetAutomatic
727 Target will be determined by the Qt3D engine
728 \value Target1D
729 GL_TEXTURE_1D
730 \value Target1DArray
731 GL_TEXTURE_1D_ARRAY
732 \value Target2D
733 GL_TEXTURE_2D
734 \value Target2DArray
735 GL_TEXTURE_2D_ARRAY
736 \value Target3D
737 GL_TEXTURE_3D
738 \value TargetCubeMap
739 GL_TEXTURE_CUBE_MAP
740 \value TargetCubeMapArray
741 GL_TEXTURE_CUBE_MAP_ARRAY
742 \value Target2DMultisample
743 GL_TEXTURE_2D_MULTISAMPLE
744 \value Target2DMultisampleArray
745 GL_TEXTURE_2D_MULTISAMPLE_ARRAY
746 \value TargetRectangle
747 GL_TEXTURE_RECTANGLE
748 \value TargetBuffer
749 GL_TEXTURE_BUFFER
750*/
751
752/*!
753 Returns the target format of the texture provider.
754*/
755QAbstractTexture::Target QAbstractTexture::target() const
756{
757 Q_D(const QAbstractTexture);
758 return d->m_target;
759}
760
761/*!
762 Adds a new Qt3DCore::QAbstractTextureImage \a textureImage to the texture provider.
763
764 \note Qt3DRender::QAbstractTextureImage should never be shared between multiple
765 Qt3DRender::QAbstractTexture instances.
766 */
767void QAbstractTexture::addTextureImage(QAbstractTextureImage *textureImage)
768{
769 Q_ASSERT(textureImage);
770 Q_D(QAbstractTexture);
771 if (!d->m_textureImages.contains(t: textureImage)) {
772 d->m_textureImages.append(t: textureImage);
773
774 // Ensures proper bookkeeping
775 d->registerDestructionHelper(node: textureImage, func: &QAbstractTexture::removeTextureImage, d->m_textureImages);
776
777 // We need to add it as a child of the current node if it has been declared inline
778 // Or not previously added as a child of the current node so that
779 // 1) The backend gets notified about it's creation
780 // 2) When the current node is destroyed, it gets destroyed as well
781 if (!textureImage->parent())
782 textureImage->setParent(this);
783
784 d->updateNode(node: textureImage, property: "textureImage", change: PropertyValueAdded);
785 }
786}
787
788/*!
789 Removes a Qt3DCore::QAbstractTextureImage \a textureImage from the texture provider.
790 */
791void QAbstractTexture::removeTextureImage(QAbstractTextureImage *textureImage)
792{
793 Q_ASSERT(textureImage);
794 Q_D(QAbstractTexture);
795 if (!d->m_textureImages.removeOne(t: textureImage))
796 return;
797 d->updateNode(node: textureImage, property: "textureImage", change: PropertyValueRemoved);
798 // Remove bookkeeping connection
799 d->unregisterDestructionHelper(node: textureImage);
800}
801
802/*!
803 Returns a list of pointers to QAbstractTextureImage objects contained in
804 the texture provider.
805 */
806QVector<QAbstractTextureImage *> QAbstractTexture::textureImages() const
807{
808 Q_D(const QAbstractTexture);
809 return d->m_textureImages;
810}
811
812/*!
813 \property Qt3DRender::QAbstractTexture::generateMipMaps
814
815 Holds whether the texture provider should auto generate mipmaps.
816 */
817/*!
818 \qmlproperty bool Qt3DRender::QAbstractTexture::generateMipMaps
819
820 Holds whether the texture provider should auto generate mipmaps.
821 */
822/*!
823 Boolean parameter \a gen sets a flag indicating whether the
824 texture provider should generate mipmaps or not.
825*/
826void QAbstractTexture::setGenerateMipMaps(bool gen)
827{
828 Q_D(QAbstractTexture);
829 if (d->m_autoMipMap != gen) {
830 d->m_autoMipMap = gen;
831 emit generateMipMapsChanged(generateMipMaps: gen);
832 }
833}
834
835bool QAbstractTexture::generateMipMaps() const
836{
837 Q_D(const QAbstractTexture);
838 return d->m_autoMipMap;
839}
840
841/*!
842 \property Qt3DRender::QAbstractTexture::minificationFilter
843
844 Holds the minification filter of the texture provider.
845 */
846/*!
847 \qmlproperty Filter Qt3DRender::QAbstractTexture::minificationFilter
848
849 Holds the minification filter of the texture provider.
850 */
851/*!
852 Set the minification filter to the specified value \a f.
853*/
854void QAbstractTexture::setMinificationFilter(Filter f)
855{
856 Q_D(QAbstractTexture);
857 if (d->m_minFilter != f) {
858 d->m_minFilter = f;
859 emit minificationFilterChanged(minificationFilter: f);
860 }
861}
862/*!
863 \enum Qt3DRender::QAbstractTexture::Filter
864
865 Holds the filter type of the texture provider.
866
867 \value Nearest
868 GL_NEAREST
869 \value Linear
870 GL_LINEAR
871 \value NearestMipMapNearest
872 GL_NEAREST_MIPMAP_NEAREST
873 \value NearestMipMapLinear
874 GL_NEAREST_MIPMAP_LINEAR
875 \value LinearMipMapNearest
876 GL_LINEAR_MIPMAP_NEAREST
877 \value LinearMipMapLinear
878 GL_LINEAR_MIPMAP_LINEAR
879*/
880/*!
881 \property Qt3DRender::QAbstractTexture::magnificationFilter
882
883 Holds the magnification filter of the texture provider.
884 */
885/*!
886 \qmlproperty Filter Qt3DRender::QAbstractTexture::magnificationFilter
887
888 Holds the magnification filter of the texture provider.
889 */
890/*!
891 Set the magnification filter to \a f.
892*/
893void QAbstractTexture::setMagnificationFilter(Filter f)
894{
895 Q_D(QAbstractTexture);
896 if (d->m_magFilter != f) {
897 d->m_magFilter = f;
898 emit magnificationFilterChanged(magnificationFilter: f);
899 }
900}
901
902QAbstractTexture::Filter QAbstractTexture::minificationFilter() const
903{
904 Q_D(const QAbstractTexture);
905 return d->m_minFilter;
906}
907
908QAbstractTexture::Filter QAbstractTexture::magnificationFilter() const
909{
910 Q_D(const QAbstractTexture);
911 return d->m_magFilter;
912}
913
914/*!
915 \property Qt3DRender::QAbstractTexture::wrapMode
916
917 Holds the wrap mode of the texture provider.
918 */
919/*!
920 \qmlproperty QTextureWrapMode Qt3DRender::QAbstractTexture::wrapMode
921
922 Holds the wrap mode of the texture provider.
923 */
924/*!
925 Set the wrapmode to the value specified in \a wrapMode.
926*/
927void QAbstractTexture::setWrapMode(const QTextureWrapMode &wrapMode)
928{
929 Q_D(QAbstractTexture);
930 if (d->m_wrapMode.x() != wrapMode.x()) {
931 d->m_wrapMode.setX(wrapMode.x());
932 d->update();
933 }
934 if (d->m_wrapMode.y() != wrapMode.y()) {
935 d->m_wrapMode.setY(wrapMode.y());
936 d->update();
937 }
938 if (d->m_wrapMode.z() != wrapMode.z()) {
939 d->m_wrapMode.setZ(wrapMode.z());
940 d->update();
941 }
942}
943
944QTextureWrapMode *QAbstractTexture::wrapMode()
945{
946 Q_D(QAbstractTexture);
947 return &d->m_wrapMode;
948}
949
950/*!
951 \property Qt3DRender::QAbstractTexture::maximumAnisotropy
952
953 Holds the maximum anisotropy of the texture provider.
954 */
955/*!
956 \qmlproperty bool Qt3DRender::QAbstractTexture::maximumAnisotropy
957
958 Holds the maximum anisotropy of the texture provider.
959 */
960/*!
961 Sets the maximum anisotropy to \a anisotropy.
962*/
963void QAbstractTexture::setMaximumAnisotropy(float anisotropy)
964{
965 Q_D(QAbstractTexture);
966 if (!qFuzzyCompare(p1: d->m_maximumAnisotropy, p2: anisotropy)) {
967 d->m_maximumAnisotropy = anisotropy;
968 emit maximumAnisotropyChanged(maximumAnisotropy: anisotropy);
969 }
970}
971
972/*!
973 * Returns the current maximum anisotropy
974 */
975float QAbstractTexture::maximumAnisotropy() const
976{
977 Q_D(const QAbstractTexture);
978 return d->m_maximumAnisotropy;
979}
980
981/*!
982 \property Qt3DRender::QAbstractTexture::comparisonFunction
983
984 Holds the comparison function of the texture provider.
985 */
986/*!
987 \qmlproperty ComparisonFunction Qt3DRender::QAbstractTexture::ComparisonFunction
988
989 Holds the comparison function of the texture provider.
990 */
991/*!
992 Set the comparison function to \a function.
993*/
994void QAbstractTexture::setComparisonFunction(QAbstractTexture::ComparisonFunction function)
995{
996 Q_D(QAbstractTexture);
997 if (d->m_comparisonFunction != function) {
998 d->m_comparisonFunction = function;
999 emit comparisonFunctionChanged(comparisonFunction: function);
1000 }
1001}
1002
1003/*!
1004 * Returns the current comparison function.
1005 */
1006QAbstractTexture::ComparisonFunction QAbstractTexture::comparisonFunction() const
1007{
1008 Q_D(const QAbstractTexture);
1009 return d->m_comparisonFunction;
1010}
1011
1012/*!
1013 \property Qt3DRender::QAbstractTexture::comparisonMode
1014
1015 Holds the comparison mode of the texture provider.
1016 */
1017
1018/*!
1019 \qmlproperty ComparisonMode Qt3DRender::QAbstractTexture::ComparisonMode
1020
1021 Holds the comparison mode of the texture provider.
1022 */
1023/*!
1024 Set the comparison mode to \a mode.
1025*/
1026void QAbstractTexture::setComparisonMode(QAbstractTexture::ComparisonMode mode)
1027{
1028 Q_D(QAbstractTexture);
1029 if (d->m_comparisonMode != mode) {
1030 d->m_comparisonMode = mode;
1031 emit comparisonModeChanged(comparisonMode: mode);
1032 }
1033}
1034
1035/*!
1036 * Returns the current comparison mode.
1037 */
1038QAbstractTexture::ComparisonMode QAbstractTexture::comparisonMode() const
1039{
1040 Q_D(const QAbstractTexture);
1041 return d->m_comparisonMode;
1042}
1043
1044/*!
1045 * Returns the current data generator.
1046 */
1047QTextureGeneratorPtr QAbstractTexture::dataGenerator() const
1048{
1049 Q_D(const QAbstractTexture);
1050 return d->m_dataFunctor;
1051}
1052
1053/*!
1054 * \property Qt3DRender::QAbstractTexture::handleType
1055 *
1056 * Holds the current texture handle type.
1057 */
1058
1059/*!
1060 * \qmlproperty enumeration AbstractTexture::handleType
1061 *
1062 * Holds the current texture handle type.
1063 *
1064 * \value AbstractTexture.NoHandle
1065 * \value AbstractTexture.OpenGLTextureId
1066 */
1067
1068/*!
1069 * \return the current texture handle type.
1070 * \since 5.13
1071 */
1072QAbstractTexture::HandleType QAbstractTexture::handleType() const
1073{
1074 Q_D(const QAbstractTexture);
1075 return d->m_handleType;
1076}
1077
1078/*!
1079 * \property Qt3DRender::QAbstractTexture::handle
1080 *
1081 * Holds the current texture handle, if Qt 3D is using the OpenGL renderer,
1082 * handle is a texture id integer.
1083 */
1084
1085/*!
1086 * \qmlproperty var AbstractTexture::handle
1087 *
1088 * Holds the current texture handle, if Qt 3D is using the OpenGL renderer,
1089 * handle is a texture id integer.
1090 */
1091
1092/*!
1093 * \return the current texture handle, if Qt 3D is using the OpenGL renderer,
1094 * handle is a texture id integer.
1095 *
1096 * \since 5.13
1097 */
1098QVariant QAbstractTexture::handle() const
1099{
1100 Q_D(const QAbstractTexture);
1101 return d->m_handle;
1102}
1103
1104/*!
1105 * Updates a sub region of the texture, defined by \a update, without having
1106 * to change the data generator or rely on adding or removing texture images.
1107 * \since 5.14
1108 */
1109void QAbstractTexture::updateData(const QTextureDataUpdate &update)
1110{
1111 Q_D(QAbstractTexture);
1112
1113 d->m_pendingDataUpdates.push_back(t: update);
1114 d->update();
1115}
1116
1117Qt3DCore::QNodeCreatedChangeBasePtr QAbstractTexture::createNodeCreationChange() const
1118{
1119 auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QAbstractTextureData>::create(arguments: this);
1120 auto &data = creationChange->data;
1121 Q_D(const QAbstractTexture);
1122 data.target = d->m_target;
1123 data.format = d->m_format;
1124 data.width = d->m_width;
1125 data.height = d->m_height;
1126 data.depth = d->m_depth;
1127 data.autoMipMap = d->m_autoMipMap;
1128 data.minFilter = d->m_minFilter;
1129 data.magFilter = d->m_magFilter;
1130 data.wrapModeX = d->m_wrapMode.x();
1131 data.wrapModeY = d->m_wrapMode.y();
1132 data.wrapModeZ = d->m_wrapMode.z();
1133 data.maximumAnisotropy = d->m_maximumAnisotropy;
1134 data.comparisonFunction = d->m_comparisonFunction;
1135 data.comparisonMode = d->m_comparisonMode;
1136 data.textureImageIds = qIdsForNodes(nodes: d->m_textureImages);
1137 data.layers = d->m_layers;
1138 data.samples = d->m_samples;
1139 data.dataFunctor = d->m_dataFunctor;
1140 data.sharedTextureId = d->m_sharedTextureId;
1141 data.initialDataUpdates = d->m_pendingDataUpdates;
1142 return creationChange;
1143}
1144
1145/*!
1146 A function for receiving and processing a \a change.
1147*/
1148void QAbstractTexture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
1149{
1150 switch (change->type()) {
1151 case PropertyUpdated: {
1152 Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(src: change);
1153 if (propertyChange->propertyName() == QByteArrayLiteral("width")) {
1154 bool blocked = blockNotifications(block: true);
1155 setWidth(propertyChange->value().toInt());
1156 blockNotifications(block: blocked);
1157 } else if (propertyChange->propertyName() == QByteArrayLiteral("height")) {
1158 bool blocked = blockNotifications(block: true);
1159 setHeight(propertyChange->value().toInt());
1160 blockNotifications(block: blocked);
1161 } else if (propertyChange->propertyName() == QByteArrayLiteral("depth")) {
1162 bool blocked = blockNotifications(block: true);
1163 setDepth(propertyChange->value().toInt());
1164 blockNotifications(block: blocked);
1165 } else if (propertyChange->propertyName() == QByteArrayLiteral("layers")) {
1166 bool blocked = blockNotifications(block: true);
1167 setLayers(propertyChange->value().toInt());
1168 blockNotifications(block: blocked);
1169 } else if (propertyChange->propertyName() == QByteArrayLiteral("format")) {
1170 bool blocked = blockNotifications(block: true);
1171 setFormat(static_cast<QAbstractTexture::TextureFormat>(propertyChange->value().toInt()));
1172 blockNotifications(block: blocked);
1173 } else if (propertyChange->propertyName() == QByteArrayLiteral("status")) {
1174 bool blocked = blockNotifications(block: true);
1175 setStatus(static_cast<QAbstractTexture::Status>(propertyChange->value().toInt()));
1176 blockNotifications(block: blocked);
1177 } else if (propertyChange->propertyName() == QByteArrayLiteral("handleType")) {
1178 setHandleType(static_cast<QAbstractTexture::HandleType>(propertyChange->value().toInt()));
1179 } else if (propertyChange->propertyName() == QByteArrayLiteral("handle")) {
1180 setHandle(propertyChange->value());
1181 }
1182 // TODO handle target changes, it's a CONSTANT property but can be affected by loader
1183 break;
1184 }
1185 default:
1186 break;
1187 }
1188}
1189
1190
1191} // namespace Qt3DRender
1192
1193QT_END_NAMESPACE
1194

source code of qt3d/src/render/texture/qabstracttexture.cpp