Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qopengltexture.cpp
Go to the documentation of this file.
1// Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB).
2// Copyright (C) 2020 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
10#include <QtGui/qcolor.h>
11#include <QtGui/qopenglcontext.h>
12#include <QtCore/qdebug.h>
13#include <private/qobject_p.h>
14#include <private/qopenglcontext_p.h>
15
17
18//this is to work around GL_TEXTURE_WRAP_R_OES which also has 0x8072 as value
19#if !defined(GL_TEXTURE_WRAP_R)
20 #define GL_TEXTURE_WRAP_R 0x8072
21#endif
22
23QOpenGLTexturePrivate::QOpenGLTexturePrivate(QOpenGLTexture::Target textureTarget,
24 QOpenGLTexture *qq)
25 : q_ptr(qq),
26 context(nullptr),
27 target(textureTarget),
28 textureId(0),
29 format(QOpenGLTexture::NoFormat),
30 formatClass(QOpenGLTexture::NoFormatClass),
31 requestedMipLevels(1),
32 mipLevels(-1),
33 layers(1),
34 faces(1),
35 samples(0),
36 fixedSamplePositions(true),
37 baseLevel(0),
38 maxLevel(1000),
39 depthStencilMode(QOpenGLTexture::DepthMode),
40 comparisonFunction(QOpenGLTexture::CompareLessEqual),
41 comparisonMode(QOpenGLTexture::CompareNone),
42 minFilter(QOpenGLTexture::Nearest),
43 magFilter(QOpenGLTexture::Nearest),
44 maxAnisotropy(1.0f),
45 minLevelOfDetail(-1000.0f),
46 maxLevelOfDetail(1000.0f),
47 levelOfDetailBias(0.0f),
48 textureView(false),
49 autoGenerateMipMaps(true),
50 storageAllocated(false),
51 texFuncs(nullptr),
52 functions(nullptr)
53{
54 dimensions[0] = dimensions[1] = dimensions[2] = 1;
55
56 switch (target) {
57 case QOpenGLTexture::Target1D:
58 bindingTarget = QOpenGLTexture::BindingTarget1D;
59 break;
60 case QOpenGLTexture::Target1DArray:
61 bindingTarget = QOpenGLTexture::BindingTarget1DArray;
62 break;
63 case QOpenGLTexture::Target2D:
64 bindingTarget = QOpenGLTexture::BindingTarget2D;
65 break;
66 case QOpenGLTexture::Target2DArray:
67 bindingTarget = QOpenGLTexture::BindingTarget2DArray;
68 break;
69 case QOpenGLTexture::Target3D:
70 bindingTarget = QOpenGLTexture::BindingTarget3D;
71 break;
72 case QOpenGLTexture::TargetCubeMap:
73 bindingTarget = QOpenGLTexture::BindingTargetCubeMap;
74 faces = 6;
75 break;
76 case QOpenGLTexture::TargetCubeMapArray:
77 bindingTarget = QOpenGLTexture::BindingTargetCubeMapArray;
78 faces = 6;
79 break;
80 case QOpenGLTexture::Target2DMultisample:
81 bindingTarget = QOpenGLTexture::BindingTarget2DMultisample;
82 break;
83 case QOpenGLTexture::Target2DMultisampleArray:
84 bindingTarget = QOpenGLTexture::BindingTarget2DMultisampleArray;
85 break;
86 case QOpenGLTexture::TargetRectangle:
87 bindingTarget = QOpenGLTexture::BindingTargetRectangle;
88 break;
89 case QOpenGLTexture::TargetBuffer:
90 bindingTarget = QOpenGLTexture::BindingTargetBuffer;
91 break;
92 }
93
94 swizzleMask[0] = QOpenGLTexture::RedValue;
95 swizzleMask[1] = QOpenGLTexture::GreenValue;
96 swizzleMask[2] = QOpenGLTexture::BlueValue;
97 swizzleMask[3] = QOpenGLTexture::AlphaValue;
98
99 wrapModes[0] = wrapModes[1] = wrapModes[2] = target == QOpenGLTexture::TargetRectangle
100 ? QOpenGLTexture::ClampToEdge : QOpenGLTexture::Repeat;
101}
102
107
109{
110 // If we already have a functions object, there is nothing to do
111 if (texFuncs)
112 return;
113
114 // See if the context already has a suitable resource we can use.
115 // If not create a functions object and add it to the context in case
116 // others wish to use it too
117 texFuncs = context->textureFunctions();
118 if (!texFuncs) {
120 auto *funcs = texFuncs; // lets us capture by pointer value below
121 context->setTextureFunctions(funcs, [funcs] { delete funcs; });
122 }
123}
124
126{
127 if (textureId != 0)
128 return true;
129
130 QOpenGLContext *ctx = QOpenGLContext::currentContext();
131 if (!ctx) {
132 qWarning("Requires a valid current OpenGL context.\n"
133 "Texture has not been created");
134 return false;
135 }
136 context = ctx;
137 functions = ctx->functions();
138
139 // Resolve any functions we will need based upon context version and create the texture
141
142 // What features do we have?
143 QOpenGLTexture::Feature feature = QOpenGLTexture::ImmutableStorage;
144 while (feature != QOpenGLTexture::MaxFeatureFlag) {
145 if (QOpenGLTexture::hasFeature(feature))
146 features |= feature;
147 feature = static_cast<QOpenGLTexture::Feature>(feature << 1);
148 }
149
150 functions->glGenTextures(1, &textureId);
151 return textureId != 0;
152}
153
155{
156 if (!textureId) {
157 // not created or already destroyed
158 return;
159 }
160 QOpenGLContext *currentContext = QOpenGLContext::currentContext();
161 if (!currentContext) {
162 qWarning("QOpenGLTexturePrivate::destroy() called without a current context.\n"
163 "Texture has not been destroyed");
164 return;
165 }
166 if (!QOpenGLContext::areSharing(currentContext, context)) {
167
168 qWarning("QOpenGLTexturePrivate::destroy() called but texture context %p"
169 " is not shared with current context %p.\n"
170 "Texture has not been destroyed",
171 static_cast<const void *>(context),
172 static_cast<const void *>(currentContext));
173 return;
174 }
175
176 functions->glDeleteTextures(1, &textureId);
177
178 context = nullptr;
179 functions = nullptr;
180 textureId = 0;
181 format = QOpenGLTexture::NoFormat;
182 formatClass = QOpenGLTexture::NoFormatClass;
184 mipLevels = -1;
185 layers = 1;
186 faces = 1;
187 samples = 0;
189 baseLevel = 0;
190 maxLevel = 1000;
191 depthStencilMode = QOpenGLTexture::DepthMode;
192 minFilter = QOpenGLTexture::Nearest;
193 magFilter = QOpenGLTexture::Nearest;
194 maxAnisotropy = 1.0f;
195 minLevelOfDetail = -1000.0f;
196 maxLevelOfDetail = 1000.0f;
197 levelOfDetailBias = 0.0f;
198 textureView = false;
199 autoGenerateMipMaps = true;
200 storageAllocated = false;
201 texFuncs = nullptr;
202
203 swizzleMask[0] = QOpenGLTexture::RedValue;
204 swizzleMask[1] = QOpenGLTexture::GreenValue;
205 swizzleMask[2] = QOpenGLTexture::BlueValue;
206 swizzleMask[3] = QOpenGLTexture::AlphaValue;
207
208 wrapModes[0] = wrapModes[1] = wrapModes[2] = target == QOpenGLTexture::TargetRectangle
209 ? QOpenGLTexture::ClampToEdge : QOpenGLTexture::Repeat;
210}
211
213{
214 functions->glBindTexture(target, textureId);
215}
216
217void QOpenGLTexturePrivate::bind(uint unit, QOpenGLTexture::TextureUnitReset reset)
218{
219 GLint oldTextureUnit = 0;
220 if (reset == QOpenGLTexture::ResetTextureUnit)
221 functions->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit);
222
223 texFuncs->glActiveTexture(GL_TEXTURE0 + unit);
224 functions->glBindTexture(target, textureId);
225
226 if (reset == QOpenGLTexture::ResetTextureUnit)
227 texFuncs->glActiveTexture(GL_TEXTURE0 + oldTextureUnit);
228}
229
231{
232 functions->glBindTexture(target, 0);
233}
234
235void QOpenGLTexturePrivate::release(uint unit, QOpenGLTexture::TextureUnitReset reset)
236{
237 GLint oldTextureUnit = 0;
238 if (reset == QOpenGLTexture::ResetTextureUnit)
239 functions->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit);
240
241 texFuncs->glActiveTexture(GL_TEXTURE0 + unit);
242 functions->glBindTexture(target, 0);
243
244 if (reset == QOpenGLTexture::ResetTextureUnit)
245 texFuncs->glActiveTexture(GL_TEXTURE0 + oldTextureUnit);
246}
247
249{
250 GLint boundTextureId = 0;
251 functions->glGetIntegerv(bindingTarget, &boundTextureId);
252 return (static_cast<GLuint>(boundTextureId) == textureId);
253}
254
255bool QOpenGLTexturePrivate::isBound(uint unit) const
256{
257 GLint oldTextureUnit = 0;
258 functions->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit);
259
260 GLint boundTextureId = 0;
261 texFuncs->glActiveTexture(GL_TEXTURE0 + unit);
262 functions->glGetIntegerv(bindingTarget, &boundTextureId);
263 bool result = (static_cast<GLuint>(boundTextureId) == textureId);
264
265 texFuncs->glActiveTexture(GL_TEXTURE0 + oldTextureUnit);
266 return result;
267}
268
270{
271 switch (target) {
272 case QOpenGLTexture::Target1D:
273 case QOpenGLTexture::Target1DArray:
274 case QOpenGLTexture::Target2D:
275 case QOpenGLTexture::Target2DArray:
276 case QOpenGLTexture::Target3D:
277 case QOpenGLTexture::TargetCubeMap:
278 case QOpenGLTexture::TargetCubeMapArray:
279 return qMin(maximumMipLevelCount(), qMax(1, requestedMipLevels));
280
281 case QOpenGLTexture::TargetRectangle:
282 case QOpenGLTexture::Target2DMultisample:
283 case QOpenGLTexture::Target2DMultisampleArray:
284 case QOpenGLTexture::TargetBuffer:
285 default:
286 return 1;
287 }
288}
289
290static bool isSizedTextureFormat(QOpenGLTexture::TextureFormat internalFormat)
291{
292 switch (internalFormat) {
293 case QOpenGLTexture::NoFormat:
294 return false;
295
296 case QOpenGLTexture::R8_UNorm:
297 case QOpenGLTexture::RG8_UNorm:
298 case QOpenGLTexture::RGB8_UNorm:
299 case QOpenGLTexture::RGBA8_UNorm:
300 case QOpenGLTexture::R16_UNorm:
301 case QOpenGLTexture::RG16_UNorm:
302 case QOpenGLTexture::RGB16_UNorm:
303 case QOpenGLTexture::RGBA16_UNorm:
304 case QOpenGLTexture::R8_SNorm:
305 case QOpenGLTexture::RG8_SNorm:
306 case QOpenGLTexture::RGB8_SNorm:
307 case QOpenGLTexture::RGBA8_SNorm:
308 case QOpenGLTexture::R16_SNorm:
309 case QOpenGLTexture::RG16_SNorm:
310 case QOpenGLTexture::RGB16_SNorm:
311 case QOpenGLTexture::RGBA16_SNorm:
312 case QOpenGLTexture::R8U:
313 case QOpenGLTexture::RG8U:
314 case QOpenGLTexture::RGB8U:
315 case QOpenGLTexture::RGBA8U:
316 case QOpenGLTexture::R16U:
317 case QOpenGLTexture::RG16U:
318 case QOpenGLTexture::RGB16U:
319 case QOpenGLTexture::RGBA16U:
320 case QOpenGLTexture::R32U:
321 case QOpenGLTexture::RG32U:
322 case QOpenGLTexture::RGB32U:
323 case QOpenGLTexture::RGBA32U:
324 case QOpenGLTexture::R8I:
325 case QOpenGLTexture::RG8I:
326 case QOpenGLTexture::RGB8I:
327 case QOpenGLTexture::RGBA8I:
328 case QOpenGLTexture::R16I:
329 case QOpenGLTexture::RG16I:
330 case QOpenGLTexture::RGB16I:
331 case QOpenGLTexture::RGBA16I:
332 case QOpenGLTexture::R32I:
333 case QOpenGLTexture::RG32I:
334 case QOpenGLTexture::RGB32I:
335 case QOpenGLTexture::RGBA32I:
336 case QOpenGLTexture::R16F:
337 case QOpenGLTexture::RG16F:
338 case QOpenGLTexture::RGB16F:
339 case QOpenGLTexture::RGBA16F:
340 case QOpenGLTexture::R32F:
341 case QOpenGLTexture::RG32F:
342 case QOpenGLTexture::RGB32F:
343 case QOpenGLTexture::RGBA32F:
344 case QOpenGLTexture::RGB9E5:
345 case QOpenGLTexture::RG11B10F:
346 case QOpenGLTexture::RG3B2:
347 case QOpenGLTexture::R5G6B5:
348 case QOpenGLTexture::RGB5A1:
349 case QOpenGLTexture::RGBA4:
350 case QOpenGLTexture::RGB10A2:
351
352 case QOpenGLTexture::D16:
353 case QOpenGLTexture::D24:
354 case QOpenGLTexture::D32:
355 case QOpenGLTexture::D32F:
356
357 case QOpenGLTexture::D24S8:
358 case QOpenGLTexture::D32FS8X24:
359
360 case QOpenGLTexture::S8:
361
362 case QOpenGLTexture::RGB_DXT1:
363 case QOpenGLTexture::RGBA_DXT1:
364 case QOpenGLTexture::RGBA_DXT3:
365 case QOpenGLTexture::RGBA_DXT5:
366 case QOpenGLTexture::R_ATI1N_UNorm:
367 case QOpenGLTexture::R_ATI1N_SNorm:
368 case QOpenGLTexture::RG_ATI2N_UNorm:
369 case QOpenGLTexture::RG_ATI2N_SNorm:
370 case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT:
371 case QOpenGLTexture::RGB_BP_SIGNED_FLOAT:
372 case QOpenGLTexture::RGB_BP_UNorm:
373 case QOpenGLTexture::SRGB8:
374 case QOpenGLTexture::SRGB8_Alpha8:
375 case QOpenGLTexture::SRGB_DXT1:
376 case QOpenGLTexture::SRGB_Alpha_DXT1:
377 case QOpenGLTexture::SRGB_Alpha_DXT3:
378 case QOpenGLTexture::SRGB_Alpha_DXT5:
379 case QOpenGLTexture::SRGB_BP_UNorm:
380 case QOpenGLTexture::R11_EAC_UNorm:
381 case QOpenGLTexture::R11_EAC_SNorm:
382 case QOpenGLTexture::RG11_EAC_UNorm:
383 case QOpenGLTexture::RG11_EAC_SNorm:
384 case QOpenGLTexture::RGB8_ETC2:
385 case QOpenGLTexture::SRGB8_ETC2:
386 case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
387 case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
388 case QOpenGLTexture::RGBA8_ETC2_EAC:
389 case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
390 case QOpenGLTexture::RGBA_ASTC_4x4:
391 case QOpenGLTexture::RGBA_ASTC_5x4:
392 case QOpenGLTexture::RGBA_ASTC_5x5:
393 case QOpenGLTexture::RGBA_ASTC_6x5:
394 case QOpenGLTexture::RGBA_ASTC_6x6:
395 case QOpenGLTexture::RGBA_ASTC_8x5:
396 case QOpenGLTexture::RGBA_ASTC_8x6:
397 case QOpenGLTexture::RGBA_ASTC_8x8:
398 case QOpenGLTexture::RGBA_ASTC_10x5:
399 case QOpenGLTexture::RGBA_ASTC_10x6:
400 case QOpenGLTexture::RGBA_ASTC_10x8:
401 case QOpenGLTexture::RGBA_ASTC_10x10:
402 case QOpenGLTexture::RGBA_ASTC_12x10:
403 case QOpenGLTexture::RGBA_ASTC_12x12:
404 case QOpenGLTexture::SRGB8_Alpha8_ASTC_4x4:
405 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x4:
406 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x5:
407 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x5:
408 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x6:
409 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x5:
410 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x6:
411 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x8:
412 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x5:
413 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x6:
414 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x8:
415 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x10:
416 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x10:
417 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x12:
418 return true;
419
420 case QOpenGLTexture::RGB8_ETC1:
421 return false;
422
423 case QOpenGLTexture::DepthFormat:
424 case QOpenGLTexture::AlphaFormat:
425
426 case QOpenGLTexture::RGBFormat:
427 case QOpenGLTexture::RGBAFormat:
428
429 case QOpenGLTexture::LuminanceFormat:
430
431 case QOpenGLTexture::LuminanceAlphaFormat:
432 return false;
433 }
434
435 Q_UNREACHABLE_RETURN(false);
436}
437
438static bool isTextureTargetMultisample(QOpenGLTexture::Target target)
439{
440 switch (target) {
441 case QOpenGLTexture::Target1D:
442 case QOpenGLTexture::Target1DArray:
443 case QOpenGLTexture::Target2D:
444 case QOpenGLTexture::Target2DArray:
445 case QOpenGLTexture::Target3D:
446 case QOpenGLTexture::TargetCubeMap:
447 case QOpenGLTexture::TargetCubeMapArray:
448 return false;
449
450 case QOpenGLTexture::Target2DMultisample:
451 case QOpenGLTexture::Target2DMultisampleArray:
452 return true;
453
454 case QOpenGLTexture::TargetRectangle:
455 case QOpenGLTexture::TargetBuffer:
456 return false;
457 }
458
459 Q_UNREACHABLE_RETURN(false);
460}
461
463{
464 // Use immutable storage whenever possible, falling back to mutable
465 // Note that if multisample textures are not supported at all, we'll still fail into
466 // the mutable storage allocation
467 return isSizedTextureFormat(format)
468 && (isTextureTargetMultisample(target)
469 ? features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage)
470 : features.testFlag(QOpenGLTexture::ImmutableStorage));
471}
472
473void QOpenGLTexturePrivate::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
474{
475 // Resolve the actual number of mipmap levels we can use
477
480 else
481 allocateMutableStorage(pixelFormat, pixelType);
482}
483
484static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpenGLTexture::TextureFormat internalFormat)
485{
486 switch (internalFormat) {
487 case QOpenGLTexture::NoFormat:
488 return QOpenGLTexture::NoSourceFormat;
489
490 case QOpenGLTexture::R8_UNorm:
491 return QOpenGLTexture::Red;
492
493 case QOpenGLTexture::RG8_UNorm:
494 return QOpenGLTexture::RG;
495
496 case QOpenGLTexture::RGB8_UNorm:
497 return QOpenGLTexture::RGB;
498
499 case QOpenGLTexture::RGBA8_UNorm:
500 return QOpenGLTexture::RGBA;
501
502 case QOpenGLTexture::R16_UNorm:
503 return QOpenGLTexture::Red;
504
505 case QOpenGLTexture::RG16_UNorm:
506 return QOpenGLTexture::RG;
507
508 case QOpenGLTexture::RGB16_UNorm:
509 return QOpenGLTexture::RGB;
510
511 case QOpenGLTexture::RGBA16_UNorm:
512 return QOpenGLTexture::RGBA;
513
514 case QOpenGLTexture::R8_SNorm:
515 return QOpenGLTexture::Red;
516
517 case QOpenGLTexture::RG8_SNorm:
518 return QOpenGLTexture::RG;
519
520 case QOpenGLTexture::RGB8_SNorm:
521 return QOpenGLTexture::RGB;
522
523 case QOpenGLTexture::RGBA8_SNorm:
524 return QOpenGLTexture::RGBA;
525
526 case QOpenGLTexture::R16_SNorm:
527 return QOpenGLTexture::Red;
528
529 case QOpenGLTexture::RG16_SNorm:
530 return QOpenGLTexture::RG;
531
532 case QOpenGLTexture::RGB16_SNorm:
533 return QOpenGLTexture::RGB;
534
535 case QOpenGLTexture::RGBA16_SNorm:
536 return QOpenGLTexture::RGBA;
537
538 case QOpenGLTexture::R8U:
539 return QOpenGLTexture::Red_Integer;
540
541 case QOpenGLTexture::RG8U:
542 return QOpenGLTexture::RG_Integer;
543
544 case QOpenGLTexture::RGB8U:
545 return QOpenGLTexture::RGB_Integer;
546
547 case QOpenGLTexture::RGBA8U:
548 return QOpenGLTexture::RGBA_Integer;
549
550 case QOpenGLTexture::R16U:
551 return QOpenGLTexture::Red_Integer;
552
553 case QOpenGLTexture::RG16U:
554 return QOpenGLTexture::RG_Integer;
555
556 case QOpenGLTexture::RGB16U:
557 return QOpenGLTexture::RGB_Integer;
558
559 case QOpenGLTexture::RGBA16U:
560 return QOpenGLTexture::RGBA_Integer;
561
562 case QOpenGLTexture::R32U:
563 return QOpenGLTexture::Red_Integer;
564
565 case QOpenGLTexture::RG32U:
566 return QOpenGLTexture::RG_Integer;
567
568 case QOpenGLTexture::RGB32U:
569 return QOpenGLTexture::RGB_Integer;
570
571 case QOpenGLTexture::RGBA32U:
572 return QOpenGLTexture::RGBA_Integer;
573
574 case QOpenGLTexture::R8I:
575 return QOpenGLTexture::Red_Integer;
576
577 case QOpenGLTexture::RG8I:
578 return QOpenGLTexture::RG_Integer;
579
580 case QOpenGLTexture::RGB8I:
581 return QOpenGLTexture::RGB_Integer;
582
583 case QOpenGLTexture::RGBA8I:
584 return QOpenGLTexture::RGBA_Integer;
586 case QOpenGLTexture::R16I:
587 return QOpenGLTexture::Red_Integer;
588
589 case QOpenGLTexture::RG16I:
590 return QOpenGLTexture::RG_Integer;
591
592 case QOpenGLTexture::RGB16I:
593 return QOpenGLTexture::RGB_Integer;
594
595 case QOpenGLTexture::RGBA16I:
596 return QOpenGLTexture::RGBA_Integer;
597
598 case QOpenGLTexture::R32I:
599 return QOpenGLTexture::Red_Integer;
600
601 case QOpenGLTexture::RG32I:
602 return QOpenGLTexture::RG_Integer;
603
604 case QOpenGLTexture::RGB32I:
605 return QOpenGLTexture::RGB_Integer;
606
607 case QOpenGLTexture::RGBA32I:
608 return QOpenGLTexture::RGBA_Integer;
609
610 case QOpenGLTexture::R16F:
611 return QOpenGLTexture::Red;
612
613 case QOpenGLTexture::RG16F:
614 return QOpenGLTexture::RG;
615
616 case QOpenGLTexture::RGB16F:
617 return QOpenGLTexture::RGB;
618
619 case QOpenGLTexture::RGBA16F:
620 return QOpenGLTexture::RGBA;
621
622 case QOpenGLTexture::R32F:
623 return QOpenGLTexture::Red;
624
625 case QOpenGLTexture::RG32F:
626 return QOpenGLTexture::RG;
627
628 case QOpenGLTexture::RGB32F:
629 return QOpenGLTexture::RGB;
630
631 case QOpenGLTexture::RGBA32F:
632 return QOpenGLTexture::RGBA;
633
634 case QOpenGLTexture::RGB9E5:
635 return QOpenGLTexture::RGB;
636
637 case QOpenGLTexture::RG11B10F:
638 return QOpenGLTexture::RGB;
639
640 case QOpenGLTexture::RG3B2:
641 return QOpenGLTexture::RGB;
642
643 case QOpenGLTexture::R5G6B5:
644 return QOpenGLTexture::RGB;
645
646 case QOpenGLTexture::RGB5A1:
647 return QOpenGLTexture::RGBA;
648
649 case QOpenGLTexture::RGBA4:
650 return QOpenGLTexture::RGBA;
651
652 case QOpenGLTexture::RGB10A2:
653 return QOpenGLTexture::RGBA;
654
655 case QOpenGLTexture::D16:
656 case QOpenGLTexture::D24:
657 case QOpenGLTexture::D32:
658 case QOpenGLTexture::D32F:
659 return QOpenGLTexture::Depth;
660
661 case QOpenGLTexture::D24S8:
662 case QOpenGLTexture::D32FS8X24:
663 return QOpenGLTexture::DepthStencil;
664
665 case QOpenGLTexture::S8:
666 return QOpenGLTexture::Stencil;
667
668 case QOpenGLTexture::RGB_DXT1:
669 case QOpenGLTexture::RGBA_DXT1:
670 case QOpenGLTexture::RGBA_DXT3:
671 case QOpenGLTexture::RGBA_DXT5:
672 case QOpenGLTexture::R_ATI1N_UNorm:
673 case QOpenGLTexture::R_ATI1N_SNorm:
674 case QOpenGLTexture::RG_ATI2N_UNorm:
675 case QOpenGLTexture::RG_ATI2N_SNorm:
676 case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT:
677 case QOpenGLTexture::RGB_BP_SIGNED_FLOAT:
678 case QOpenGLTexture::RGB_BP_UNorm:
679 case QOpenGLTexture::SRGB8:
680 case QOpenGLTexture::SRGB8_Alpha8:
681 case QOpenGLTexture::SRGB_DXT1:
682 case QOpenGLTexture::SRGB_Alpha_DXT1:
683 case QOpenGLTexture::SRGB_Alpha_DXT3:
684 case QOpenGLTexture::SRGB_Alpha_DXT5:
685 case QOpenGLTexture::SRGB_BP_UNorm:
686 case QOpenGLTexture::RGB8_ETC1:
687 return QOpenGLTexture::RGBA;
688
689 case QOpenGLTexture::R11_EAC_UNorm:
690 case QOpenGLTexture::R11_EAC_SNorm:
691 return QOpenGLTexture::Red;
692
693 case QOpenGLTexture::RG11_EAC_UNorm:
694 case QOpenGLTexture::RG11_EAC_SNorm:
695 return QOpenGLTexture::RG;
696
697 case QOpenGLTexture::RGB8_ETC2:
698 case QOpenGLTexture::SRGB8_ETC2:
699 return QOpenGLTexture::RGB;
700
701 case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
702 case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
703 return QOpenGLTexture::RGBA;
704
705 case QOpenGLTexture::RGBA8_ETC2_EAC:
706 case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
707 return QOpenGLTexture::RGBA;
708
709 case QOpenGLTexture::RGBA_ASTC_4x4:
710 case QOpenGLTexture::RGBA_ASTC_5x4:
711 case QOpenGLTexture::RGBA_ASTC_5x5:
712 case QOpenGLTexture::RGBA_ASTC_6x5:
713 case QOpenGLTexture::RGBA_ASTC_6x6:
714 case QOpenGLTexture::RGBA_ASTC_8x5:
715 case QOpenGLTexture::RGBA_ASTC_8x6:
716 case QOpenGLTexture::RGBA_ASTC_8x8:
717 case QOpenGLTexture::RGBA_ASTC_10x5:
718 case QOpenGLTexture::RGBA_ASTC_10x6:
719 case QOpenGLTexture::RGBA_ASTC_10x8:
720 case QOpenGLTexture::RGBA_ASTC_10x10:
721 case QOpenGLTexture::RGBA_ASTC_12x10:
722 case QOpenGLTexture::RGBA_ASTC_12x12:
723 case QOpenGLTexture::SRGB8_Alpha8_ASTC_4x4:
724 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x4:
725 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x5:
726 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x5:
727 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x6:
728 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x5:
729 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x6:
730 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x8:
731 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x5:
732 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x6:
733 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x8:
734 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x10:
735 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x10:
736 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x12:
737 return QOpenGLTexture::RGBA;
738
739 case QOpenGLTexture::DepthFormat:
740 return QOpenGLTexture::Depth;
741
742 case QOpenGLTexture::AlphaFormat:
743 return QOpenGLTexture::Alpha;
744
745 case QOpenGLTexture::RGBFormat:
746 return QOpenGLTexture::RGB;
747
748 case QOpenGLTexture::RGBAFormat:
749 return QOpenGLTexture::RGBA;
750
751 case QOpenGLTexture::LuminanceFormat:
752 return QOpenGLTexture::Luminance;
753
754 case QOpenGLTexture::LuminanceAlphaFormat:
755 return QOpenGLTexture::LuminanceAlpha;
756 }
757
758 Q_UNREACHABLE_RETURN(QOpenGLTexture::NoSourceFormat);
759}
760
761static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTexture::TextureFormat internalFormat)
762{
763 switch (internalFormat) {
764 case QOpenGLTexture::NoFormat:
765 return QOpenGLTexture::NoPixelType;
766
767 case QOpenGLTexture::R8_UNorm:
768 case QOpenGLTexture::RG8_UNorm:
769 case QOpenGLTexture::RGB8_UNorm:
770 case QOpenGLTexture::RGBA8_UNorm:
771 case QOpenGLTexture::R16_UNorm:
772 case QOpenGLTexture::RG16_UNorm:
773 case QOpenGLTexture::RGB16_UNorm:
774 case QOpenGLTexture::RGBA16_UNorm:
775 return QOpenGLTexture::UInt8;
776
777 case QOpenGLTexture::R8_SNorm:
778 case QOpenGLTexture::RG8_SNorm:
779 case QOpenGLTexture::RGB8_SNorm:
780 case QOpenGLTexture::RGBA8_SNorm:
781 case QOpenGLTexture::R16_SNorm:
782 case QOpenGLTexture::RG16_SNorm:
783 case QOpenGLTexture::RGB16_SNorm:
784 case QOpenGLTexture::RGBA16_SNorm:
785 return QOpenGLTexture::Int8;
786
787 case QOpenGLTexture::R8U:
788 case QOpenGLTexture::RG8U:
789 case QOpenGLTexture::RGB8U:
790 case QOpenGLTexture::RGBA8U:
791 case QOpenGLTexture::R16U:
792 case QOpenGLTexture::RG16U:
793 case QOpenGLTexture::RGB16U:
794 case QOpenGLTexture::RGBA16U:
795 case QOpenGLTexture::R32U:
796 case QOpenGLTexture::RG32U:
797 case QOpenGLTexture::RGB32U:
798 case QOpenGLTexture::RGBA32U:
799 return QOpenGLTexture::UInt8;
800
801 case QOpenGLTexture::R8I:
802 case QOpenGLTexture::RG8I:
803 case QOpenGLTexture::RGB8I:
804 case QOpenGLTexture::RGBA8I:
805 case QOpenGLTexture::R16I:
806 case QOpenGLTexture::RG16I:
807 case QOpenGLTexture::RGB16I:
808 case QOpenGLTexture::RGBA16I:
809 case QOpenGLTexture::R32I:
810 case QOpenGLTexture::RG32I:
811 case QOpenGLTexture::RGB32I:
812 case QOpenGLTexture::RGBA32I:
813 return QOpenGLTexture::Int8;
814
815 case QOpenGLTexture::R16F:
816 case QOpenGLTexture::RG16F:
817 case QOpenGLTexture::RGB16F:
818 case QOpenGLTexture::RGBA16F:
819 return QOpenGLTexture::Float16;
820
821 case QOpenGLTexture::R32F:
822 case QOpenGLTexture::RG32F:
823 case QOpenGLTexture::RGB32F:
824 case QOpenGLTexture::RGBA32F:
825 return QOpenGLTexture::Float32;
826
827 case QOpenGLTexture::RGB9E5:
828 return QOpenGLTexture::UInt16_RGB5A1_Rev;
829
830 case QOpenGLTexture::RG11B10F:
831 return QOpenGLTexture::UInt32_RG11B10F;
832
833 case QOpenGLTexture::RG3B2:
834 return QOpenGLTexture::UInt8_RG3B2;
835
836 case QOpenGLTexture::R5G6B5:
837 return QOpenGLTexture::UInt16_R5G6B5;
838
839 case QOpenGLTexture::RGB5A1:
840 return QOpenGLTexture::UInt16_RGB5A1;
841
842 case QOpenGLTexture::RGBA4:
843 return QOpenGLTexture::UInt16_RGBA4;
844
845 case QOpenGLTexture::RGB10A2:
846 return QOpenGLTexture::UInt32_RGB10A2;
847
848 case QOpenGLTexture::D16:
849 return QOpenGLTexture::UInt16;
850
851 case QOpenGLTexture::D24:
852 case QOpenGLTexture::D32:
853 return QOpenGLTexture::UInt32;
854
855 case QOpenGLTexture::D32F:
856 return QOpenGLTexture::Float32;
857
858 case QOpenGLTexture::D24S8:
859 return QOpenGLTexture::UInt32_D24S8;
860
861 case QOpenGLTexture::D32FS8X24:
862 return QOpenGLTexture::Float32_D32_UInt32_S8_X24;
863
864 case QOpenGLTexture::S8:
865 return QOpenGLTexture::UInt8;
866
867 case QOpenGLTexture::RGB_DXT1:
868 case QOpenGLTexture::RGBA_DXT1:
869 case QOpenGLTexture::RGBA_DXT3:
870 case QOpenGLTexture::RGBA_DXT5:
871 case QOpenGLTexture::R_ATI1N_UNorm:
872 case QOpenGLTexture::R_ATI1N_SNorm:
873 case QOpenGLTexture::RG_ATI2N_UNorm:
874 case QOpenGLTexture::RG_ATI2N_SNorm:
875 case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT:
876 case QOpenGLTexture::RGB_BP_SIGNED_FLOAT:
877 case QOpenGLTexture::RGB_BP_UNorm:
878 case QOpenGLTexture::SRGB8:
879 case QOpenGLTexture::SRGB8_Alpha8:
880 case QOpenGLTexture::SRGB_DXT1:
881 case QOpenGLTexture::SRGB_Alpha_DXT1:
882 case QOpenGLTexture::SRGB_Alpha_DXT3:
883 case QOpenGLTexture::SRGB_Alpha_DXT5:
884 case QOpenGLTexture::SRGB_BP_UNorm:
885 case QOpenGLTexture::R11_EAC_UNorm:
886 case QOpenGLTexture::R11_EAC_SNorm:
887 case QOpenGLTexture::RG11_EAC_UNorm:
888 case QOpenGLTexture::RG11_EAC_SNorm:
889 case QOpenGLTexture::RGB8_ETC2:
890 case QOpenGLTexture::SRGB8_ETC2:
891 case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
892 case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
893 case QOpenGLTexture::RGBA8_ETC2_EAC:
894 case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
895 case QOpenGLTexture::RGB8_ETC1:
896 case QOpenGLTexture::RGBA_ASTC_4x4:
897 case QOpenGLTexture::RGBA_ASTC_5x4:
898 case QOpenGLTexture::RGBA_ASTC_5x5:
899 case QOpenGLTexture::RGBA_ASTC_6x5:
900 case QOpenGLTexture::RGBA_ASTC_6x6:
901 case QOpenGLTexture::RGBA_ASTC_8x5:
902 case QOpenGLTexture::RGBA_ASTC_8x6:
903 case QOpenGLTexture::RGBA_ASTC_8x8:
904 case QOpenGLTexture::RGBA_ASTC_10x5:
905 case QOpenGLTexture::RGBA_ASTC_10x6:
906 case QOpenGLTexture::RGBA_ASTC_10x8:
907 case QOpenGLTexture::RGBA_ASTC_10x10:
908 case QOpenGLTexture::RGBA_ASTC_12x10:
909 case QOpenGLTexture::RGBA_ASTC_12x12:
910 case QOpenGLTexture::SRGB8_Alpha8_ASTC_4x4:
911 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x4:
912 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x5:
913 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x5:
914 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x6:
915 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x5:
916 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x6:
917 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x8:
918 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x5:
919 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x6:
920 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x8:
921 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x10:
922 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x10:
923 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x12:
924 return QOpenGLTexture::UInt8;
925
926 case QOpenGLTexture::DepthFormat:
927 return QOpenGLTexture::UInt32;
928
929 case QOpenGLTexture::AlphaFormat:
930 case QOpenGLTexture::RGBFormat:
931 case QOpenGLTexture::RGBAFormat:
932 case QOpenGLTexture::LuminanceFormat:
933 case QOpenGLTexture::LuminanceAlphaFormat:
934 return QOpenGLTexture::UInt8;
935 }
936
937 Q_UNREACHABLE_RETURN(QOpenGLTexture::NoPixelType);
938}
939
940static bool isCompressedFormat(QOpenGLTexture::TextureFormat internalFormat)
941{
942 switch (internalFormat) {
943 case QOpenGLTexture::NoFormat:
944
945 case QOpenGLTexture::R8_UNorm:
946 case QOpenGLTexture::RG8_UNorm:
947 case QOpenGLTexture::RGB8_UNorm:
948 case QOpenGLTexture::RGBA8_UNorm:
949 case QOpenGLTexture::R16_UNorm:
950 case QOpenGLTexture::RG16_UNorm:
951 case QOpenGLTexture::RGB16_UNorm:
952 case QOpenGLTexture::RGBA16_UNorm:
953 case QOpenGLTexture::R8_SNorm:
954 case QOpenGLTexture::RG8_SNorm:
955 case QOpenGLTexture::RGB8_SNorm:
956 case QOpenGLTexture::RGBA8_SNorm:
957 case QOpenGLTexture::R16_SNorm:
958 case QOpenGLTexture::RG16_SNorm:
959 case QOpenGLTexture::RGB16_SNorm:
960 case QOpenGLTexture::RGBA16_SNorm:
961 case QOpenGLTexture::R8U:
962 case QOpenGLTexture::RG8U:
963 case QOpenGLTexture::RGB8U:
964 case QOpenGLTexture::RGBA8U:
965 case QOpenGLTexture::R16U:
966 case QOpenGLTexture::RG16U:
967 case QOpenGLTexture::RGB16U:
968 case QOpenGLTexture::RGBA16U:
969 case QOpenGLTexture::R32U:
970 case QOpenGLTexture::RG32U:
971 case QOpenGLTexture::RGB32U:
972 case QOpenGLTexture::RGBA32U:
973 case QOpenGLTexture::R8I:
974 case QOpenGLTexture::RG8I:
975 case QOpenGLTexture::RGB8I:
976 case QOpenGLTexture::RGBA8I:
977 case QOpenGLTexture::R16I:
978 case QOpenGLTexture::RG16I:
979 case QOpenGLTexture::RGB16I:
980 case QOpenGLTexture::RGBA16I:
981 case QOpenGLTexture::R32I:
982 case QOpenGLTexture::RG32I:
983 case QOpenGLTexture::RGB32I:
984 case QOpenGLTexture::RGBA32I:
985 case QOpenGLTexture::R16F:
986 case QOpenGLTexture::RG16F:
987 case QOpenGLTexture::RGB16F:
988 case QOpenGLTexture::RGBA16F:
989 case QOpenGLTexture::R32F:
990 case QOpenGLTexture::RG32F:
991 case QOpenGLTexture::RGB32F:
992 case QOpenGLTexture::RGBA32F:
993 case QOpenGLTexture::RGB9E5:
994 case QOpenGLTexture::RG11B10F:
995 case QOpenGLTexture::RG3B2:
996 case QOpenGLTexture::R5G6B5:
997 case QOpenGLTexture::RGB5A1:
998 case QOpenGLTexture::RGBA4:
999 case QOpenGLTexture::RGB10A2:
1000
1001 case QOpenGLTexture::D16:
1002 case QOpenGLTexture::D24:
1003 case QOpenGLTexture::D32:
1004 case QOpenGLTexture::D32F:
1005
1006 case QOpenGLTexture::D24S8:
1007 case QOpenGLTexture::D32FS8X24:
1008
1009 case QOpenGLTexture::S8:
1010 return false;
1011
1012 case QOpenGLTexture::RGB_DXT1:
1013 case QOpenGLTexture::RGBA_DXT1:
1014 case QOpenGLTexture::RGBA_DXT3:
1015 case QOpenGLTexture::RGBA_DXT5:
1016 case QOpenGLTexture::R_ATI1N_UNorm:
1017 case QOpenGLTexture::R_ATI1N_SNorm:
1018 case QOpenGLTexture::RG_ATI2N_UNorm:
1019 case QOpenGLTexture::RG_ATI2N_SNorm:
1020 case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT:
1021 case QOpenGLTexture::RGB_BP_SIGNED_FLOAT:
1022 case QOpenGLTexture::RGB_BP_UNorm:
1023 case QOpenGLTexture::SRGB8:
1024 case QOpenGLTexture::SRGB8_Alpha8:
1025 case QOpenGLTexture::SRGB_DXT1:
1026 case QOpenGLTexture::SRGB_Alpha_DXT1:
1027 case QOpenGLTexture::SRGB_Alpha_DXT3:
1028 case QOpenGLTexture::SRGB_Alpha_DXT5:
1029 case QOpenGLTexture::SRGB_BP_UNorm:
1030 case QOpenGLTexture::R11_EAC_UNorm:
1031 case QOpenGLTexture::R11_EAC_SNorm:
1032 case QOpenGLTexture::RG11_EAC_UNorm:
1033 case QOpenGLTexture::RG11_EAC_SNorm:
1034 case QOpenGLTexture::RGB8_ETC2:
1035 case QOpenGLTexture::SRGB8_ETC2:
1036 case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
1037 case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
1038 case QOpenGLTexture::RGBA8_ETC2_EAC:
1039 case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
1040 case QOpenGLTexture::RGB8_ETC1:
1041 case QOpenGLTexture::RGBA_ASTC_4x4:
1042 case QOpenGLTexture::RGBA_ASTC_5x4:
1043 case QOpenGLTexture::RGBA_ASTC_5x5:
1044 case QOpenGLTexture::RGBA_ASTC_6x5:
1045 case QOpenGLTexture::RGBA_ASTC_6x6:
1046 case QOpenGLTexture::RGBA_ASTC_8x5:
1047 case QOpenGLTexture::RGBA_ASTC_8x6:
1048 case QOpenGLTexture::RGBA_ASTC_8x8:
1049 case QOpenGLTexture::RGBA_ASTC_10x5:
1050 case QOpenGLTexture::RGBA_ASTC_10x6:
1051 case QOpenGLTexture::RGBA_ASTC_10x8:
1052 case QOpenGLTexture::RGBA_ASTC_10x10:
1053 case QOpenGLTexture::RGBA_ASTC_12x10:
1054 case QOpenGLTexture::RGBA_ASTC_12x12:
1055 case QOpenGLTexture::SRGB8_Alpha8_ASTC_4x4:
1056 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x4:
1057 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x5:
1058 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x5:
1059 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x6:
1060 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x5:
1061 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x6:
1062 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x8:
1063 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x5:
1064 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x6:
1065 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x8:
1066 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x10:
1067 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x10:
1068 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x12:
1069 return true;
1070
1071 case QOpenGLTexture::DepthFormat:
1072 case QOpenGLTexture::AlphaFormat:
1073 case QOpenGLTexture::RGBFormat:
1074 case QOpenGLTexture::RGBAFormat:
1075 case QOpenGLTexture::LuminanceFormat:
1076 case QOpenGLTexture::LuminanceAlphaFormat:
1077 return false;
1078 }
1079
1080 Q_UNREACHABLE_RETURN(false);
1081}
1082
1083void QOpenGLTexturePrivate::allocateMutableStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
1084{
1085 // There is no way to allocate mutable storage for compressed textures in in
1086 // versions older than OpenGL 3.1 and OpenGL ES 3.0, because the older specs
1087 // do not mandate accepting null data pointers for glCompressedTexImage*D,
1088 // unlike glTexImage*D (which in turn does not accept compressed formats).
1089 if (isCompressedFormat(format)) {
1090 storageAllocated = true;
1091 return;
1092 }
1093
1094 switch (target) {
1095 case QOpenGLTexture::TargetBuffer:
1096 // Buffer textures get their storage from an external OpenGL buffer
1097 qWarning("Buffer textures do not allocate storage");
1098 return;
1099
1100 case QOpenGLTexture::Target1D:
1101 if (features.testFlag(QOpenGLTexture::Texture1D)) {
1102 for (int level = 0; level < mipLevels; ++level)
1103 texFuncs->glTextureImage1D(textureId, target, bindingTarget, level, format,
1105 0,
1106 pixelFormat, pixelType, nullptr);
1107 } else {
1108 qWarning("1D textures are not supported");
1109 return;
1110 }
1111 break;
1112
1113 case QOpenGLTexture::Target1DArray:
1114 if (features.testFlag(QOpenGLTexture::Texture1D)
1115 && features.testFlag(QOpenGLTexture::TextureArrays)) {
1116 for (int level = 0; level < mipLevels; ++level)
1117 texFuncs->glTextureImage2D(textureId, target, bindingTarget, level, format,
1119 layers,
1120 0,
1121 pixelFormat, pixelType, nullptr);
1122 } else {
1123 qWarning("1D array textures are not supported");
1124 return;
1125 }
1126 break;
1127
1128 case QOpenGLTexture::Target2D:
1129 case QOpenGLTexture::TargetRectangle:
1130 for (int level = 0; level < mipLevels; ++level)
1131 texFuncs->glTextureImage2D(textureId, target, bindingTarget, level, format,
1134 0,
1135 pixelFormat, pixelType, nullptr);
1136 break;
1137
1138 case QOpenGLTexture::TargetCubeMap: {
1139 // Cubemaps are the odd one out. We have to allocate storage for each
1140 // face and miplevel using the special cubemap face targets rather than
1141 // GL_TARGET_CUBEMAP.
1142 const QOpenGLTexture::CubeMapFace faceTargets[] = {
1143 QOpenGLTexture::CubeMapPositiveX, QOpenGLTexture::CubeMapNegativeX,
1144 QOpenGLTexture::CubeMapPositiveY, QOpenGLTexture::CubeMapNegativeY,
1145 QOpenGLTexture::CubeMapPositiveZ, QOpenGLTexture::CubeMapNegativeZ
1146 };
1147
1148 for (int faceTarget = 0; faceTarget < 6; ++faceTarget) {
1149 for (int level = 0; level < mipLevels; ++level) {
1150 texFuncs->glTextureImage2D(textureId, faceTargets[faceTarget], bindingTarget,
1151 level, format,
1154 0,
1155 pixelFormat, pixelType, nullptr);
1156 }
1157 }
1158 break;
1159 }
1160
1161 case QOpenGLTexture::Target2DArray:
1162 if (features.testFlag(QOpenGLTexture::TextureArrays)) {
1163 for (int level = 0; level < mipLevels; ++level)
1164 texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format,
1167 layers,
1168 0,
1169 pixelFormat, pixelType, nullptr);
1170 } else {
1171 qWarning("Array textures are not supported");
1172 return;
1173 }
1174 break;
1175
1176 case QOpenGLTexture::TargetCubeMapArray:
1177 // Cubemap arrays must specify number of layer-faces (6 * layers) as depth parameter
1178 if (features.testFlag(QOpenGLTexture::TextureCubeMapArrays)) {
1179 for (int level = 0; level < mipLevels; ++level)
1180 texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format,
1183 6 * layers,
1184 0,
1185 pixelFormat, pixelType, nullptr);
1186 } else {
1187 qWarning("Cubemap Array textures are not supported");
1188 return;
1189 }
1190 break;
1191
1192 case QOpenGLTexture::Target3D:
1193 if (features.testFlag(QOpenGLTexture::Texture3D)) {
1194 for (int level = 0; level < mipLevels; ++level)
1195 texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format,
1199 0,
1200 pixelFormat, pixelType, nullptr);
1201 } else {
1202 qWarning("3D textures are not supported");
1203 return;
1204 }
1205 break;
1206
1207 case QOpenGLTexture::Target2DMultisample:
1208 if (features.testFlag(QOpenGLTexture::TextureMultisample)) {
1209 texFuncs->glTextureImage2DMultisample(textureId, target, bindingTarget, samples, format,
1210 dimensions[0], dimensions[1],
1212 } else {
1213 qWarning("Multisample textures are not supported");
1214 return;
1215 }
1216 break;
1217
1218 case QOpenGLTexture::Target2DMultisampleArray:
1219 if (features.testFlag(QOpenGLTexture::TextureMultisample)
1220 && features.testFlag(QOpenGLTexture::TextureArrays)) {
1221 texFuncs->glTextureImage3DMultisample(textureId, target, bindingTarget, samples, format,
1224 } else {
1225 qWarning("Multisample array textures are not supported");
1226 return;
1227 }
1228 break;
1229 }
1230
1231 storageAllocated = true;
1232}
1233
1235{
1236 switch (target) {
1237 case QOpenGLTexture::TargetBuffer:
1238 // Buffer textures get their storage from an external OpenGL buffer
1239 qWarning("Buffer textures do not allocate storage");
1240 return;
1241
1242 case QOpenGLTexture::Target1D:
1243 if (features.testFlag(QOpenGLTexture::Texture1D)) {
1244 texFuncs->glTextureStorage1D(textureId, target, bindingTarget, mipLevels, format,
1245 dimensions[0]);
1246 } else {
1247 qWarning("1D textures are not supported");
1248 return;
1249 }
1250 break;
1251
1252 case QOpenGLTexture::Target1DArray:
1253 if (features.testFlag(QOpenGLTexture::Texture1D)
1254 && features.testFlag(QOpenGLTexture::TextureArrays)) {
1255 texFuncs->glTextureStorage2D(textureId, target, bindingTarget, mipLevels, format,
1256 dimensions[0], layers);
1257 } else {
1258 qWarning("1D array textures are not supported");
1259 return;
1260 }
1261 break;
1262
1263 case QOpenGLTexture::Target2D:
1264 case QOpenGLTexture::TargetCubeMap:
1265 case QOpenGLTexture::TargetRectangle:
1266 texFuncs->glTextureStorage2D(textureId, target, bindingTarget, mipLevels, format,
1267 dimensions[0], dimensions[1]);
1268 break;
1269
1270 case QOpenGLTexture::Target2DArray:
1271 if (features.testFlag(QOpenGLTexture::TextureArrays)) {
1272 texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format,
1273 dimensions[0], dimensions[1], layers);
1274 } else {
1275 qWarning("Array textures are not supported");
1276 return;
1277 }
1278 break;
1279
1280 case QOpenGLTexture::TargetCubeMapArray:
1281 // Cubemap arrays must specify number of layer-faces (6 * layers) as depth parameter
1282 if (features.testFlag(QOpenGLTexture::TextureCubeMapArrays)) {
1283 texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format,
1284 dimensions[0], dimensions[1], 6 * layers);
1285 } else {
1286 qWarning("Cubemap Array textures are not supported");
1287 return;
1288 }
1289 break;
1290
1291 case QOpenGLTexture::Target3D:
1292 if (features.testFlag(QOpenGLTexture::Texture3D)) {
1293 texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format,
1294 dimensions[0], dimensions[1], dimensions[2]);
1295 } else {
1296 qWarning("3D textures are not supported");
1297 return;
1298 }
1299 break;
1300
1301 case QOpenGLTexture::Target2DMultisample:
1302 if (features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage)) {
1303 texFuncs->glTextureStorage2DMultisample(textureId, target, bindingTarget, samples, format,
1304 dimensions[0], dimensions[1],
1306 } else {
1307 qWarning("Multisample textures are not supported");
1308 return;
1309 }
1310 break;
1311
1312 case QOpenGLTexture::Target2DMultisampleArray:
1313 if (features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage)
1314 && features.testFlag(QOpenGLTexture::TextureArrays)) {
1315 texFuncs->glTextureStorage3DMultisample(textureId, target, bindingTarget, samples, format,
1318 } else {
1319 qWarning("Multisample array textures are not supported");
1320 return;
1321 }
1322 break;
1323 }
1324
1325 storageAllocated = true;
1326}
1327
1328void QOpenGLTexturePrivate::setData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace,
1329 QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType,
1330 const void *data, const QOpenGLPixelTransferOptions * const options)
1331{
1332 switch (target) {
1333 case QOpenGLTexture::Target1D:
1334 Q_UNUSED(layer);
1335 Q_UNUSED(cubeFace);
1336 Q_UNUSED(layerCount);
1337 texFuncs->glTextureSubImage1D(textureId, target, bindingTarget, mipLevel,
1338 0, mipLevelSize( mipLevel, dimensions[0] ),
1339 sourceFormat, sourceType, data, options);
1340 break;
1341
1342 case QOpenGLTexture::Target1DArray:
1343 Q_UNUSED(cubeFace);
1344 texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
1345 0, layer,
1346 mipLevelSize(mipLevel, dimensions[0]),
1347 layerCount,
1348 sourceFormat, sourceType, data, options);
1349 break;
1350
1351 case QOpenGLTexture::Target2D:
1352 Q_UNUSED(layer);
1353 Q_UNUSED(cubeFace);
1354 Q_UNUSED(layerCount);
1355 texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
1356 0, 0,
1357 mipLevelSize(mipLevel, dimensions[0]),
1358 mipLevelSize(mipLevel, dimensions[1]),
1359 sourceFormat, sourceType, data, options);
1360 break;
1361
1362 case QOpenGLTexture::Target2DArray:
1363 Q_UNUSED(cubeFace);
1364 texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
1365 0, 0, layer,
1366 mipLevelSize(mipLevel, dimensions[0]),
1367 mipLevelSize(mipLevel, dimensions[1]),
1368 layerCount,
1369 sourceFormat, sourceType, data, options);
1370 break;
1371
1372 case QOpenGLTexture::Target3D:
1373 Q_UNUSED(cubeFace);
1374 Q_UNUSED(layerCount);
1375 texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
1376 0, 0, layer,
1377 mipLevelSize(mipLevel, dimensions[0]),
1378 mipLevelSize(mipLevel, dimensions[1]),
1379 mipLevelSize(mipLevel, dimensions[2]),
1380 sourceFormat, sourceType, data, options);
1381 break;
1382
1383 case QOpenGLTexture::TargetCubeMap:
1384 Q_UNUSED(layer);
1385 Q_UNUSED(layerCount);
1386 texFuncs->glTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel,
1387 0, 0,
1388 mipLevelSize(mipLevel, dimensions[0]),
1389 mipLevelSize(mipLevel, dimensions[1]),
1390 sourceFormat, sourceType, data, options);
1391 break;
1392
1393 case QOpenGLTexture::TargetCubeMapArray: {
1394 int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX;
1395 int layerFace = 6 * layer + faceIndex;
1396 texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
1397 0, 0, layerFace,
1398 mipLevelSize(mipLevel, dimensions[0]),
1399 mipLevelSize(mipLevel, dimensions[1]),
1400 layerCount,
1401 sourceFormat, sourceType, data, options);
1402 break;
1403 }
1404
1405 case QOpenGLTexture::TargetRectangle:
1406 Q_UNUSED(mipLevel);
1407 Q_UNUSED(layer);
1408 Q_UNUSED(cubeFace);
1409 Q_UNUSED(layerCount);
1410 texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, 0,
1411 0, 0,
1412 dimensions[0],
1413 dimensions[1],
1414 sourceFormat, sourceType, data, options);
1415 break;
1416
1417 case QOpenGLTexture::Target2DMultisample:
1418 case QOpenGLTexture::Target2DMultisampleArray:
1419 case QOpenGLTexture::TargetBuffer:
1420 // We don't upload pixel data for these targets
1421 qWarning("QOpenGLTexture::setData(): Texture target does not support pixel data upload");
1422 break;
1423 }
1424
1425 // If requested perform automatic mip map generation
1426 if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) {
1427 Q_Q(QOpenGLTexture);
1428 q->generateMipMaps();
1429 }
1430}
1431
1432void QOpenGLTexturePrivate::setData(int xOffset, int yOffset, int zOffset, int width, int height, int depth,
1433 int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace,
1434 QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType,
1435 const void *data, const QOpenGLPixelTransferOptions * const options)
1436{
1437 switch (target) {
1438 case QOpenGLTexture::Target1D:
1439 Q_UNUSED(layer);
1440 Q_UNUSED(cubeFace);
1441 Q_UNUSED(layerCount);
1442 Q_UNUSED(yOffset);
1443 Q_UNUSED(zOffset);
1444 Q_UNUSED(height);
1445 Q_UNUSED(depth);
1446 texFuncs->glTextureSubImage1D(textureId, target, bindingTarget, mipLevel,
1447 xOffset, width,
1448 sourceFormat, sourceType, data, options);
1449 break;
1450
1451 case QOpenGLTexture::Target1DArray:
1452 Q_UNUSED(cubeFace);
1453 Q_UNUSED(yOffset);
1454 Q_UNUSED(zOffset);
1455 Q_UNUSED(height);
1456 Q_UNUSED(depth);
1457 texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
1458 xOffset, layer,
1459 width,
1460 layerCount,
1461 sourceFormat, sourceType, data, options);
1462 break;
1463
1464 case QOpenGLTexture::Target2D:
1465 Q_UNUSED(layer);
1466 Q_UNUSED(cubeFace);
1467 Q_UNUSED(layerCount);
1468 Q_UNUSED(zOffset);
1469 Q_UNUSED(depth);
1470 texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
1471 xOffset, yOffset,
1472 width, height,
1473 sourceFormat, sourceType, data, options);
1474 break;
1475
1476 case QOpenGLTexture::Target2DArray:
1477 Q_UNUSED(cubeFace);
1478 Q_UNUSED(zOffset);
1479 Q_UNUSED(depth);
1480 texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
1481 xOffset, yOffset, layer,
1482 width, height, layerCount,
1483 sourceFormat, sourceType, data, options);
1484 break;
1485
1486 case QOpenGLTexture::Target3D:
1487 Q_UNUSED(cubeFace);
1488 Q_UNUSED(layerCount);
1489 texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
1490 xOffset, yOffset, zOffset,
1491 width, height, depth,
1492 sourceFormat, sourceType, data, options);
1493 break;
1494
1495 case QOpenGLTexture::TargetCubeMap:
1496 Q_UNUSED(layer);
1497 Q_UNUSED(layerCount);
1498 Q_UNUSED(zOffset);
1499 Q_UNUSED(depth);
1500 texFuncs->glTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel,
1501 xOffset, yOffset,
1502 width, height,
1503 sourceFormat, sourceType, data, options);
1504 break;
1505
1506 case QOpenGLTexture::TargetCubeMapArray: {
1507 Q_UNUSED(zOffset);
1508 Q_UNUSED(depth);
1509 int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX;
1510 int layerFace = 6 * layer + faceIndex;
1511 texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
1512 xOffset, yOffset, layerFace,
1513 width, height,
1514 layerCount,
1515 sourceFormat, sourceType, data, options);
1516 break;
1517 }
1518
1519 case QOpenGLTexture::TargetRectangle:
1520 Q_UNUSED(mipLevel);
1521 Q_UNUSED(layer);
1522 Q_UNUSED(cubeFace);
1523 Q_UNUSED(layerCount);
1524 Q_UNUSED(zOffset);
1525 Q_UNUSED(depth);
1526 texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, 0,
1527 xOffset, yOffset,
1528 width, height,
1529 sourceFormat, sourceType, data, options);
1530 break;
1531
1532 case QOpenGLTexture::Target2DMultisample:
1533 case QOpenGLTexture::Target2DMultisampleArray:
1534 case QOpenGLTexture::TargetBuffer:
1535 // We don't upload pixel data for these targets
1536 qWarning("QOpenGLTexture::setData(): Texture target does not support pixel data upload");
1537 break;
1538 }
1539
1540 // If requested perform automatic mip map generation
1541 if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) {
1542 Q_Q(QOpenGLTexture);
1543 q->generateMipMaps();
1544 }
1545}
1546
1547
1548void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, int layerCount,
1549 QOpenGLTexture::CubeMapFace cubeFace,
1550 int dataSize, const void *data,
1551 const QOpenGLPixelTransferOptions * const options)
1552{
1553 if (!isCompressedFormat(format)) {
1554 qWarning("Cannot set compressed data for non-compressed format 0x%x", format);
1555 return;
1556 }
1557
1558 const bool needsFullSpec = !isUsingImmutableStorage(); // was allocateStorage() a no-op?
1559
1560 switch (target) {
1561 case QOpenGLTexture::Target1D:
1562 Q_UNUSED(layer);
1563 Q_UNUSED(cubeFace);
1564 Q_UNUSED(layerCount);
1565 if (needsFullSpec) {
1566 texFuncs->glCompressedTextureImage1D(textureId, target, bindingTarget, mipLevel,
1567 format,
1568 mipLevelSize(mipLevel, dimensions[0]),
1569 0, dataSize, data, options);
1570 } else {
1571 texFuncs->glCompressedTextureSubImage1D(textureId, target, bindingTarget, mipLevel,
1572 0, mipLevelSize( mipLevel, dimensions[0] ),
1573 format, dataSize, data, options);
1574 }
1575 break;
1576
1577 case QOpenGLTexture::Target1DArray:
1578 Q_UNUSED(cubeFace);
1579 if (!needsFullSpec) {
1580 texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
1581 0, layer,
1582 mipLevelSize(mipLevel, dimensions[0]),
1583 layerCount,
1584 format, dataSize, data, options);
1585 }
1586 break;
1587
1588 case QOpenGLTexture::Target2D:
1589 Q_UNUSED(layer);
1590 Q_UNUSED(cubeFace);
1591 Q_UNUSED(layerCount);
1592 if (needsFullSpec) {
1593 texFuncs->glCompressedTextureImage2D(textureId, target, bindingTarget, mipLevel,
1594 format,
1595 mipLevelSize(mipLevel, dimensions[0]),
1596 mipLevelSize(mipLevel, dimensions[1]),
1597 0, dataSize, data, options);
1598 } else {
1599 texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
1600 0, 0,
1601 mipLevelSize(mipLevel, dimensions[0]),
1602 mipLevelSize(mipLevel, dimensions[1]),
1603 format, dataSize, data, options);
1604 }
1605 break;
1606
1607 case QOpenGLTexture::Target2DArray:
1608 Q_UNUSED(cubeFace);
1609 if (!needsFullSpec) {
1610 texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
1611 0, 0, layer,
1612 mipLevelSize(mipLevel, dimensions[0]),
1613 mipLevelSize(mipLevel, dimensions[1]),
1614 layerCount,
1615 format, dataSize, data, options);
1616 }
1617 break;
1618
1619 case QOpenGLTexture::Target3D:
1620 Q_UNUSED(cubeFace);
1621 Q_UNUSED(layerCount);
1622 if (needsFullSpec) {
1623 texFuncs->glCompressedTextureImage3D(textureId, target, bindingTarget, mipLevel,
1624 format,
1625 mipLevelSize(mipLevel, dimensions[0]),
1626 mipLevelSize(mipLevel, dimensions[1]),
1627 mipLevelSize(mipLevel, dimensions[2]),
1628 0, dataSize, data, options);
1629 } else {
1630 texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
1631 0, 0, layer,
1632 mipLevelSize(mipLevel, dimensions[0]),
1633 mipLevelSize(mipLevel, dimensions[1]),
1634 mipLevelSize(mipLevel, dimensions[2]),
1635 format, dataSize, data, options);
1636 }
1637 break;
1638
1639 case QOpenGLTexture::TargetCubeMap:
1640 Q_UNUSED(layer);
1641 Q_UNUSED(layerCount);
1642 if (needsFullSpec) {
1643 texFuncs->glCompressedTextureImage2D(textureId, cubeFace, bindingTarget, mipLevel,
1644 format,
1645 mipLevelSize(mipLevel, dimensions[0]),
1646 mipLevelSize(mipLevel, dimensions[1]),
1647 0, dataSize, data, options);
1648 } else {
1649 texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel,
1650 0, 0,
1651 mipLevelSize(mipLevel, dimensions[0]),
1652 mipLevelSize(mipLevel, dimensions[1]),
1653 format, dataSize, data, options);
1654 }
1655 break;
1656
1657 case QOpenGLTexture::TargetCubeMapArray: {
1658 int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX;
1659 int layerFace = 6 * layer + faceIndex;
1660 if (!needsFullSpec) {
1661 texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
1662 0, 0, layerFace,
1663 mipLevelSize(mipLevel, dimensions[0]),
1664 mipLevelSize(mipLevel, dimensions[1]),
1665 layerCount,
1666 format, dataSize, data, options);
1667 }
1668 break;
1669 }
1670
1671 case QOpenGLTexture::TargetRectangle:
1672 case QOpenGLTexture::Target2DMultisample:
1673 case QOpenGLTexture::Target2DMultisampleArray:
1674 case QOpenGLTexture::TargetBuffer:
1675 // We don't upload pixel data for these targets
1676 qWarning("QOpenGLTexture::setCompressedData(): Texture target does not support pixel data upload");
1677 break;
1678 }
1679
1680 // If requested perform automatic mip map generation
1681 if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) {
1682 Q_Q(QOpenGLTexture);
1683 q->generateMipMaps();
1684 }
1685}
1686
1687void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::WrapMode mode)
1688{
1689 switch (target) {
1690 case QOpenGLTexture::Target1D:
1691 case QOpenGLTexture::Target1DArray:
1692 case QOpenGLTexture::TargetBuffer:
1693 wrapModes[0] = mode;
1694 texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
1695 break;
1696
1697 case QOpenGLTexture::Target2D:
1698 case QOpenGLTexture::Target2DArray:
1699 case QOpenGLTexture::TargetCubeMap:
1700 case QOpenGLTexture::TargetCubeMapArray:
1701 case QOpenGLTexture::Target2DMultisample:
1702 case QOpenGLTexture::Target2DMultisampleArray:
1703 case QOpenGLTexture::TargetRectangle:
1704 wrapModes[0] = wrapModes[1] = mode;
1705 texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
1706 texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode);
1707 break;
1708
1709 case QOpenGLTexture::Target3D:
1710 wrapModes[0] = wrapModes[1] = wrapModes[2] = mode;
1711 texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
1712 texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode);
1713 texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_R, mode);
1714 break;
1715 }
1716}
1717
1718void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::CoordinateDirection direction, QOpenGLTexture::WrapMode mode)
1719{
1720 switch (target) {
1721 case QOpenGLTexture::Target1D:
1722 case QOpenGLTexture::Target1DArray:
1723 case QOpenGLTexture::TargetBuffer:
1724 switch (direction) {
1725 case QOpenGLTexture::DirectionS:
1726 wrapModes[0] = mode;
1727 texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
1728 break;
1729
1730 case QOpenGLTexture::DirectionT:
1731 case QOpenGLTexture::DirectionR:
1732 qWarning("QOpenGLTexture::setWrapMode() direction not valid for this texture target");
1733 break;
1734 }
1735 break;
1736
1737 case QOpenGLTexture::Target2D:
1738 case QOpenGLTexture::Target2DArray:
1739 case QOpenGLTexture::TargetCubeMap:
1740 case QOpenGLTexture::TargetCubeMapArray:
1741 case QOpenGLTexture::Target2DMultisample:
1742 case QOpenGLTexture::Target2DMultisampleArray:
1743 case QOpenGLTexture::TargetRectangle:
1744 switch (direction) {
1745 case QOpenGLTexture::DirectionS:
1746 wrapModes[0] = mode;
1747 texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
1748 break;
1749
1750 case QOpenGLTexture::DirectionT:
1751 wrapModes[1] = mode;
1752 texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode);
1753 break;
1754
1755 case QOpenGLTexture::DirectionR:
1756 qWarning("QOpenGLTexture::setWrapMode() direction not valid for this texture target");
1757 break;
1758 }
1759 break;
1760
1761 case QOpenGLTexture::Target3D:
1762 switch (direction) {
1763 case QOpenGLTexture::DirectionS:
1764 wrapModes[0] = mode;
1765 texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode);
1766 break;
1767
1768 case QOpenGLTexture::DirectionT:
1769 wrapModes[1] = mode;
1770 texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode);
1771 break;
1772
1773 case QOpenGLTexture::DirectionR:
1774 wrapModes[2] = mode;
1775 texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode);
1776 break;
1777 }
1778 break;
1779 }
1780}
1781
1782QOpenGLTexture::WrapMode QOpenGLTexturePrivate::wrapMode(QOpenGLTexture::CoordinateDirection direction) const
1783{
1784 switch (target) {
1785 case QOpenGLTexture::Target1D:
1786 case QOpenGLTexture::Target1DArray:
1787 case QOpenGLTexture::TargetBuffer:
1788 switch (direction) {
1789 case QOpenGLTexture::DirectionS:
1790 return wrapModes[0];
1791
1792 case QOpenGLTexture::DirectionT:
1793 case QOpenGLTexture::DirectionR:
1794 qWarning("QOpenGLTexture::wrapMode() direction not valid for this texture target");
1795 return QOpenGLTexture::Repeat;
1796 }
1797 break;
1798
1799 case QOpenGLTexture::Target2D:
1800 case QOpenGLTexture::Target2DArray:
1801 case QOpenGLTexture::TargetCubeMap:
1802 case QOpenGLTexture::TargetCubeMapArray:
1803 case QOpenGLTexture::Target2DMultisample:
1804 case QOpenGLTexture::Target2DMultisampleArray:
1805 case QOpenGLTexture::TargetRectangle:
1806 switch (direction) {
1807 case QOpenGLTexture::DirectionS:
1808 return wrapModes[0];
1809
1810 case QOpenGLTexture::DirectionT:
1811 return wrapModes[1];
1812
1813 case QOpenGLTexture::DirectionR:
1814 qWarning("QOpenGLTexture::wrapMode() direction not valid for this texture target");
1815 return QOpenGLTexture::Repeat;
1816 }
1817 break;
1818
1819 case QOpenGLTexture::Target3D:
1820 switch (direction) {
1821 case QOpenGLTexture::DirectionS:
1822 return wrapModes[0];
1823
1824 case QOpenGLTexture::DirectionT:
1825 return wrapModes[1];
1826
1827 case QOpenGLTexture::DirectionR:
1828 return wrapModes[2];
1829 }
1830 break;
1831 }
1832 // Should never get here
1833 Q_ASSERT(false);
1834 return QOpenGLTexture::Repeat;
1835}
1836
1837QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target viewTarget,
1838 QOpenGLTexture::TextureFormat viewFormat,
1839 int minimumMipmapLevel, int maximumMipmapLevel,
1840 int minimumLayer, int maximumLayer) const
1841{
1842 // Do sanity checks - see http://www.opengl.org/wiki/GLAPI/glTextureView
1843
1844 // Check the targets are compatible
1845 bool viewTargetCompatible = false;
1846 switch (target) {
1847 case QOpenGLTexture::Target1D:
1848 case QOpenGLTexture::Target1DArray:
1849 viewTargetCompatible = (viewTarget == QOpenGLTexture::Target1D
1850 || viewTarget == QOpenGLTexture::Target1DArray);
1851 break;
1852
1853
1854 case QOpenGLTexture::Target2D:
1855 case QOpenGLTexture::Target2DArray:
1856 viewTargetCompatible = (viewTarget == QOpenGLTexture::Target2D
1857 || viewTarget == QOpenGLTexture::Target2DArray);
1858 break;
1859
1860 case QOpenGLTexture::Target3D:
1861 viewTargetCompatible = (viewTarget == QOpenGLTexture::Target3D);
1862 break;
1863
1864 case QOpenGLTexture::TargetCubeMap:
1865 case QOpenGLTexture::TargetCubeMapArray:
1866 viewTargetCompatible = (viewTarget == QOpenGLTexture::TargetCubeMap
1867 || viewTarget == QOpenGLTexture::Target2D
1868 || viewTarget == QOpenGLTexture::Target2DArray
1869 || viewTarget == QOpenGLTexture::TargetCubeMapArray);
1870 break;
1871
1872 case QOpenGLTexture::Target2DMultisample:
1873 case QOpenGLTexture::Target2DMultisampleArray:
1874 viewTargetCompatible = (viewTarget == QOpenGLTexture::Target2DMultisample
1875 || viewTarget == QOpenGLTexture::Target2DMultisampleArray);
1876 break;
1877
1878 case QOpenGLTexture::TargetRectangle:
1879 viewTargetCompatible = (viewTarget == QOpenGLTexture::TargetRectangle);
1880 break;
1881
1882 case QOpenGLTexture::TargetBuffer:
1883 // Cannot be used with texture views
1884 break;
1885 }
1886
1887 if (!viewTargetCompatible) {
1888 qWarning("QOpenGLTexture::createTextureView(): Incompatible source and view targets");
1889 return nullptr;
1890 }
1891
1892 // Check the formats are compatible
1893 bool viewFormatCompatible = false;
1894 switch (formatClass) {
1895 case QOpenGLTexture::NoFormatClass:
1896 break;
1897
1898 case QOpenGLTexture::FormatClass_128Bit:
1899 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA32F
1900 || viewFormat == QOpenGLTexture::RGBA32U
1901 || viewFormat == QOpenGLTexture::RGBA32I);
1902 break;
1903
1904 case QOpenGLTexture::FormatClass_96Bit:
1905 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB32F
1906 || viewFormat == QOpenGLTexture::RGB32U
1907 || viewFormat == QOpenGLTexture::RGB32I);
1908 break;
1909
1910 case QOpenGLTexture::FormatClass_64Bit:
1911 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA16F
1912 || viewFormat == QOpenGLTexture::RG32F
1913 || viewFormat == QOpenGLTexture::RGBA16U
1914 || viewFormat == QOpenGLTexture::RG32U
1915 || viewFormat == QOpenGLTexture::RGBA16I
1916 || viewFormat == QOpenGLTexture::RG32I
1917 || viewFormat == QOpenGLTexture::RGBA16_UNorm
1918 || viewFormat == QOpenGLTexture::RGBA16_SNorm);
1919 break;
1920
1921 case QOpenGLTexture::FormatClass_48Bit:
1922 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB16_UNorm
1923 || viewFormat == QOpenGLTexture::RGB16_SNorm
1924 || viewFormat == QOpenGLTexture::RGB16F
1925 || viewFormat == QOpenGLTexture::RGB16U
1926 || viewFormat == QOpenGLTexture::RGB16I);
1927 break;
1928
1929 case QOpenGLTexture::FormatClass_32Bit:
1930 viewFormatCompatible = (viewFormat == QOpenGLTexture::RG16F
1931 || viewFormat == QOpenGLTexture::RG11B10F
1932 || viewFormat == QOpenGLTexture::R32F
1933 || viewFormat == QOpenGLTexture::RGB10A2
1934 || viewFormat == QOpenGLTexture::RGBA8U
1935 || viewFormat == QOpenGLTexture::RG16U
1936 || viewFormat == QOpenGLTexture::R32U
1937 || viewFormat == QOpenGLTexture::RGBA8I
1938 || viewFormat == QOpenGLTexture::RG16I
1939 || viewFormat == QOpenGLTexture::R32I
1940 || viewFormat == QOpenGLTexture::RGBA8_UNorm
1941 || viewFormat == QOpenGLTexture::RG16_UNorm
1942 || viewFormat == QOpenGLTexture::RGBA8_SNorm
1943 || viewFormat == QOpenGLTexture::RG16_SNorm
1944 || viewFormat == QOpenGLTexture::SRGB8_Alpha8
1945 || viewFormat == QOpenGLTexture::RGB9E5);
1946 break;
1947
1948 case QOpenGLTexture::FormatClass_24Bit:
1949 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB8_UNorm
1950 || viewFormat == QOpenGLTexture::RGB8_SNorm
1951 || viewFormat == QOpenGLTexture::SRGB8
1952 || viewFormat == QOpenGLTexture::RGB8U
1953 || viewFormat == QOpenGLTexture::RGB8I);
1954 break;
1955
1956 case QOpenGLTexture::FormatClass_16Bit:
1957 viewFormatCompatible = (viewFormat == QOpenGLTexture::R16F
1958 || viewFormat == QOpenGLTexture::RG8U
1959 || viewFormat == QOpenGLTexture::R16U
1960 || viewFormat == QOpenGLTexture::RG8I
1961 || viewFormat == QOpenGLTexture::R16I
1962 || viewFormat == QOpenGLTexture::RG8_UNorm
1963 || viewFormat == QOpenGLTexture::R16_UNorm
1964 || viewFormat == QOpenGLTexture::RG8_SNorm
1965 || viewFormat == QOpenGLTexture::R16_SNorm);
1966 break;
1967
1968 case QOpenGLTexture::FormatClass_8Bit:
1969 viewFormatCompatible = (viewFormat == QOpenGLTexture::R8U
1970 || viewFormat == QOpenGLTexture::R8I
1971 || viewFormat == QOpenGLTexture::R8_UNorm
1972 || viewFormat == QOpenGLTexture::R8_SNorm);
1973 break;
1974
1975 case QOpenGLTexture::FormatClass_RGTC1_R:
1976 viewFormatCompatible = (viewFormat == QOpenGLTexture::R_ATI1N_UNorm
1977 || viewFormat == QOpenGLTexture::R_ATI1N_SNorm);
1978 break;
1979
1980 case QOpenGLTexture::FormatClass_RGTC2_RG:
1981 viewFormatCompatible = (viewFormat == QOpenGLTexture::RG_ATI2N_UNorm
1982 || viewFormat == QOpenGLTexture::RG_ATI2N_SNorm);
1983 break;
1984
1985 case QOpenGLTexture::FormatClass_BPTC_Unorm:
1986 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB_BP_UNorm
1987 || viewFormat == QOpenGLTexture::SRGB_BP_UNorm);
1988 break;
1989
1990 case QOpenGLTexture::FormatClass_BPTC_Float:
1991 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT
1992 || viewFormat == QOpenGLTexture::RGB_BP_SIGNED_FLOAT);
1993 break;
1994
1995 case QOpenGLTexture::FormatClass_S3TC_DXT1_RGB:
1996 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB_DXT1
1997 || viewFormat == QOpenGLTexture::SRGB_DXT1);
1998 break;
1999
2000 case QOpenGLTexture::FormatClass_S3TC_DXT1_RGBA:
2001 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA_DXT1
2002 || viewFormat == QOpenGLTexture::SRGB_Alpha_DXT1);
2003 break;
2004
2005 case QOpenGLTexture::FormatClass_S3TC_DXT3_RGBA:
2006 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA_DXT3
2007 || viewFormat == QOpenGLTexture::SRGB_Alpha_DXT3);
2008 break;
2009
2010 case QOpenGLTexture::FormatClass_S3TC_DXT5_RGBA:
2011 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA_DXT5
2012 || viewFormat == QOpenGLTexture::SRGB_Alpha_DXT5);
2013 break;
2014
2015 case QOpenGLTexture::FormatClass_Unique:
2016 viewFormatCompatible = (viewFormat == format);
2017 break;
2018 }
2019
2020 if (!viewFormatCompatible) {
2021 qWarning("QOpenGLTexture::createTextureView(): Incompatible source and view formats");
2022 return nullptr;
2023 }
2024
2025
2026 // Create a view
2027 QOpenGLTexture *view = new QOpenGLTexture(viewTarget);
2028 view->setFormat(viewFormat);
2029 view->create();
2030 view->d_ptr->textureView = true;
2031 texFuncs->glTextureView(view->textureId(), viewTarget, textureId, viewFormat,
2032 minimumMipmapLevel, maximumMipmapLevel - minimumMipmapLevel + 1,
2033 minimumLayer, maximumLayer - minimumLayer + 1);
2034 return view;
2035}
2036
2037
2038/*!
2039 \class QOpenGLTexture
2040 \inmodule QtGui
2041 \since 5.2
2042 \wrapper
2043 \brief The QOpenGLTexture class encapsulates an OpenGL texture object.
2044
2045 QOpenGLTexture makes it easy to work with OpenGL textures and the myriad features
2046 and targets that they offer depending upon the capabilities of your OpenGL implementation.
2047
2048 The typical usage pattern for QOpenGLTexture is
2049 \list
2050 \li Instantiate the object specifying the texture target type
2051 \li Set properties that affect the storage requirements e.g. storage format, dimensions
2052 \li Allocate the server-side storage
2053 \li Optionally upload pixel data
2054 \li Optionally set any additional properties e.g. filtering and border options
2055 \li Render with texture or render to texture
2056 \endlist
2057
2058 In the common case of simply using a QImage as the source of texture pixel data
2059 most of the above steps are performed automatically.
2060
2061 \code
2062 // Prepare texture
2063 QOpenGLTexture *texture = new QOpenGLTexture(QImage(fileName).flipped());
2064 texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
2065 texture->setMagnificationFilter(QOpenGLTexture::Linear);
2066 ...
2067 // Render with texture
2068 texture->bind();
2069 glDrawArrays(...);
2070 \endcode
2071
2072 Note that the QImage is flipped vertically to account for the fact that
2073 OpenGL and QImage use opposite directions for the y axis. Another option
2074 would be to transform your texture coordinates.
2075
2076 \warning All data consumed by QOpenGLTexture is expected to be trusted
2077 content. Pixel and image data is passed on to the underlying OpenGL
2078 implementation. Application developers are advised to carefully consider the
2079 potential implications before passing in user-provided content to functions
2080 such as setData().
2081*/
2082
2083/*!
2084 \enum QOpenGLTexture::Filter
2085 This enum defines the filtering parameters for a QOpenGLTexture object.
2086 \value Nearest Equivalent to GL_NEAREST
2087 \value Linear Equivalent to GL_LINEAR
2088 \value NearestMipMapNearest Equivalent to GL_NEAREST_MIPMAP_NEAREST
2089 \value NearestMipMapLinear Equivalent to GL_NEAREST_MIPMAP_LINEAR
2090 \value LinearMipMapNearest Equivalent to GL_LINEAR_MIPMAP_NEAREST
2091 \value LinearMipMapLinear Equivalent to GL_LINEAR_MIPMAP_LINEAR
2092*/
2093
2094/*!
2095 \enum QOpenGLTexture::Target
2096 This enum defines the texture target of a QOpenGLTexture object.
2097 For more information on creating array textures, see \l{Array Texture}.
2098
2099 \value Target1D A 1-dimensional texture.
2100 Equivalent to GL_TEXTURE_1D.
2101 \value Target1DArray An array of 1-dimensional textures.
2102 Equivalent to GL_TEXTURE_1D_ARRAY
2103 \value Target2D A 2-dimensional texture.
2104 Equivalent to GL_TEXTURE_2D
2105 \value Target2DArray An array of 2-dimensional textures.
2106 Equivalent to GL_TEXTURE_2D_ARRAY
2107 \value Target3D A 3-dimensional texture.
2108 Equivalent to GL_TEXTURE_3D
2109 \value TargetCubeMap A cubemap texture.
2110 Equivalent to GL_TEXTURE_CUBE_MAP
2111 \value TargetCubeMapArray An array of cubemap textures.
2112 Equivalent to GL_TEXTURE_CUBE_MAP_ARRAY
2113 \value Target2DMultisample A 2-dimensional texture with multisample support.
2114 Equivalent to GL_TEXTURE_2D_MULTISAMPLE
2115 \value Target2DMultisampleArray An array of 2-dimensional textures with multisample support.
2116 Equivalent to GL_TEXTURE_2D_MULTISAMPLE_ARRAY
2117 \value TargetRectangle A rectangular 2-dimensional texture.
2118 Equivalent to GL_TEXTURE_RECTANGLE
2119 \value TargetBuffer A texture with data from an OpenGL buffer object.
2120 Equivalent to GL_TEXTURE_BUFFER
2121*/
2122
2123/*!
2124 \enum QOpenGLTexture::BindingTarget
2125 This enum defines the possible binding targets of texture units.
2126
2127 \value BindingTarget1D Equivalent to GL_TEXTURE_BINDING_1D
2128 \value BindingTarget1DArray Equivalent to GL_TEXTURE_BINDING_1D_ARRAY
2129 \value BindingTarget2D Equivalent to GL_TEXTURE_BINDING_2D
2130 \value BindingTarget2DArray Equivalent to GL_TEXTURE_BINDING_2D_ARRAY
2131 \value BindingTarget3D Equivalent to GL_TEXTURE_BINDING_3D
2132 \value BindingTargetCubeMap Equivalent to GL_TEXTURE_BINDING_CUBE_MAP
2133 \value BindingTargetCubeMapArray Equivalent to GL_TEXTURE_BINDING_CUBE_MAP_ARRAY
2134 \value BindingTarget2DMultisample Equivalent to GL_TEXTURE_BINDING_2D_MULTISAMPLE
2135 \value BindingTarget2DMultisampleArray Equivalent to GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY
2136 \value BindingTargetRectangle Equivalent to GL_TEXTURE_BINDING_RECTANGLE
2137 \value BindingTargetBuffer Equivalent to GL_TEXTURE_BINDING_BUFFER
2138*/
2139
2140/*!
2141 \enum QOpenGLTexture::MipMapGeneration
2142 This enum defines the options to control mipmap generation.
2143
2144 \value GenerateMipMaps Mipmaps should be generated
2145 \value DontGenerateMipMaps Mipmaps should not be generated
2146*/
2147
2148/*!
2149 \enum QOpenGLTexture::TextureUnitReset
2150 This enum defines options ot control texture unit activation.
2151
2152 \value ResetTextureUnit The previous active texture unit will be reset
2153 \value DontResetTextureUnit The previous active texture unit will not be rest
2154*/
2155
2156/*!
2157 \enum QOpenGLTexture::TextureFormat
2158 This enum defines the possible texture formats. Depending upon your OpenGL
2159 implementation only a subset of these may be supported.
2160
2161 \value NoFormat Equivalent to GL_NONE
2162
2163 \value R8_UNorm Equivalent to GL_R8
2164 \value RG8_UNorm Equivalent to GL_RG8
2165 \value RGB8_UNorm Equivalent to GL_RGB8
2166 \value RGBA8_UNorm Equivalent to GL_RGBA8
2167
2168 \value R16_UNorm Equivalent to GL_R16
2169 \value RG16_UNorm Equivalent to GL_RG16
2170 \value RGB16_UNorm Equivalent to GL_RGB16
2171 \value RGBA16_UNorm Equivalent to GL_RGBA16
2172
2173 \value R8_SNorm Equivalent to GL_R8_SNORM
2174 \value RG8_SNorm Equivalent to GL_RG8_SNORM
2175 \value RGB8_SNorm Equivalent to GL_RGB8_SNORM
2176 \value RGBA8_SNorm Equivalent to GL_RGBA8_SNORM
2177
2178 \value R16_SNorm Equivalent to GL_R16_SNORM
2179 \value RG16_SNorm Equivalent to GL_RG16_SNORM
2180 \value RGB16_SNorm Equivalent to GL_RGB16_SNORM
2181 \value RGBA16_SNorm Equivalent to GL_RGBA16_SNORM
2182
2183 \value R8U Equivalent to GL_R8UI
2184 \value RG8U Equivalent to GL_RG8UI
2185 \value RGB8U Equivalent to GL_RGB8UI
2186 \value RGBA8U Equivalent to GL_RGBA8UI
2187
2188 \value R16U Equivalent to GL_R16UI
2189 \value RG16U Equivalent to GL_RG16UI
2190 \value RGB16U Equivalent to GL_RGB16UI
2191 \value RGBA16U Equivalent to GL_RGBA16UI
2192
2193 \value R32U Equivalent to GL_R32UI
2194 \value RG32U Equivalent to GL_RG32UI
2195 \value RGB32U Equivalent to GL_RGB32UI
2196 \value RGBA32U Equivalent to GL_RGBA32UI
2197
2198 \value R8I Equivalent to GL_R8I
2199 \value RG8I Equivalent to GL_RG8I
2200 \value RGB8I Equivalent to GL_RGB8I
2201 \value RGBA8I Equivalent to GL_RGBA8I
2202
2203 \value R16I Equivalent to GL_R16I
2204 \value RG16I Equivalent to GL_RG16I
2205 \value RGB16I Equivalent to GL_RGB16I
2206 \value RGBA16I Equivalent to GL_RGBA16I
2207
2208 \value R32I Equivalent to GL_R32I
2209 \value RG32I Equivalent to GL_RG32I
2210 \value RGB32I Equivalent to GL_RGB32I
2211 \value RGBA32I Equivalent to GL_RGBA32I
2212
2213 \value R16F Equivalent to GL_R16F
2214 \value RG16F Equivalent to GL_RG16F
2215 \value RGB16F Equivalent to GL_RGB16F
2216 \value RGBA16F Equivalent to GL_RGBA16F
2217
2218 \value R32F Equivalent to GL_R32F
2219 \value RG32F Equivalent to GL_RG32F
2220 \value RGB32F Equivalent to GL_RGB32F
2221 \value RGBA32F Equivalent to GL_RGBA32F
2222
2223 \value RGB9E5 Equivalent to GL_RGB9_E5
2224 \value RG11B10F Equivalent to GL_R11F_G11F_B10F
2225 \value RG3B2 Equivalent to GL_R3_G3_B2
2226 \value R5G6B5 Equivalent to GL_RGB565
2227 \value RGB5A1 Equivalent to GL_RGB5_A1
2228 \value RGBA4 Equivalent to GL_RGBA4
2229 \value RGB10A2 Equivalent to GL_RGB10_A2UI
2230
2231 \value D16 Equivalent to GL_DEPTH_COMPONENT16
2232 \value D24 Equivalent to GL_DEPTH_COMPONENT24
2233 \value D24S8 Equivalent to GL_DEPTH24_STENCIL8
2234 \value D32 Equivalent to GL_DEPTH_COMPONENT32
2235 \value D32F Equivalent to GL_DEPTH_COMPONENT32F
2236 \value D32FS8X24 Equivalent to GL_DEPTH32F_STENCIL8
2237 \value S8 Equivalent to GL_STENCIL_INDEX8. Introduced in Qt 5.4
2238
2239 \value RGB_DXT1 Equivalent to GL_COMPRESSED_RGB_S3TC_DXT1_EXT
2240 \value RGBA_DXT1 Equivalent to GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
2241 \value RGBA_DXT3 Equivalent to GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
2242 \value RGBA_DXT5 Equivalent to GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
2243 \value R_ATI1N_UNorm Equivalent to GL_COMPRESSED_RED_RGTC1
2244 \value R_ATI1N_SNorm Equivalent to GL_COMPRESSED_SIGNED_RED_RGTC1
2245 \value RG_ATI2N_UNorm Equivalent to GL_COMPRESSED_RG_RGTC2
2246 \value RG_ATI2N_SNorm Equivalent to GL_COMPRESSED_SIGNED_RG_RGTC2
2247 \value RGB_BP_UNSIGNED_FLOAT Equivalent to GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB
2248 \value RGB_BP_SIGNED_FLOAT Equivalent to GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB
2249 \value RGB_BP_UNorm Equivalent to GL_COMPRESSED_RGBA_BPTC_UNORM_ARB
2250 \value R11_EAC_UNorm Equivalent to GL_COMPRESSED_R11_EAC
2251 \value R11_EAC_SNorm Equivalent to GL_COMPRESSED_SIGNED_R11_EAC
2252 \value RG11_EAC_UNorm Equivalent to GL_COMPRESSED_RG11_EAC
2253 \value RG11_EAC_SNorm Equivalent to GL_COMPRESSED_SIGNED_RG11_EAC
2254 \value RGB8_ETC2 Equivalent to GL_COMPRESSED_RGB8_ETC2
2255 \value SRGB8_ETC2 Equivalent to GL_COMPRESSED_SRGB8_ETC2
2256 \value RGB8_PunchThrough_Alpha1_ETC2 Equivalent to GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
2257 \value SRGB8_PunchThrough_Alpha1_ETC2 Equivalent to GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
2258 \value RGBA8_ETC2_EAC Equivalent to GL_COMPRESSED_RGBA8_ETC2_EAC
2259 \value SRGB8_Alpha8_ETC2_EAC Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
2260 \value RGB8_ETC1 Equivalent to GL_ETC1_RGB8_OES
2261 \value RGBA_ASTC_4x4 Equivalent to GL_COMPRESSED_RGBA_ASTC_4x4_KHR
2262 \value RGBA_ASTC_5x4 Equivalent to GL_COMPRESSED_RGBA_ASTC_5x4_KHR
2263 \value RGBA_ASTC_5x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_5x5_KHR
2264 \value RGBA_ASTC_6x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_6x5_KHR
2265 \value RGBA_ASTC_6x6 Equivalent to GL_COMPRESSED_RGBA_ASTC_6x6_KHR
2266 \value RGBA_ASTC_8x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_8x5_KHR
2267 \value RGBA_ASTC_8x6 Equivalent to GL_COMPRESSED_RGBA_ASTC_8x6_KHR
2268 \value RGBA_ASTC_8x8 Equivalent to GL_COMPRESSED_RGBA_ASTC_8x8_KHR
2269 \value RGBA_ASTC_10x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x5_KHR
2270 \value RGBA_ASTC_10x6 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x6_KHR
2271 \value RGBA_ASTC_10x8 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x8_KHR
2272 \value RGBA_ASTC_10x10 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x10_KHR
2273 \value RGBA_ASTC_12x10 Equivalent to GL_COMPRESSED_RGBA_ASTC_12x10_KHR
2274 \value RGBA_ASTC_12x12 Equivalent to GL_COMPRESSED_RGBA_ASTC_12x12_KHR
2275 \value SRGB8_Alpha8_ASTC_4x4 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
2276 \value SRGB8_Alpha8_ASTC_5x4 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR
2277 \value SRGB8_Alpha8_ASTC_5x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR
2278 \value SRGB8_Alpha8_ASTC_6x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR
2279 \value SRGB8_Alpha8_ASTC_6x6 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR
2280 \value SRGB8_Alpha8_ASTC_8x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR
2281 \value SRGB8_Alpha8_ASTC_8x6 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR
2282 \value SRGB8_Alpha8_ASTC_8x8 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR
2283 \value SRGB8_Alpha8_ASTC_10x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR
2284 \value SRGB8_Alpha8_ASTC_10x6 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR
2285 \value SRGB8_Alpha8_ASTC_10x8 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR
2286 \value SRGB8_Alpha8_ASTC_10x10 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR
2287 \value SRGB8_Alpha8_ASTC_12x10 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR
2288 \value SRGB8_Alpha8_ASTC_12x12 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR
2289
2290 \value SRGB8 Equivalent to GL_SRGB8
2291 \value SRGB8_Alpha8 Equivalent to GL_SRGB8_ALPHA8
2292 \value SRGB_DXT1 Equivalent to GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
2293 \value SRGB_Alpha_DXT1 Equivalent to GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
2294 \value SRGB_Alpha_DXT3 Equivalent to GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
2295 \value SRGB_Alpha_DXT5 Equivalent to GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
2296 \value SRGB_BP_UNorm Equivalent to GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB
2297
2298 \value DepthFormat Equivalent to GL_DEPTH_COMPONENT (only OpenGL ES 3 or ES 2 with OES_depth_texture)
2299 \value AlphaFormat Equivalent to GL_ALPHA (OpenGL ES 2 only)
2300 \value RGBFormat Equivalent to GL_RGB (OpenGL ES 2 only)
2301 \value RGBAFormat Equivalent to GL_RGBA (OpenGL ES 2 only)
2302 \value LuminanceFormat Equivalent to GL_LUMINANCE (OpenGL ES 2 only)
2303 \value LuminanceAlphaFormat Equivalent to GL_LUMINANCE_ALPHA (OpenGL ES 2 only)
2304*/
2305
2306/*!
2307 \enum QOpenGLTexture::CubeMapFace
2308 This enum defines the possible CubeMap faces.
2309
2310 \value CubeMapPositiveX Equivalent to GL_TEXTURE_CUBE_MAP_POSITIVE_X
2311 \value CubeMapNegativeX Equivalent to GL_TEXTURE_CUBE_MAP_NEGATIVE_X
2312 \value CubeMapPositiveY Equivalent to GL_TEXTURE_CUBE_MAP_POSITIVE_Y
2313 \value CubeMapNegativeY Equivalent to GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
2314 \value CubeMapPositiveZ Equivalent to GL_TEXTURE_CUBE_MAP_POSITIVE_Z
2315 \value CubeMapNegativeZ Equivalent to GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
2316*/
2317
2318/*!
2319 \enum QOpenGLTexture::PixelFormat
2320 This enum defines the possible client-side pixel formats for a pixel
2321 transfer operation.
2322
2323 \value NoSourceFormat Equivalent to GL_NONE
2324 \value Red Equivalent to GL_RED
2325 \value RG Equivalent to GL_RG
2326 \value RGB Equivalent to GL_RGB
2327 \value BGR Equivalent to GL_BGR
2328 \value RGBA Equivalent to GL_RGBA
2329 \value BGRA Equivalent to GL_BGRA
2330 \value Red_Integer Equivalent to GL_RED_INTEGER
2331 \value RG_Integer Equivalent to GL_RG_INTEGER
2332 \value RGB_Integer Equivalent to GL_RGB_INTEGER
2333 \value BGR_Integer Equivalent to GL_BGR_INTEGER
2334 \value RGBA_Integer Equivalent to GL_RGBA_INTEGER
2335 \value BGRA_Integer Equivalent to GL_BGRA_INTEGER
2336 \value Stencil Equivalent to GL_STENCIL_INDEX. Introduced in Qt 5.4
2337 \value Depth Equivalent to GL_DEPTH_COMPONENT
2338 \value DepthStencil Equivalent to GL_DEPTH_STENCIL
2339 \value Alpha Equivalent to GL_ALPHA (OpenGL ES 2 only)
2340 \value Luminance Equivalent to GL_LUMINANCE (OpenGL ES 2 only)
2341 \value LuminanceAlpha Equivalent to GL_LUMINANCE_ALPHA (OpenGL ES 2 only)
2342
2343*/
2344
2345/*!
2346 \enum QOpenGLTexture::PixelType
2347 This enum defines the possible pixel data types for a pixel transfer operation
2348
2349 \value NoPixelType Equivalent to GL_NONE
2350 \value Int8 Equivalent to GL_BYTE
2351 \value UInt8 Equivalent to GL_UNSIGNED_BYTE
2352 \value Int16 Equivalent to GL_SHORT
2353 \value UInt16 Equivalent to GL_UNSIGNED_SHORT
2354 \value Int32 Equivalent to GL_INT
2355 \value UInt32 Equivalent to GL_UNSIGNED_INT
2356 \value Float16 Equivalent to GL_HALF_FLOAT
2357 \value Float16OES Equivalent to GL_HALF_FLOAT_OES
2358 \value Float32 Equivalent to GL_FLOAT
2359 \value UInt32_RGB9_E5 Equivalent to GL_UNSIGNED_INT_5_9_9_9_REV
2360 \value UInt32_RG11B10F Equivalent to GL_UNSIGNED_INT_10F_11F_11F_REV
2361 \value UInt8_RG3B2 Equivalent to GL_UNSIGNED_BYTE_3_3_2
2362 \value UInt8_RG3B2_Rev Equivalent to GL_UNSIGNED_BYTE_2_3_3_REV
2363 \value UInt16_RGB5A1 Equivalent to GL_UNSIGNED_SHORT_5_5_5_1
2364 \value UInt16_RGB5A1_Rev Equivalent to GL_UNSIGNED_SHORT_1_5_5_5_REV
2365 \value UInt16_R5G6B5 Equivalent to GL_UNSIGNED_SHORT_5_6_5
2366 \value UInt16_R5G6B5_Rev Equivalent to GL_UNSIGNED_SHORT_5_6_5_REV
2367 \value UInt16_RGBA4 Equivalent to GL_UNSIGNED_SHORT_4_4_4_4
2368 \value UInt16_RGBA4_Rev Equivalent to GL_UNSIGNED_SHORT_4_4_4_4_REV
2369 \value UInt32_RGBA8 Equivalent to GL_UNSIGNED_INT_8_8_8_8
2370 \value UInt32_RGBA8_Rev Equivalent to GL_UNSIGNED_INT_8_8_8_8_REV
2371 \value UInt32_RGB10A2 Equivalent to GL_UNSIGNED_INT_10_10_10_2
2372 \value UInt32_RGB10A2_Rev Equivalent to GL_UNSIGNED_INT_2_10_10_10_REV
2373 \value UInt32_D24S8 Equivalent to GL_UNSIGNED_INT_24_8. Introduced in Qt 5.4
2374 \value Float32_D32_UInt32_S8_X24 Equivalent to GL_FLOAT_32_UNSIGNED_INT_24_8_REV. Introduced in Qt 5.4
2375*/
2376
2377/*!
2378 \enum QOpenGLTexture::Feature
2379 This enum defines the OpenGL texture-related features that can be tested for.
2380
2381 \value ImmutableStorage Support for immutable texture storage
2382 \value ImmutableMultisampleStorage Support for immutable texture storage with
2383 multisample targets
2384 \value TextureRectangle Support for the GL_TEXTURE_RECTANGLE target
2385 \value TextureArrays Support for texture targets with array layers
2386 \value Texture3D Support for the 3 dimensional texture target
2387 \value TextureMultisample Support for texture targets that have multisample capabilities
2388 \value TextureBuffer Support for textures that use OpenGL buffer objects
2389 as their data source
2390 \value TextureCubeMapArrays Support for cubemap array texture target
2391 \value Swizzle Support for texture component swizzle masks
2392 \value StencilTexturing Support for stencil texturing (i.e. looking up depth or stencil
2393 components of a combined depth/stencil format texture in GLSL shaders).
2394 \value AnisotropicFiltering Support for anisotropic texture filtering
2395 \value NPOTTextures Basic support for non-power-of-two textures
2396 \value NPOTTextureRepeat Full support for non-power-of-two textures including texture
2397 repeat modes
2398 \value Texture1D Support for the 1 dimensional texture target
2399 \value TextureComparisonOperators Support for texture comparison operators
2400 \value TextureMipMapLevel Support for setting the base and maximum mipmap levels
2401*/
2402
2403/*!
2404 \enum QOpenGLTexture::SwizzleComponent
2405 This enum defines the texture color components that can be assigned a swizzle mask.
2406
2407 \value SwizzleRed The red component. Equivalent to GL_TEXTURE_SWIZZLE_R
2408 \value SwizzleGreen The green component. Equivalent to GL_TEXTURE_SWIZZLE_G
2409 \value SwizzleBlue The blue component. Equivalent to GL_TEXTURE_SWIZZLE_B
2410 \value SwizzleAlpha The alpha component. Equivalent to GL_TEXTURE_SWIZZLE_A
2411*/
2412
2413/*!
2414 \enum QOpenGLTexture::SwizzleValue
2415 This enum defines the possible mask values for texture swizzling.
2416
2417 \value RedValue Maps the component to the red channel. Equivalent to GL_RED
2418 \value GreenValue Maps the component to the green channel. Equivalent to GL_GREEN
2419 \value BlueValue Maps the component to the blue channel. Equivalent to GL_BLUE
2420 \value AlphaValue Maps the component to the alpha channel. Equivalent to GL_ALPHA
2421 \value ZeroValue Maps the component to a fixed value of 0. Equivalent to GL_ZERO
2422 \value OneValue Maps the component to a fixed value of 1. Equivalent to GL_ONE
2423*/
2424
2425/*!
2426 \enum QOpenGLTexture::WrapMode
2427 This enum defines the possible texture coordinate wrapping modes.
2428
2429 \value Repeat Texture coordinate is repeated. Equivalent to GL_REPEAT
2430 \value MirroredRepeat Texture coordinate is reflected about 0 and 1. Equivalent to GL_MIRRORED_REPEAT
2431 \value ClampToEdge Clamps the texture coordinates to [0,1]. Equivalent to GL_CLAMP_TO_EDGE
2432 \value ClampToBorder As for ClampToEdge but also blends samples at 0 and 1 with a
2433 fixed border color. Equivalent to GL_CLAMP_TO_BORDER
2434*/
2435
2436/*!
2437 \enum QOpenGLTexture::CoordinateDirection
2438 This enum defines the possible texture coordinate directions
2439
2440 \value DirectionS The horizontal direction. Equivalent to GL_TEXTURE_WRAP_S
2441 \value DirectionT The vertical direction. Equivalent to GL_TEXTURE_WRAP_T
2442 \value DirectionR The depth direction. Equivalent to GL_TEXTURE_WRAP_R
2443*/
2444
2445/*!
2446 Creates a QOpenGLTexture object that can later be bound to \a target.
2447
2448 This does not create the underlying OpenGL texture object. Therefore,
2449 construction using this constructor does not require a valid current
2450 OpenGL context.
2451*/
2452QOpenGLTexture::QOpenGLTexture(Target target)
2453 : d_ptr(new QOpenGLTexturePrivate(target, this))
2454{
2455}
2456
2457/*!
2458 Creates a QOpenGLTexture object that can later be bound to the 2D texture
2459 target and contains the pixel data contained in \a image. If you wish
2460 to have a chain of mipmaps generated then set \a genMipMaps to \c true (this
2461 is the default).
2462
2463 This does create the underlying OpenGL texture object. Therefore,
2464 construction using this constructor does require a valid current
2465 OpenGL context.
2466
2467 \note \a image is automatically converted to QImage::Format_RGBA8888 which
2468 may have performance implications for large images with a different format.
2469*/
2470QOpenGLTexture::QOpenGLTexture(const QImage& image, MipMapGeneration genMipMaps)
2471 : QOpenGLTexture(QOpenGLTexture::Target2D)
2472{
2473 setData(image, genMipMaps);
2474}
2475
2476QOpenGLTexture::~QOpenGLTexture()
2477{
2478}
2479
2480/*!
2481 Returns the binding target of this texture.
2482
2483 \since 5.4
2484*/
2485QOpenGLTexture::Target QOpenGLTexture::target() const
2486{
2487 Q_D(const QOpenGLTexture);
2488 return d->target;
2489}
2490
2491/*!
2492 Creates the underlying OpenGL texture object. This requires a current valid
2493 OpenGL context. If the texture object already exists, this function does
2494 nothing.
2495
2496 Once the texture object is created you can obtain the object
2497 name from the textureId() function. This may be useful if you wish to make
2498 some raw OpenGL calls related to this texture.
2499
2500 Normally it should not be necessary to call this function directly as all
2501 functions that set properties of the texture object implicitly call create()
2502 on your behalf.
2503
2504 Returns \c true if the creation succeeded, otherwise returns \c false.
2505
2506 \sa destroy(), isCreated(), textureId()
2507*/
2508bool QOpenGLTexture::create()
2509{
2510 Q_D(QOpenGLTexture);
2511 return d->create();
2512}
2513
2514/*!
2515 Destroys the underlying OpenGL texture object. This requires a current valid
2516 OpenGL context.
2517
2518 \sa create(), isCreated(), textureId()
2519*/
2520void QOpenGLTexture::destroy()
2521{
2522 Q_D(QOpenGLTexture);
2523 return d->destroy();
2524}
2525
2526/*!
2527 Returns \c true if the underlying OpenGL texture object has been created.
2528
2529 \sa create(), destroy(), textureId()
2530*/
2531bool QOpenGLTexture::isCreated() const
2532{
2533 Q_D(const QOpenGLTexture);
2534 return d->textureId != 0;
2535}
2536
2537/*!
2538 Returns the name of the underlying OpenGL texture object or 0 if it has
2539 not yet been created.
2540
2541 \sa create(), destroy(), isCreated()
2542*/
2543GLuint QOpenGLTexture::textureId() const
2544{
2545 Q_D(const QOpenGLTexture);
2546 return d->textureId;
2547}
2548
2549/*!
2550 Binds this texture to the currently active texture unit ready for
2551 rendering. Note that you do not need to bind QOpenGLTexture objects
2552 in order to modify them as the implementation makes use of the
2553 EXT_direct_state_access extension where available and simulates it
2554 where it is not.
2555
2556 \sa release()
2557*/
2558void QOpenGLTexture::bind()
2559{
2560 Q_D(QOpenGLTexture);
2561 Q_ASSERT(d->textureId);
2562 d->bind();
2563}
2564
2565/*!
2566 Binds this texture to texture unit \a unit ready for
2567 rendering. Note that you do not need to bind QOpenGLTexture objects
2568 in order to modify them as the implementation makes use of the
2569 EXT_direct_state_access extension where available and simulates it
2570 where it is not.
2571
2572 If parameter \a reset is \c true then this function will restore
2573 the active unit to the texture unit that was active upon entry.
2574
2575 \sa release()
2576*/
2577void QOpenGLTexture::bind(uint unit, TextureUnitReset reset)
2578{
2579 Q_D(QOpenGLTexture);
2580 Q_ASSERT(d->textureId);
2581 d->bind(unit, reset);
2582}
2583
2584/*!
2585 Unbinds this texture from the currently active texture unit.
2586
2587 \sa bind()
2588*/
2589void QOpenGLTexture::release()
2590{
2591 Q_D(QOpenGLTexture);
2592 d->release();
2593}
2594
2595/*!
2596 Unbinds this texture from texture unit \a unit.
2597
2598 If parameter \a reset is \c true then this function
2599 will restore the active unit to the texture unit that was active
2600 upon entry.
2601*/
2602void QOpenGLTexture::release(uint unit, TextureUnitReset reset)
2603{
2604 Q_D(QOpenGLTexture);
2605 d->release(unit, reset);
2606}
2607
2608/*!
2609 Returns \c true if this texture is bound to the corresponding target
2610 of the currently active texture unit.
2611
2612 \sa bind(), release()
2613*/
2614bool QOpenGLTexture::isBound() const
2615{
2616 Q_D(const QOpenGLTexture);
2617 Q_ASSERT(d->textureId);
2618 return d->isBound();
2619}
2620
2621/*!
2622 Returns \c true if this texture is bound to the corresponding target
2623 of texture unit \a unit.
2624
2625 \sa bind(), release()
2626*/
2627bool QOpenGLTexture::isBound(uint unit)
2628{
2629 Q_D(const QOpenGLTexture);
2630 Q_ASSERT(d->textureId);
2631 return d->isBound(unit);
2632}
2633
2634/*!
2635 Returns the textureId of the texture that is bound to the \a target
2636 of the currently active texture unit.
2637*/
2638GLuint QOpenGLTexture::boundTextureId(BindingTarget target)
2639{
2640 QOpenGLContext *ctx = QOpenGLContext::currentContext();
2641 if (!ctx) {
2642 qWarning("QOpenGLTexture::boundTextureId() requires a valid current context");
2643 return 0;
2644 }
2645
2646 GLint textureId = 0;
2647 ctx->functions()->glGetIntegerv(target, &textureId);
2648 return static_cast<GLuint>(textureId);
2649}
2650
2651/*!
2652 Returns the textureId of the texture that is bound to the \a target
2653 of the texture unit \a unit.
2654*/
2655GLuint QOpenGLTexture::boundTextureId(uint unit, BindingTarget target)
2656{
2657 QOpenGLContext *ctx = QOpenGLContext::currentContext();
2658 if (!ctx) {
2659 qWarning("QOpenGLTexture::boundTextureId() requires a valid current context");
2660 return 0;
2661 }
2662
2663 QOpenGLFunctions *funcs = ctx->functions();
2664 funcs->initializeOpenGLFunctions();
2665
2666 GLint oldTextureUnit = 0;
2667 funcs->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit);
2668
2669 funcs->glActiveTexture(unit);
2670 GLint textureId = 0;
2671 funcs->glGetIntegerv(target, &textureId);
2672 funcs->glActiveTexture(oldTextureUnit);
2673
2674 return static_cast<GLuint>(textureId);
2675}
2676
2677/*!
2678 Sets the format of this texture object to \a format. This function
2679 must be called before texture storage is allocated.
2680
2681 Note that all formats may not be supported. The exact set of supported
2682 formats is dependent upon your OpenGL implementation and version.
2683
2684 \sa format(), allocateStorage()
2685*/
2686void QOpenGLTexture::setFormat(TextureFormat format)
2687{
2688 Q_D(QOpenGLTexture);
2689 d->create();
2690 if (isStorageAllocated()) {
2691 qWarning("QOpenGLTexture::setFormat(): Cannot change format once storage has been allocated");
2692 return;
2693 }
2694
2695 d->format = format;
2696
2697 switch (format) {
2698 case NoFormat:
2699 d->formatClass = NoFormatClass;
2700 break;
2701
2702 case RGBA32F:
2703 case RGBA32U:
2704 case RGBA32I:
2705 d->formatClass = FormatClass_128Bit;
2706 break;
2707
2708 case RGB32F:
2709 case RGB32U:
2710 case RGB32I:
2711 d->formatClass = FormatClass_96Bit;
2712 break;
2713
2714 case RGBA16F:
2715 case RG32F:
2716 case RGBA16U:
2717 case RG32U:
2718 case RGBA16I:
2719 case RG32I:
2720 case RGBA16_UNorm:
2721 case RGBA16_SNorm:
2722 d->formatClass = FormatClass_64Bit;
2723 break;
2724
2725 case RGB16_UNorm:
2726 case RGB16_SNorm:
2727 case RGB16F:
2728 case RGB16U:
2729 case RGB16I:
2730 d->formatClass = FormatClass_48Bit;
2731 break;
2732
2733 case RG16F:
2734 case RG11B10F:
2735 case R32F:
2736 case RGB10A2:
2737 case RGBA8U:
2738 case RG16U:
2739 case R32U:
2740 case RGBA8I:
2741 case RG16I:
2742 case R32I:
2743 case RGBA8_UNorm:
2744 case RG16_UNorm:
2745 case RGBA8_SNorm:
2746 case RG16_SNorm:
2747 case SRGB8_Alpha8:
2748 case RGB9E5:
2749 d->formatClass = FormatClass_32Bit;
2750 break;
2751
2752 case RGB8_UNorm:
2753 case RGB8_SNorm:
2754 case SRGB8:
2755 case RGB8U:
2756 case RGB8I:
2757 d->formatClass = FormatClass_24Bit;
2758 break;
2759
2760 case R16F:
2761 case RG8U:
2762 case R16U:
2763 case RG8I:
2764 case R16I:
2765 case RG8_UNorm:
2766 case R16_UNorm:
2767 case RG8_SNorm:
2768 case R16_SNorm:
2769 d->formatClass = FormatClass_16Bit;
2770 break;
2771
2772 case R8U:
2773 case R8I:
2774 case R8_UNorm:
2775 case R8_SNorm:
2776 d->formatClass = FormatClass_8Bit;
2777 break;
2778
2779 case R_ATI1N_UNorm:
2780 case R_ATI1N_SNorm:
2781 d->formatClass = FormatClass_RGTC1_R;
2782 break;
2783
2784 case RG_ATI2N_UNorm:
2785 case RG_ATI2N_SNorm:
2786 d->formatClass = FormatClass_RGTC2_RG;
2787 break;
2788
2789 case RGB_BP_UNorm:
2790 case SRGB_BP_UNorm:
2791 d->formatClass = FormatClass_BPTC_Unorm;
2792 break;
2793
2794 case RGB_BP_UNSIGNED_FLOAT:
2795 case RGB_BP_SIGNED_FLOAT:
2796 d->formatClass = FormatClass_BPTC_Float;
2797 break;
2798
2799 case RGB_DXT1:
2800 case SRGB_DXT1:
2801 d->formatClass = FormatClass_S3TC_DXT1_RGB;
2802 break;
2803
2804 case RGBA_DXT1:
2805 case SRGB_Alpha_DXT1:
2806 d->formatClass = FormatClass_S3TC_DXT1_RGBA;
2807 break;
2808
2809 case RGBA_DXT3:
2810 case SRGB_Alpha_DXT3:
2811 d->formatClass = FormatClass_S3TC_DXT3_RGBA;
2812 break;
2813
2814 case RGBA_DXT5:
2815 case SRGB_Alpha_DXT5:
2816 d->formatClass = FormatClass_S3TC_DXT5_RGBA;
2817 break;
2818
2819 case QOpenGLTexture::R11_EAC_UNorm:
2820 case QOpenGLTexture::R11_EAC_SNorm:
2821 case QOpenGLTexture::RG11_EAC_UNorm:
2822 case QOpenGLTexture::RG11_EAC_SNorm:
2823 case QOpenGLTexture::RGB8_ETC2:
2824 case QOpenGLTexture::SRGB8_ETC2:
2825 case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
2826 case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
2827 case QOpenGLTexture::RGBA8_ETC2_EAC:
2828 case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
2829 case QOpenGLTexture::RGB8_ETC1:
2830 case RG3B2:
2831 case R5G6B5:
2832 case RGB5A1:
2833 case RGBA4:
2834 case D16:
2835 case D24:
2836 case D24S8:
2837 case D32:
2838 case D32F:
2839 case D32FS8X24:
2840 case S8:
2841 case DepthFormat:
2842 case AlphaFormat:
2843 case RGBFormat:
2844 case RGBAFormat:
2845 case LuminanceFormat:
2846 case LuminanceAlphaFormat:
2847 case QOpenGLTexture::RGBA_ASTC_4x4:
2848 case QOpenGLTexture::RGBA_ASTC_5x4:
2849 case QOpenGLTexture::RGBA_ASTC_5x5:
2850 case QOpenGLTexture::RGBA_ASTC_6x5:
2851 case QOpenGLTexture::RGBA_ASTC_6x6:
2852 case QOpenGLTexture::RGBA_ASTC_8x5:
2853 case QOpenGLTexture::RGBA_ASTC_8x6:
2854 case QOpenGLTexture::RGBA_ASTC_8x8:
2855 case QOpenGLTexture::RGBA_ASTC_10x5:
2856 case QOpenGLTexture::RGBA_ASTC_10x6:
2857 case QOpenGLTexture::RGBA_ASTC_10x8:
2858 case QOpenGLTexture::RGBA_ASTC_10x10:
2859 case QOpenGLTexture::RGBA_ASTC_12x10:
2860 case QOpenGLTexture::RGBA_ASTC_12x12:
2861 case QOpenGLTexture::SRGB8_Alpha8_ASTC_4x4:
2862 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x4:
2863 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x5:
2864 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x5:
2865 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x6:
2866 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x5:
2867 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x6:
2868 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x8:
2869 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x5:
2870 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x6:
2871 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x8:
2872 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x10:
2873 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x10:
2874 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x12:
2875 d->formatClass = FormatClass_Unique;
2876 break;
2877 }
2878}
2879
2880/*!
2881 Returns the format of this texture object.
2882
2883 \sa setFormat()
2884*/
2885QOpenGLTexture::TextureFormat QOpenGLTexture::format() const
2886{
2887 Q_D(const QOpenGLTexture);
2888 return d->format;
2889}
2890
2891static bool isNpot(int width, int height = 1, int depth = 1)
2892{
2893 return width & (width-1) || height & (height-1) || depth & (depth-1);
2894}
2895
2896/*!
2897 Sets the dimensions of this texture object to \a width,
2898 \a height, and \a depth. The default for each dimension is 1.
2899 The maximum allowable texture size is dependent upon your OpenGL
2900 implementation. Allocating storage for a texture less than the
2901 maximum size can still fail if your system is low on resources.
2902
2903 If a non-power-of-two \a width, \a height or \a depth is provided and your
2904 OpenGL implementation doesn't have support for repeating non-power-of-two
2905 textures, then the wrap mode is automatically set to ClampToEdge.
2906
2907 \sa width(), height(), depth()
2908*/
2909void QOpenGLTexture::setSize(int width, int height, int depth)
2910{
2911 Q_D(QOpenGLTexture);
2912 d->create();
2913 if (isStorageAllocated()) {
2914 qWarning("Cannot resize a texture that already has storage allocated.\n"
2915 "To do so, destroy() the texture and then create() and setSize()");
2916 return;
2917 }
2918
2919 if (isNpot(width, height, depth) && !hasFeature(Feature::NPOTTextureRepeat) && d->target != Target::TargetRectangle)
2920 d->setWrapMode(WrapMode::ClampToEdge);
2921
2922 switch (d->target) {
2923 case QOpenGLTexture::Target1D:
2924 case QOpenGLTexture::Target1DArray:
2925 case QOpenGLTexture::TargetBuffer:
2926 d->dimensions[0] = width;
2927 Q_UNUSED(height);
2928 Q_UNUSED(depth);
2929 break;
2930
2931 case QOpenGLTexture::Target2D:
2932 case QOpenGLTexture::Target2DArray:
2933 case QOpenGLTexture::TargetRectangle:
2934 case QOpenGLTexture::Target2DMultisample:
2935 case QOpenGLTexture::Target2DMultisampleArray:
2936 d->dimensions[0] = width;
2937 d->dimensions[1] = height;
2938 Q_UNUSED(depth);
2939 break;
2940
2941 case QOpenGLTexture::TargetCubeMap:
2942 case QOpenGLTexture::TargetCubeMapArray:
2943 if (width != height)
2944 qWarning("QAbstractOpenGLTexture::setSize(): Cube map textures must be square");
2945 d->dimensions[0] = d->dimensions[1] = width;
2946 Q_UNUSED(depth);
2947 break;
2948
2949 case QOpenGLTexture::Target3D:
2950 d->dimensions[0] = width;
2951 d->dimensions[1] = height;
2952 d->dimensions[2] = depth;
2953 break;
2954 }
2955}
2956
2957/*!
2958 Returns the width of a 1D, 2D or 3D texture.
2959
2960 \sa height(), depth(), setSize()
2961*/
2962int QOpenGLTexture::width() const
2963{
2964 Q_D(const QOpenGLTexture);
2965 return d->dimensions[0];
2966}
2967
2968/*!
2969 Returns the height of a 2D or 3D texture.
2970
2971 \sa width(), depth(), setSize()
2972*/
2973int QOpenGLTexture::height() const
2974{
2975 Q_D(const QOpenGLTexture);
2976 return d->dimensions[1];
2977}
2978
2979/*!
2980 Returns the depth of a 3D texture.
2981
2982 \sa width(), height(), setSize()
2983*/
2984int QOpenGLTexture::depth() const
2985{
2986 Q_D(const QOpenGLTexture);
2987 return d->dimensions[2];
2988}
2989
2990/*!
2991 For texture targets that support mipmaps, this function
2992 sets the requested number of mipmap \a levels to allocate storage
2993 for. This function should be called before storage is allocated
2994 for the texture.
2995
2996 If the texture target does not support mipmaps this function
2997 has no effect.
2998
2999 \sa mipLevels(), maximumMipLevels(), isStorageAllocated()
3000*/
3001void QOpenGLTexture::setMipLevels(int levels)
3002{
3003 Q_D(QOpenGLTexture);
3004 d->create();
3005 if (isStorageAllocated()) {
3006 qWarning("Cannot set mip levels on a texture that already has storage allocated.\n"
3007 "To do so, destroy() the texture and then create() and setMipLevels()");
3008 return;
3009 }
3010
3011 switch (d->target) {
3012 case QOpenGLTexture::Target1D:
3013 case QOpenGLTexture::Target1DArray:
3014 case QOpenGLTexture::Target2D:
3015 case QOpenGLTexture::Target2DArray:
3016 case QOpenGLTexture::TargetCubeMap:
3017 case QOpenGLTexture::TargetCubeMapArray:
3018 case QOpenGLTexture::Target3D:
3019 d->requestedMipLevels = levels;
3020 break;
3021
3022 case QOpenGLTexture::TargetBuffer:
3023 case QOpenGLTexture::TargetRectangle:
3024 case QOpenGLTexture::Target2DMultisample:
3025 case QOpenGLTexture::Target2DMultisampleArray:
3026 qWarning("QAbstractOpenGLTexture::setMipLevels(): This texture target does not support mipmaps");
3027 break;
3028 }
3029}
3030
3031/*!
3032 Returns the number of mipmap levels for this texture. If storage
3033 has not yet been allocated for this texture it returns the
3034 requested number of mipmap levels.
3035
3036 \sa setMipLevels(), maximumMipLevels(), isStorageAllocated()
3037*/
3038int QOpenGLTexture::mipLevels() const
3039{
3040 Q_D(const QOpenGLTexture);
3041 return isStorageAllocated() ? d->mipLevels : d->requestedMipLevels;
3042}
3043
3044/*!
3045 Returns the maximum number of mipmap levels that this texture
3046 can have given the current dimensions.
3047
3048 \sa setMipLevels(), mipLevels(), setSize()
3049*/
3050int QOpenGLTexture::maximumMipLevels() const
3051{
3052 Q_D(const QOpenGLTexture);
3053 return d->maximumMipLevelCount();
3054}
3055
3056/*!
3057 Sets the number of array \a layers to allocate storage for. This
3058 function should be called before storage is allocated for the texture.
3059
3060 For targets that do not support array layers this function has
3061 no effect.
3062
3063 \sa layers(), isStorageAllocated()
3064*/
3065void QOpenGLTexture::setLayers(int layers)
3066{
3067 Q_D(QOpenGLTexture);
3068 d->create();
3069 if (isStorageAllocated()) {
3070 qWarning("Cannot set layers on a texture that already has storage allocated.\n"
3071 "To do so, destroy() the texture and then create() and setLayers()");
3072 return;
3073 }
3074
3075 switch (d->target) {
3076 case QOpenGLTexture::Target1DArray:
3077 case QOpenGLTexture::Target2DArray:
3078 case QOpenGLTexture::TargetCubeMapArray:
3079 case QOpenGLTexture::Target2DMultisampleArray:
3080 d->layers = layers;
3081 break;
3082
3083 case QOpenGLTexture::Target1D:
3084 case QOpenGLTexture::Target2D:
3085 case QOpenGLTexture::Target3D:
3086 case QOpenGLTexture::TargetCubeMap:
3087 case QOpenGLTexture::TargetBuffer:
3088 case QOpenGLTexture::TargetRectangle:
3089 case QOpenGLTexture::Target2DMultisample:
3090 qWarning("Texture target does not support array layers");
3091 break;
3092 }
3093}
3094
3095/*!
3096 Returns the number of array layers for this texture. If
3097 storage has not yet been allocated for this texture then
3098 this function returns the requested number of array layers.
3099
3100 For texture targets that do not support array layers this
3101 will return 1.
3102
3103 \sa setLayers(), isStorageAllocated()
3104*/
3105int QOpenGLTexture::layers() const
3106{
3107 Q_D(const QOpenGLTexture);
3108 return d->layers;
3109}
3110
3111/*!
3112 Returns the number of faces for this texture. For cubemap
3113 and cubemap array type targets this will be 6.
3114
3115 For non-cubemap type targets this will return 1.
3116*/
3117int QOpenGLTexture::faces() const
3118{
3119 Q_D(const QOpenGLTexture);
3120 return d->faces;
3121}
3122
3123/*!
3124 Sets the number of \a samples to allocate storage for when rendering to
3125 a multisample capable texture target. This function should
3126 be called before storage is allocated for the texture.
3127
3128 For targets that do not support multisampling this function has
3129 no effect.
3130
3131 \sa samples(), isStorageAllocated()
3132*/
3133void QOpenGLTexture::setSamples(int samples)
3134{
3135 Q_D(QOpenGLTexture);
3136 d->create();
3137 if (isStorageAllocated()) {
3138 qWarning("Cannot set sample count on a texture that already has storage allocated.\n"
3139 "To do so, destroy() the texture and then create() and setSamples()");
3140 return;
3141 }
3142
3143 switch (d->target) {
3144 case QOpenGLTexture::Target2DMultisample:
3145 case QOpenGLTexture::Target2DMultisampleArray:
3146 d->samples = samples;
3147 break;
3148
3149 case QOpenGLTexture::Target1D:
3150 case QOpenGLTexture::Target2D:
3151 case QOpenGLTexture::Target3D:
3152 case QOpenGLTexture::Target1DArray:
3153 case QOpenGLTexture::Target2DArray:
3154 case QOpenGLTexture::TargetCubeMap:
3155 case QOpenGLTexture::TargetCubeMapArray:
3156 case QOpenGLTexture::TargetBuffer:
3157 case QOpenGLTexture::TargetRectangle:
3158
3159 qWarning("Texture target does not support multisampling");
3160 break;
3161 }
3162}
3163
3164/*!
3165 Returns the number of multisample sample points for this texture.
3166 If storage has not yet been allocated for this texture then
3167 this function returns the requested number of samples.
3168
3169 For texture targets that do not support multisampling this
3170 will return 0.
3171
3172 \sa setSamples(), isStorageAllocated()
3173*/
3174int QOpenGLTexture::samples() const
3175{
3176 Q_D(const QOpenGLTexture);
3177 return d->samples;
3178}
3179
3180/*!
3181 Sets whether the sample positions and number of samples used with
3182 a multisample capable texture target to \a fixed. If set to \c true
3183 the sample positions and number of samples used are the same for
3184 all texels in the image and will not depend upon the image size or
3185 internal format. This function should be called before storage is allocated
3186 for the texture.
3187
3188 For targets that do not support multisampling this function has
3189 no effect.
3190
3191 The default value is \c true.
3192
3193 \sa isFixedSamplePositions(), isStorageAllocated()
3194*/
3195void QOpenGLTexture::setFixedSamplePositions(bool fixed)
3196{
3197 Q_D(QOpenGLTexture);
3198 d->create();
3199 if (isStorageAllocated()) {
3200 qWarning("Cannot set sample positions on a texture that already has storage allocated.\n"
3201 "To do so, destroy() the texture and then create() and setFixedSamplePositions()");
3202 return;
3203 }
3204
3205 switch (d->target) {
3206 case QOpenGLTexture::Target2DMultisample:
3207 case QOpenGLTexture::Target2DMultisampleArray:
3208 d->fixedSamplePositions = fixed;
3209 break;
3210
3211 case QOpenGLTexture::Target1D:
3212 case QOpenGLTexture::Target2D:
3213 case QOpenGLTexture::Target3D:
3214 case QOpenGLTexture::Target1DArray:
3215 case QOpenGLTexture::Target2DArray:
3216 case QOpenGLTexture::TargetCubeMap:
3217 case QOpenGLTexture::TargetCubeMapArray:
3218 case QOpenGLTexture::TargetBuffer:
3219 case QOpenGLTexture::TargetRectangle:
3220
3221 qWarning("Texture target does not support multisampling");
3222 break;
3223 }
3224}
3225
3226/*!
3227 Returns whether this texture uses a fixed pattern of multisample
3228 samples. If storage has not yet been allocated for this texture then
3229 this function returns the requested fixed sample position setting.
3230
3231 For texture targets that do not support multisampling this
3232 will return \c true.
3233
3234 \sa setFixedSamplePositions(), isStorageAllocated()
3235*/
3236bool QOpenGLTexture::isFixedSamplePositions() const
3237{
3238 Q_D(const QOpenGLTexture);
3239 return d->fixedSamplePositions;
3240}
3241
3242/*!
3243 Allocates server-side storage for this texture object taking
3244 into account, the format, dimensions, mipmap levels, array
3245 layers and cubemap faces.
3246
3247 Once storage has been allocated it is no longer possible to change
3248 these properties.
3249
3250 If supported QOpenGLTexture makes use of immutable texture
3251 storage.
3252
3253 Once storage has been allocated for the texture then pixel data
3254 can be uploaded via one of the setData() overloads.
3255
3256 \note If immutable texture storage is not available,
3257 then a default pixel format and pixel type will be used to
3258 create the mutable storage. You can use the other
3259 allocateStorage() overload to specify exactly the pixel format
3260 and the pixel type to use when allocating mutable storage;
3261 this is particularly useful under certain OpenGL ES implementations
3262 (notably, OpenGL ES 2), where the pixel format and the pixel type
3263 used at allocation time must perfectly match the format
3264 and the type passed to any subsequent setData() call.
3265
3266 \sa isStorageAllocated(), setData()
3267*/
3268void QOpenGLTexture::allocateStorage()
3269{
3270 Q_D(QOpenGLTexture);
3271 if (d->create()) {
3272 const QOpenGLTexture::PixelFormat pixelFormat = pixelFormatCompatibleWithInternalFormat(d->format);
3273 const QOpenGLTexture::PixelType pixelType = pixelTypeCompatibleWithInternalFormat(d->format);
3274 d->allocateStorage(pixelFormat, pixelType);
3275 }
3276}
3277
3278/*!
3279 \since 5.5
3280
3281 Allocates server-side storage for this texture object taking
3282 into account, the format, dimensions, mipmap levels, array
3283 layers and cubemap faces.
3284
3285 Once storage has been allocated it is no longer possible to change
3286 these properties.
3287
3288 If supported QOpenGLTexture makes use of immutable texture
3289 storage. However, if immutable texture storage is not available,
3290 then the specified \a pixelFormat and \a pixelType will be used
3291 to allocate mutable storage; note that in certain OpenGL implementations
3292 (notably, OpenGL ES 2) they must perfectly match the format
3293 and the type passed to any subsequent setData() call.
3294
3295 Once storage has been allocated for the texture then pixel data
3296 can be uploaded via one of the setData() overloads.
3297
3298 \sa isStorageAllocated(), setData()
3299*/
3300void QOpenGLTexture::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
3301{
3302 Q_D(QOpenGLTexture);
3303 if (d->create())
3304 d->allocateStorage(pixelFormat, pixelType);
3305}
3306
3307/*!
3308 Returns \c true if server-side storage for this texture as been
3309 allocated.
3310
3311 The texture format, dimensions, mipmap levels and array layers
3312 cannot be altered once storage ihas been allocated.
3313
3314 \sa allocateStorage(), setSize(), setMipLevels(), setLayers(), setFormat()
3315*/
3316bool QOpenGLTexture::isStorageAllocated() const
3317{
3318 Q_D(const QOpenGLTexture);
3319 return d->storageAllocated;
3320}
3321
3322/*!
3323 Attempts to create a texture view onto this texture. A texture
3324 view is somewhat analogous to a view in SQL in that it presents
3325 a restricted or reinterpreted view of the original data. Texture
3326 views do not allocate any more server-side storage, instead relying
3327 on the storage buffer of the source texture.
3328
3329 Texture views are only available when using immutable storage. For
3330 more information on texture views see
3331 http://www.opengl.org/wiki/Texture_Storage#Texture_views.
3332
3333 The \a target argument specifies the target to use for the view.
3334 Only some targets can be used depending upon the target of the original
3335 target. For e.g. a view onto a Target1DArray texture can specify
3336 either Target1DArray or Target1D but for the latter the number of
3337 array layers specified with \a minimumLayer and \a maximumLayer must
3338 be exactly 1.
3339
3340 Simpliar constraints apply for the \a viewFormat. See the above link
3341 and the specification for more details.
3342
3343 The \a minimumMipmapLevel, \a maximumMipmapLevel, \a minimumLayer,
3344 and \a maximumLayer arguments serve to restrict the parts of the
3345 texture accessible by the texture view.
3346
3347 If creation of the texture view fails this function will return
3348 0. If the function succeeds it will return a pointer to a new
3349 QOpenGLTexture object that will return \c true from its isTextureView()
3350 function.
3351
3352 \sa isTextureView()
3353*/
3354QOpenGLTexture *QOpenGLTexture::createTextureView(Target target,
3355 TextureFormat viewFormat,
3356 int minimumMipmapLevel, int maximumMipmapLevel,
3357 int minimumLayer, int maximumLayer) const
3358{
3359 Q_D(const QOpenGLTexture);
3360 if (!isStorageAllocated()) {
3361 qWarning("Cannot set create a texture view of a texture that does not have storage allocated.");
3362 return nullptr;
3363 }
3364 Q_ASSERT(maximumMipmapLevel >= minimumMipmapLevel);
3365 Q_ASSERT(maximumLayer >= minimumLayer);
3366 return d->createTextureView(target, viewFormat,
3367 minimumMipmapLevel, maximumMipmapLevel,
3368 minimumLayer, maximumLayer);
3369}
3370
3371/*!
3372 Returns \c true if this texture object is actually a view onto another
3373 texture object.
3374
3375 \sa createTextureView()
3376*/
3377bool QOpenGLTexture::isTextureView() const
3378{
3379 Q_D(const QOpenGLTexture);
3380 Q_ASSERT(d->textureId);
3381 return d->textureView;
3382}
3383
3384/*!
3385 Uploads pixel \a data for this texture object \a mipLevel, array \a layer, and \a cubeFace.
3386 Storage must have been allocated before uploading pixel data. Some overloads of setData()
3387 will set appropriate dimensions, mipmap levels, and array layers and then allocate storage
3388 for you if they have enough information to do so. This will be noted in the function
3389 documentation.
3390
3391 The structure of the pixel data pointed to by \a data is specified by \a sourceFormat
3392 and \a sourceType. The pixel data upload can optionally be controlled by \a options.
3393
3394 If using a compressed format() then you should use setCompressedData() instead of this
3395 function.
3396
3397 \since 5.3
3398 \sa setCompressedData()
3399*/
3400void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace,
3401 PixelFormat sourceFormat, PixelType sourceType,
3402 const void *data, const QOpenGLPixelTransferOptions * const options)
3403{
3404 Q_D(QOpenGLTexture);
3405 Q_ASSERT(d->textureId);
3406 if (!isStorageAllocated()) {
3407 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3408 "To do so call allocateStorage() before this function");
3409 return;
3410 }
3411 d->setData(mipLevel, layer, 1, cubeFace, sourceFormat, sourceType, data, options);
3412}
3413
3414/*!
3415 \since 5.9
3416 \overload
3417
3418 Parameter \a layerCount is the number of layers in a texture array
3419 that are being uploaded/populated by this call.
3420*/
3421void QOpenGLTexture::setData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions * const options)
3422{
3423 Q_D(QOpenGLTexture);
3424 Q_ASSERT(d->textureId);
3425 if (!isStorageAllocated()) {
3426 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3427 "To do so call allocateStorage() before this function");
3428 return;
3429 }
3430 d->setData(mipLevel, layer, layerCount, cubeFace, sourceFormat, sourceType, data, options);
3431}
3432
3433/*!
3434 \since 5.3
3435 \overload
3436*/
3437void QOpenGLTexture::setData(int mipLevel, int layer,
3438 PixelFormat sourceFormat, PixelType sourceType,
3439 const void *data, const QOpenGLPixelTransferOptions * const options)
3440{
3441 Q_D(QOpenGLTexture);
3442 Q_ASSERT(d->textureId);
3443 d->setData(mipLevel, layer, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
3444}
3445
3446/*!
3447 \since 5.3
3448 \overload
3449*/
3450void QOpenGLTexture::setData(int mipLevel,
3451 PixelFormat sourceFormat, PixelType sourceType,
3452 const void *data, const QOpenGLPixelTransferOptions * const options)
3453{
3454 Q_D(QOpenGLTexture);
3455 Q_ASSERT(d->textureId);
3456 d->setData(mipLevel, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
3457}
3458
3459/*!
3460 \since 5.3
3461 \overload
3462*/
3463void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType,
3464 const void *data, const QOpenGLPixelTransferOptions * const options)
3465{
3466 Q_D(QOpenGLTexture);
3467 Q_ASSERT(d->textureId);
3468 d->setData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
3469}
3470
3471/*!
3472 \since 5.14
3473 \overload
3474
3475 This overload is to be used to update a part of the texture. Parameters \a
3476 xOffset, \a yOffset, \a zOffset specify the texel offsets within the
3477 texture. Parameters \a width, \a height and \a depth specify the dimensions
3478 of the sub image.
3479
3480 The structure of the pixel data pointed to by \a data is specified by \a
3481 sourceFormat and \a sourceType. The pixel data upload can optionally be
3482 controlled by \a options.
3483*/
3484void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3485 int width, int height, int depth,
3486 PixelFormat sourceFormat, PixelType sourceType,
3487 const void *data, const QOpenGLPixelTransferOptions * const options)
3488{
3489 Q_D(QOpenGLTexture);
3490 Q_ASSERT(d->textureId);
3491 d->setData(xOffset, yOffset, zOffset,
3492 width, height, depth,
3493 0, 0, 1,
3494 QOpenGLTexture::CubeMapPositiveX, sourceFormat,
3495 sourceType, data, options);
3496}
3497
3498/*!
3499 \since 5.14
3500 \overload
3501
3502 This overload is to be used to update a part of the texture. Parameters \a
3503 xOffset, \a yOffset, \a zOffset specify the texel offsets within the
3504 texture. Parameters \a width, \a height and \a depth specify the dimensions
3505 of the sub image. The mip map level the sub image we want to
3506 update is specified with \a mipLevel.
3507
3508 The structure of the pixel data pointed to by \a data is specified by \a
3509 sourceFormat and \a sourceType. The pixel data upload can optionally be
3510 controlled by \a options.
3511*/
3512void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3513 int width, int height, int depth,
3514 int mipLevel,
3515 PixelFormat sourceFormat, PixelType sourceType,
3516 const void *data, const QOpenGLPixelTransferOptions * const options)
3517{
3518 Q_D(QOpenGLTexture);
3519 Q_ASSERT(d->textureId);
3520 d->setData(xOffset, yOffset, zOffset,
3521 width, height, depth,
3522 mipLevel, 0, 1,
3523 QOpenGLTexture::CubeMapPositiveX, sourceFormat,
3524 sourceType, data, options);
3525}
3526
3527/*!
3528 \since 5.14
3529 \overload
3530
3531 This overload is to be used to update a part of the texture. Parameters \a
3532 xOffset, \a yOffset, \a zOffset specify the texel offsets within the
3533 texture. Parameters \a width, \a height and \a depth specify the dimensions
3534 of the sub image. The mip map level and layerof the sub image we want to
3535 update are specified with \a mipLevel and \a layer.
3536
3537 The structure of the pixel data pointed to by \a data is specified by \a
3538 sourceFormat and \a sourceType. The pixel data upload can optionally be
3539 controlled by \a options.
3540*/
3541void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3542 int width, int height, int depth,
3543 int mipLevel, int layer,
3544 PixelFormat sourceFormat, PixelType sourceType,
3545 const void *data, const QOpenGLPixelTransferOptions * const options)
3546{
3547 Q_D(QOpenGLTexture);
3548 Q_ASSERT(d->textureId);
3549 d->setData(xOffset, yOffset, zOffset,
3550 width, height, depth,
3551 mipLevel, layer, 1,
3552 QOpenGLTexture::CubeMapPositiveX, sourceFormat,
3553 sourceType, data, options);
3554}
3555
3556/*!
3557 \since 5.14
3558 \overload
3559
3560 This overload is to be used to update a part of the texture. Parameters \a
3561 xOffset, \a yOffset, \a zOffset specify the texel offsets within the
3562 texture. Parameters \a width, \a height and \a depth specify the dimensions
3563 of the sub image.The mip map level, layer and cube map face of the sub
3564 image we want to update are specified with \a mipLevel, \a layer and \a
3565 face.
3566
3567 The structure of the pixel data pointed to by \a data is specified by \a
3568 sourceFormat and \a sourceType. The pixel data upload can optionally be
3569 controlled by \a options.
3570*/
3571void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3572 int width, int height, int depth,
3573 int mipLevel, int layer,
3574 CubeMapFace face,
3575 PixelFormat sourceFormat, PixelType sourceType,
3576 const void *data, const QOpenGLPixelTransferOptions * const options)
3577{
3578 Q_D(QOpenGLTexture);
3579 Q_ASSERT(d->textureId);
3580 d->setData(xOffset, yOffset, zOffset,
3581 width, height, depth,
3582 mipLevel, layer, 1,
3583 face, sourceFormat,
3584 sourceType, data, options);
3585}
3586
3587/*!
3588 \since 5.14
3589 \overload
3590
3591 This overload is to be used to update a part of the texture. Parameters \a
3592 xOffset, \a yOffset, \a zOffset specify the texel offsets within the
3593 texture. Parameters \a width, \a height and \a depth specify the dimensions
3594 of the sub image.The mip map level, starting layer, cube map face and
3595 number of layers of the sub image we want to update are specified with \a
3596 mipLevel, \a layer, \a face and \a layerCount.
3597
3598 The structure of the pixel data pointed to by \a data is specified by \a
3599 sourceFormat and \a sourceType. The pixel data upload can optionally be
3600 controlled by \a options.
3601*/
3602void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3603 int width, int height, int depth,
3604 int mipLevel, int layer,
3605 CubeMapFace face, int layerCount,
3606 PixelFormat sourceFormat, PixelType sourceType,
3607 const void *data, const QOpenGLPixelTransferOptions * const options)
3608{
3609 Q_D(QOpenGLTexture);
3610 Q_ASSERT(d->textureId);
3611 d->setData(xOffset, yOffset, zOffset,
3612 width, height, depth,
3613 mipLevel, layer, layerCount,
3614 face, sourceFormat,
3615 sourceType, data, options);
3616}
3617
3618/*!
3619 This overload of setData() will allocate storage for you.
3620 The pixel data is contained in \a image. Mipmaps are generated by default.
3621 Set \a genMipMaps to \l DontGenerateMipMaps to turn off mipmap generation.
3622
3623 \note \a image is automatically converted to QImage::Format_RGBA8888 which
3624 may have performance implications for large images with a different format.
3625
3626 \overload
3627*/
3628void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps)
3629{
3630 QOpenGLContext *context = QOpenGLContext::currentContext();
3631 if (!context) {
3632 qWarning("QOpenGLTexture::setData() requires a valid current context");
3633 return;
3634 }
3635
3636 if (image.isNull()) {
3637 qWarning("QOpenGLTexture::setData() tried to set a null image");
3638 return;
3639 }
3640
3641 QImage glImage = image.convertToFormat(QImage::Format_RGBA8888);
3642 if (glImage.isNull()) {
3643 qWarning("QOpenGLTexture::setData() failed to convert image");
3644 return;
3645 }
3646
3647 if (context->isOpenGLES() && context->format().majorVersion() < 3)
3648 setFormat(QOpenGLTexture::RGBAFormat);
3649 else
3650 setFormat(QOpenGLTexture::RGBA8_UNorm);
3651
3652 setSize(image.width(), image.height());
3653 setMipLevels(genMipMaps == GenerateMipMaps ? maximumMipLevels() : 1);
3654 allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
3655
3656 // Upload pixel data and generate mipmaps
3657 QOpenGLPixelTransferOptions uploadOptions;
3658 uploadOptions.setAlignment(1);
3659 setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, glImage.constBits(), &uploadOptions);
3660}
3661
3662/*!
3663 Uploads compressed pixel \a data to \a mipLevel, array \a layer, and \a cubeFace.
3664 The pixel transfer can optionally be controlled with \a options. The \a dataSize
3665 argument should specify the size of the data pointed to by \a data.
3666
3667 If not using a compressed format() then you should use setData() instead of this
3668 function.
3669
3670 \since 5.3
3671*/
3672void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
3673 int dataSize, const void *data,
3674 const QOpenGLPixelTransferOptions * const options)
3675{
3676 Q_D(QOpenGLTexture);
3677 Q_ASSERT(d->textureId);
3678 if (!isStorageAllocated()) {
3679 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3680 "To do so call allocateStorage() before this function");
3681 return;
3682 }
3683 d->setCompressedData(mipLevel, layer, 1, cubeFace, dataSize, data, options);
3684}
3685
3686/*!
3687 \since 5.9
3688 \overload
3689
3690 Parameter \a layerCount is the number of layers in a texture array
3691 that are being uploaded/populated by this call.
3692*/
3693void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, int dataSize, const void *data, const QOpenGLPixelTransferOptions * const options)
3694{
3695 Q_D(QOpenGLTexture);
3696 Q_ASSERT(d->textureId);
3697 if (!isStorageAllocated()) {
3698 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3699 "To do so call allocateStorage() before this function");
3700 return;
3701 }
3702 d->setCompressedData(mipLevel, layer, layerCount, cubeFace, dataSize, data, options);
3703}
3704
3705/*!
3706 \overload
3707*/
3708void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int dataSize, const void *data,
3709 const QOpenGLPixelTransferOptions * const options)
3710{
3711 Q_D(QOpenGLTexture);
3712 Q_ASSERT(d->textureId);
3713 d->setCompressedData(mipLevel, layer, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
3714}
3715
3716/*!
3717 \overload
3718*/
3719void QOpenGLTexture::setCompressedData(int mipLevel, int dataSize, const void *data,
3720 const QOpenGLPixelTransferOptions * const options)
3721{
3722 Q_D(QOpenGLTexture);
3723 Q_ASSERT(d->textureId);
3724 d->setCompressedData(mipLevel, 0, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
3725}
3726
3727/*!
3728 \overload
3729*/
3730void QOpenGLTexture::setCompressedData(int dataSize, const void *data,
3731 const QOpenGLPixelTransferOptions * const options)
3732{
3733 Q_D(QOpenGLTexture);
3734 Q_ASSERT(d->textureId);
3735 d->setCompressedData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
3736}
3737
3738/*!
3739 Returns \c true if your OpenGL implementation and version supports the texture
3740 feature \a feature.
3741*/
3742bool QOpenGLTexture::hasFeature(Feature feature)
3743{
3744 QOpenGLContext *ctx = QOpenGLContext::currentContext();
3745 if (!ctx) {
3746 qWarning("QOpenGLTexture::hasFeature() requires a valid current context");
3747 return false;
3748 }
3749
3750 QSurfaceFormat f = ctx->format();
3751
3752 bool supported = false;
3753
3754#if !QT_CONFIG(opengles2)
3755 if (!ctx->isOpenGLES()) {
3756 switch (feature) {
3757 case ImmutableMultisampleStorage:
3758 supported = f.version() >= std::pair(4, 3)
3759 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage_multisample"));
3760 break;
3761
3762 case TextureBuffer:
3763 supported = f.version() >= std::pair(3, 0)
3764 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_buffer_object"));
3765 break;
3766
3767 case StencilTexturing:
3768 supported = f.version() >= std::pair(4, 3)
3769 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_stencil_texturing"));
3770 break;
3771
3772 case ImmutableStorage:
3773 supported = f.version() >= std::pair(4, 2)
3774 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage"))
3775 || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_storage"));
3776 break;
3777
3778 case TextureCubeMapArrays:
3779 supported = f.version() >= std::pair(4, 0)
3780 || ctx->hasExtension(QByteArrayLiteral("ARB_texture_cube_map_array"));
3781 break;
3782
3783 case Swizzle:
3784 supported = f.version() >= std::pair(3, 3)
3785 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_swizzle"));
3786 break;
3787
3788 case TextureMultisample:
3789 supported = f.version() >= std::pair(3, 2)
3790 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_multisample"));
3791 break;
3792
3793 case TextureArrays:
3794 supported = f.version() >= std::pair(3, 0)
3795 || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_array"));
3796 break;
3797
3798 case TextureRectangle:
3799 supported = f.version() >= std::pair(2, 1)
3800 || ctx->hasExtension(QByteArrayLiteral("ARB_texture_rectangle"));
3801 break;
3802
3803 case Texture3D:
3804 supported = f.version() >= std::pair(1, 3);
3805 break;
3806
3807 case AnisotropicFiltering:
3808 supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
3809 break;
3810
3811 case NPOTTextures:
3812 case NPOTTextureRepeat:
3813 supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
3814 break;
3815
3816 case Texture1D:
3817 supported = f.version() >= std::pair(1, 1);
3818 break;
3819
3820 case TextureComparisonOperators:
3821 // GL 1.4 and GL_ARB_shadow alone support only LEQUAL and GEQUAL;
3822 // since we're talking about history anyhow avoid to be extra pedantic
3823 // in the feature set, and simply claim supported if we have the full set of operators
3824 // (which has been added into 1.5 / GL_EXT_shadow_funcs).
3825 supported = f.version() >= std::pair(1, 5)
3826 || (ctx->hasExtension(QByteArrayLiteral("GL_ARB_shadow"))
3827 && ctx->hasExtension(QByteArrayLiteral("GL_EXT_shadow_funcs")));
3828 break;
3829
3830 case TextureMipMapLevel:
3831 supported = f.version() >= std::pair(1, 2);
3832 break;
3833
3834 case MaxFeatureFlag:
3835 break;
3836 }
3837 }
3838
3839 if (ctx->isOpenGLES())
3840#endif
3841 {
3842 const char *renderer = reinterpret_cast<const char *>(ctx->functions()->glGetString(GL_RENDERER));
3843 switch (feature) {
3844 case ImmutableStorage:
3845 supported = (f.version() >= std::pair(3, 0) || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_storage")))
3846 && !(renderer && strstr(renderer, "Mali")); // do not use on Mali: QTBUG-45106
3847 break;
3848
3849 case ImmutableMultisampleStorage:
3850 supported = f.version() >= std::pair(3, 1);
3851 break;
3852
3853 case TextureRectangle:
3854 break;
3855
3856 case TextureArrays:
3857 supported = f.version() >= std::pair(3, 0);
3858 break;
3859
3860 case Texture3D:
3861 supported = f.version() >= std::pair(3, 0)
3862 || ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
3863 break;
3864
3865 case TextureMultisample:
3866 supported = f.version() >= std::pair(3, 1);
3867 break;
3868
3869 case TextureBuffer:
3870 break;
3871
3872 case TextureCubeMapArrays:
3873 break;
3874
3875 case Swizzle:
3876 supported = f.version() >= std::pair(3, 0);
3877 break;
3878
3879 case StencilTexturing:
3880 break;
3881
3882 case AnisotropicFiltering:
3883 supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
3884 break;
3885
3886 case NPOTTextures:
3887 case NPOTTextureRepeat:
3888 supported = f.version() >= std::pair(3,0)
3889 || ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"))
3890 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
3891 break;
3892
3893 case Texture1D:
3894 break;
3895
3896 case TextureComparisonOperators:
3897 supported = f.version() >= std::pair(3, 0)
3898 || ctx->hasExtension(QByteArrayLiteral("GL_EXT_shadow_samplers"));
3899 break;
3900
3901 case TextureMipMapLevel:
3902 supported = f.version() >= std::pair(3, 0);
3903 break;
3904
3905 case MaxFeatureFlag:
3906 break;
3907 }
3908 }
3909
3910 return supported;
3911}
3912
3913/*!
3914 Sets the base mipmap level used for all texture lookups with this texture to \a baseLevel.
3915
3916 \note This function has no effect on Qt built for OpenGL ES 2.
3917 \sa mipBaseLevel(), setMipMaxLevel(), setMipLevelRange()
3918*/
3919void QOpenGLTexture::setMipBaseLevel(int baseLevel)
3920{
3921 Q_D(QOpenGLTexture);
3922 d->create();
3923 if (!d->features.testFlag(TextureMipMapLevel)) {
3924 qWarning("QOpenGLTexture::setMipBaseLevel: requires OpenGL >= 1.2 or OpenGL ES >= 3.0");
3925 return;
3926 }
3927 Q_ASSERT(d->textureId);
3928 Q_ASSERT(d->texFuncs);
3929 Q_ASSERT(baseLevel <= d->maxLevel);
3930 d->baseLevel = baseLevel;
3931 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
3932}
3933
3934/*!
3935 Returns the mipmap base level used for all texture lookups with this texture.
3936 The default is 0.
3937
3938 \sa setMipBaseLevel(), mipMaxLevel(), mipLevelRange()
3939*/
3940int QOpenGLTexture::mipBaseLevel() const
3941{
3942 Q_D(const QOpenGLTexture);
3943 return d->baseLevel;
3944}
3945
3946/*!
3947 Sets the maximum mipmap level used for all texture lookups with this texture to \a maxLevel.
3948
3949 \note This function has no effect on Qt built for OpenGL ES 2.
3950 \sa mipMaxLevel(), setMipBaseLevel(), setMipLevelRange()
3951*/
3952void QOpenGLTexture::setMipMaxLevel(int maxLevel)
3953{
3954 Q_D(QOpenGLTexture);
3955 d->create();
3956 if (!d->features.testFlag(TextureMipMapLevel)) {
3957 qWarning("QOpenGLTexture::setMipMaxLevel: requires OpenGL >= 1.2 or OpenGL ES >= 3.0");
3958 return;
3959 }
3960 Q_ASSERT(d->textureId);
3961 Q_ASSERT(d->texFuncs);
3962 Q_ASSERT(d->baseLevel <= maxLevel);
3963 d->maxLevel = maxLevel;
3964 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
3965}
3966
3967/*!
3968 Returns the mipmap maximum level used for all texture lookups with this texture.
3969
3970 \sa setMipMaxLevel(), mipBaseLevel(), mipLevelRange()
3971*/
3972int QOpenGLTexture::mipMaxLevel() const
3973{
3974 Q_D(const QOpenGLTexture);
3975 return d->maxLevel;
3976}
3977
3978/*!
3979 Sets the range of mipmap levels that can be used for texture lookups with this texture
3980 to range from \a baseLevel to \a maxLevel.
3981
3982 \note This function has no effect on Qt built for OpenGL ES 2.
3983 \sa setMipBaseLevel(), setMipMaxLevel(), mipLevelRange()
3984*/
3985void QOpenGLTexture::setMipLevelRange(int baseLevel, int maxLevel)
3986{
3987 Q_D(QOpenGLTexture);
3988 d->create();
3989 if (!d->features.testFlag(TextureMipMapLevel)) {
3990 qWarning("QOpenGLTexture::setMipLevelRange: requires OpenGL >= 1.2 or OpenGL ES >= 3.0");
3991 return;
3992 }
3993 Q_ASSERT(d->textureId);
3994 Q_ASSERT(d->texFuncs);
3995 Q_ASSERT(baseLevel <= maxLevel);
3996 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
3997 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
3998}
3999
4000/*!
4001 Returns the range of mipmap levels that can be used for texture lookups with this texture.
4002
4003 \sa mipBaseLevel(), mipMaxLevel()
4004*/
4005std::pair<int, int> QOpenGLTexture::mipLevelRange() const
4006{
4007 Q_D(const QOpenGLTexture);
4008 return std::pair(d->baseLevel, d->maxLevel);
4009}
4010
4011/*!
4012 If \a enabled is \c true, enables automatic mipmap generation for this texture object
4013 to occur whenever the level 0 mipmap data is set via setData().
4014
4015 The automatic mipmap generation is enabled by default.
4016
4017 \note Mipmap generation is not supported for compressed textures with OpenGL ES 2.0.
4018
4019 \sa isAutoMipMapGenerationEnabled(), generateMipMaps()
4020*/
4021void QOpenGLTexture::setAutoMipMapGenerationEnabled(bool enabled)
4022{
4023 Q_D(QOpenGLTexture);
4024 d->autoGenerateMipMaps = enabled;
4025}
4026
4027/*!
4028 Returns whether auto mipmap generation is enabled for this texture object.
4029
4030 \sa setAutoMipMapGenerationEnabled(), generateMipMaps()
4031*/
4032bool QOpenGLTexture::isAutoMipMapGenerationEnabled() const
4033{
4034 Q_D(const QOpenGLTexture);
4035 return d->autoGenerateMipMaps;
4036}
4037
4038/*!
4039 Generates mipmaps for this texture object from mipmap level 0. If you are
4040 using a texture target and filtering option that requires mipmaps and you
4041 have disabled automatic mipmap generation then you need to call this function
4042 or the overload to create the mipmap chain.
4043
4044 \note Mipmap generation is not supported for compressed textures with OpenGL ES.
4045
4046 \sa setAutoMipMapGenerationEnabled(), setMipLevels(), mipLevels()
4047*/
4048void QOpenGLTexture::generateMipMaps()
4049{
4050 Q_D(QOpenGLTexture);
4051 Q_ASSERT(d->texFuncs);
4052 Q_ASSERT(d->textureId);
4053 if (isCompressedFormat(d->format)) {
4054 if (QOpenGLContext *ctx = QOpenGLContext::currentContext())
4055 if (ctx->isOpenGLES())
4056 return;
4057 }
4058 d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget);
4059}
4060
4061/*!
4062 Generates mipmaps for this texture object from mipmap level \a baseLevel. If you are
4063 using a texture target and filtering option that requires mipmaps and you
4064 have disabled automatic mipmap generation then you need to call this function
4065 or the overload to create the mipmap chain.
4066
4067 The generation of mipmaps to above \a baseLevel is achieved by setting the mipmap
4068 base level to \a baseLevel and then generating the mipmap chain. If \a resetBaseLevel
4069 is \c true, then the baseLevel of the texture will be reset to its previous value.
4070
4071 \sa setAutoMipMapGenerationEnabled(), setMipLevels(), mipLevels()
4072*/
4073void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel)
4074{
4075 Q_D(QOpenGLTexture);
4076 Q_ASSERT(d->texFuncs);
4077 Q_ASSERT(d->textureId);
4078 if (isCompressedFormat(d->format)) {
4079 if (QOpenGLContext *ctx = QOpenGLContext::currentContext())
4080 if (ctx->isOpenGLES())
4081 return;
4082 }
4083 int oldBaseLevel;
4084 if (resetBaseLevel)
4085 oldBaseLevel = mipBaseLevel();
4086 setMipBaseLevel(baseLevel);
4087 d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget);
4088 if (resetBaseLevel)
4089 setMipBaseLevel(oldBaseLevel);
4090}
4091
4092/*!
4093 GLSL shaders are able to reorder the components of the vec4 returned by texture
4094 functions. It is also desirable to be able to control this reordering from CPU
4095 side code. This is made possible by swizzle masks since OpenGL 3.3.
4096
4097 Each component of the texture can be mapped to one of the SwizzleValue options.
4098
4099 This function maps \a component to the output \a value.
4100
4101 \note This function has no effect on Mac and Qt built for OpenGL ES 2.
4102 \sa swizzleMask()
4103*/
4104void QOpenGLTexture::setSwizzleMask(SwizzleComponent component, SwizzleValue value)
4105{
4106#if !defined(Q_OS_APPLE) && !QT_CONFIG(opengles2)
4107 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4108 Q_D(QOpenGLTexture);
4109 d->create();
4110 Q_ASSERT(d->texFuncs);
4111 Q_ASSERT(d->textureId);
4112 if (!d->features.testFlag(Swizzle)) {
4113 qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
4114 return;
4115 }
4116 d->swizzleMask[component - SwizzleRed] = value;
4117 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, component, value);
4118 return;
4119 }
4120#else
4121 Q_UNUSED(component);
4122 Q_UNUSED(value);
4123#endif
4124 qWarning("QOpenGLTexture: Texture swizzling is not supported");
4125}
4126
4127/*!
4128 Parameters \a {r}, \a {g}, \a {b}, and \a {a} are values used for setting
4129 the colors red, green, blue, and the alpha value.
4130 \overload
4131*/
4132void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g,
4133 SwizzleValue b, SwizzleValue a)
4134{
4135#if !defined(Q_OS_APPLE) && !QT_CONFIG(opengles2)
4136 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4137 Q_D(QOpenGLTexture);
4138 d->create();
4139 Q_ASSERT(d->texFuncs);
4140 Q_ASSERT(d->textureId);
4141 if (!d->features.testFlag(Swizzle)) {
4142 qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
4143 return;
4144 }
4145 GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
4146 d->swizzleMask[0] = r;
4147 d->swizzleMask[1] = g;
4148 d->swizzleMask[2] = b;
4149 d->swizzleMask[3] = a;
4150 d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
4151 return;
4152 }
4153#else
4154 Q_UNUSED(r);
4155 Q_UNUSED(g);
4156 Q_UNUSED(b);
4157 Q_UNUSED(a);
4158#endif
4159 qWarning("QOpenGLTexture: Texture swizzling is not supported");
4160}
4161
4162/*!
4163 Returns the swizzle mask for texture \a component.
4164*/
4165QOpenGLTexture::SwizzleValue QOpenGLTexture::swizzleMask(SwizzleComponent component) const
4166{
4167 Q_D(const QOpenGLTexture);
4168 return d->swizzleMask[component - SwizzleRed];
4169}
4170
4171/*!
4172 \enum QOpenGLTexture::DepthStencilMode
4173 \since 5.4
4174 This enum specifies which component of a depth/stencil texture is
4175 accessed when the texture is sampled.
4176
4177 \value DepthMode Equivalent to GL_DEPTH_COMPONENT.
4178 \value StencilMode Equivalent to GL_STENCIL_INDEX.
4179*/
4180
4181/*!
4182 If using a texture that has a combined depth/stencil format this function sets
4183 which component of the texture is accessed to \a mode.
4184
4185 When the parameter is set to DepthMode, then accessing it from the
4186 shader will access the depth component as a single float, as normal. But when
4187 the parameter is set to StencilMode, the shader will access the stencil component.
4188
4189 \note This function has no effect on Mac and Qt built for OpenGL ES 2.
4190 \since 5.4
4191 \sa depthStencilMode()
4192*/
4193void QOpenGLTexture::setDepthStencilMode(QOpenGLTexture::DepthStencilMode mode)
4194{
4195#if !defined(Q_OS_APPLE) && !QT_CONFIG(opengles2)
4196 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4197 Q_D(QOpenGLTexture);
4198 d->create();
4199 Q_ASSERT(d->texFuncs);
4200 Q_ASSERT(d->textureId);
4201 if (!d->features.testFlag(StencilTexturing)) {
4202 qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3 or GL_ARB_stencil_texturing");
4203 return;
4204 }
4205 d->depthStencilMode = mode;
4206 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, mode);
4207 return;
4208 }
4209#else
4210 Q_UNUSED(mode);
4211#endif
4212 qWarning("QOpenGLTexture: DepthStencil Mode is not supported");
4213}
4214
4215/*!
4216 Returns the depth stencil mode for textures using a combined depth/stencil format.
4217
4218 \since 5.4
4219 \sa setDepthStencilMode()
4220*/
4221QOpenGLTexture::DepthStencilMode QOpenGLTexture::depthStencilMode() const
4222{
4223 Q_D(const QOpenGLTexture);
4224 return d->depthStencilMode;
4225}
4226
4227/*!
4228 \enum QOpenGLTexture::ComparisonFunction
4229 \since 5.5
4230 This enum specifies which comparison operator is used when texture comparison
4231 is enabled on this texture.
4232
4233 \value CompareLessEqual Equivalent to GL_LEQUAL.
4234 \value CompareGreaterEqual Equivalent to GL_GEQUAL.
4235 \value CompareLess Equivalent to GL_LESS.
4236 \value CompareGreater Equivalent to GL_GREATER.
4237 \value CompareEqual Equivalent to GL_EQUAL.
4238 \value CompareNotEqual Equivalent to GL_NOTEQUAL.
4239 \value CompareAlways Equivalent to GL_ALWAYS.
4240 \value CompareNever Equivalent to GL_NEVER.
4241
4242 \omitvalue CommpareNotEqual
4243*/
4244
4245/*!
4246 \since 5.5
4247
4248 Sets the texture comparison function on this texture to \a function. The texture
4249 comparison function is used by shadow samplers when sampling a depth texture.
4250
4251 \sa comparisonFunction()
4252*/
4253void QOpenGLTexture::setComparisonFunction(QOpenGLTexture::ComparisonFunction function)
4254{
4255 Q_D(QOpenGLTexture);
4256 d->create();
4257 if (!d->features.testFlag(TextureComparisonOperators)) {
4258 qWarning("QOpenGLTexture::setComparisonFunction: requires OpenGL >= 1.5 or OpenGL ES >= 3.0");
4259 return;
4260 }
4261 d->comparisonFunction = function;
4262 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_COMPARE_FUNC, function);
4263}
4264
4265/*!
4266 \since 5.5
4267
4268 Returns the texture comparison operator set on this texture. By default, a
4269 texture has a CompareLessEqual comparison function.
4270
4271 \sa setComparisonFunction()
4272*/
4273QOpenGLTexture::ComparisonFunction QOpenGLTexture::comparisonFunction() const
4274{
4275 Q_D(const QOpenGLTexture);
4276 return d->comparisonFunction;
4277}
4278
4279/*!
4280 \enum QOpenGLTexture::ComparisonMode
4281 \since 5.5
4282 This enum specifies which comparison mode is used when sampling this texture.
4283
4284 \value CompareRefToTexture Equivalent to GL_COMPARE_REF_TO_TEXTURE.
4285 \value CompareNone Equivalent to GL_NONE.
4286*/
4287
4288/*!
4289 \since 5.5
4290
4291 Sets the texture comparison mode on this texture to \a mode. The texture
4292 comparison mode is used by shadow samplers when sampling a depth texture.
4293
4294 \sa comparisonMode()
4295*/
4296void QOpenGLTexture::setComparisonMode(QOpenGLTexture::ComparisonMode mode)
4297{
4298 Q_D(QOpenGLTexture);
4299 d->create();
4300 if (!d->features.testFlag(TextureComparisonOperators)) {
4301 qWarning("QOpenGLTexture::setComparisonMode: requires OpenGL >= 1.5 or OpenGL ES >= 3.0");
4302 return;
4303 }
4304 d->comparisonMode = mode;
4305 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_COMPARE_MODE, mode);
4306}
4307
4308/*!
4309 \since 5.5
4310
4311 Returns the texture comparison mode set on this texture. By default, a
4312 texture has a CompareNone comparison mode (i.e. comparisons are disabled).
4313
4314 \sa setComparisonMode()
4315*/
4316QOpenGLTexture::ComparisonMode QOpenGLTexture::comparisonMode() const
4317{
4318 Q_D(const QOpenGLTexture);
4319 return d->comparisonMode;
4320}
4321
4322/*!
4323 Sets the filter used for minification to \a filter.
4324
4325 \sa minificationFilter(), setMagnificationFilter(), setMinMagFilters()
4326*/
4327void QOpenGLTexture::setMinificationFilter(QOpenGLTexture::Filter filter)
4328{
4329 Q_D(QOpenGLTexture);
4330 d->create();
4331 Q_ASSERT(d->texFuncs);
4332 Q_ASSERT(d->textureId);
4333 d->minFilter = filter;
4334 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, filter);
4335}
4336
4337/*!
4338 Returns the minification filter.
4339
4340 \sa setMinificationFilter()
4341*/
4342QOpenGLTexture::Filter QOpenGLTexture::minificationFilter() const
4343{
4344 Q_D(const QOpenGLTexture);
4345 return d->minFilter;
4346}
4347
4348/*!
4349 Sets the magnification filter to \a filter.
4350
4351 \sa magnificationFilter(), setMinificationFilter(), setMinMagFilters()
4352*/
4353void QOpenGLTexture::setMagnificationFilter(QOpenGLTexture::Filter filter)
4354{
4355 Q_D(QOpenGLTexture);
4356 d->create();
4357 Q_ASSERT(d->texFuncs);
4358 Q_ASSERT(d->textureId);
4359 d->magFilter = filter;
4360 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, filter);
4361}
4362
4363/*!
4364 Returns the magnification filter.
4365
4366 \sa setMagnificationFilter()
4367*/
4368QOpenGLTexture::Filter QOpenGLTexture::magnificationFilter() const
4369{
4370 Q_D(const QOpenGLTexture);
4371 return d->magFilter;
4372}
4373
4374/*!
4375 Sets the minification filter to \a minificationFilter and the magnification filter
4376 to \a magnificationFilter.
4377
4378 \sa minMagFilters(), setMinificationFilter(), setMagnificationFilter()
4379*/
4380void QOpenGLTexture::setMinMagFilters(QOpenGLTexture::Filter minificationFilter,
4381 QOpenGLTexture::Filter magnificationFilter)
4382{
4383 Q_D(QOpenGLTexture);
4384 d->create();
4385 Q_ASSERT(d->texFuncs);
4386 Q_ASSERT(d->textureId);
4387 d->minFilter = minificationFilter;
4388 d->magFilter = magnificationFilter;
4389 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, minificationFilter);
4390 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, magnificationFilter);
4391}
4392
4393/*!
4394 Returns the current minification and magnification filters.
4395
4396 \sa setMinMagFilters()
4397*/
4398std::pair<QOpenGLTexture::Filter, QOpenGLTexture::Filter> QOpenGLTexture::minMagFilters() const
4399{
4400 Q_D(const QOpenGLTexture);
4401 return std::pair<QOpenGLTexture::Filter, QOpenGLTexture::Filter>(d->minFilter, d->magFilter);
4402}
4403
4404/*!
4405 If your OpenGL implementation supports the GL_EXT_texture_filter_anisotropic extension
4406 this function sets the maximum anisotropy level to \a anisotropy.
4407
4408 \sa maximumAnisotropy()
4409*/
4410void QOpenGLTexture::setMaximumAnisotropy(float anisotropy)
4411{
4412 Q_D(QOpenGLTexture);
4413 d->create();
4414 Q_ASSERT(d->texFuncs);
4415 Q_ASSERT(d->textureId);
4416 if (!d->features.testFlag(AnisotropicFiltering)) {
4417 qWarning("QOpenGLTexture::setMaximumAnisotropy() requires GL_EXT_texture_filter_anisotropic");
4418 return;
4419 }
4420 d->maxAnisotropy = anisotropy;
4421 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
4422}
4423
4424/*!
4425 Returns the maximum level of anisotropy to be accounted for when performing texture lookups.
4426 This requires the GL_EXT_texture_filter_anisotropic extension.
4427
4428 \sa setMaximumAnisotropy()
4429*/
4430float QOpenGLTexture::maximumAnisotropy() const
4431{
4432 Q_D(const QOpenGLTexture);
4433 return d->maxAnisotropy;
4434}
4435
4436/*!
4437 Sets the wrap (or repeat mode) for all texture dimensions to \a mode.
4438
4439 \sa wrapMode()
4440*/
4441void QOpenGLTexture::setWrapMode(QOpenGLTexture::WrapMode mode)
4442{
4443 Q_D(QOpenGLTexture);
4444 d->create();
4445 Q_ASSERT(d->texFuncs);
4446 Q_ASSERT(d->textureId);
4447 d->setWrapMode(mode);
4448}
4449
4450/*!
4451 Sets the wrap (or repeat mode) for the texture dimension \a direction
4452 to \a mode.
4453 \overload
4454*/
4455void QOpenGLTexture::setWrapMode(QOpenGLTexture::CoordinateDirection direction, QOpenGLTexture::WrapMode mode)
4456{
4457 Q_D(QOpenGLTexture);
4458 d->create();
4459 Q_ASSERT(d->texFuncs);
4460 Q_ASSERT(d->textureId);
4461 d->setWrapMode(direction, mode);
4462}
4463
4464/*!
4465 Returns the wrap mode for the texture dimension \a direction.
4466
4467 \sa setWrapMode()
4468*/
4469QOpenGLTexture::WrapMode QOpenGLTexture::wrapMode(QOpenGLTexture::CoordinateDirection direction) const
4470{
4471 Q_D(const QOpenGLTexture);
4472 return d->wrapMode(direction);
4473}
4474
4475/*!
4476 Sets the border color of the texture to \a color.
4477
4478 \note This function has no effect on Mac and Qt built for OpenGL ES 2.
4479 \sa borderColor()
4480*/
4481void QOpenGLTexture::setBorderColor(const QColor &color)
4482{
4483 setBorderColor(static_cast<float>(color.redF()), static_cast<float>(color.greenF()),
4484 static_cast<float>(color.blueF()), static_cast<float>(color.alphaF()));
4485}
4486
4487/*!
4488 Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and \a {a} to the
4489 alpha value.
4490 \overload
4491*/
4492void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
4493{
4494#if !QT_CONFIG(opengles2)
4495 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4496 Q_D(QOpenGLTexture);
4497 d->create();
4498 Q_ASSERT(d->texFuncs);
4499 Q_ASSERT(d->textureId);
4500 float values[4];
4501 values[0] = r;
4502 values[1] = g;
4503 values[2] = b;
4504 values[3] = a;
4505 d->borderColor.clear();
4506 for (int i = 0; i < 4; ++i)
4507 d->borderColor.append(QVariant(values[i]));
4508 d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
4509 return;
4510 }
4511#else
4512 Q_UNUSED(r);
4513 Q_UNUSED(g);
4514 Q_UNUSED(b);
4515 Q_UNUSED(a);
4516#endif
4517 qWarning("QOpenGLTexture: Border color is not supported");
4518}
4519
4520/*!
4521 Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and the alpha
4522 value to \a {a}.
4523 \overload
4524*/
4525void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
4526{
4527#if !QT_CONFIG(opengles2)
4528 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4529 Q_D(QOpenGLTexture);
4530 d->create();
4531 Q_ASSERT(d->texFuncs);
4532 Q_ASSERT(d->textureId);
4533 int values[4];
4534 values[0] = r;
4535 values[1] = g;
4536 values[2] = b;
4537 values[3] = a;
4538 d->borderColor.clear();
4539 for (int i = 0; i < 4; ++i)
4540 d->borderColor.append(QVariant(values[i]));
4541 d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
4542 return;
4543 }
4544#else
4545 Q_UNUSED(r);
4546 Q_UNUSED(g);
4547 Q_UNUSED(b);
4548 Q_UNUSED(a);
4549#endif
4550 qWarning("QOpenGLTexture: Border color is not supported");
4551
4552 // TODO Handle case of using glTextureParameterIiv() based on format
4553}
4554
4555/*!
4556 Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and the alpha
4557 value to \a {a}.
4558 \overload
4559*/
4560void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a)
4561{
4562#if !QT_CONFIG(opengles2)
4563 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4564 Q_D(QOpenGLTexture);
4565 d->create();
4566 Q_ASSERT(d->texFuncs);
4567 Q_ASSERT(d->textureId);
4568 int values[4];
4569 values[0] = int(r);
4570 values[1] = int(g);
4571 values[2] = int(b);
4572 values[3] = int(a);
4573 d->borderColor.clear();
4574 for (int i = 0; i < 4; ++i)
4575 d->borderColor.append(QVariant(values[i]));
4576 d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
4577 return;
4578 }
4579#else
4580 Q_UNUSED(r);
4581 Q_UNUSED(g);
4582 Q_UNUSED(b);
4583 Q_UNUSED(a);
4584#endif
4585 qWarning("QOpenGLTexture: Border color is not supported");
4586
4587 // TODO Handle case of using glTextureParameterIuiv() based on format
4588}
4589
4590/*!
4591 Returns the borderColor of this texture.
4592
4593 \sa setBorderColor()
4594*/
4595QColor QOpenGLTexture::borderColor() const
4596{
4597 Q_D(const QOpenGLTexture);
4598 QColor c(0.0f, 0.0f, 0.0f, 0.0f);
4599 if (!d->borderColor.isEmpty()) {
4600 c.setRedF(d->borderColor.at(0).toFloat());
4601 c.setGreenF(d->borderColor.at(1).toFloat());
4602 c.setBlueF(d->borderColor.at(2).toFloat());
4603 c.setAlphaF(d->borderColor.at(3).toFloat());
4604 }
4605 return c;
4606}
4607
4608/*!
4609 Writes the texture border color into the first four elements
4610 of the array pointed to by \a border.
4611
4612 \sa setBorderColor()
4613*/
4614void QOpenGLTexture::borderColor(float *border) const
4615{
4616 Q_D(const QOpenGLTexture);
4617 Q_ASSERT(border);
4618 if (d->borderColor.isEmpty()) {
4619 for (int i = 0; i < 4; ++i)
4620 border[i] = 0.0f;
4621 } else {
4622 for (int i = 0; i < 4; ++i)
4623 border[i] = d->borderColor.at(i).toFloat();
4624 }
4625}
4626
4627/*!
4628 Writes the texture border color into the first four elements
4629 of the array pointed to by \a border.
4630
4631 \overload
4632*/
4633void QOpenGLTexture::borderColor(int *border) const
4634{
4635 Q_D(const QOpenGLTexture);
4636 Q_ASSERT(border);
4637 if (d->borderColor.isEmpty()) {
4638 for (int i = 0; i < 4; ++i)
4639 border[i] = 0;
4640 } else {
4641 for (int i = 0; i < 4; ++i)
4642 border[i] = d->borderColor.at(i).toInt();
4643 }
4644}
4645
4646/*!
4647 Writes the texture border color into the first four elements
4648 of the array pointed to by \a border.
4649
4650 \overload
4651*/
4652void QOpenGLTexture::borderColor(unsigned int *border) const
4653{
4654 Q_D(const QOpenGLTexture);
4655 Q_ASSERT(border);
4656 if (d->borderColor.isEmpty()) {
4657 for (int i = 0; i < 4; ++i)
4658 border[i] = 0;
4659 } else {
4660 for (int i = 0; i < 4; ++i)
4661 border[i] = d->borderColor.at(i).toUInt();
4662 }
4663}
4664
4665/*!
4666 Sets the minimum level of detail to \a value. This limits the selection of highest
4667 resolution mipmap (lowest mipmap level). The default value is -1000.
4668
4669 \note This function has no effect on Qt built for OpenGL ES 2.
4670 \sa minimumLevelOfDetail(), setMaximumLevelOfDetail(), setLevelOfDetailRange()
4671*/
4672void QOpenGLTexture::setMinimumLevelOfDetail(float value)
4673{
4674#if !QT_CONFIG(opengles2)
4675 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4676 Q_D(QOpenGLTexture);
4677 d->create();
4678 Q_ASSERT(d->texFuncs);
4679 Q_ASSERT(d->textureId);
4680 Q_ASSERT(value < d->maxLevelOfDetail);
4681 d->minLevelOfDetail = value;
4682 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, value);
4683 return;
4684 }
4685#else
4686 Q_UNUSED(value);
4687#endif
4688 qWarning("QOpenGLTexture: Detail level is not supported");
4689}
4690
4691/*!
4692 Returns the minimum level of detail parameter.
4693
4694 \sa setMinimumLevelOfDetail(), maximumLevelOfDetail(), levelOfDetailRange()
4695*/
4696float QOpenGLTexture::minimumLevelOfDetail() const
4697{
4698 Q_D(const QOpenGLTexture);
4699 return d->minLevelOfDetail;
4700}
4701
4702/*!
4703 Sets the maximum level of detail to \a value. This limits the selection of lowest
4704 resolution mipmap (highest mipmap level). The default value is 1000.
4705
4706 \note This function has no effect on Qt built for OpenGL ES 2.
4707 \sa maximumLevelOfDetail(), setMinimumLevelOfDetail(), setLevelOfDetailRange()
4708*/
4709void QOpenGLTexture::setMaximumLevelOfDetail(float value)
4710{
4711#if !QT_CONFIG(opengles2)
4712 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4713 Q_D(QOpenGLTexture);
4714 d->create();
4715 Q_ASSERT(d->texFuncs);
4716 Q_ASSERT(d->textureId);
4717 Q_ASSERT(value > d->minLevelOfDetail);
4718 d->maxLevelOfDetail = value;
4719 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, value);
4720 return;
4721 }
4722#else
4723 Q_UNUSED(value);
4724#endif
4725 qWarning("QOpenGLTexture: Detail level is not supported");
4726}
4727
4728/*!
4729 Returns the maximum level of detail parameter.
4730
4731 \sa setMaximumLevelOfDetail(), minimumLevelOfDetail(), levelOfDetailRange()
4732*/
4733float QOpenGLTexture::maximumLevelOfDetail() const
4734{
4735 Q_D(const QOpenGLTexture);
4736 return d->maxLevelOfDetail;
4737}
4738
4739/*!
4740 Sets the minimum level of detail parameters to \a min and the maximum level
4741 to \a max.
4742 \note This function has no effect on Qt built for OpenGL ES 2.
4743 \sa levelOfDetailRange(), setMinimumLevelOfDetail(), setMaximumLevelOfDetail()
4744*/
4745void QOpenGLTexture::setLevelOfDetailRange(float min, float max)
4746{
4747#if !QT_CONFIG(opengles2)
4748 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4749 Q_D(QOpenGLTexture);
4750 d->create();
4751 Q_ASSERT(d->texFuncs);
4752 Q_ASSERT(d->textureId);
4753 Q_ASSERT(min < max);
4754 d->minLevelOfDetail = min;
4755 d->maxLevelOfDetail = max;
4756 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, min);
4757 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, max);
4758 return;
4759 }
4760#else
4761 Q_UNUSED(min);
4762 Q_UNUSED(max);
4763#endif
4764 qWarning("QOpenGLTexture: Detail level is not supported");
4765}
4766
4767/*!
4768 Returns the minimum and maximum level of detail parameters.
4769
4770 \sa setLevelOfDetailRange(), minimumLevelOfDetail(), maximumLevelOfDetail()
4771*/
4772std::pair<float, float> QOpenGLTexture::levelOfDetailRange() const
4773{
4774 Q_D(const QOpenGLTexture);
4775 return std::pair(d->minLevelOfDetail, d->maxLevelOfDetail);
4776}
4777
4778/*!
4779 Sets the level of detail bias to \a bias.
4780 Level of detail bias affects the point at which mipmapping levels change.
4781 Increasing values for level of detail bias makes the overall images blurrier
4782 or smoother. Decreasing values make the overall images sharper.
4783
4784 \note This function has no effect on Qt built for OpenGL ES 2.
4785 \sa levelofDetailBias()
4786*/
4787void QOpenGLTexture::setLevelofDetailBias(float bias)
4788{
4789#if !QT_CONFIG(opengles2)
4790 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4791 Q_D(QOpenGLTexture);
4792 d->create();
4793 Q_ASSERT(d->texFuncs);
4794 Q_ASSERT(d->textureId);
4795 d->levelOfDetailBias = bias;
4796 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_LOD_BIAS, bias);
4797 return;
4798 }
4799#else
4800 Q_UNUSED(bias);
4801#endif
4802 qWarning("QOpenGLTexture: Detail level is not supported");
4803}
4804
4805/*!
4806 Returns the level of detail bias parameter.
4807
4808 \sa setLevelofDetailBias()
4809*/
4810float QOpenGLTexture::levelofDetailBias() const
4811{
4812 Q_D(const QOpenGLTexture);
4813 return d->levelOfDetailBias;
4814}
4815
4816#ifndef QT_NO_DEBUG_STREAM
4817QDebug operator<<(QDebug debug, const QOpenGLTexture *t)
4818{
4819 QDebugStateSaver saver(debug);
4820 debug.nospace();
4821 debug << "QOpenGLTexture(";
4822 if (t) {
4823 const QOpenGLTexturePrivate *d = t->d_ptr.data();
4824 debug << d->target << ", bindingTarget=" << d->bindingTarget
4825 << ", size=[" << d->dimensions[0]
4826 << ", " << d->dimensions[1];
4827 if (d->target == QOpenGLTexture::Target3D)
4828 debug << ", " << d->dimensions[2];
4829 debug << "], format=" << d->format << ", formatClass=" << d->formatClass;
4830 if (t->isCreated())
4831 debug << ", textureId=" << d->textureId;
4832 if (t->isBound())
4833 debug << ", [bound]";
4834 if (t->isTextureView())
4835 debug << ", [view]";
4837 debug << ", [fixedSamplePositions]";
4838 debug << ", mipLevels=" << d->requestedMipLevels << ", layers=" << d->layers
4839 << ", faces=" << d->faces << ", samples=" << d->samples
4840 << ", depthStencilMode=" << d->depthStencilMode << ", comparisonFunction="
4841 << d->comparisonFunction << ", comparisonMode=" << d->comparisonMode
4842 << ", features=" << d->features << ", minificationFilter=" << d->minFilter
4843 << ", magnificationFilter=" << d->magFilter << ", wrapMode=" << d->wrapModes[0];
4844 } else {
4845 debug << "0x0";
4846 }
4847 debug << ')';
4848 return debug;
4849}
4850#endif // QT_NO_DEBUG_STREAM
4851
4852QT_END_NAMESPACE
4853
4854#include "moc_qopengltexture.cpp"
QOpenGLTextureHelper(QOpenGLContext *context)
void setWrapMode(QOpenGLTexture::CoordinateDirection direction, QOpenGLTexture::WrapMode mode)
void allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
void setData(int xOffset, int yOffset, int zOffset, int width, int height, int depth, int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions *const options)
void setData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions *const options)
QOpenGLFunctions * functions
bool isUsingImmutableStorage() const
void allocateMutableStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
void setWrapMode(QOpenGLTexture::WrapMode mode)
int maximumMipLevelCount() const
void release(uint unit, QOpenGLTexture::TextureUnitReset reset=QOpenGLTexture::DontResetTextureUnit)
QOpenGLTexture * createTextureView(QOpenGLTexture::Target target, QOpenGLTexture::TextureFormat viewFormat, int minimumMipmapLevel, int maximumMipmapLevel, int minimumLayer, int maximumLayer) const
bool isBound(uint unit) const
void bind(uint unit, QOpenGLTexture::TextureUnitReset reset=QOpenGLTexture::DontResetTextureUnit)
void setCompressedData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, int dataSize, const void *data, const QOpenGLPixelTransferOptions *const options)
static int mipLevelSize(int mipLevel, int baseLevelSize)
QOpenGLTextureHelper * texFuncs
QOpenGLContext * context
Combined button and popup list for selecting options.
#define GL_TEXTURE_COMPARE_FUNC
Definition qopenglext.h:338
#define GL_TEXTURE0
Definition qopenglext.h:129
#define GL_TEXTURE_WRAP_R
Definition qopenglext.h:87
#define GL_TEXTURE_BASE_LEVEL
Definition qopenglext.h:103
#define GL_TEXTURE_MAX_LEVEL
Definition qopenglext.h:104
#define GL_ACTIVE_TEXTURE
Definition qopenglext.h:161
#define GL_TEXTURE_COMPARE_MODE
Definition qopenglext.h:337
static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpenGLTexture::TextureFormat internalFormat)
static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTexture::TextureFormat internalFormat)
static bool isNpot(int width, int height=1, int depth=1)
static bool isCompressedFormat(QOpenGLTexture::TextureFormat internalFormat)
static bool isTextureTargetMultisample(QOpenGLTexture::Target target)
static bool isSizedTextureFormat(QOpenGLTexture::TextureFormat internalFormat)