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 | |
47 | QT_BEGIN_NAMESPACE |
48 | |
49 | using namespace Qt3DCore; |
50 | |
51 | namespace Qt3DRender { |
52 | |
53 | QAbstractTexturePrivate::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 | |
76 | QTextureGeneratorPtr QAbstractTexturePrivate::dataFunctor() const |
77 | { |
78 | return m_dataFunctor; |
79 | } |
80 | |
81 | void QAbstractTexturePrivate::setDataFunctor(const QTextureGeneratorPtr &generator) |
82 | { |
83 | if (generator != m_dataFunctor) { |
84 | m_dataFunctor = generator; |
85 | update(); |
86 | } |
87 | } |
88 | |
89 | void 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 | |
100 | void 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 | |
111 | void 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 | */ |
392 | QAbstractTexture::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 | */ |
401 | QAbstractTexture::QAbstractTexture(Target target, QNode *parent) |
402 | : QNode(*new QAbstractTexturePrivate, parent) |
403 | { |
404 | d_func()->m_target = target; |
405 | } |
406 | |
407 | /*! \internal */ |
408 | QAbstractTexture::~QAbstractTexture() |
409 | { |
410 | } |
411 | |
412 | /*! \internal */ |
413 | QAbstractTexture::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 | */ |
421 | void 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 | */ |
442 | void 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 | */ |
464 | void 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 | */ |
486 | void 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 | */ |
498 | int 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 | */ |
507 | int 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 | */ |
516 | int 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 | */ |
543 | void 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 | */ |
558 | int 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 | */ |
585 | void 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 | */ |
600 | int 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 | */ |
619 | void 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 | */ |
631 | QAbstractTexture::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 | */ |
661 | void 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 | */ |
675 | void 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 | */ |
689 | void 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 | */ |
703 | QAbstractTexture::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 | */ |
755 | QAbstractTexture::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 | */ |
767 | void 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 | */ |
791 | void 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 | */ |
806 | QVector<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 | */ |
826 | void 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 | |
835 | bool 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 | */ |
854 | void 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 | */ |
893 | void 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 | |
902 | QAbstractTexture::Filter QAbstractTexture::minificationFilter() const |
903 | { |
904 | Q_D(const QAbstractTexture); |
905 | return d->m_minFilter; |
906 | } |
907 | |
908 | QAbstractTexture::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 | */ |
927 | void 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 | |
944 | QTextureWrapMode *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 | */ |
963 | void 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 | */ |
975 | float 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 | */ |
994 | void 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 | */ |
1006 | QAbstractTexture::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 | */ |
1026 | void 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 | */ |
1038 | QAbstractTexture::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 | */ |
1047 | QTextureGeneratorPtr 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 | */ |
1072 | QAbstractTexture::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 | */ |
1098 | QVariant 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 | */ |
1109 | void QAbstractTexture::updateData(const QTextureDataUpdate &update) |
1110 | { |
1111 | Q_D(QAbstractTexture); |
1112 | |
1113 | d->m_pendingDataUpdates.push_back(t: update); |
1114 | d->update(); |
1115 | } |
1116 | |
1117 | Qt3DCore::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 | */ |
1148 | void 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 | |
1193 | QT_END_NAMESPACE |
1194 | |