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
2077/*!
2078 \enum QOpenGLTexture::Filter
2079 This enum defines the filtering parameters for a QOpenGLTexture object.
2080 \value Nearest Equivalent to GL_NEAREST
2081 \value Linear Equivalent to GL_LINEAR
2082 \value NearestMipMapNearest Equivalent to GL_NEAREST_MIPMAP_NEAREST
2083 \value NearestMipMapLinear Equivalent to GL_NEAREST_MIPMAP_LINEAR
2084 \value LinearMipMapNearest Equivalent to GL_LINEAR_MIPMAP_NEAREST
2085 \value LinearMipMapLinear Equivalent to GL_LINEAR_MIPMAP_LINEAR
2086*/
2087
2088/*!
2089 \enum QOpenGLTexture::Target
2090 This enum defines the texture target of a QOpenGLTexture object.
2091 For more information on creating array textures, see \l{Array Texture}.
2092
2093 \value Target1D A 1-dimensional texture.
2094 Equivalent to GL_TEXTURE_1D.
2095 \value Target1DArray An array of 1-dimensional textures.
2096 Equivalent to GL_TEXTURE_1D_ARRAY
2097 \value Target2D A 2-dimensional texture.
2098 Equivalent to GL_TEXTURE_2D
2099 \value Target2DArray An array of 2-dimensional textures.
2100 Equivalent to GL_TEXTURE_2D_ARRAY
2101 \value Target3D A 3-dimensional texture.
2102 Equivalent to GL_TEXTURE_3D
2103 \value TargetCubeMap A cubemap texture.
2104 Equivalent to GL_TEXTURE_CUBE_MAP
2105 \value TargetCubeMapArray An array of cubemap textures.
2106 Equivalent to GL_TEXTURE_CUBE_MAP_ARRAY
2107 \value Target2DMultisample A 2-dimensional texture with multisample support.
2108 Equivalent to GL_TEXTURE_2D_MULTISAMPLE
2109 \value Target2DMultisampleArray An array of 2-dimensional textures with multisample support.
2110 Equivalent to GL_TEXTURE_2D_MULTISAMPLE_ARRAY
2111 \value TargetRectangle A rectangular 2-dimensional texture.
2112 Equivalent to GL_TEXTURE_RECTANGLE
2113 \value TargetBuffer A texture with data from an OpenGL buffer object.
2114 Equivalent to GL_TEXTURE_BUFFER
2115*/
2116
2117/*!
2118 \enum QOpenGLTexture::BindingTarget
2119 This enum defines the possible binding targets of texture units.
2120
2121 \value BindingTarget1D Equivalent to GL_TEXTURE_BINDING_1D
2122 \value BindingTarget1DArray Equivalent to GL_TEXTURE_BINDING_1D_ARRAY
2123 \value BindingTarget2D Equivalent to GL_TEXTURE_BINDING_2D
2124 \value BindingTarget2DArray Equivalent to GL_TEXTURE_BINDING_2D_ARRAY
2125 \value BindingTarget3D Equivalent to GL_TEXTURE_BINDING_3D
2126 \value BindingTargetCubeMap Equivalent to GL_TEXTURE_BINDING_CUBE_MAP
2127 \value BindingTargetCubeMapArray Equivalent to GL_TEXTURE_BINDING_CUBE_MAP_ARRAY
2128 \value BindingTarget2DMultisample Equivalent to GL_TEXTURE_BINDING_2D_MULTISAMPLE
2129 \value BindingTarget2DMultisampleArray Equivalent to GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY
2130 \value BindingTargetRectangle Equivalent to GL_TEXTURE_BINDING_RECTANGLE
2131 \value BindingTargetBuffer Equivalent to GL_TEXTURE_BINDING_BUFFER
2132*/
2133
2134/*!
2135 \enum QOpenGLTexture::MipMapGeneration
2136 This enum defines the options to control mipmap generation.
2137
2138 \value GenerateMipMaps Mipmaps should be generated
2139 \value DontGenerateMipMaps Mipmaps should not be generated
2140*/
2141
2142/*!
2143 \enum QOpenGLTexture::TextureUnitReset
2144 This enum defines options ot control texture unit activation.
2145
2146 \value ResetTextureUnit The previous active texture unit will be reset
2147 \value DontResetTextureUnit The previous active texture unit will not be rest
2148*/
2149
2150/*!
2151 \enum QOpenGLTexture::TextureFormat
2152 This enum defines the possible texture formats. Depending upon your OpenGL
2153 implementation only a subset of these may be supported.
2154
2155 \value NoFormat Equivalent to GL_NONE
2156
2157 \value R8_UNorm Equivalent to GL_R8
2158 \value RG8_UNorm Equivalent to GL_RG8
2159 \value RGB8_UNorm Equivalent to GL_RGB8
2160 \value RGBA8_UNorm Equivalent to GL_RGBA8
2161
2162 \value R16_UNorm Equivalent to GL_R16
2163 \value RG16_UNorm Equivalent to GL_RG16
2164 \value RGB16_UNorm Equivalent to GL_RGB16
2165 \value RGBA16_UNorm Equivalent to GL_RGBA16
2166
2167 \value R8_SNorm Equivalent to GL_R8_SNORM
2168 \value RG8_SNorm Equivalent to GL_RG8_SNORM
2169 \value RGB8_SNorm Equivalent to GL_RGB8_SNORM
2170 \value RGBA8_SNorm Equivalent to GL_RGBA8_SNORM
2171
2172 \value R16_SNorm Equivalent to GL_R16_SNORM
2173 \value RG16_SNorm Equivalent to GL_RG16_SNORM
2174 \value RGB16_SNorm Equivalent to GL_RGB16_SNORM
2175 \value RGBA16_SNorm Equivalent to GL_RGBA16_SNORM
2176
2177 \value R8U Equivalent to GL_R8UI
2178 \value RG8U Equivalent to GL_RG8UI
2179 \value RGB8U Equivalent to GL_RGB8UI
2180 \value RGBA8U Equivalent to GL_RGBA8UI
2181
2182 \value R16U Equivalent to GL_R16UI
2183 \value RG16U Equivalent to GL_RG16UI
2184 \value RGB16U Equivalent to GL_RGB16UI
2185 \value RGBA16U Equivalent to GL_RGBA16UI
2186
2187 \value R32U Equivalent to GL_R32UI
2188 \value RG32U Equivalent to GL_RG32UI
2189 \value RGB32U Equivalent to GL_RGB32UI
2190 \value RGBA32U Equivalent to GL_RGBA32UI
2191
2192 \value R8I Equivalent to GL_R8I
2193 \value RG8I Equivalent to GL_RG8I
2194 \value RGB8I Equivalent to GL_RGB8I
2195 \value RGBA8I Equivalent to GL_RGBA8I
2196
2197 \value R16I Equivalent to GL_R16I
2198 \value RG16I Equivalent to GL_RG16I
2199 \value RGB16I Equivalent to GL_RGB16I
2200 \value RGBA16I Equivalent to GL_RGBA16I
2201
2202 \value R32I Equivalent to GL_R32I
2203 \value RG32I Equivalent to GL_RG32I
2204 \value RGB32I Equivalent to GL_RGB32I
2205 \value RGBA32I Equivalent to GL_RGBA32I
2206
2207 \value R16F Equivalent to GL_R16F
2208 \value RG16F Equivalent to GL_RG16F
2209 \value RGB16F Equivalent to GL_RGB16F
2210 \value RGBA16F Equivalent to GL_RGBA16F
2211
2212 \value R32F Equivalent to GL_R32F
2213 \value RG32F Equivalent to GL_RG32F
2214 \value RGB32F Equivalent to GL_RGB32F
2215 \value RGBA32F Equivalent to GL_RGBA32F
2216
2217 \value RGB9E5 Equivalent to GL_RGB9_E5
2218 \value RG11B10F Equivalent to GL_R11F_G11F_B10F
2219 \value RG3B2 Equivalent to GL_R3_G3_B2
2220 \value R5G6B5 Equivalent to GL_RGB565
2221 \value RGB5A1 Equivalent to GL_RGB5_A1
2222 \value RGBA4 Equivalent to GL_RGBA4
2223 \value RGB10A2 Equivalent to GL_RGB10_A2UI
2224
2225 \value D16 Equivalent to GL_DEPTH_COMPONENT16
2226 \value D24 Equivalent to GL_DEPTH_COMPONENT24
2227 \value D24S8 Equivalent to GL_DEPTH24_STENCIL8
2228 \value D32 Equivalent to GL_DEPTH_COMPONENT32
2229 \value D32F Equivalent to GL_DEPTH_COMPONENT32F
2230 \value D32FS8X24 Equivalent to GL_DEPTH32F_STENCIL8
2231 \value S8 Equivalent to GL_STENCIL_INDEX8. Introduced in Qt 5.4
2232
2233 \value RGB_DXT1 Equivalent to GL_COMPRESSED_RGB_S3TC_DXT1_EXT
2234 \value RGBA_DXT1 Equivalent to GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
2235 \value RGBA_DXT3 Equivalent to GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
2236 \value RGBA_DXT5 Equivalent to GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
2237 \value R_ATI1N_UNorm Equivalent to GL_COMPRESSED_RED_RGTC1
2238 \value R_ATI1N_SNorm Equivalent to GL_COMPRESSED_SIGNED_RED_RGTC1
2239 \value RG_ATI2N_UNorm Equivalent to GL_COMPRESSED_RG_RGTC2
2240 \value RG_ATI2N_SNorm Equivalent to GL_COMPRESSED_SIGNED_RG_RGTC2
2241 \value RGB_BP_UNSIGNED_FLOAT Equivalent to GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB
2242 \value RGB_BP_SIGNED_FLOAT Equivalent to GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB
2243 \value RGB_BP_UNorm Equivalent to GL_COMPRESSED_RGBA_BPTC_UNORM_ARB
2244 \value R11_EAC_UNorm Equivalent to GL_COMPRESSED_R11_EAC
2245 \value R11_EAC_SNorm Equivalent to GL_COMPRESSED_SIGNED_R11_EAC
2246 \value RG11_EAC_UNorm Equivalent to GL_COMPRESSED_RG11_EAC
2247 \value RG11_EAC_SNorm Equivalent to GL_COMPRESSED_SIGNED_RG11_EAC
2248 \value RGB8_ETC2 Equivalent to GL_COMPRESSED_RGB8_ETC2
2249 \value SRGB8_ETC2 Equivalent to GL_COMPRESSED_SRGB8_ETC2
2250 \value RGB8_PunchThrough_Alpha1_ETC2 Equivalent to GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
2251 \value SRGB8_PunchThrough_Alpha1_ETC2 Equivalent to GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
2252 \value RGBA8_ETC2_EAC Equivalent to GL_COMPRESSED_RGBA8_ETC2_EAC
2253 \value SRGB8_Alpha8_ETC2_EAC Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
2254 \value RGB8_ETC1 Equivalent to GL_ETC1_RGB8_OES
2255 \value RGBA_ASTC_4x4 Equivalent to GL_COMPRESSED_RGBA_ASTC_4x4_KHR
2256 \value RGBA_ASTC_5x4 Equivalent to GL_COMPRESSED_RGBA_ASTC_5x4_KHR
2257 \value RGBA_ASTC_5x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_5x5_KHR
2258 \value RGBA_ASTC_6x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_6x5_KHR
2259 \value RGBA_ASTC_6x6 Equivalent to GL_COMPRESSED_RGBA_ASTC_6x6_KHR
2260 \value RGBA_ASTC_8x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_8x5_KHR
2261 \value RGBA_ASTC_8x6 Equivalent to GL_COMPRESSED_RGBA_ASTC_8x6_KHR
2262 \value RGBA_ASTC_8x8 Equivalent to GL_COMPRESSED_RGBA_ASTC_8x8_KHR
2263 \value RGBA_ASTC_10x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x5_KHR
2264 \value RGBA_ASTC_10x6 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x6_KHR
2265 \value RGBA_ASTC_10x8 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x8_KHR
2266 \value RGBA_ASTC_10x10 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x10_KHR
2267 \value RGBA_ASTC_12x10 Equivalent to GL_COMPRESSED_RGBA_ASTC_12x10_KHR
2268 \value RGBA_ASTC_12x12 Equivalent to GL_COMPRESSED_RGBA_ASTC_12x12_KHR
2269 \value SRGB8_Alpha8_ASTC_4x4 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
2270 \value SRGB8_Alpha8_ASTC_5x4 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR
2271 \value SRGB8_Alpha8_ASTC_5x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR
2272 \value SRGB8_Alpha8_ASTC_6x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR
2273 \value SRGB8_Alpha8_ASTC_6x6 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR
2274 \value SRGB8_Alpha8_ASTC_8x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR
2275 \value SRGB8_Alpha8_ASTC_8x6 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR
2276 \value SRGB8_Alpha8_ASTC_8x8 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR
2277 \value SRGB8_Alpha8_ASTC_10x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR
2278 \value SRGB8_Alpha8_ASTC_10x6 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR
2279 \value SRGB8_Alpha8_ASTC_10x8 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR
2280 \value SRGB8_Alpha8_ASTC_10x10 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR
2281 \value SRGB8_Alpha8_ASTC_12x10 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR
2282 \value SRGB8_Alpha8_ASTC_12x12 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR
2283
2284 \value SRGB8 Equivalent to GL_SRGB8
2285 \value SRGB8_Alpha8 Equivalent to GL_SRGB8_ALPHA8
2286 \value SRGB_DXT1 Equivalent to GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
2287 \value SRGB_Alpha_DXT1 Equivalent to GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
2288 \value SRGB_Alpha_DXT3 Equivalent to GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
2289 \value SRGB_Alpha_DXT5 Equivalent to GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
2290 \value SRGB_BP_UNorm Equivalent to GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB
2291
2292 \value DepthFormat Equivalent to GL_DEPTH_COMPONENT (only OpenGL ES 3 or ES 2 with OES_depth_texture)
2293 \value AlphaFormat Equivalent to GL_ALPHA (OpenGL ES 2 only)
2294 \value RGBFormat Equivalent to GL_RGB (OpenGL ES 2 only)
2295 \value RGBAFormat Equivalent to GL_RGBA (OpenGL ES 2 only)
2296 \value LuminanceFormat Equivalent to GL_LUMINANCE (OpenGL ES 2 only)
2297 \value LuminanceAlphaFormat Equivalent to GL_LUMINANCE_ALPHA (OpenGL ES 2 only)
2298*/
2299
2300/*!
2301 \enum QOpenGLTexture::CubeMapFace
2302 This enum defines the possible CubeMap faces.
2303
2304 \value CubeMapPositiveX Equivalent to GL_TEXTURE_CUBE_MAP_POSITIVE_X
2305 \value CubeMapNegativeX Equivalent to GL_TEXTURE_CUBE_MAP_NEGATIVE_X
2306 \value CubeMapPositiveY Equivalent to GL_TEXTURE_CUBE_MAP_POSITIVE_Y
2307 \value CubeMapNegativeY Equivalent to GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
2308 \value CubeMapPositiveZ Equivalent to GL_TEXTURE_CUBE_MAP_POSITIVE_Z
2309 \value CubeMapNegativeZ Equivalent to GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
2310*/
2311
2312/*!
2313 \enum QOpenGLTexture::PixelFormat
2314 This enum defines the possible client-side pixel formats for a pixel
2315 transfer operation.
2316
2317 \value NoSourceFormat Equivalent to GL_NONE
2318 \value Red Equivalent to GL_RED
2319 \value RG Equivalent to GL_RG
2320 \value RGB Equivalent to GL_RGB
2321 \value BGR Equivalent to GL_BGR
2322 \value RGBA Equivalent to GL_RGBA
2323 \value BGRA Equivalent to GL_BGRA
2324 \value Red_Integer Equivalent to GL_RED_INTEGER
2325 \value RG_Integer Equivalent to GL_RG_INTEGER
2326 \value RGB_Integer Equivalent to GL_RGB_INTEGER
2327 \value BGR_Integer Equivalent to GL_BGR_INTEGER
2328 \value RGBA_Integer Equivalent to GL_RGBA_INTEGER
2329 \value BGRA_Integer Equivalent to GL_BGRA_INTEGER
2330 \value Stencil Equivalent to GL_STENCIL_INDEX. Introduced in Qt 5.4
2331 \value Depth Equivalent to GL_DEPTH_COMPONENT
2332 \value DepthStencil Equivalent to GL_DEPTH_STENCIL
2333 \value Alpha Equivalent to GL_ALPHA (OpenGL ES 2 only)
2334 \value Luminance Equivalent to GL_LUMINANCE (OpenGL ES 2 only)
2335 \value LuminanceAlpha Equivalent to GL_LUMINANCE_ALPHA (OpenGL ES 2 only)
2336
2337*/
2338
2339/*!
2340 \enum QOpenGLTexture::PixelType
2341 This enum defines the possible pixel data types for a pixel transfer operation
2342
2343 \value NoPixelType Equivalent to GL_NONE
2344 \value Int8 Equivalent to GL_BYTE
2345 \value UInt8 Equivalent to GL_UNSIGNED_BYTE
2346 \value Int16 Equivalent to GL_SHORT
2347 \value UInt16 Equivalent to GL_UNSIGNED_SHORT
2348 \value Int32 Equivalent to GL_INT
2349 \value UInt32 Equivalent to GL_UNSIGNED_INT
2350 \value Float16 Equivalent to GL_HALF_FLOAT
2351 \value Float16OES Equivalent to GL_HALF_FLOAT_OES
2352 \value Float32 Equivalent to GL_FLOAT
2353 \value UInt32_RGB9_E5 Equivalent to GL_UNSIGNED_INT_5_9_9_9_REV
2354 \value UInt32_RG11B10F Equivalent to GL_UNSIGNED_INT_10F_11F_11F_REV
2355 \value UInt8_RG3B2 Equivalent to GL_UNSIGNED_BYTE_3_3_2
2356 \value UInt8_RG3B2_Rev Equivalent to GL_UNSIGNED_BYTE_2_3_3_REV
2357 \value UInt16_RGB5A1 Equivalent to GL_UNSIGNED_SHORT_5_5_5_1
2358 \value UInt16_RGB5A1_Rev Equivalent to GL_UNSIGNED_SHORT_1_5_5_5_REV
2359 \value UInt16_R5G6B5 Equivalent to GL_UNSIGNED_SHORT_5_6_5
2360 \value UInt16_R5G6B5_Rev Equivalent to GL_UNSIGNED_SHORT_5_6_5_REV
2361 \value UInt16_RGBA4 Equivalent to GL_UNSIGNED_SHORT_4_4_4_4
2362 \value UInt16_RGBA4_Rev Equivalent to GL_UNSIGNED_SHORT_4_4_4_4_REV
2363 \value UInt32_RGBA8 Equivalent to GL_UNSIGNED_INT_8_8_8_8
2364 \value UInt32_RGBA8_Rev Equivalent to GL_UNSIGNED_INT_8_8_8_8_REV
2365 \value UInt32_RGB10A2 Equivalent to GL_UNSIGNED_INT_10_10_10_2
2366 \value UInt32_RGB10A2_Rev Equivalent to GL_UNSIGNED_INT_2_10_10_10_REV
2367 \value UInt32_D24S8 Equivalent to GL_UNSIGNED_INT_24_8. Introduced in Qt 5.4
2368 \value Float32_D32_UInt32_S8_X24 Equivalent to GL_FLOAT_32_UNSIGNED_INT_24_8_REV. Introduced in Qt 5.4
2369*/
2370
2371/*!
2372 \enum QOpenGLTexture::Feature
2373 This enum defines the OpenGL texture-related features that can be tested for.
2374
2375 \value ImmutableStorage Support for immutable texture storage
2376 \value ImmutableMultisampleStorage Support for immutable texture storage with
2377 multisample targets
2378 \value TextureRectangle Support for the GL_TEXTURE_RECTANGLE target
2379 \value TextureArrays Support for texture targets with array layers
2380 \value Texture3D Support for the 3 dimensional texture target
2381 \value TextureMultisample Support for texture targets that have multisample capabilities
2382 \value TextureBuffer Support for textures that use OpenGL buffer objects
2383 as their data source
2384 \value TextureCubeMapArrays Support for cubemap array texture target
2385 \value Swizzle Support for texture component swizzle masks
2386 \value StencilTexturing Support for stencil texturing (i.e. looking up depth or stencil
2387 components of a combined depth/stencil format texture in GLSL shaders).
2388 \value AnisotropicFiltering Support for anisotropic texture filtering
2389 \value NPOTTextures Basic support for non-power-of-two textures
2390 \value NPOTTextureRepeat Full support for non-power-of-two textures including texture
2391 repeat modes
2392 \value Texture1D Support for the 1 dimensional texture target
2393 \value TextureComparisonOperators Support for texture comparison operators
2394 \value TextureMipMapLevel Support for setting the base and maximum mipmap levels
2395*/
2396
2397/*!
2398 \enum QOpenGLTexture::SwizzleComponent
2399 This enum defines the texture color components that can be assigned a swizzle mask.
2400
2401 \value SwizzleRed The red component. Equivalent to GL_TEXTURE_SWIZZLE_R
2402 \value SwizzleGreen The green component. Equivalent to GL_TEXTURE_SWIZZLE_G
2403 \value SwizzleBlue The blue component. Equivalent to GL_TEXTURE_SWIZZLE_B
2404 \value SwizzleAlpha The alpha component. Equivalent to GL_TEXTURE_SWIZZLE_A
2405*/
2406
2407/*!
2408 \enum QOpenGLTexture::SwizzleValue
2409 This enum defines the possible mask values for texture swizzling.
2410
2411 \value RedValue Maps the component to the red channel. Equivalent to GL_RED
2412 \value GreenValue Maps the component to the green channel. Equivalent to GL_GREEN
2413 \value BlueValue Maps the component to the blue channel. Equivalent to GL_BLUE
2414 \value AlphaValue Maps the component to the alpha channel. Equivalent to GL_ALPHA
2415 \value ZeroValue Maps the component to a fixed value of 0. Equivalent to GL_ZERO
2416 \value OneValue Maps the component to a fixed value of 1. Equivalent to GL_ONE
2417*/
2418
2419/*!
2420 \enum QOpenGLTexture::WrapMode
2421 This enum defines the possible texture coordinate wrapping modes.
2422
2423 \value Repeat Texture coordinate is repeated. Equivalent to GL_REPEAT
2424 \value MirroredRepeat Texture coordinate is reflected about 0 and 1. Equivalent to GL_MIRRORED_REPEAT
2425 \value ClampToEdge Clamps the texture coordinates to [0,1]. Equivalent to GL_CLAMP_TO_EDGE
2426 \value ClampToBorder As for ClampToEdge but also blends samples at 0 and 1 with a
2427 fixed border color. Equivalent to GL_CLAMP_TO_BORDER
2428*/
2429
2430/*!
2431 \enum QOpenGLTexture::CoordinateDirection
2432 This enum defines the possible texture coordinate directions
2433
2434 \value DirectionS The horizontal direction. Equivalent to GL_TEXTURE_WRAP_S
2435 \value DirectionT The vertical direction. Equivalent to GL_TEXTURE_WRAP_T
2436 \value DirectionR The depth direction. Equivalent to GL_TEXTURE_WRAP_R
2437*/
2438
2439/*!
2440 Creates a QOpenGLTexture object that can later be bound to \a target.
2441
2442 This does not create the underlying OpenGL texture object. Therefore,
2443 construction using this constructor does not require a valid current
2444 OpenGL context.
2445*/
2446QOpenGLTexture::QOpenGLTexture(Target target)
2447 : d_ptr(new QOpenGLTexturePrivate(target, this))
2448{
2449}
2450
2451/*!
2452 Creates a QOpenGLTexture object that can later be bound to the 2D texture
2453 target and contains the pixel data contained in \a image. If you wish
2454 to have a chain of mipmaps generated then set \a genMipMaps to \c true (this
2455 is the default).
2456
2457 This does create the underlying OpenGL texture object. Therefore,
2458 construction using this constructor does require a valid current
2459 OpenGL context.
2460
2461 \note \a image is automatically converted to QImage::Format_RGBA8888 which
2462 may have performance implications for large images with a different format.
2463*/
2464QOpenGLTexture::QOpenGLTexture(const QImage& image, MipMapGeneration genMipMaps)
2465 : QOpenGLTexture(QOpenGLTexture::Target2D)
2466{
2467 setData(image, genMipMaps);
2468}
2469
2470QOpenGLTexture::~QOpenGLTexture()
2471{
2472}
2473
2474/*!
2475 Returns the binding target of this texture.
2476
2477 \since 5.4
2478*/
2479QOpenGLTexture::Target QOpenGLTexture::target() const
2480{
2481 Q_D(const QOpenGLTexture);
2482 return d->target;
2483}
2484
2485/*!
2486 Creates the underlying OpenGL texture object. This requires a current valid
2487 OpenGL context. If the texture object already exists, this function does
2488 nothing.
2489
2490 Once the texture object is created you can obtain the object
2491 name from the textureId() function. This may be useful if you wish to make
2492 some raw OpenGL calls related to this texture.
2493
2494 Normally it should not be necessary to call this function directly as all
2495 functions that set properties of the texture object implicitly call create()
2496 on your behalf.
2497
2498 Returns \c true if the creation succeeded, otherwise returns \c false.
2499
2500 \sa destroy(), isCreated(), textureId()
2501*/
2502bool QOpenGLTexture::create()
2503{
2504 Q_D(QOpenGLTexture);
2505 return d->create();
2506}
2507
2508/*!
2509 Destroys the underlying OpenGL texture object. This requires a current valid
2510 OpenGL context.
2511
2512 \sa create(), isCreated(), textureId()
2513*/
2514void QOpenGLTexture::destroy()
2515{
2516 Q_D(QOpenGLTexture);
2517 return d->destroy();
2518}
2519
2520/*!
2521 Returns \c true if the underlying OpenGL texture object has been created.
2522
2523 \sa create(), destroy(), textureId()
2524*/
2525bool QOpenGLTexture::isCreated() const
2526{
2527 Q_D(const QOpenGLTexture);
2528 return d->textureId != 0;
2529}
2530
2531/*!
2532 Returns the name of the underlying OpenGL texture object or 0 if it has
2533 not yet been created.
2534
2535 \sa create(), destroy(), isCreated()
2536*/
2537GLuint QOpenGLTexture::textureId() const
2538{
2539 Q_D(const QOpenGLTexture);
2540 return d->textureId;
2541}
2542
2543/*!
2544 Binds this texture to the currently active texture unit ready for
2545 rendering. Note that you do not need to bind QOpenGLTexture objects
2546 in order to modify them as the implementation makes use of the
2547 EXT_direct_state_access extension where available and simulates it
2548 where it is not.
2549
2550 \sa release()
2551*/
2552void QOpenGLTexture::bind()
2553{
2554 Q_D(QOpenGLTexture);
2555 Q_ASSERT(d->textureId);
2556 d->bind();
2557}
2558
2559/*!
2560 Binds this texture to texture unit \a unit ready for
2561 rendering. Note that you do not need to bind QOpenGLTexture objects
2562 in order to modify them as the implementation makes use of the
2563 EXT_direct_state_access extension where available and simulates it
2564 where it is not.
2565
2566 If parameter \a reset is \c true then this function will restore
2567 the active unit to the texture unit that was active upon entry.
2568
2569 \sa release()
2570*/
2571void QOpenGLTexture::bind(uint unit, TextureUnitReset reset)
2572{
2573 Q_D(QOpenGLTexture);
2574 Q_ASSERT(d->textureId);
2575 d->bind(unit, reset);
2576}
2577
2578/*!
2579 Unbinds this texture from the currently active texture unit.
2580
2581 \sa bind()
2582*/
2583void QOpenGLTexture::release()
2584{
2585 Q_D(QOpenGLTexture);
2586 d->release();
2587}
2588
2589/*!
2590 Unbinds this texture from texture unit \a unit.
2591
2592 If parameter \a reset is \c true then this function
2593 will restore the active unit to the texture unit that was active
2594 upon entry.
2595*/
2596void QOpenGLTexture::release(uint unit, TextureUnitReset reset)
2597{
2598 Q_D(QOpenGLTexture);
2599 d->release(unit, reset);
2600}
2601
2602/*!
2603 Returns \c true if this texture is bound to the corresponding target
2604 of the currently active texture unit.
2605
2606 \sa bind(), release()
2607*/
2608bool QOpenGLTexture::isBound() const
2609{
2610 Q_D(const QOpenGLTexture);
2611 Q_ASSERT(d->textureId);
2612 return d->isBound();
2613}
2614
2615/*!
2616 Returns \c true if this texture is bound to the corresponding target
2617 of texture unit \a unit.
2618
2619 \sa bind(), release()
2620*/
2621bool QOpenGLTexture::isBound(uint unit)
2622{
2623 Q_D(const QOpenGLTexture);
2624 Q_ASSERT(d->textureId);
2625 return d->isBound(unit);
2626}
2627
2628/*!
2629 Returns the textureId of the texture that is bound to the \a target
2630 of the currently active texture unit.
2631*/
2632GLuint QOpenGLTexture::boundTextureId(BindingTarget target)
2633{
2634 QOpenGLContext *ctx = QOpenGLContext::currentContext();
2635 if (!ctx) {
2636 qWarning("QOpenGLTexture::boundTextureId() requires a valid current context");
2637 return 0;
2638 }
2639
2640 GLint textureId = 0;
2641 ctx->functions()->glGetIntegerv(target, &textureId);
2642 return static_cast<GLuint>(textureId);
2643}
2644
2645/*!
2646 Returns the textureId of the texture that is bound to the \a target
2647 of the texture unit \a unit.
2648*/
2649GLuint QOpenGLTexture::boundTextureId(uint unit, BindingTarget target)
2650{
2651 QOpenGLContext *ctx = QOpenGLContext::currentContext();
2652 if (!ctx) {
2653 qWarning("QOpenGLTexture::boundTextureId() requires a valid current context");
2654 return 0;
2655 }
2656
2657 QOpenGLFunctions *funcs = ctx->functions();
2658 funcs->initializeOpenGLFunctions();
2659
2660 GLint oldTextureUnit = 0;
2661 funcs->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit);
2662
2663 funcs->glActiveTexture(unit);
2664 GLint textureId = 0;
2665 funcs->glGetIntegerv(target, &textureId);
2666 funcs->glActiveTexture(oldTextureUnit);
2667
2668 return static_cast<GLuint>(textureId);
2669}
2670
2671/*!
2672 Sets the format of this texture object to \a format. This function
2673 must be called before texture storage is allocated.
2674
2675 Note that all formats may not be supported. The exact set of supported
2676 formats is dependent upon your OpenGL implementation and version.
2677
2678 \sa format(), allocateStorage()
2679*/
2680void QOpenGLTexture::setFormat(TextureFormat format)
2681{
2682 Q_D(QOpenGLTexture);
2683 d->create();
2684 if (isStorageAllocated()) {
2685 qWarning("QOpenGLTexture::setFormat(): Cannot change format once storage has been allocated");
2686 return;
2687 }
2688
2689 d->format = format;
2690
2691 switch (format) {
2692 case NoFormat:
2693 d->formatClass = NoFormatClass;
2694 break;
2695
2696 case RGBA32F:
2697 case RGBA32U:
2698 case RGBA32I:
2699 d->formatClass = FormatClass_128Bit;
2700 break;
2701
2702 case RGB32F:
2703 case RGB32U:
2704 case RGB32I:
2705 d->formatClass = FormatClass_96Bit;
2706 break;
2707
2708 case RGBA16F:
2709 case RG32F:
2710 case RGBA16U:
2711 case RG32U:
2712 case RGBA16I:
2713 case RG32I:
2714 case RGBA16_UNorm:
2715 case RGBA16_SNorm:
2716 d->formatClass = FormatClass_64Bit;
2717 break;
2718
2719 case RGB16_UNorm:
2720 case RGB16_SNorm:
2721 case RGB16F:
2722 case RGB16U:
2723 case RGB16I:
2724 d->formatClass = FormatClass_48Bit;
2725 break;
2726
2727 case RG16F:
2728 case RG11B10F:
2729 case R32F:
2730 case RGB10A2:
2731 case RGBA8U:
2732 case RG16U:
2733 case R32U:
2734 case RGBA8I:
2735 case RG16I:
2736 case R32I:
2737 case RGBA8_UNorm:
2738 case RG16_UNorm:
2739 case RGBA8_SNorm:
2740 case RG16_SNorm:
2741 case SRGB8_Alpha8:
2742 case RGB9E5:
2743 d->formatClass = FormatClass_32Bit;
2744 break;
2745
2746 case RGB8_UNorm:
2747 case RGB8_SNorm:
2748 case SRGB8:
2749 case RGB8U:
2750 case RGB8I:
2751 d->formatClass = FormatClass_24Bit;
2752 break;
2753
2754 case R16F:
2755 case RG8U:
2756 case R16U:
2757 case RG8I:
2758 case R16I:
2759 case RG8_UNorm:
2760 case R16_UNorm:
2761 case RG8_SNorm:
2762 case R16_SNorm:
2763 d->formatClass = FormatClass_16Bit;
2764 break;
2765
2766 case R8U:
2767 case R8I:
2768 case R8_UNorm:
2769 case R8_SNorm:
2770 d->formatClass = FormatClass_8Bit;
2771 break;
2772
2773 case R_ATI1N_UNorm:
2774 case R_ATI1N_SNorm:
2775 d->formatClass = FormatClass_RGTC1_R;
2776 break;
2777
2778 case RG_ATI2N_UNorm:
2779 case RG_ATI2N_SNorm:
2780 d->formatClass = FormatClass_RGTC2_RG;
2781 break;
2782
2783 case RGB_BP_UNorm:
2784 case SRGB_BP_UNorm:
2785 d->formatClass = FormatClass_BPTC_Unorm;
2786 break;
2787
2788 case RGB_BP_UNSIGNED_FLOAT:
2789 case RGB_BP_SIGNED_FLOAT:
2790 d->formatClass = FormatClass_BPTC_Float;
2791 break;
2792
2793 case RGB_DXT1:
2794 case SRGB_DXT1:
2795 d->formatClass = FormatClass_S3TC_DXT1_RGB;
2796 break;
2797
2798 case RGBA_DXT1:
2799 case SRGB_Alpha_DXT1:
2800 d->formatClass = FormatClass_S3TC_DXT1_RGBA;
2801 break;
2802
2803 case RGBA_DXT3:
2804 case SRGB_Alpha_DXT3:
2805 d->formatClass = FormatClass_S3TC_DXT3_RGBA;
2806 break;
2807
2808 case RGBA_DXT5:
2809 case SRGB_Alpha_DXT5:
2810 d->formatClass = FormatClass_S3TC_DXT5_RGBA;
2811 break;
2812
2813 case QOpenGLTexture::R11_EAC_UNorm:
2814 case QOpenGLTexture::R11_EAC_SNorm:
2815 case QOpenGLTexture::RG11_EAC_UNorm:
2816 case QOpenGLTexture::RG11_EAC_SNorm:
2817 case QOpenGLTexture::RGB8_ETC2:
2818 case QOpenGLTexture::SRGB8_ETC2:
2819 case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
2820 case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
2821 case QOpenGLTexture::RGBA8_ETC2_EAC:
2822 case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
2823 case QOpenGLTexture::RGB8_ETC1:
2824 case RG3B2:
2825 case R5G6B5:
2826 case RGB5A1:
2827 case RGBA4:
2828 case D16:
2829 case D24:
2830 case D24S8:
2831 case D32:
2832 case D32F:
2833 case D32FS8X24:
2834 case S8:
2835 case DepthFormat:
2836 case AlphaFormat:
2837 case RGBFormat:
2838 case RGBAFormat:
2839 case LuminanceFormat:
2840 case LuminanceAlphaFormat:
2841 case QOpenGLTexture::RGBA_ASTC_4x4:
2842 case QOpenGLTexture::RGBA_ASTC_5x4:
2843 case QOpenGLTexture::RGBA_ASTC_5x5:
2844 case QOpenGLTexture::RGBA_ASTC_6x5:
2845 case QOpenGLTexture::RGBA_ASTC_6x6:
2846 case QOpenGLTexture::RGBA_ASTC_8x5:
2847 case QOpenGLTexture::RGBA_ASTC_8x6:
2848 case QOpenGLTexture::RGBA_ASTC_8x8:
2849 case QOpenGLTexture::RGBA_ASTC_10x5:
2850 case QOpenGLTexture::RGBA_ASTC_10x6:
2851 case QOpenGLTexture::RGBA_ASTC_10x8:
2852 case QOpenGLTexture::RGBA_ASTC_10x10:
2853 case QOpenGLTexture::RGBA_ASTC_12x10:
2854 case QOpenGLTexture::RGBA_ASTC_12x12:
2855 case QOpenGLTexture::SRGB8_Alpha8_ASTC_4x4:
2856 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x4:
2857 case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x5:
2858 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x5:
2859 case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x6:
2860 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x5:
2861 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x6:
2862 case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x8:
2863 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x5:
2864 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x6:
2865 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x8:
2866 case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x10:
2867 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x10:
2868 case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x12:
2869 d->formatClass = FormatClass_Unique;
2870 break;
2871 }
2872}
2873
2874/*!
2875 Returns the format of this texture object.
2876
2877 \sa setFormat()
2878*/
2879QOpenGLTexture::TextureFormat QOpenGLTexture::format() const
2880{
2881 Q_D(const QOpenGLTexture);
2882 return d->format;
2883}
2884
2885static bool isNpot(int width, int height = 1, int depth = 1)
2886{
2887 return width & (width-1) || height & (height-1) || depth & (depth-1);
2888}
2889
2890/*!
2891 Sets the dimensions of this texture object to \a width,
2892 \a height, and \a depth. The default for each dimension is 1.
2893 The maximum allowable texture size is dependent upon your OpenGL
2894 implementation. Allocating storage for a texture less than the
2895 maximum size can still fail if your system is low on resources.
2896
2897 If a non-power-of-two \a width, \a height or \a depth is provided and your
2898 OpenGL implementation doesn't have support for repeating non-power-of-two
2899 textures, then the wrap mode is automatically set to ClampToEdge.
2900
2901 \sa width(), height(), depth()
2902*/
2903void QOpenGLTexture::setSize(int width, int height, int depth)
2904{
2905 Q_D(QOpenGLTexture);
2906 d->create();
2907 if (isStorageAllocated()) {
2908 qWarning("Cannot resize a texture that already has storage allocated.\n"
2909 "To do so, destroy() the texture and then create() and setSize()");
2910 return;
2911 }
2912
2913 if (isNpot(width, height, depth) && !hasFeature(Feature::NPOTTextureRepeat) && d->target != Target::TargetRectangle)
2914 d->setWrapMode(WrapMode::ClampToEdge);
2915
2916 switch (d->target) {
2917 case QOpenGLTexture::Target1D:
2918 case QOpenGLTexture::Target1DArray:
2919 case QOpenGLTexture::TargetBuffer:
2920 d->dimensions[0] = width;
2921 Q_UNUSED(height);
2922 Q_UNUSED(depth);
2923 break;
2924
2925 case QOpenGLTexture::Target2D:
2926 case QOpenGLTexture::Target2DArray:
2927 case QOpenGLTexture::TargetRectangle:
2928 case QOpenGLTexture::Target2DMultisample:
2929 case QOpenGLTexture::Target2DMultisampleArray:
2930 d->dimensions[0] = width;
2931 d->dimensions[1] = height;
2932 Q_UNUSED(depth);
2933 break;
2934
2935 case QOpenGLTexture::TargetCubeMap:
2936 case QOpenGLTexture::TargetCubeMapArray:
2937 if (width != height)
2938 qWarning("QAbstractOpenGLTexture::setSize(): Cube map textures must be square");
2939 d->dimensions[0] = d->dimensions[1] = width;
2940 Q_UNUSED(depth);
2941 break;
2942
2943 case QOpenGLTexture::Target3D:
2944 d->dimensions[0] = width;
2945 d->dimensions[1] = height;
2946 d->dimensions[2] = depth;
2947 break;
2948 }
2949}
2950
2951/*!
2952 Returns the width of a 1D, 2D or 3D texture.
2953
2954 \sa height(), depth(), setSize()
2955*/
2956int QOpenGLTexture::width() const
2957{
2958 Q_D(const QOpenGLTexture);
2959 return d->dimensions[0];
2960}
2961
2962/*!
2963 Returns the height of a 2D or 3D texture.
2964
2965 \sa width(), depth(), setSize()
2966*/
2967int QOpenGLTexture::height() const
2968{
2969 Q_D(const QOpenGLTexture);
2970 return d->dimensions[1];
2971}
2972
2973/*!
2974 Returns the depth of a 3D texture.
2975
2976 \sa width(), height(), setSize()
2977*/
2978int QOpenGLTexture::depth() const
2979{
2980 Q_D(const QOpenGLTexture);
2981 return d->dimensions[2];
2982}
2983
2984/*!
2985 For texture targets that support mipmaps, this function
2986 sets the requested number of mipmap \a levels to allocate storage
2987 for. This function should be called before storage is allocated
2988 for the texture.
2989
2990 If the texture target does not support mipmaps this function
2991 has no effect.
2992
2993 \sa mipLevels(), maximumMipLevels(), isStorageAllocated()
2994*/
2995void QOpenGLTexture::setMipLevels(int levels)
2996{
2997 Q_D(QOpenGLTexture);
2998 d->create();
2999 if (isStorageAllocated()) {
3000 qWarning("Cannot set mip levels on a texture that already has storage allocated.\n"
3001 "To do so, destroy() the texture and then create() and setMipLevels()");
3002 return;
3003 }
3004
3005 switch (d->target) {
3006 case QOpenGLTexture::Target1D:
3007 case QOpenGLTexture::Target1DArray:
3008 case QOpenGLTexture::Target2D:
3009 case QOpenGLTexture::Target2DArray:
3010 case QOpenGLTexture::TargetCubeMap:
3011 case QOpenGLTexture::TargetCubeMapArray:
3012 case QOpenGLTexture::Target3D:
3013 d->requestedMipLevels = levels;
3014 break;
3015
3016 case QOpenGLTexture::TargetBuffer:
3017 case QOpenGLTexture::TargetRectangle:
3018 case QOpenGLTexture::Target2DMultisample:
3019 case QOpenGLTexture::Target2DMultisampleArray:
3020 qWarning("QAbstractOpenGLTexture::setMipLevels(): This texture target does not support mipmaps");
3021 break;
3022 }
3023}
3024
3025/*!
3026 Returns the number of mipmap levels for this texture. If storage
3027 has not yet been allocated for this texture it returns the
3028 requested number of mipmap levels.
3029
3030 \sa setMipLevels(), maximumMipLevels(), isStorageAllocated()
3031*/
3032int QOpenGLTexture::mipLevels() const
3033{
3034 Q_D(const QOpenGLTexture);
3035 return isStorageAllocated() ? d->mipLevels : d->requestedMipLevels;
3036}
3037
3038/*!
3039 Returns the maximum number of mipmap levels that this texture
3040 can have given the current dimensions.
3041
3042 \sa setMipLevels(), mipLevels(), setSize()
3043*/
3044int QOpenGLTexture::maximumMipLevels() const
3045{
3046 Q_D(const QOpenGLTexture);
3047 return d->maximumMipLevelCount();
3048}
3049
3050/*!
3051 Sets the number of array \a layers to allocate storage for. This
3052 function should be called before storage is allocated for the texture.
3053
3054 For targets that do not support array layers this function has
3055 no effect.
3056
3057 \sa layers(), isStorageAllocated()
3058*/
3059void QOpenGLTexture::setLayers(int layers)
3060{
3061 Q_D(QOpenGLTexture);
3062 d->create();
3063 if (isStorageAllocated()) {
3064 qWarning("Cannot set layers on a texture that already has storage allocated.\n"
3065 "To do so, destroy() the texture and then create() and setLayers()");
3066 return;
3067 }
3068
3069 switch (d->target) {
3070 case QOpenGLTexture::Target1DArray:
3071 case QOpenGLTexture::Target2DArray:
3072 case QOpenGLTexture::TargetCubeMapArray:
3073 case QOpenGLTexture::Target2DMultisampleArray:
3074 d->layers = layers;
3075 break;
3076
3077 case QOpenGLTexture::Target1D:
3078 case QOpenGLTexture::Target2D:
3079 case QOpenGLTexture::Target3D:
3080 case QOpenGLTexture::TargetCubeMap:
3081 case QOpenGLTexture::TargetBuffer:
3082 case QOpenGLTexture::TargetRectangle:
3083 case QOpenGLTexture::Target2DMultisample:
3084 qWarning("Texture target does not support array layers");
3085 break;
3086 }
3087}
3088
3089/*!
3090 Returns the number of array layers for this texture. If
3091 storage has not yet been allocated for this texture then
3092 this function returns the requested number of array layers.
3093
3094 For texture targets that do not support array layers this
3095 will return 1.
3096
3097 \sa setLayers(), isStorageAllocated()
3098*/
3099int QOpenGLTexture::layers() const
3100{
3101 Q_D(const QOpenGLTexture);
3102 return d->layers;
3103}
3104
3105/*!
3106 Returns the number of faces for this texture. For cubemap
3107 and cubemap array type targets this will be 6.
3108
3109 For non-cubemap type targets this will return 1.
3110*/
3111int QOpenGLTexture::faces() const
3112{
3113 Q_D(const QOpenGLTexture);
3114 return d->faces;
3115}
3116
3117/*!
3118 Sets the number of \a samples to allocate storage for when rendering to
3119 a multisample capable texture target. This function should
3120 be called before storage is allocated for the texture.
3121
3122 For targets that do not support multisampling this function has
3123 no effect.
3124
3125 \sa samples(), isStorageAllocated()
3126*/
3127void QOpenGLTexture::setSamples(int samples)
3128{
3129 Q_D(QOpenGLTexture);
3130 d->create();
3131 if (isStorageAllocated()) {
3132 qWarning("Cannot set sample count on a texture that already has storage allocated.\n"
3133 "To do so, destroy() the texture and then create() and setSamples()");
3134 return;
3135 }
3136
3137 switch (d->target) {
3138 case QOpenGLTexture::Target2DMultisample:
3139 case QOpenGLTexture::Target2DMultisampleArray:
3140 d->samples = samples;
3141 break;
3142
3143 case QOpenGLTexture::Target1D:
3144 case QOpenGLTexture::Target2D:
3145 case QOpenGLTexture::Target3D:
3146 case QOpenGLTexture::Target1DArray:
3147 case QOpenGLTexture::Target2DArray:
3148 case QOpenGLTexture::TargetCubeMap:
3149 case QOpenGLTexture::TargetCubeMapArray:
3150 case QOpenGLTexture::TargetBuffer:
3151 case QOpenGLTexture::TargetRectangle:
3152
3153 qWarning("Texture target does not support multisampling");
3154 break;
3155 }
3156}
3157
3158/*!
3159 Returns the number of multisample sample points for this texture.
3160 If storage has not yet been allocated for this texture then
3161 this function returns the requested number of samples.
3162
3163 For texture targets that do not support multisampling this
3164 will return 0.
3165
3166 \sa setSamples(), isStorageAllocated()
3167*/
3168int QOpenGLTexture::samples() const
3169{
3170 Q_D(const QOpenGLTexture);
3171 return d->samples;
3172}
3173
3174/*!
3175 Sets whether the sample positions and number of samples used with
3176 a multisample capable texture target to \a fixed. If set to \c true
3177 the sample positions and number of samples used are the same for
3178 all texels in the image and will not depend upon the image size or
3179 internal format. This function should be called before storage is allocated
3180 for the texture.
3181
3182 For targets that do not support multisampling this function has
3183 no effect.
3184
3185 The default value is \c true.
3186
3187 \sa isFixedSamplePositions(), isStorageAllocated()
3188*/
3189void QOpenGLTexture::setFixedSamplePositions(bool fixed)
3190{
3191 Q_D(QOpenGLTexture);
3192 d->create();
3193 if (isStorageAllocated()) {
3194 qWarning("Cannot set sample positions on a texture that already has storage allocated.\n"
3195 "To do so, destroy() the texture and then create() and setFixedSamplePositions()");
3196 return;
3197 }
3198
3199 switch (d->target) {
3200 case QOpenGLTexture::Target2DMultisample:
3201 case QOpenGLTexture::Target2DMultisampleArray:
3202 d->fixedSamplePositions = fixed;
3203 break;
3204
3205 case QOpenGLTexture::Target1D:
3206 case QOpenGLTexture::Target2D:
3207 case QOpenGLTexture::Target3D:
3208 case QOpenGLTexture::Target1DArray:
3209 case QOpenGLTexture::Target2DArray:
3210 case QOpenGLTexture::TargetCubeMap:
3211 case QOpenGLTexture::TargetCubeMapArray:
3212 case QOpenGLTexture::TargetBuffer:
3213 case QOpenGLTexture::TargetRectangle:
3214
3215 qWarning("Texture target does not support multisampling");
3216 break;
3217 }
3218}
3219
3220/*!
3221 Returns whether this texture uses a fixed pattern of multisample
3222 samples. If storage has not yet been allocated for this texture then
3223 this function returns the requested fixed sample position setting.
3224
3225 For texture targets that do not support multisampling this
3226 will return \c true.
3227
3228 \sa setFixedSamplePositions(), isStorageAllocated()
3229*/
3230bool QOpenGLTexture::isFixedSamplePositions() const
3231{
3232 Q_D(const QOpenGLTexture);
3233 return d->fixedSamplePositions;
3234}
3235
3236/*!
3237 Allocates server-side storage for this texture object taking
3238 into account, the format, dimensions, mipmap levels, array
3239 layers and cubemap faces.
3240
3241 Once storage has been allocated it is no longer possible to change
3242 these properties.
3243
3244 If supported QOpenGLTexture makes use of immutable texture
3245 storage.
3246
3247 Once storage has been allocated for the texture then pixel data
3248 can be uploaded via one of the setData() overloads.
3249
3250 \note If immutable texture storage is not available,
3251 then a default pixel format and pixel type will be used to
3252 create the mutable storage. You can use the other
3253 allocateStorage() overload to specify exactly the pixel format
3254 and the pixel type to use when allocating mutable storage;
3255 this is particularly useful under certain OpenGL ES implementations
3256 (notably, OpenGL ES 2), where the pixel format and the pixel type
3257 used at allocation time must perfectly match the format
3258 and the type passed to any subsequent setData() call.
3259
3260 \sa isStorageAllocated(), setData()
3261*/
3262void QOpenGLTexture::allocateStorage()
3263{
3264 Q_D(QOpenGLTexture);
3265 if (d->create()) {
3266 const QOpenGLTexture::PixelFormat pixelFormat = pixelFormatCompatibleWithInternalFormat(d->format);
3267 const QOpenGLTexture::PixelType pixelType = pixelTypeCompatibleWithInternalFormat(d->format);
3268 d->allocateStorage(pixelFormat, pixelType);
3269 }
3270}
3271
3272/*!
3273 \since 5.5
3274
3275 Allocates server-side storage for this texture object taking
3276 into account, the format, dimensions, mipmap levels, array
3277 layers and cubemap faces.
3278
3279 Once storage has been allocated it is no longer possible to change
3280 these properties.
3281
3282 If supported QOpenGLTexture makes use of immutable texture
3283 storage. However, if immutable texture storage is not available,
3284 then the specified \a pixelFormat and \a pixelType will be used
3285 to allocate mutable storage; note that in certain OpenGL implementations
3286 (notably, OpenGL ES 2) they must perfectly match the format
3287 and the type passed to any subsequent setData() call.
3288
3289 Once storage has been allocated for the texture then pixel data
3290 can be uploaded via one of the setData() overloads.
3291
3292 \sa isStorageAllocated(), setData()
3293*/
3294void QOpenGLTexture::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
3295{
3296 Q_D(QOpenGLTexture);
3297 if (d->create())
3298 d->allocateStorage(pixelFormat, pixelType);
3299}
3300
3301/*!
3302 Returns \c true if server-side storage for this texture as been
3303 allocated.
3304
3305 The texture format, dimensions, mipmap levels and array layers
3306 cannot be altered once storage ihas been allocated.
3307
3308 \sa allocateStorage(), setSize(), setMipLevels(), setLayers(), setFormat()
3309*/
3310bool QOpenGLTexture::isStorageAllocated() const
3311{
3312 Q_D(const QOpenGLTexture);
3313 return d->storageAllocated;
3314}
3315
3316/*!
3317 Attempts to create a texture view onto this texture. A texture
3318 view is somewhat analogous to a view in SQL in that it presents
3319 a restricted or reinterpreted view of the original data. Texture
3320 views do not allocate any more server-side storage, instead relying
3321 on the storage buffer of the source texture.
3322
3323 Texture views are only available when using immutable storage. For
3324 more information on texture views see
3325 http://www.opengl.org/wiki/Texture_Storage#Texture_views.
3326
3327 The \a target argument specifies the target to use for the view.
3328 Only some targets can be used depending upon the target of the original
3329 target. For e.g. a view onto a Target1DArray texture can specify
3330 either Target1DArray or Target1D but for the latter the number of
3331 array layers specified with \a minimumLayer and \a maximumLayer must
3332 be exactly 1.
3333
3334 Simpliar constraints apply for the \a viewFormat. See the above link
3335 and the specification for more details.
3336
3337 The \a minimumMipmapLevel, \a maximumMipmapLevel, \a minimumLayer,
3338 and \a maximumLayer arguments serve to restrict the parts of the
3339 texture accessible by the texture view.
3340
3341 If creation of the texture view fails this function will return
3342 0. If the function succeeds it will return a pointer to a new
3343 QOpenGLTexture object that will return \c true from its isTextureView()
3344 function.
3345
3346 \sa isTextureView()
3347*/
3348QOpenGLTexture *QOpenGLTexture::createTextureView(Target target,
3349 TextureFormat viewFormat,
3350 int minimumMipmapLevel, int maximumMipmapLevel,
3351 int minimumLayer, int maximumLayer) const
3352{
3353 Q_D(const QOpenGLTexture);
3354 if (!isStorageAllocated()) {
3355 qWarning("Cannot set create a texture view of a texture that does not have storage allocated.");
3356 return nullptr;
3357 }
3358 Q_ASSERT(maximumMipmapLevel >= minimumMipmapLevel);
3359 Q_ASSERT(maximumLayer >= minimumLayer);
3360 return d->createTextureView(target, viewFormat,
3361 minimumMipmapLevel, maximumMipmapLevel,
3362 minimumLayer, maximumLayer);
3363}
3364
3365/*!
3366 Returns \c true if this texture object is actually a view onto another
3367 texture object.
3368
3369 \sa createTextureView()
3370*/
3371bool QOpenGLTexture::isTextureView() const
3372{
3373 Q_D(const QOpenGLTexture);
3374 Q_ASSERT(d->textureId);
3375 return d->textureView;
3376}
3377
3378/*!
3379 Uploads pixel \a data for this texture object \a mipLevel, array \a layer, and \a cubeFace.
3380 Storage must have been allocated before uploading pixel data. Some overloads of setData()
3381 will set appropriate dimensions, mipmap levels, and array layers and then allocate storage
3382 for you if they have enough information to do so. This will be noted in the function
3383 documentation.
3384
3385 The structure of the pixel data pointed to by \a data is specified by \a sourceFormat
3386 and \a sourceType. The pixel data upload can optionally be controlled by \a options.
3387
3388 If using a compressed format() then you should use setCompressedData() instead of this
3389 function.
3390
3391 \since 5.3
3392 \sa setCompressedData()
3393*/
3394void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace,
3395 PixelFormat sourceFormat, PixelType sourceType,
3396 const void *data, const QOpenGLPixelTransferOptions * const options)
3397{
3398 Q_D(QOpenGLTexture);
3399 Q_ASSERT(d->textureId);
3400 if (!isStorageAllocated()) {
3401 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3402 "To do so call allocateStorage() before this function");
3403 return;
3404 }
3405 d->setData(mipLevel, layer, 1, cubeFace, sourceFormat, sourceType, data, options);
3406}
3407
3408/*!
3409 \since 5.9
3410 \overload
3411
3412 Parameter \a layerCount is the number of layers in a texture array
3413 that are being uploaded/populated by this call.
3414*/
3415void QOpenGLTexture::setData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions * const options)
3416{
3417 Q_D(QOpenGLTexture);
3418 Q_ASSERT(d->textureId);
3419 if (!isStorageAllocated()) {
3420 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3421 "To do so call allocateStorage() before this function");
3422 return;
3423 }
3424 d->setData(mipLevel, layer, layerCount, cubeFace, sourceFormat, sourceType, data, options);
3425}
3426
3427/*!
3428 \since 5.3
3429 \overload
3430*/
3431void QOpenGLTexture::setData(int mipLevel, int layer,
3432 PixelFormat sourceFormat, PixelType sourceType,
3433 const void *data, const QOpenGLPixelTransferOptions * const options)
3434{
3435 Q_D(QOpenGLTexture);
3436 Q_ASSERT(d->textureId);
3437 d->setData(mipLevel, layer, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
3438}
3439
3440/*!
3441 \since 5.3
3442 \overload
3443*/
3444void QOpenGLTexture::setData(int mipLevel,
3445 PixelFormat sourceFormat, PixelType sourceType,
3446 const void *data, const QOpenGLPixelTransferOptions * const options)
3447{
3448 Q_D(QOpenGLTexture);
3449 Q_ASSERT(d->textureId);
3450 d->setData(mipLevel, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
3451}
3452
3453/*!
3454 \since 5.3
3455 \overload
3456*/
3457void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType,
3458 const void *data, const QOpenGLPixelTransferOptions * const options)
3459{
3460 Q_D(QOpenGLTexture);
3461 Q_ASSERT(d->textureId);
3462 d->setData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
3463}
3464
3465/*!
3466 \since 5.14
3467 \overload
3468
3469 This overload is to be used to update a part of the texture. Parameters \a
3470 xOffset, \a yOffset, \a zOffset specify the texel offsets within the
3471 texture. Parameters \a width, \a height and \a depth specify the dimensions
3472 of the sub image.
3473
3474 The structure of the pixel data pointed to by \a data is specified by \a
3475 sourceFormat and \a sourceType. The pixel data upload can optionally be
3476 controlled by \a options.
3477*/
3478void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3479 int width, int height, int depth,
3480 PixelFormat sourceFormat, PixelType sourceType,
3481 const void *data, const QOpenGLPixelTransferOptions * const options)
3482{
3483 Q_D(QOpenGLTexture);
3484 Q_ASSERT(d->textureId);
3485 d->setData(xOffset, yOffset, zOffset,
3486 width, height, depth,
3487 0, 0, 1,
3488 QOpenGLTexture::CubeMapPositiveX, sourceFormat,
3489 sourceType, data, options);
3490}
3491
3492/*!
3493 \since 5.14
3494 \overload
3495
3496 This overload is to be used to update a part of the texture. Parameters \a
3497 xOffset, \a yOffset, \a zOffset specify the texel offsets within the
3498 texture. Parameters \a width, \a height and \a depth specify the dimensions
3499 of the sub image. The mip map level the sub image we want to
3500 update is specified with \a mipLevel.
3501
3502 The structure of the pixel data pointed to by \a data is specified by \a
3503 sourceFormat and \a sourceType. The pixel data upload can optionally be
3504 controlled by \a options.
3505*/
3506void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3507 int width, int height, int depth,
3508 int mipLevel,
3509 PixelFormat sourceFormat, PixelType sourceType,
3510 const void *data, const QOpenGLPixelTransferOptions * const options)
3511{
3512 Q_D(QOpenGLTexture);
3513 Q_ASSERT(d->textureId);
3514 d->setData(xOffset, yOffset, zOffset,
3515 width, height, depth,
3516 mipLevel, 0, 1,
3517 QOpenGLTexture::CubeMapPositiveX, sourceFormat,
3518 sourceType, data, options);
3519}
3520
3521/*!
3522 \since 5.14
3523 \overload
3524
3525 This overload is to be used to update a part of the texture. Parameters \a
3526 xOffset, \a yOffset, \a zOffset specify the texel offsets within the
3527 texture. Parameters \a width, \a height and \a depth specify the dimensions
3528 of the sub image. The mip map level and layerof the sub image we want to
3529 update are specified with \a mipLevel and \a layer.
3530
3531 The structure of the pixel data pointed to by \a data is specified by \a
3532 sourceFormat and \a sourceType. The pixel data upload can optionally be
3533 controlled by \a options.
3534*/
3535void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3536 int width, int height, int depth,
3537 int mipLevel, int layer,
3538 PixelFormat sourceFormat, PixelType sourceType,
3539 const void *data, const QOpenGLPixelTransferOptions * const options)
3540{
3541 Q_D(QOpenGLTexture);
3542 Q_ASSERT(d->textureId);
3543 d->setData(xOffset, yOffset, zOffset,
3544 width, height, depth,
3545 mipLevel, layer, 1,
3546 QOpenGLTexture::CubeMapPositiveX, sourceFormat,
3547 sourceType, data, options);
3548}
3549
3550/*!
3551 \since 5.14
3552 \overload
3553
3554 This overload is to be used to update a part of the texture. Parameters \a
3555 xOffset, \a yOffset, \a zOffset specify the texel offsets within the
3556 texture. Parameters \a width, \a height and \a depth specify the dimensions
3557 of the sub image.The mip map level, layer and cube map face of the sub
3558 image we want to update are specified with \a mipLevel, \a layer and \a
3559 face.
3560
3561 The structure of the pixel data pointed to by \a data is specified by \a
3562 sourceFormat and \a sourceType. The pixel data upload can optionally be
3563 controlled by \a options.
3564*/
3565void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3566 int width, int height, int depth,
3567 int mipLevel, int layer,
3568 CubeMapFace face,
3569 PixelFormat sourceFormat, PixelType sourceType,
3570 const void *data, const QOpenGLPixelTransferOptions * const options)
3571{
3572 Q_D(QOpenGLTexture);
3573 Q_ASSERT(d->textureId);
3574 d->setData(xOffset, yOffset, zOffset,
3575 width, height, depth,
3576 mipLevel, layer, 1,
3577 face, sourceFormat,
3578 sourceType, data, options);
3579}
3580
3581/*!
3582 \since 5.14
3583 \overload
3584
3585 This overload is to be used to update a part of the texture. Parameters \a
3586 xOffset, \a yOffset, \a zOffset specify the texel offsets within the
3587 texture. Parameters \a width, \a height and \a depth specify the dimensions
3588 of the sub image.The mip map level, starting layer, cube map face and
3589 number of layers of the sub image we want to update are specified with \a
3590 mipLevel, \a layer, \a face and \a layerCount.
3591
3592 The structure of the pixel data pointed to by \a data is specified by \a
3593 sourceFormat and \a sourceType. The pixel data upload can optionally be
3594 controlled by \a options.
3595*/
3596void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3597 int width, int height, int depth,
3598 int mipLevel, int layer,
3599 CubeMapFace face, int layerCount,
3600 PixelFormat sourceFormat, PixelType sourceType,
3601 const void *data, const QOpenGLPixelTransferOptions * const options)
3602{
3603 Q_D(QOpenGLTexture);
3604 Q_ASSERT(d->textureId);
3605 d->setData(xOffset, yOffset, zOffset,
3606 width, height, depth,
3607 mipLevel, layer, layerCount,
3608 face, sourceFormat,
3609 sourceType, data, options);
3610}
3611
3612/*!
3613 This overload of setData() will allocate storage for you.
3614 The pixel data is contained in \a image. Mipmaps are generated by default.
3615 Set \a genMipMaps to \l DontGenerateMipMaps to turn off mipmap generation.
3616
3617 \note \a image is automatically converted to QImage::Format_RGBA8888 which
3618 may have performance implications for large images with a different format.
3619
3620 \overload
3621*/
3622void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps)
3623{
3624 QOpenGLContext *context = QOpenGLContext::currentContext();
3625 if (!context) {
3626 qWarning("QOpenGLTexture::setData() requires a valid current context");
3627 return;
3628 }
3629
3630 if (image.isNull()) {
3631 qWarning("QOpenGLTexture::setData() tried to set a null image");
3632 return;
3633 }
3634
3635 QImage glImage = image.convertToFormat(QImage::Format_RGBA8888);
3636 if (glImage.isNull()) {
3637 qWarning("QOpenGLTexture::setData() failed to convert image");
3638 return;
3639 }
3640
3641 if (context->isOpenGLES() && context->format().majorVersion() < 3)
3642 setFormat(QOpenGLTexture::RGBAFormat);
3643 else
3644 setFormat(QOpenGLTexture::RGBA8_UNorm);
3645
3646 setSize(image.width(), image.height());
3647 setMipLevels(genMipMaps == GenerateMipMaps ? maximumMipLevels() : 1);
3648 allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
3649
3650 // Upload pixel data and generate mipmaps
3651 QOpenGLPixelTransferOptions uploadOptions;
3652 uploadOptions.setAlignment(1);
3653 setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, glImage.constBits(), &uploadOptions);
3654}
3655
3656/*!
3657 Uploads compressed pixel \a data to \a mipLevel, array \a layer, and \a cubeFace.
3658 The pixel transfer can optionally be controlled with \a options. The \a dataSize
3659 argument should specify the size of the data pointed to by \a data.
3660
3661 If not using a compressed format() then you should use setData() instead of this
3662 function.
3663
3664 \since 5.3
3665*/
3666void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
3667 int dataSize, const void *data,
3668 const QOpenGLPixelTransferOptions * const options)
3669{
3670 Q_D(QOpenGLTexture);
3671 Q_ASSERT(d->textureId);
3672 if (!isStorageAllocated()) {
3673 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3674 "To do so call allocateStorage() before this function");
3675 return;
3676 }
3677 d->setCompressedData(mipLevel, layer, 1, cubeFace, dataSize, data, options);
3678}
3679
3680/*!
3681 \since 5.9
3682 \overload
3683
3684 Parameter \a layerCount is the number of layers in a texture array
3685 that are being uploaded/populated by this call.
3686*/
3687void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, int dataSize, const void *data, const QOpenGLPixelTransferOptions * const options)
3688{
3689 Q_D(QOpenGLTexture);
3690 Q_ASSERT(d->textureId);
3691 if (!isStorageAllocated()) {
3692 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3693 "To do so call allocateStorage() before this function");
3694 return;
3695 }
3696 d->setCompressedData(mipLevel, layer, layerCount, cubeFace, dataSize, data, options);
3697}
3698
3699/*!
3700 \overload
3701*/
3702void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int dataSize, const void *data,
3703 const QOpenGLPixelTransferOptions * const options)
3704{
3705 Q_D(QOpenGLTexture);
3706 Q_ASSERT(d->textureId);
3707 d->setCompressedData(mipLevel, layer, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
3708}
3709
3710/*!
3711 \overload
3712*/
3713void QOpenGLTexture::setCompressedData(int mipLevel, int dataSize, const void *data,
3714 const QOpenGLPixelTransferOptions * const options)
3715{
3716 Q_D(QOpenGLTexture);
3717 Q_ASSERT(d->textureId);
3718 d->setCompressedData(mipLevel, 0, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
3719}
3720
3721/*!
3722 \overload
3723*/
3724void QOpenGLTexture::setCompressedData(int dataSize, const void *data,
3725 const QOpenGLPixelTransferOptions * const options)
3726{
3727 Q_D(QOpenGLTexture);
3728 Q_ASSERT(d->textureId);
3729 d->setCompressedData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
3730}
3731
3732/*!
3733 Returns \c true if your OpenGL implementation and version supports the texture
3734 feature \a feature.
3735*/
3736bool QOpenGLTexture::hasFeature(Feature feature)
3737{
3738 QOpenGLContext *ctx = QOpenGLContext::currentContext();
3739 if (!ctx) {
3740 qWarning("QOpenGLTexture::hasFeature() requires a valid current context");
3741 return false;
3742 }
3743
3744 QSurfaceFormat f = ctx->format();
3745
3746 bool supported = false;
3747
3748#if !QT_CONFIG(opengles2)
3749 if (!ctx->isOpenGLES()) {
3750 switch (feature) {
3751 case ImmutableMultisampleStorage:
3752 supported = f.version() >= std::pair(4, 3)
3753 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage_multisample"));
3754 break;
3755
3756 case TextureBuffer:
3757 supported = f.version() >= std::pair(3, 0)
3758 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_buffer_object"));
3759 break;
3760
3761 case StencilTexturing:
3762 supported = f.version() >= std::pair(4, 3)
3763 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_stencil_texturing"));
3764 break;
3765
3766 case ImmutableStorage:
3767 supported = f.version() >= std::pair(4, 2)
3768 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage"))
3769 || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_storage"));
3770 break;
3771
3772 case TextureCubeMapArrays:
3773 supported = f.version() >= std::pair(4, 0)
3774 || ctx->hasExtension(QByteArrayLiteral("ARB_texture_cube_map_array"));
3775 break;
3776
3777 case Swizzle:
3778 supported = f.version() >= std::pair(3, 3)
3779 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_swizzle"));
3780 break;
3781
3782 case TextureMultisample:
3783 supported = f.version() >= std::pair(3, 2)
3784 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_multisample"));
3785 break;
3786
3787 case TextureArrays:
3788 supported = f.version() >= std::pair(3, 0)
3789 || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_array"));
3790 break;
3791
3792 case TextureRectangle:
3793 supported = f.version() >= std::pair(2, 1)
3794 || ctx->hasExtension(QByteArrayLiteral("ARB_texture_rectangle"));
3795 break;
3796
3797 case Texture3D:
3798 supported = f.version() >= std::pair(1, 3);
3799 break;
3800
3801 case AnisotropicFiltering:
3802 supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
3803 break;
3804
3805 case NPOTTextures:
3806 case NPOTTextureRepeat:
3807 supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
3808 break;
3809
3810 case Texture1D:
3811 supported = f.version() >= std::pair(1, 1);
3812 break;
3813
3814 case TextureComparisonOperators:
3815 // GL 1.4 and GL_ARB_shadow alone support only LEQUAL and GEQUAL;
3816 // since we're talking about history anyhow avoid to be extra pedantic
3817 // in the feature set, and simply claim supported if we have the full set of operators
3818 // (which has been added into 1.5 / GL_EXT_shadow_funcs).
3819 supported = f.version() >= std::pair(1, 5)
3820 || (ctx->hasExtension(QByteArrayLiteral("GL_ARB_shadow"))
3821 && ctx->hasExtension(QByteArrayLiteral("GL_EXT_shadow_funcs")));
3822 break;
3823
3824 case TextureMipMapLevel:
3825 supported = f.version() >= std::pair(1, 2);
3826 break;
3827
3828 case MaxFeatureFlag:
3829 break;
3830 }
3831 }
3832
3833 if (ctx->isOpenGLES())
3834#endif
3835 {
3836 const char *renderer = reinterpret_cast<const char *>(ctx->functions()->glGetString(GL_RENDERER));
3837 switch (feature) {
3838 case ImmutableStorage:
3839 supported = (f.version() >= std::pair(3, 0) || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_storage")))
3840 && !(renderer && strstr(renderer, "Mali")); // do not use on Mali: QTBUG-45106
3841 break;
3842
3843 case ImmutableMultisampleStorage:
3844 supported = f.version() >= std::pair(3, 1);
3845 break;
3846
3847 case TextureRectangle:
3848 break;
3849
3850 case TextureArrays:
3851 supported = f.version() >= std::pair(3, 0);
3852 break;
3853
3854 case Texture3D:
3855 supported = f.version() >= std::pair(3, 0)
3856 || ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
3857 break;
3858
3859 case TextureMultisample:
3860 supported = f.version() >= std::pair(3, 1);
3861 break;
3862
3863 case TextureBuffer:
3864 break;
3865
3866 case TextureCubeMapArrays:
3867 break;
3868
3869 case Swizzle:
3870 supported = f.version() >= std::pair(3, 0);
3871 break;
3872
3873 case StencilTexturing:
3874 break;
3875
3876 case AnisotropicFiltering:
3877 supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
3878 break;
3879
3880 case NPOTTextures:
3881 case NPOTTextureRepeat:
3882 supported = f.version() >= std::pair(3,0)
3883 || ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"))
3884 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
3885 break;
3886
3887 case Texture1D:
3888 break;
3889
3890 case TextureComparisonOperators:
3891 supported = f.version() >= std::pair(3, 0)
3892 || ctx->hasExtension(QByteArrayLiteral("GL_EXT_shadow_samplers"));
3893 break;
3894
3895 case TextureMipMapLevel:
3896 supported = f.version() >= std::pair(3, 0);
3897 break;
3898
3899 case MaxFeatureFlag:
3900 break;
3901 }
3902 }
3903
3904 return supported;
3905}
3906
3907/*!
3908 Sets the base mipmap level used for all texture lookups with this texture to \a baseLevel.
3909
3910 \note This function has no effect on Qt built for OpenGL ES 2.
3911 \sa mipBaseLevel(), setMipMaxLevel(), setMipLevelRange()
3912*/
3913void QOpenGLTexture::setMipBaseLevel(int baseLevel)
3914{
3915 Q_D(QOpenGLTexture);
3916 d->create();
3917 if (!d->features.testFlag(TextureMipMapLevel)) {
3918 qWarning("QOpenGLTexture::setMipBaseLevel: requires OpenGL >= 1.2 or OpenGL ES >= 3.0");
3919 return;
3920 }
3921 Q_ASSERT(d->textureId);
3922 Q_ASSERT(d->texFuncs);
3923 Q_ASSERT(baseLevel <= d->maxLevel);
3924 d->baseLevel = baseLevel;
3925 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
3926}
3927
3928/*!
3929 Returns the mipmap base level used for all texture lookups with this texture.
3930 The default is 0.
3931
3932 \sa setMipBaseLevel(), mipMaxLevel(), mipLevelRange()
3933*/
3934int QOpenGLTexture::mipBaseLevel() const
3935{
3936 Q_D(const QOpenGLTexture);
3937 return d->baseLevel;
3938}
3939
3940/*!
3941 Sets the maximum mipmap level used for all texture lookups with this texture to \a maxLevel.
3942
3943 \note This function has no effect on Qt built for OpenGL ES 2.
3944 \sa mipMaxLevel(), setMipBaseLevel(), setMipLevelRange()
3945*/
3946void QOpenGLTexture::setMipMaxLevel(int maxLevel)
3947{
3948 Q_D(QOpenGLTexture);
3949 d->create();
3950 if (!d->features.testFlag(TextureMipMapLevel)) {
3951 qWarning("QOpenGLTexture::setMipMaxLevel: requires OpenGL >= 1.2 or OpenGL ES >= 3.0");
3952 return;
3953 }
3954 Q_ASSERT(d->textureId);
3955 Q_ASSERT(d->texFuncs);
3956 Q_ASSERT(d->baseLevel <= maxLevel);
3957 d->maxLevel = maxLevel;
3958 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
3959}
3960
3961/*!
3962 Returns the mipmap maximum level used for all texture lookups with this texture.
3963
3964 \sa setMipMaxLevel(), mipBaseLevel(), mipLevelRange()
3965*/
3966int QOpenGLTexture::mipMaxLevel() const
3967{
3968 Q_D(const QOpenGLTexture);
3969 return d->maxLevel;
3970}
3971
3972/*!
3973 Sets the range of mipmap levels that can be used for texture lookups with this texture
3974 to range from \a baseLevel to \a maxLevel.
3975
3976 \note This function has no effect on Qt built for OpenGL ES 2.
3977 \sa setMipBaseLevel(), setMipMaxLevel(), mipLevelRange()
3978*/
3979void QOpenGLTexture::setMipLevelRange(int baseLevel, int maxLevel)
3980{
3981 Q_D(QOpenGLTexture);
3982 d->create();
3983 if (!d->features.testFlag(TextureMipMapLevel)) {
3984 qWarning("QOpenGLTexture::setMipLevelRange: requires OpenGL >= 1.2 or OpenGL ES >= 3.0");
3985 return;
3986 }
3987 Q_ASSERT(d->textureId);
3988 Q_ASSERT(d->texFuncs);
3989 Q_ASSERT(baseLevel <= maxLevel);
3990 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
3991 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
3992}
3993
3994/*!
3995 Returns the range of mipmap levels that can be used for texture lookups with this texture.
3996
3997 \sa mipBaseLevel(), mipMaxLevel()
3998*/
3999std::pair<int, int> QOpenGLTexture::mipLevelRange() const
4000{
4001 Q_D(const QOpenGLTexture);
4002 return std::pair(d->baseLevel, d->maxLevel);
4003}
4004
4005/*!
4006 If \a enabled is \c true, enables automatic mipmap generation for this texture object
4007 to occur whenever the level 0 mipmap data is set via setData().
4008
4009 The automatic mipmap generation is enabled by default.
4010
4011 \note Mipmap generation is not supported for compressed textures with OpenGL ES 2.0.
4012
4013 \sa isAutoMipMapGenerationEnabled(), generateMipMaps()
4014*/
4015void QOpenGLTexture::setAutoMipMapGenerationEnabled(bool enabled)
4016{
4017 Q_D(QOpenGLTexture);
4018 d->autoGenerateMipMaps = enabled;
4019}
4020
4021/*!
4022 Returns whether auto mipmap generation is enabled for this texture object.
4023
4024 \sa setAutoMipMapGenerationEnabled(), generateMipMaps()
4025*/
4026bool QOpenGLTexture::isAutoMipMapGenerationEnabled() const
4027{
4028 Q_D(const QOpenGLTexture);
4029 return d->autoGenerateMipMaps;
4030}
4031
4032/*!
4033 Generates mipmaps for this texture object from mipmap level 0. If you are
4034 using a texture target and filtering option that requires mipmaps and you
4035 have disabled automatic mipmap generation then you need to call this function
4036 or the overload to create the mipmap chain.
4037
4038 \note Mipmap generation is not supported for compressed textures with OpenGL ES.
4039
4040 \sa setAutoMipMapGenerationEnabled(), setMipLevels(), mipLevels()
4041*/
4042void QOpenGLTexture::generateMipMaps()
4043{
4044 Q_D(QOpenGLTexture);
4045 Q_ASSERT(d->texFuncs);
4046 Q_ASSERT(d->textureId);
4047 if (isCompressedFormat(d->format)) {
4048 if (QOpenGLContext *ctx = QOpenGLContext::currentContext())
4049 if (ctx->isOpenGLES())
4050 return;
4051 }
4052 d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget);
4053}
4054
4055/*!
4056 Generates mipmaps for this texture object from mipmap level \a baseLevel. If you are
4057 using a texture target and filtering option that requires mipmaps and you
4058 have disabled automatic mipmap generation then you need to call this function
4059 or the overload to create the mipmap chain.
4060
4061 The generation of mipmaps to above \a baseLevel is achieved by setting the mipmap
4062 base level to \a baseLevel and then generating the mipmap chain. If \a resetBaseLevel
4063 is \c true, then the baseLevel of the texture will be reset to its previous value.
4064
4065 \sa setAutoMipMapGenerationEnabled(), setMipLevels(), mipLevels()
4066*/
4067void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel)
4068{
4069 Q_D(QOpenGLTexture);
4070 Q_ASSERT(d->texFuncs);
4071 Q_ASSERT(d->textureId);
4072 if (isCompressedFormat(d->format)) {
4073 if (QOpenGLContext *ctx = QOpenGLContext::currentContext())
4074 if (ctx->isOpenGLES())
4075 return;
4076 }
4077 int oldBaseLevel;
4078 if (resetBaseLevel)
4079 oldBaseLevel = mipBaseLevel();
4080 setMipBaseLevel(baseLevel);
4081 d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget);
4082 if (resetBaseLevel)
4083 setMipBaseLevel(oldBaseLevel);
4084}
4085
4086/*!
4087 GLSL shaders are able to reorder the components of the vec4 returned by texture
4088 functions. It is also desirable to be able to control this reordering from CPU
4089 side code. This is made possible by swizzle masks since OpenGL 3.3.
4090
4091 Each component of the texture can be mapped to one of the SwizzleValue options.
4092
4093 This function maps \a component to the output \a value.
4094
4095 \note This function has no effect on Mac and Qt built for OpenGL ES 2.
4096 \sa swizzleMask()
4097*/
4098void QOpenGLTexture::setSwizzleMask(SwizzleComponent component, SwizzleValue value)
4099{
4100#if !defined(Q_OS_MAC) && !QT_CONFIG(opengles2)
4101 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4102 Q_D(QOpenGLTexture);
4103 d->create();
4104 Q_ASSERT(d->texFuncs);
4105 Q_ASSERT(d->textureId);
4106 if (!d->features.testFlag(Swizzle)) {
4107 qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
4108 return;
4109 }
4110 d->swizzleMask[component - SwizzleRed] = value;
4111 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, component, value);
4112 return;
4113 }
4114#else
4115 Q_UNUSED(component);
4116 Q_UNUSED(value);
4117#endif
4118 qWarning("QOpenGLTexture: Texture swizzling is not supported");
4119}
4120
4121/*!
4122 Parameters \a {r}, \a {g}, \a {b}, and \a {a} are values used for setting
4123 the colors red, green, blue, and the alpha value.
4124 \overload
4125*/
4126void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g,
4127 SwizzleValue b, SwizzleValue a)
4128{
4129#if !defined(Q_OS_MAC) && !QT_CONFIG(opengles2)
4130 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4131 Q_D(QOpenGLTexture);
4132 d->create();
4133 Q_ASSERT(d->texFuncs);
4134 Q_ASSERT(d->textureId);
4135 if (!d->features.testFlag(Swizzle)) {
4136 qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
4137 return;
4138 }
4139 GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
4140 d->swizzleMask[0] = r;
4141 d->swizzleMask[1] = g;
4142 d->swizzleMask[2] = b;
4143 d->swizzleMask[3] = a;
4144 d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
4145 return;
4146 }
4147#else
4148 Q_UNUSED(r);
4149 Q_UNUSED(g);
4150 Q_UNUSED(b);
4151 Q_UNUSED(a);
4152#endif
4153 qWarning("QOpenGLTexture: Texture swizzling is not supported");
4154}
4155
4156/*!
4157 Returns the swizzle mask for texture \a component.
4158*/
4159QOpenGLTexture::SwizzleValue QOpenGLTexture::swizzleMask(SwizzleComponent component) const
4160{
4161 Q_D(const QOpenGLTexture);
4162 return d->swizzleMask[component - SwizzleRed];
4163}
4164
4165/*!
4166 \enum QOpenGLTexture::DepthStencilMode
4167 \since 5.4
4168 This enum specifies which component of a depth/stencil texture is
4169 accessed when the texture is sampled.
4170
4171 \value DepthMode Equivalent to GL_DEPTH_COMPONENT.
4172 \value StencilMode Equivalent to GL_STENCIL_INDEX.
4173*/
4174
4175/*!
4176 If using a texture that has a combined depth/stencil format this function sets
4177 which component of the texture is accessed to \a mode.
4178
4179 When the parameter is set to DepthMode, then accessing it from the
4180 shader will access the depth component as a single float, as normal. But when
4181 the parameter is set to StencilMode, the shader will access the stencil component.
4182
4183 \note This function has no effect on Mac and Qt built for OpenGL ES 2.
4184 \since 5.4
4185 \sa depthStencilMode()
4186*/
4187void QOpenGLTexture::setDepthStencilMode(QOpenGLTexture::DepthStencilMode mode)
4188{
4189#if !defined(Q_OS_MAC) && !QT_CONFIG(opengles2)
4190 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4191 Q_D(QOpenGLTexture);
4192 d->create();
4193 Q_ASSERT(d->texFuncs);
4194 Q_ASSERT(d->textureId);
4195 if (!d->features.testFlag(StencilTexturing)) {
4196 qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3 or GL_ARB_stencil_texturing");
4197 return;
4198 }
4199 d->depthStencilMode = mode;
4200 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, mode);
4201 return;
4202 }
4203#else
4204 Q_UNUSED(mode);
4205#endif
4206 qWarning("QOpenGLTexture: DepthStencil Mode is not supported");
4207}
4208
4209/*!
4210 Returns the depth stencil mode for textures using a combined depth/stencil format.
4211
4212 \since 5.4
4213 \sa setDepthStencilMode()
4214*/
4215QOpenGLTexture::DepthStencilMode QOpenGLTexture::depthStencilMode() const
4216{
4217 Q_D(const QOpenGLTexture);
4218 return d->depthStencilMode;
4219}
4220
4221/*!
4222 \enum QOpenGLTexture::ComparisonFunction
4223 \since 5.5
4224 This enum specifies which comparison operator is used when texture comparison
4225 is enabled on this texture.
4226
4227 \value CompareLessEqual Equivalent to GL_LEQUAL.
4228 \value CompareGreaterEqual Equivalent to GL_GEQUAL.
4229 \value CompareLess Equivalent to GL_LESS.
4230 \value CompareGreater Equivalent to GL_GREATER.
4231 \value CompareEqual Equivalent to GL_EQUAL.
4232 \value CompareNotEqual Equivalent to GL_NOTEQUAL.
4233 \value CompareAlways Equivalent to GL_ALWAYS.
4234 \value CompareNever Equivalent to GL_NEVER.
4235
4236 \omitvalue CommpareNotEqual
4237*/
4238
4239/*!
4240 \since 5.5
4241
4242 Sets the texture comparison function on this texture to \a function. The texture
4243 comparison function is used by shadow samplers when sampling a depth texture.
4244
4245 \sa comparisonFunction()
4246*/
4247void QOpenGLTexture::setComparisonFunction(QOpenGLTexture::ComparisonFunction function)
4248{
4249 Q_D(QOpenGLTexture);
4250 d->create();
4251 if (!d->features.testFlag(TextureComparisonOperators)) {
4252 qWarning("QOpenGLTexture::setComparisonFunction: requires OpenGL >= 1.5 or OpenGL ES >= 3.0");
4253 return;
4254 }
4255 d->comparisonFunction = function;
4256 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_COMPARE_FUNC, function);
4257}
4258
4259/*!
4260 \since 5.5
4261
4262 Returns the texture comparison operator set on this texture. By default, a
4263 texture has a CompareLessEqual comparison function.
4264
4265 \sa setComparisonFunction()
4266*/
4267QOpenGLTexture::ComparisonFunction QOpenGLTexture::comparisonFunction() const
4268{
4269 Q_D(const QOpenGLTexture);
4270 return d->comparisonFunction;
4271}
4272
4273/*!
4274 \enum QOpenGLTexture::ComparisonMode
4275 \since 5.5
4276 This enum specifies which comparison mode is used when sampling this texture.
4277
4278 \value CompareRefToTexture Equivalent to GL_COMPARE_REF_TO_TEXTURE.
4279 \value CompareNone Equivalent to GL_NONE.
4280*/
4281
4282/*!
4283 \since 5.5
4284
4285 Sets the texture comparison mode on this texture to \a mode. The texture
4286 comparison mode is used by shadow samplers when sampling a depth texture.
4287
4288 \sa comparisonMode()
4289*/
4290void QOpenGLTexture::setComparisonMode(QOpenGLTexture::ComparisonMode mode)
4291{
4292 Q_D(QOpenGLTexture);
4293 d->create();
4294 if (!d->features.testFlag(TextureComparisonOperators)) {
4295 qWarning("QOpenGLTexture::setComparisonMode: requires OpenGL >= 1.5 or OpenGL ES >= 3.0");
4296 return;
4297 }
4298 d->comparisonMode = mode;
4299 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_COMPARE_MODE, mode);
4300}
4301
4302/*!
4303 \since 5.5
4304
4305 Returns the texture comparison mode set on this texture. By default, a
4306 texture has a CompareNone comparison mode (i.e. comparisons are disabled).
4307
4308 \sa setComparisonMode()
4309*/
4310QOpenGLTexture::ComparisonMode QOpenGLTexture::comparisonMode() const
4311{
4312 Q_D(const QOpenGLTexture);
4313 return d->comparisonMode;
4314}
4315
4316/*!
4317 Sets the filter used for minification to \a filter.
4318
4319 \sa minificationFilter(), setMagnificationFilter(), setMinMagFilters()
4320*/
4321void QOpenGLTexture::setMinificationFilter(QOpenGLTexture::Filter filter)
4322{
4323 Q_D(QOpenGLTexture);
4324 d->create();
4325 Q_ASSERT(d->texFuncs);
4326 Q_ASSERT(d->textureId);
4327 d->minFilter = filter;
4328 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, filter);
4329}
4330
4331/*!
4332 Returns the minification filter.
4333
4334 \sa setMinificationFilter()
4335*/
4336QOpenGLTexture::Filter QOpenGLTexture::minificationFilter() const
4337{
4338 Q_D(const QOpenGLTexture);
4339 return d->minFilter;
4340}
4341
4342/*!
4343 Sets the magnification filter to \a filter.
4344
4345 \sa magnificationFilter(), setMinificationFilter(), setMinMagFilters()
4346*/
4347void QOpenGLTexture::setMagnificationFilter(QOpenGLTexture::Filter filter)
4348{
4349 Q_D(QOpenGLTexture);
4350 d->create();
4351 Q_ASSERT(d->texFuncs);
4352 Q_ASSERT(d->textureId);
4353 d->magFilter = filter;
4354 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, filter);
4355}
4356
4357/*!
4358 Returns the magnification filter.
4359
4360 \sa setMagnificationFilter()
4361*/
4362QOpenGLTexture::Filter QOpenGLTexture::magnificationFilter() const
4363{
4364 Q_D(const QOpenGLTexture);
4365 return d->magFilter;
4366}
4367
4368/*!
4369 Sets the minification filter to \a minificationFilter and the magnification filter
4370 to \a magnificationFilter.
4371
4372 \sa minMagFilters(), setMinificationFilter(), setMagnificationFilter()
4373*/
4374void QOpenGLTexture::setMinMagFilters(QOpenGLTexture::Filter minificationFilter,
4375 QOpenGLTexture::Filter magnificationFilter)
4376{
4377 Q_D(QOpenGLTexture);
4378 d->create();
4379 Q_ASSERT(d->texFuncs);
4380 Q_ASSERT(d->textureId);
4381 d->minFilter = minificationFilter;
4382 d->magFilter = magnificationFilter;
4383 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, minificationFilter);
4384 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, magnificationFilter);
4385}
4386
4387/*!
4388 Returns the current minification and magnification filters.
4389
4390 \sa setMinMagFilters()
4391*/
4392std::pair<QOpenGLTexture::Filter, QOpenGLTexture::Filter> QOpenGLTexture::minMagFilters() const
4393{
4394 Q_D(const QOpenGLTexture);
4395 return std::pair<QOpenGLTexture::Filter, QOpenGLTexture::Filter>(d->minFilter, d->magFilter);
4396}
4397
4398/*!
4399 If your OpenGL implementation supports the GL_EXT_texture_filter_anisotropic extension
4400 this function sets the maximum anisotropy level to \a anisotropy.
4401
4402 \sa maximumAnisotropy()
4403*/
4404void QOpenGLTexture::setMaximumAnisotropy(float anisotropy)
4405{
4406 Q_D(QOpenGLTexture);
4407 d->create();
4408 Q_ASSERT(d->texFuncs);
4409 Q_ASSERT(d->textureId);
4410 if (!d->features.testFlag(AnisotropicFiltering)) {
4411 qWarning("QOpenGLTexture::setMaximumAnisotropy() requires GL_EXT_texture_filter_anisotropic");
4412 return;
4413 }
4414 d->maxAnisotropy = anisotropy;
4415 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
4416}
4417
4418/*!
4419 Returns the maximum level of anisotropy to be accounted for when performing texture lookups.
4420 This requires the GL_EXT_texture_filter_anisotropic extension.
4421
4422 \sa setMaximumAnisotropy()
4423*/
4424float QOpenGLTexture::maximumAnisotropy() const
4425{
4426 Q_D(const QOpenGLTexture);
4427 return d->maxAnisotropy;
4428}
4429
4430/*!
4431 Sets the wrap (or repeat mode) for all texture dimensions to \a mode.
4432
4433 \sa wrapMode()
4434*/
4435void QOpenGLTexture::setWrapMode(QOpenGLTexture::WrapMode mode)
4436{
4437 Q_D(QOpenGLTexture);
4438 d->create();
4439 Q_ASSERT(d->texFuncs);
4440 Q_ASSERT(d->textureId);
4441 d->setWrapMode(mode);
4442}
4443
4444/*!
4445 Sets the wrap (or repeat mode) for the texture dimension \a direction
4446 to \a mode.
4447 \overload
4448*/
4449void QOpenGLTexture::setWrapMode(QOpenGLTexture::CoordinateDirection direction, QOpenGLTexture::WrapMode mode)
4450{
4451 Q_D(QOpenGLTexture);
4452 d->create();
4453 Q_ASSERT(d->texFuncs);
4454 Q_ASSERT(d->textureId);
4455 d->setWrapMode(direction, mode);
4456}
4457
4458/*!
4459 Returns the wrap mode for the texture dimension \a direction.
4460
4461 \sa setWrapMode()
4462*/
4463QOpenGLTexture::WrapMode QOpenGLTexture::wrapMode(QOpenGLTexture::CoordinateDirection direction) const
4464{
4465 Q_D(const QOpenGLTexture);
4466 return d->wrapMode(direction);
4467}
4468
4469/*!
4470 Sets the border color of the texture to \a color.
4471
4472 \note This function has no effect on Mac and Qt built for OpenGL ES 2.
4473 \sa borderColor()
4474*/
4475void QOpenGLTexture::setBorderColor(const QColor &color)
4476{
4477 setBorderColor(static_cast<float>(color.redF()), static_cast<float>(color.greenF()),
4478 static_cast<float>(color.blueF()), static_cast<float>(color.alphaF()));
4479}
4480
4481/*!
4482 Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and \a {a} to the
4483 alpha value.
4484 \overload
4485*/
4486void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
4487{
4488#if !QT_CONFIG(opengles2)
4489 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4490 Q_D(QOpenGLTexture);
4491 d->create();
4492 Q_ASSERT(d->texFuncs);
4493 Q_ASSERT(d->textureId);
4494 float values[4];
4495 values[0] = r;
4496 values[1] = g;
4497 values[2] = b;
4498 values[3] = a;
4499 d->borderColor.clear();
4500 for (int i = 0; i < 4; ++i)
4501 d->borderColor.append(QVariant(values[i]));
4502 d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
4503 return;
4504 }
4505#else
4506 Q_UNUSED(r);
4507 Q_UNUSED(g);
4508 Q_UNUSED(b);
4509 Q_UNUSED(a);
4510#endif
4511 qWarning("QOpenGLTexture: Border color is not supported");
4512}
4513
4514/*!
4515 Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and the alpha
4516 value to \a {a}.
4517 \overload
4518*/
4519void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
4520{
4521#if !QT_CONFIG(opengles2)
4522 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4523 Q_D(QOpenGLTexture);
4524 d->create();
4525 Q_ASSERT(d->texFuncs);
4526 Q_ASSERT(d->textureId);
4527 int values[4];
4528 values[0] = r;
4529 values[1] = g;
4530 values[2] = b;
4531 values[3] = a;
4532 d->borderColor.clear();
4533 for (int i = 0; i < 4; ++i)
4534 d->borderColor.append(QVariant(values[i]));
4535 d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
4536 return;
4537 }
4538#else
4539 Q_UNUSED(r);
4540 Q_UNUSED(g);
4541 Q_UNUSED(b);
4542 Q_UNUSED(a);
4543#endif
4544 qWarning("QOpenGLTexture: Border color is not supported");
4545
4546 // TODO Handle case of using glTextureParameterIiv() based on format
4547}
4548
4549/*!
4550 Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and the alpha
4551 value to \a {a}.
4552 \overload
4553*/
4554void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a)
4555{
4556#if !QT_CONFIG(opengles2)
4557 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4558 Q_D(QOpenGLTexture);
4559 d->create();
4560 Q_ASSERT(d->texFuncs);
4561 Q_ASSERT(d->textureId);
4562 int values[4];
4563 values[0] = int(r);
4564 values[1] = int(g);
4565 values[2] = int(b);
4566 values[3] = int(a);
4567 d->borderColor.clear();
4568 for (int i = 0; i < 4; ++i)
4569 d->borderColor.append(QVariant(values[i]));
4570 d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
4571 return;
4572 }
4573#else
4574 Q_UNUSED(r);
4575 Q_UNUSED(g);
4576 Q_UNUSED(b);
4577 Q_UNUSED(a);
4578#endif
4579 qWarning("QOpenGLTexture: Border color is not supported");
4580
4581 // TODO Handle case of using glTextureParameterIuiv() based on format
4582}
4583
4584/*!
4585 Returns the borderColor of this texture.
4586
4587 \sa setBorderColor()
4588*/
4589QColor QOpenGLTexture::borderColor() const
4590{
4591 Q_D(const QOpenGLTexture);
4592 QColor c(0.0f, 0.0f, 0.0f, 0.0f);
4593 if (!d->borderColor.isEmpty()) {
4594 c.setRedF(d->borderColor.at(0).toFloat());
4595 c.setGreenF(d->borderColor.at(1).toFloat());
4596 c.setBlueF(d->borderColor.at(2).toFloat());
4597 c.setAlphaF(d->borderColor.at(3).toFloat());
4598 }
4599 return c;
4600}
4601
4602/*!
4603 Writes the texture border color into the first four elements
4604 of the array pointed to by \a border.
4605
4606 \sa setBorderColor()
4607*/
4608void QOpenGLTexture::borderColor(float *border) const
4609{
4610 Q_D(const QOpenGLTexture);
4611 Q_ASSERT(border);
4612 if (d->borderColor.isEmpty()) {
4613 for (int i = 0; i < 4; ++i)
4614 border[i] = 0.0f;
4615 } else {
4616 for (int i = 0; i < 4; ++i)
4617 border[i] = d->borderColor.at(i).toFloat();
4618 }
4619}
4620
4621/*!
4622 Writes the texture border color into the first four elements
4623 of the array pointed to by \a border.
4624
4625 \overload
4626*/
4627void QOpenGLTexture::borderColor(int *border) const
4628{
4629 Q_D(const QOpenGLTexture);
4630 Q_ASSERT(border);
4631 if (d->borderColor.isEmpty()) {
4632 for (int i = 0; i < 4; ++i)
4633 border[i] = 0;
4634 } else {
4635 for (int i = 0; i < 4; ++i)
4636 border[i] = d->borderColor.at(i).toInt();
4637 }
4638}
4639
4640/*!
4641 Writes the texture border color into the first four elements
4642 of the array pointed to by \a border.
4643
4644 \overload
4645*/
4646void QOpenGLTexture::borderColor(unsigned int *border) const
4647{
4648 Q_D(const QOpenGLTexture);
4649 Q_ASSERT(border);
4650 if (d->borderColor.isEmpty()) {
4651 for (int i = 0; i < 4; ++i)
4652 border[i] = 0;
4653 } else {
4654 for (int i = 0; i < 4; ++i)
4655 border[i] = d->borderColor.at(i).toUInt();
4656 }
4657}
4658
4659/*!
4660 Sets the minimum level of detail to \a value. This limits the selection of highest
4661 resolution mipmap (lowest mipmap level). The default value is -1000.
4662
4663 \note This function has no effect on Qt built for OpenGL ES 2.
4664 \sa minimumLevelOfDetail(), setMaximumLevelOfDetail(), setLevelOfDetailRange()
4665*/
4666void QOpenGLTexture::setMinimumLevelOfDetail(float value)
4667{
4668#if !QT_CONFIG(opengles2)
4669 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4670 Q_D(QOpenGLTexture);
4671 d->create();
4672 Q_ASSERT(d->texFuncs);
4673 Q_ASSERT(d->textureId);
4674 Q_ASSERT(value < d->maxLevelOfDetail);
4675 d->minLevelOfDetail = value;
4676 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, value);
4677 return;
4678 }
4679#else
4680 Q_UNUSED(value);
4681#endif
4682 qWarning("QOpenGLTexture: Detail level is not supported");
4683}
4684
4685/*!
4686 Returns the minimum level of detail parameter.
4687
4688 \sa setMinimumLevelOfDetail(), maximumLevelOfDetail(), levelOfDetailRange()
4689*/
4690float QOpenGLTexture::minimumLevelOfDetail() const
4691{
4692 Q_D(const QOpenGLTexture);
4693 return d->minLevelOfDetail;
4694}
4695
4696/*!
4697 Sets the maximum level of detail to \a value. This limits the selection of lowest
4698 resolution mipmap (highest mipmap level). The default value is 1000.
4699
4700 \note This function has no effect on Qt built for OpenGL ES 2.
4701 \sa maximumLevelOfDetail(), setMinimumLevelOfDetail(), setLevelOfDetailRange()
4702*/
4703void QOpenGLTexture::setMaximumLevelOfDetail(float value)
4704{
4705#if !QT_CONFIG(opengles2)
4706 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4707 Q_D(QOpenGLTexture);
4708 d->create();
4709 Q_ASSERT(d->texFuncs);
4710 Q_ASSERT(d->textureId);
4711 Q_ASSERT(value > d->minLevelOfDetail);
4712 d->maxLevelOfDetail = value;
4713 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, value);
4714 return;
4715 }
4716#else
4717 Q_UNUSED(value);
4718#endif
4719 qWarning("QOpenGLTexture: Detail level is not supported");
4720}
4721
4722/*!
4723 Returns the maximum level of detail parameter.
4724
4725 \sa setMaximumLevelOfDetail(), minimumLevelOfDetail(), levelOfDetailRange()
4726*/
4727float QOpenGLTexture::maximumLevelOfDetail() const
4728{
4729 Q_D(const QOpenGLTexture);
4730 return d->maxLevelOfDetail;
4731}
4732
4733/*!
4734 Sets the minimum level of detail parameters to \a min and the maximum level
4735 to \a max.
4736 \note This function has no effect on Qt built for OpenGL ES 2.
4737 \sa levelOfDetailRange(), setMinimumLevelOfDetail(), setMaximumLevelOfDetail()
4738*/
4739void QOpenGLTexture::setLevelOfDetailRange(float min, float max)
4740{
4741#if !QT_CONFIG(opengles2)
4742 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4743 Q_D(QOpenGLTexture);
4744 d->create();
4745 Q_ASSERT(d->texFuncs);
4746 Q_ASSERT(d->textureId);
4747 Q_ASSERT(min < max);
4748 d->minLevelOfDetail = min;
4749 d->maxLevelOfDetail = max;
4750 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, min);
4751 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, max);
4752 return;
4753 }
4754#else
4755 Q_UNUSED(min);
4756 Q_UNUSED(max);
4757#endif
4758 qWarning("QOpenGLTexture: Detail level is not supported");
4759}
4760
4761/*!
4762 Returns the minimum and maximum level of detail parameters.
4763
4764 \sa setLevelOfDetailRange(), minimumLevelOfDetail(), maximumLevelOfDetail()
4765*/
4766std::pair<float, float> QOpenGLTexture::levelOfDetailRange() const
4767{
4768 Q_D(const QOpenGLTexture);
4769 return std::pair(d->minLevelOfDetail, d->maxLevelOfDetail);
4770}
4771
4772/*!
4773 Sets the level of detail bias to \a bias.
4774 Level of detail bias affects the point at which mipmapping levels change.
4775 Increasing values for level of detail bias makes the overall images blurrier
4776 or smoother. Decreasing values make the overall images sharper.
4777
4778 \note This function has no effect on Qt built for OpenGL ES 2.
4779 \sa levelofDetailBias()
4780*/
4781void QOpenGLTexture::setLevelofDetailBias(float bias)
4782{
4783#if !QT_CONFIG(opengles2)
4784 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4785 Q_D(QOpenGLTexture);
4786 d->create();
4787 Q_ASSERT(d->texFuncs);
4788 Q_ASSERT(d->textureId);
4789 d->levelOfDetailBias = bias;
4790 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_LOD_BIAS, bias);
4791 return;
4792 }
4793#else
4794 Q_UNUSED(bias);
4795#endif
4796 qWarning("QOpenGLTexture: Detail level is not supported");
4797}
4798
4799/*!
4800 Returns the level of detail bias parameter.
4801
4802 \sa setLevelofDetailBias()
4803*/
4804float QOpenGLTexture::levelofDetailBias() const
4805{
4806 Q_D(const QOpenGLTexture);
4807 return d->levelOfDetailBias;
4808}
4809
4810#ifndef QT_NO_DEBUG_STREAM
4811QDebug operator<<(QDebug debug, const QOpenGLTexture *t)
4812{
4813 QDebugStateSaver saver(debug);
4814 debug.nospace();
4815 debug << "QOpenGLTexture(";
4816 if (t) {
4817 const QOpenGLTexturePrivate *d = t->d_ptr.data();
4818 debug << d->target << ", bindingTarget=" << d->bindingTarget
4819 << ", size=[" << d->dimensions[0]
4820 << ", " << d->dimensions[1];
4821 if (d->target == QOpenGLTexture::Target3D)
4822 debug << ", " << d->dimensions[2];
4823 debug << "], format=" << d->format << ", formatClass=" << d->formatClass;
4824 if (t->isCreated())
4825 debug << ", textureId=" << d->textureId;
4826 if (t->isBound())
4827 debug << ", [bound]";
4828 if (t->isTextureView())
4829 debug << ", [view]";
4831 debug << ", [fixedSamplePositions]";
4832 debug << ", mipLevels=" << d->requestedMipLevels << ", layers=" << d->layers
4833 << ", faces=" << d->faces << ", samples=" << d->samples
4834 << ", depthStencilMode=" << d->depthStencilMode << ", comparisonFunction="
4835 << d->comparisonFunction << ", comparisonMode=" << d->comparisonMode
4836 << ", features=" << d->features << ", minificationFilter=" << d->minFilter
4837 << ", magnificationFilter=" << d->magFilter << ", wrapMode=" << d->wrapModes[0];
4838 } else {
4839 debug << "0x0";
4840 }
4841 debug << ')';
4842 return debug;
4843}
4844#endif // QT_NO_DEBUG_STREAM
4845
4846QT_END_NAMESPACE
4847
4848#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)