Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
5#include "qopengltexture.h"
6#include "qopengltexture_p.h"
8#include "qopenglfunctions.h"
9#include <QtGui/qcolor.h>
10#include <QtGui/qopenglcontext.h>
11#include <QtCore/qdebug.h>
12#include <private/qobject_p.h>
13#include <private/qopenglcontext_p.h>
14
16
17//this is to work around GL_TEXTURE_WRAP_R_OES which also has 0x8072 as value
18#if !defined(GL_TEXTURE_WRAP_R)
19 #define GL_TEXTURE_WRAP_R 0x8072
20#endif
21
24 : q_ptr(qq),
26 target(textureTarget),
27 textureId(0),
28 format(QOpenGLTexture::NoFormat),
29 formatClass(QOpenGLTexture::NoFormatClass),
30 requestedMipLevels(1),
31 mipLevels(-1),
32 layers(1),
33 faces(1),
34 samples(0),
35 fixedSamplePositions(true),
36 baseLevel(0),
37 maxLevel(1000),
38 depthStencilMode(QOpenGLTexture::DepthMode),
39 comparisonFunction(QOpenGLTexture::CompareLessEqual),
40 comparisonMode(QOpenGLTexture::CompareNone),
41 minFilter(QOpenGLTexture::Nearest),
42 magFilter(QOpenGLTexture::Nearest),
43 maxAnisotropy(1.0f),
44 minLevelOfDetail(-1000.0f),
45 maxLevelOfDetail(1000.0f),
46 levelOfDetailBias(0.0f),
47 textureView(false),
48 autoGenerateMipMaps(true),
49 storageAllocated(false),
50 texFuncs(nullptr),
51 functions(nullptr)
52{
53 dimensions[0] = dimensions[1] = dimensions[2] = 1;
54
55 switch (target) {
58 break;
61 break;
64 break;
67 break;
70 break;
73 faces = 6;
74 break;
77 faces = 6;
78 break;
81 break;
84 break;
87 break;
90 break;
91 }
92
97
100}
101
106
108{
109 // If we already have a functions object, there is nothing to do
110 if (texFuncs)
111 return;
112
113 // See if the context already has a suitable resource we can use.
114 // If not create a functions object and add it to the context in case
115 // others wish to use it too
116 texFuncs = context->textureFunctions();
117 if (!texFuncs) {
119 auto *funcs = texFuncs; // lets us capture by pointer value below
120 context->setTextureFunctions(funcs, [funcs] { delete funcs; });
121 }
122}
123
125{
126 if (textureId != 0)
127 return true;
128
130 if (!ctx) {
131 qWarning("Requires a valid current OpenGL context.\n"
132 "Texture has not been created");
133 return false;
134 }
135 context = ctx;
136 functions = ctx->functions();
137
138 // Resolve any functions we will need based upon context version and create the texture
140
141 // What features do we have?
143 while (feature != QOpenGLTexture::MaxFeatureFlag) {
144 if (QOpenGLTexture::hasFeature(feature))
145 features |= feature;
146 feature = static_cast<QOpenGLTexture::Feature>(feature << 1);
147 }
148
150 return textureId != 0;
151}
152
154{
155 if (!textureId) {
156 // not created or already destroyed
157 return;
158 }
160 if (!currentContext) {
161 qWarning("QOpenGLTexturePrivate::destroy() called without a current context.\n"
162 "Texture has not been destroyed");
163 return;
164 }
165 if (!QOpenGLContext::areSharing(currentContext, context)) {
166
167 qWarning("QOpenGLTexturePrivate::destroy() called but texture context %p"
168 " is not shared with current context %p.\n"
169 "Texture has not been destroyed",
170 static_cast<const void *>(context),
171 static_cast<const void *>(currentContext));
172 return;
173 }
174
176
177 context = nullptr;
178 functions = nullptr;
179 textureId = 0;
183 mipLevels = -1;
184 layers = 1;
185 faces = 1;
186 samples = 0;
188 baseLevel = 0;
189 maxLevel = 1000;
193 maxAnisotropy = 1.0f;
194 minLevelOfDetail = -1000.0f;
195 maxLevelOfDetail = 1000.0f;
196 levelOfDetailBias = 0.0f;
197 textureView = false;
198 autoGenerateMipMaps = true;
199 storageAllocated = false;
200 texFuncs = nullptr;
201
206
209}
210
215
228
233
246
248{
249 GLint boundTextureId = 0;
250 functions->glGetIntegerv(bindingTarget, &boundTextureId);
251 return (static_cast<GLuint>(boundTextureId) == textureId);
252}
253
255{
256 GLint oldTextureUnit = 0;
257 functions->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit);
258
259 GLint boundTextureId = 0;
261 functions->glGetIntegerv(bindingTarget, &boundTextureId);
262 bool result = (static_cast<GLuint>(boundTextureId) == textureId);
263
264 texFuncs->glActiveTexture(GL_TEXTURE0 + oldTextureUnit);
265 return result;
266}
267
288
290{
291 switch (internalFormat) {
293 return false;
294
350
355
358
360
417 return true;
418
420 return false;
421
424
427
429
431 return false;
432 }
433
434 Q_UNREACHABLE_RETURN(false);
435}
436
438{
439 switch (target) {
447 return false;
448
451 return true;
452
455 return false;
456 }
457
458 Q_UNREACHABLE_RETURN(false);
459}
460
462{
463 // Use immutable storage whenever possible, falling back to mutable
464 // Note that if multisample textures are not supported at all, we'll still fail into
465 // the mutable storage allocation
470}
471
473{
474 // Resolve the actual number of mipmap levels we can use
476
479 else
480 allocateMutableStorage(pixelFormat, pixelType);
481}
482
484{
485 switch (internalFormat) {
488
490 return QOpenGLTexture::Red;
491
493 return QOpenGLTexture::RG;
494
496 return QOpenGLTexture::RGB;
497
500
502 return QOpenGLTexture::Red;
503
505 return QOpenGLTexture::RG;
506
508 return QOpenGLTexture::RGB;
509
512
514 return QOpenGLTexture::Red;
515
517 return QOpenGLTexture::RG;
518
520 return QOpenGLTexture::RGB;
521
524
526 return QOpenGLTexture::Red;
527
529 return QOpenGLTexture::RG;
530
532 return QOpenGLTexture::RGB;
533
536
539
542
545
548
551
554
557
560
563
566
569
572
575
578
581
587
590
593
596
599
602
605
608
610 return QOpenGLTexture::Red;
611
613 return QOpenGLTexture::RG;
614
616 return QOpenGLTexture::RGB;
617
620
622 return QOpenGLTexture::Red;
623
625 return QOpenGLTexture::RG;
626
628 return QOpenGLTexture::RGB;
629
632
634 return QOpenGLTexture::RGB;
635
637 return QOpenGLTexture::RGB;
638
640 return QOpenGLTexture::RGB;
641
643 return QOpenGLTexture::RGB;
644
647
650
653
659
663
666
687
690 return QOpenGLTexture::Red;
691
694 return QOpenGLTexture::RG;
695
698 return QOpenGLTexture::RGB;
699
703
707
737
740
743
745 return QOpenGLTexture::RGB;
746
749
752
755 }
756
757 Q_UNREACHABLE_RETURN(QOpenGLTexture::NoSourceFormat);
758}
759
761{
762 switch (internalFormat) {
765
775
785
799
813
819
825
828
831
834
837
840
843
846
849
853
856
859
862
865
924
927
934 }
935
936 Q_UNREACHABLE_RETURN(QOpenGLTexture::NoPixelType);
937}
938
940{
941 switch (internalFormat) {
943
999
1004
1007
1008 case QOpenGLTexture::S8:
1009 return false;
1010
1068 return true;
1069
1076 return false;
1077 }
1078
1079 Q_UNREACHABLE_RETURN(false);
1080}
1081
1083{
1084 // There is no way to allocate mutable storage for compressed textures in in
1085 // versions older than OpenGL 3.1 and OpenGL ES 3.0, because the older specs
1086 // do not mandate accepting null data pointers for glCompressedTexImage*D,
1087 // unlike glTexImage*D (which in turn does not accept compressed formats).
1089 storageAllocated = true;
1090 return;
1091 }
1092
1093 switch (target) {
1095 // Buffer textures get their storage from an external OpenGL buffer
1096 qWarning("Buffer textures do not allocate storage");
1097 return;
1098
1100 if (features.testFlag(QOpenGLTexture::Texture1D)) {
1101 for (int level = 0; level < mipLevels; ++level)
1104 0,
1105 pixelFormat, pixelType, nullptr);
1106 } else {
1107 qWarning("1D textures are not supported");
1108 return;
1109 }
1110 break;
1111
1115 for (int level = 0; level < mipLevels; ++level)
1118 layers,
1119 0,
1120 pixelFormat, pixelType, nullptr);
1121 } else {
1122 qWarning("1D array textures are not supported");
1123 return;
1124 }
1125 break;
1126
1129 for (int level = 0; level < mipLevels; ++level)
1133 0,
1134 pixelFormat, pixelType, nullptr);
1135 break;
1136
1138 // Cubemaps are the odd one out. We have to allocate storage for each
1139 // face and miplevel using the special cubemap face targets rather than
1140 // GL_TARGET_CUBEMAP.
1141 const QOpenGLTexture::CubeMapFace faceTargets[] = {
1145 };
1146
1147 for (int faceTarget = 0; faceTarget < 6; ++faceTarget) {
1148 for (int level = 0; level < mipLevels; ++level) {
1149 texFuncs->glTextureImage2D(textureId, faceTargets[faceTarget], bindingTarget,
1150 level, format,
1153 0,
1154 pixelFormat, pixelType, nullptr);
1155 }
1156 }
1157 break;
1158 }
1159
1162 for (int level = 0; level < mipLevels; ++level)
1166 layers,
1167 0,
1168 pixelFormat, pixelType, nullptr);
1169 } else {
1170 qWarning("Array textures are not supported");
1171 return;
1172 }
1173 break;
1174
1176 // Cubemap arrays must specify number of layer-faces (6 * layers) as depth parameter
1178 for (int level = 0; level < mipLevels; ++level)
1182 6 * layers,
1183 0,
1184 pixelFormat, pixelType, nullptr);
1185 } else {
1186 qWarning("Cubemap Array textures are not supported");
1187 return;
1188 }
1189 break;
1190
1192 if (features.testFlag(QOpenGLTexture::Texture3D)) {
1193 for (int level = 0; level < mipLevels; ++level)
1198 0,
1199 pixelFormat, pixelType, nullptr);
1200 } else {
1201 qWarning("3D textures are not supported");
1202 return;
1203 }
1204 break;
1205
1209 dimensions[0], dimensions[1],
1211 } else {
1212 qWarning("Multisample textures are not supported");
1213 return;
1214 }
1215 break;
1216
1223 } else {
1224 qWarning("Multisample array textures are not supported");
1225 return;
1226 }
1227 break;
1228 }
1229
1230 storageAllocated = true;
1231}
1232
1234{
1235 switch (target) {
1237 // Buffer textures get their storage from an external OpenGL buffer
1238 qWarning("Buffer textures do not allocate storage");
1239 return;
1240
1242 if (features.testFlag(QOpenGLTexture::Texture1D)) {
1244 dimensions[0]);
1245 } else {
1246 qWarning("1D textures are not supported");
1247 return;
1248 }
1249 break;
1250
1255 dimensions[0], layers);
1256 } else {
1257 qWarning("1D array textures are not supported");
1258 return;
1259 }
1260 break;
1261
1266 dimensions[0], dimensions[1]);
1267 break;
1268
1272 dimensions[0], dimensions[1], layers);
1273 } else {
1274 qWarning("Array textures are not supported");
1275 return;
1276 }
1277 break;
1278
1280 // Cubemap arrays must specify number of layer-faces (6 * layers) as depth parameter
1283 dimensions[0], dimensions[1], 6 * layers);
1284 } else {
1285 qWarning("Cubemap Array textures are not supported");
1286 return;
1287 }
1288 break;
1289
1291 if (features.testFlag(QOpenGLTexture::Texture3D)) {
1293 dimensions[0], dimensions[1], dimensions[2]);
1294 } else {
1295 qWarning("3D textures are not supported");
1296 return;
1297 }
1298 break;
1299
1303 dimensions[0], dimensions[1],
1305 } else {
1306 qWarning("Multisample textures are not supported");
1307 return;
1308 }
1309 break;
1310
1317 } else {
1318 qWarning("Multisample array textures are not supported");
1319 return;
1320 }
1321 break;
1322 }
1323
1324 storageAllocated = true;
1325}
1326
1327void QOpenGLTexturePrivate::setData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace,
1329 const void *data, const QOpenGLPixelTransferOptions * const options)
1330{
1331 switch (target) {
1333 Q_UNUSED(layer);
1334 Q_UNUSED(cubeFace);
1335 Q_UNUSED(layerCount);
1337 0, mipLevelSize( mipLevel, dimensions[0] ),
1338 sourceFormat, sourceType, data, options);
1339 break;
1340
1342 Q_UNUSED(cubeFace);
1344 0, layer,
1345 mipLevelSize(mipLevel, dimensions[0]),
1346 layerCount,
1347 sourceFormat, sourceType, data, options);
1348 break;
1349
1351 Q_UNUSED(layer);
1352 Q_UNUSED(cubeFace);
1353 Q_UNUSED(layerCount);
1355 0, 0,
1356 mipLevelSize(mipLevel, dimensions[0]),
1357 mipLevelSize(mipLevel, dimensions[1]),
1358 sourceFormat, sourceType, data, options);
1359 break;
1360
1362 Q_UNUSED(cubeFace);
1364 0, 0, layer,
1365 mipLevelSize(mipLevel, dimensions[0]),
1366 mipLevelSize(mipLevel, dimensions[1]),
1367 layerCount,
1368 sourceFormat, sourceType, data, options);
1369 break;
1370
1372 Q_UNUSED(cubeFace);
1373 Q_UNUSED(layerCount);
1375 0, 0, layer,
1376 mipLevelSize(mipLevel, dimensions[0]),
1377 mipLevelSize(mipLevel, dimensions[1]),
1378 mipLevelSize(mipLevel, dimensions[2]),
1379 sourceFormat, sourceType, data, options);
1380 break;
1381
1383 Q_UNUSED(layer);
1384 Q_UNUSED(layerCount);
1386 0, 0,
1387 mipLevelSize(mipLevel, dimensions[0]),
1388 mipLevelSize(mipLevel, dimensions[1]),
1389 sourceFormat, sourceType, data, options);
1390 break;
1391
1394 int layerFace = 6 * layer + faceIndex;
1396 0, 0, layerFace,
1397 mipLevelSize(mipLevel, dimensions[0]),
1398 mipLevelSize(mipLevel, dimensions[1]),
1399 layerCount,
1400 sourceFormat, sourceType, data, options);
1401 break;
1402 }
1403
1405 Q_UNUSED(mipLevel);
1406 Q_UNUSED(layer);
1407 Q_UNUSED(cubeFace);
1408 Q_UNUSED(layerCount);
1410 0, 0,
1411 dimensions[0],
1412 dimensions[1],
1413 sourceFormat, sourceType, data, options);
1414 break;
1415
1419 // We don't upload pixel data for these targets
1420 qWarning("QOpenGLTexture::setData(): Texture target does not support pixel data upload");
1421 break;
1422 }
1423
1424 // If requested perform automatic mip map generation
1425 if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) {
1426 Q_Q(QOpenGLTexture);
1427 q->generateMipMaps();
1428 }
1429}
1430
1431void QOpenGLTexturePrivate::setData(int xOffset, int yOffset, int zOffset, int width, int height, int depth,
1432 int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace,
1434 const void *data, const QOpenGLPixelTransferOptions * const options)
1435{
1436 switch (target) {
1438 Q_UNUSED(layer);
1439 Q_UNUSED(cubeFace);
1440 Q_UNUSED(layerCount);
1441 Q_UNUSED(yOffset);
1442 Q_UNUSED(zOffset);
1444 Q_UNUSED(depth);
1446 xOffset, width,
1447 sourceFormat, sourceType, data, options);
1448 break;
1449
1451 Q_UNUSED(cubeFace);
1452 Q_UNUSED(yOffset);
1453 Q_UNUSED(zOffset);
1455 Q_UNUSED(depth);
1457 xOffset, layer,
1458 width,
1459 layerCount,
1460 sourceFormat, sourceType, data, options);
1461 break;
1462
1464 Q_UNUSED(layer);
1465 Q_UNUSED(cubeFace);
1466 Q_UNUSED(layerCount);
1467 Q_UNUSED(zOffset);
1468 Q_UNUSED(depth);
1470 xOffset, yOffset,
1471 width, height,
1472 sourceFormat, sourceType, data, options);
1473 break;
1474
1476 Q_UNUSED(cubeFace);
1477 Q_UNUSED(zOffset);
1478 Q_UNUSED(depth);
1480 xOffset, yOffset, layer,
1481 width, height, layerCount,
1482 sourceFormat, sourceType, data, options);
1483 break;
1484
1486 Q_UNUSED(cubeFace);
1487 Q_UNUSED(layerCount);
1489 xOffset, yOffset, zOffset,
1490 width, height, depth,
1491 sourceFormat, sourceType, data, options);
1492 break;
1493
1495 Q_UNUSED(layer);
1496 Q_UNUSED(layerCount);
1497 Q_UNUSED(zOffset);
1498 Q_UNUSED(depth);
1500 xOffset, yOffset,
1501 width, height,
1502 sourceFormat, sourceType, data, options);
1503 break;
1504
1506 Q_UNUSED(zOffset);
1507 Q_UNUSED(depth);
1509 int layerFace = 6 * layer + faceIndex;
1511 xOffset, yOffset, layerFace,
1512 width, height,
1513 layerCount,
1514 sourceFormat, sourceType, data, options);
1515 break;
1516 }
1517
1519 Q_UNUSED(mipLevel);
1520 Q_UNUSED(layer);
1521 Q_UNUSED(cubeFace);
1522 Q_UNUSED(layerCount);
1523 Q_UNUSED(zOffset);
1524 Q_UNUSED(depth);
1526 xOffset, yOffset,
1527 width, height,
1528 sourceFormat, sourceType, data, options);
1529 break;
1530
1534 // We don't upload pixel data for these targets
1535 qWarning("QOpenGLTexture::setData(): Texture target does not support pixel data upload");
1536 break;
1537 }
1538
1539 // If requested perform automatic mip map generation
1540 if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) {
1541 Q_Q(QOpenGLTexture);
1542 q->generateMipMaps();
1543 }
1544}
1545
1546
1547void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, int layerCount,
1549 int dataSize, const void *data,
1550 const QOpenGLPixelTransferOptions * const options)
1551{
1552 if (!isCompressedFormat(format)) {
1553 qWarning("Cannot set compressed data for non-compressed format 0x%x", format);
1554 return;
1555 }
1556
1557 const bool needsFullSpec = !isUsingImmutableStorage(); // was allocateStorage() a no-op?
1558
1559 switch (target) {
1561 Q_UNUSED(layer);
1562 Q_UNUSED(cubeFace);
1563 Q_UNUSED(layerCount);
1564 if (needsFullSpec) {
1566 format,
1567 mipLevelSize(mipLevel, dimensions[0]),
1568 0, dataSize, data, options);
1569 } else {
1571 0, mipLevelSize( mipLevel, dimensions[0] ),
1572 format, dataSize, data, options);
1573 }
1574 break;
1575
1577 Q_UNUSED(cubeFace);
1578 if (!needsFullSpec) {
1580 0, layer,
1581 mipLevelSize(mipLevel, dimensions[0]),
1582 layerCount,
1583 format, dataSize, data, options);
1584 }
1585 break;
1586
1588 Q_UNUSED(layer);
1589 Q_UNUSED(cubeFace);
1590 Q_UNUSED(layerCount);
1591 if (needsFullSpec) {
1593 format,
1594 mipLevelSize(mipLevel, dimensions[0]),
1595 mipLevelSize(mipLevel, dimensions[1]),
1596 0, dataSize, data, options);
1597 } else {
1599 0, 0,
1600 mipLevelSize(mipLevel, dimensions[0]),
1601 mipLevelSize(mipLevel, dimensions[1]),
1602 format, dataSize, data, options);
1603 }
1604 break;
1605
1607 Q_UNUSED(cubeFace);
1608 if (!needsFullSpec) {
1610 0, 0, layer,
1611 mipLevelSize(mipLevel, dimensions[0]),
1612 mipLevelSize(mipLevel, dimensions[1]),
1613 layerCount,
1614 format, dataSize, data, options);
1615 }
1616 break;
1617
1619 Q_UNUSED(cubeFace);
1620 Q_UNUSED(layerCount);
1621 if (needsFullSpec) {
1623 format,
1624 mipLevelSize(mipLevel, dimensions[0]),
1625 mipLevelSize(mipLevel, dimensions[1]),
1626 mipLevelSize(mipLevel, dimensions[2]),
1627 0, dataSize, data, options);
1628 } else {
1630 0, 0, layer,
1631 mipLevelSize(mipLevel, dimensions[0]),
1632 mipLevelSize(mipLevel, dimensions[1]),
1633 mipLevelSize(mipLevel, dimensions[2]),
1634 format, dataSize, data, options);
1635 }
1636 break;
1637
1639 Q_UNUSED(layer);
1640 Q_UNUSED(layerCount);
1641 if (needsFullSpec) {
1643 format,
1644 mipLevelSize(mipLevel, dimensions[0]),
1645 mipLevelSize(mipLevel, dimensions[1]),
1646 0, dataSize, data, options);
1647 } else {
1649 0, 0,
1650 mipLevelSize(mipLevel, dimensions[0]),
1651 mipLevelSize(mipLevel, dimensions[1]),
1652 format, dataSize, data, options);
1653 }
1654 break;
1655
1658 int layerFace = 6 * layer + faceIndex;
1659 if (!needsFullSpec) {
1661 0, 0, layerFace,
1662 mipLevelSize(mipLevel, dimensions[0]),
1663 mipLevelSize(mipLevel, dimensions[1]),
1664 layerCount,
1665 format, dataSize, data, options);
1666 }
1667 break;
1668 }
1669
1674 // We don't upload pixel data for these targets
1675 qWarning("QOpenGLTexture::setCompressedData(): Texture target does not support pixel data upload");
1676 break;
1677 }
1678
1679 // If requested perform automatic mip map generation
1680 if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) {
1681 Q_Q(QOpenGLTexture);
1682 q->generateMipMaps();
1683 }
1684}
1685
1716
1718{
1719 switch (target) {
1723 switch (direction) {
1725 wrapModes[0] = mode;
1727 break;
1728
1731 qWarning("QOpenGLTexture::setWrapMode() direction not valid for this texture target");
1732 break;
1733 }
1734 break;
1735
1743 switch (direction) {
1745 wrapModes[0] = mode;
1747 break;
1748
1750 wrapModes[1] = mode;
1752 break;
1753
1755 qWarning("QOpenGLTexture::setWrapMode() direction not valid for this texture target");
1756 break;
1757 }
1758 break;
1759
1761 switch (direction) {
1763 wrapModes[0] = mode;
1765 break;
1766
1768 wrapModes[1] = mode;
1770 break;
1771
1773 wrapModes[2] = mode;
1775 break;
1776 }
1777 break;
1778 }
1779}
1780
1782{
1783 switch (target) {
1787 switch (direction) {
1789 return wrapModes[0];
1790
1793 qWarning("QOpenGLTexture::wrapMode() direction not valid for this texture target");
1795 }
1796 break;
1797
1805 switch (direction) {
1807 return wrapModes[0];
1808
1810 return wrapModes[1];
1811
1813 qWarning("QOpenGLTexture::wrapMode() direction not valid for this texture target");
1815 }
1816 break;
1817
1819 switch (direction) {
1821 return wrapModes[0];
1822
1824 return wrapModes[1];
1825
1827 return wrapModes[2];
1828 }
1829 break;
1830 }
1831 // Should never get here
1832 Q_ASSERT(false);
1834}
1835
1838 int minimumMipmapLevel, int maximumMipmapLevel,
1839 int minimumLayer, int maximumLayer) const
1840{
1841 // Do sanity checks - see http://www.opengl.org/wiki/GLAPI/glTextureView
1842
1843 // Check the targets are compatible
1844 bool viewTargetCompatible = false;
1845 switch (target) {
1848 viewTargetCompatible = (viewTarget == QOpenGLTexture::Target1D
1849 || viewTarget == QOpenGLTexture::Target1DArray);
1850 break;
1851
1852
1855 viewTargetCompatible = (viewTarget == QOpenGLTexture::Target2D
1856 || viewTarget == QOpenGLTexture::Target2DArray);
1857 break;
1858
1860 viewTargetCompatible = (viewTarget == QOpenGLTexture::Target3D);
1861 break;
1862
1865 viewTargetCompatible = (viewTarget == QOpenGLTexture::TargetCubeMap
1866 || viewTarget == QOpenGLTexture::Target2D
1867 || viewTarget == QOpenGLTexture::Target2DArray
1868 || viewTarget == QOpenGLTexture::TargetCubeMapArray);
1869 break;
1870
1873 viewTargetCompatible = (viewTarget == QOpenGLTexture::Target2DMultisample
1875 break;
1876
1878 viewTargetCompatible = (viewTarget == QOpenGLTexture::TargetRectangle);
1879 break;
1880
1882 // Cannot be used with texture views
1883 break;
1884 }
1885
1886 if (!viewTargetCompatible) {
1887 qWarning("QOpenGLTexture::createTextureView(): Incompatible source and view targets");
1888 return nullptr;
1889 }
1890
1891 // Check the formats are compatible
1892 bool viewFormatCompatible = false;
1893 switch (formatClass) {
1895 break;
1896
1898 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA32F
1899 || viewFormat == QOpenGLTexture::RGBA32U
1900 || viewFormat == QOpenGLTexture::RGBA32I);
1901 break;
1902
1904 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB32F
1905 || viewFormat == QOpenGLTexture::RGB32U
1906 || viewFormat == QOpenGLTexture::RGB32I);
1907 break;
1908
1910 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA16F
1911 || viewFormat == QOpenGLTexture::RG32F
1912 || viewFormat == QOpenGLTexture::RGBA16U
1913 || viewFormat == QOpenGLTexture::RG32U
1914 || viewFormat == QOpenGLTexture::RGBA16I
1915 || viewFormat == QOpenGLTexture::RG32I
1916 || viewFormat == QOpenGLTexture::RGBA16_UNorm
1917 || viewFormat == QOpenGLTexture::RGBA16_SNorm);
1918 break;
1919
1921 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB16_UNorm
1922 || viewFormat == QOpenGLTexture::RGB16_SNorm
1923 || viewFormat == QOpenGLTexture::RGB16F
1924 || viewFormat == QOpenGLTexture::RGB16U
1925 || viewFormat == QOpenGLTexture::RGB16I);
1926 break;
1927
1929 viewFormatCompatible = (viewFormat == QOpenGLTexture::RG16F
1930 || viewFormat == QOpenGLTexture::RG11B10F
1931 || viewFormat == QOpenGLTexture::R32F
1932 || viewFormat == QOpenGLTexture::RGB10A2
1933 || viewFormat == QOpenGLTexture::RGBA8U
1934 || viewFormat == QOpenGLTexture::RG16U
1935 || viewFormat == QOpenGLTexture::R32U
1936 || viewFormat == QOpenGLTexture::RGBA8I
1937 || viewFormat == QOpenGLTexture::RG16I
1938 || viewFormat == QOpenGLTexture::R32I
1939 || viewFormat == QOpenGLTexture::RGBA8_UNorm
1940 || viewFormat == QOpenGLTexture::RG16_UNorm
1941 || viewFormat == QOpenGLTexture::RGBA8_SNorm
1942 || viewFormat == QOpenGLTexture::RG16_SNorm
1943 || viewFormat == QOpenGLTexture::SRGB8_Alpha8
1944 || viewFormat == QOpenGLTexture::RGB9E5);
1945 break;
1946
1948 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB8_UNorm
1949 || viewFormat == QOpenGLTexture::RGB8_SNorm
1950 || viewFormat == QOpenGLTexture::SRGB8
1951 || viewFormat == QOpenGLTexture::RGB8U
1952 || viewFormat == QOpenGLTexture::RGB8I);
1953 break;
1954
1956 viewFormatCompatible = (viewFormat == QOpenGLTexture::R16F
1957 || viewFormat == QOpenGLTexture::RG8U
1958 || viewFormat == QOpenGLTexture::R16U
1959 || viewFormat == QOpenGLTexture::RG8I
1960 || viewFormat == QOpenGLTexture::R16I
1961 || viewFormat == QOpenGLTexture::RG8_UNorm
1962 || viewFormat == QOpenGLTexture::R16_UNorm
1963 || viewFormat == QOpenGLTexture::RG8_SNorm
1964 || viewFormat == QOpenGLTexture::R16_SNorm);
1965 break;
1966
1968 viewFormatCompatible = (viewFormat == QOpenGLTexture::R8U
1969 || viewFormat == QOpenGLTexture::R8I
1970 || viewFormat == QOpenGLTexture::R8_UNorm
1971 || viewFormat == QOpenGLTexture::R8_SNorm);
1972 break;
1973
1975 viewFormatCompatible = (viewFormat == QOpenGLTexture::R_ATI1N_UNorm
1976 || viewFormat == QOpenGLTexture::R_ATI1N_SNorm);
1977 break;
1978
1980 viewFormatCompatible = (viewFormat == QOpenGLTexture::RG_ATI2N_UNorm
1981 || viewFormat == QOpenGLTexture::RG_ATI2N_SNorm);
1982 break;
1983
1985 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB_BP_UNorm
1986 || viewFormat == QOpenGLTexture::SRGB_BP_UNorm);
1987 break;
1988
1990 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT
1991 || viewFormat == QOpenGLTexture::RGB_BP_SIGNED_FLOAT);
1992 break;
1993
1995 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB_DXT1
1996 || viewFormat == QOpenGLTexture::SRGB_DXT1);
1997 break;
1998
2000 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA_DXT1
2001 || viewFormat == QOpenGLTexture::SRGB_Alpha_DXT1);
2002 break;
2003
2005 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA_DXT3
2006 || viewFormat == QOpenGLTexture::SRGB_Alpha_DXT3);
2007 break;
2008
2010 viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA_DXT5
2011 || viewFormat == QOpenGLTexture::SRGB_Alpha_DXT5);
2012 break;
2013
2015 viewFormatCompatible = (viewFormat == format);
2016 break;
2017 }
2018
2019 if (!viewFormatCompatible) {
2020 qWarning("QOpenGLTexture::createTextureView(): Incompatible source and view formats");
2021 return nullptr;
2022 }
2023
2024
2025 // Create a view
2026 QOpenGLTexture *view = new QOpenGLTexture(viewTarget);
2027 view->setFormat(viewFormat);
2028 view->create();
2029 view->d_ptr->textureView = true;
2030 texFuncs->glTextureView(view->textureId(), viewTarget, textureId, viewFormat,
2031 minimumMipmapLevel, maximumMipmapLevel - minimumMipmapLevel + 1,
2032 minimumLayer, maximumLayer - minimumLayer + 1);
2033 return view;
2034}
2035
2036
2449
2464 : QOpenGLTexture(QOpenGLTexture::Target2D)
2465{
2466 setData(image, genMipMaps);
2467}
2468
2472
2479{
2480 Q_D(const QOpenGLTexture);
2481 return d->target;
2482}
2483
2502{
2503 Q_D(QOpenGLTexture);
2504 return d->create();
2505}
2506
2514{
2515 Q_D(QOpenGLTexture);
2516 return d->destroy();
2517}
2518
2525{
2526 Q_D(const QOpenGLTexture);
2527 return d->textureId != 0;
2528}
2529
2537{
2538 Q_D(const QOpenGLTexture);
2539 return d->textureId;
2540}
2541
2552{
2553 Q_D(QOpenGLTexture);
2554 Q_ASSERT(d->textureId);
2555 d->bind();
2556}
2557
2571{
2572 Q_D(QOpenGLTexture);
2573 Q_ASSERT(d->textureId);
2574 d->bind(unit, reset);
2575}
2576
2583{
2584 Q_D(QOpenGLTexture);
2585 d->release();
2586}
2587
2596{
2597 Q_D(QOpenGLTexture);
2598 d->release(unit, reset);
2599}
2600
2608{
2609 Q_D(const QOpenGLTexture);
2610 Q_ASSERT(d->textureId);
2611 return d->isBound();
2612}
2613
2621{
2622 Q_D(const QOpenGLTexture);
2623 Q_ASSERT(d->textureId);
2624 return d->isBound(unit);
2625}
2626
2632{
2634 if (!ctx) {
2635 qWarning("QOpenGLTexture::boundTextureId() requires a valid current context");
2636 return 0;
2637 }
2638
2639 GLint textureId = 0;
2640 ctx->functions()->glGetIntegerv(target, &textureId);
2641 return static_cast<GLuint>(textureId);
2642}
2643
2649{
2651 if (!ctx) {
2652 qWarning("QOpenGLTexture::boundTextureId() requires a valid current context");
2653 return 0;
2654 }
2655
2656 QOpenGLFunctions *funcs = ctx->functions();
2657 funcs->initializeOpenGLFunctions();
2658
2659 GLint oldTextureUnit = 0;
2660 funcs->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit);
2661
2662 funcs->glActiveTexture(unit);
2663 GLint textureId = 0;
2664 funcs->glGetIntegerv(target, &textureId);
2665 funcs->glActiveTexture(oldTextureUnit);
2666
2667 return static_cast<GLuint>(textureId);
2668}
2669
2680{
2681 Q_D(QOpenGLTexture);
2682 d->create();
2683 if (isStorageAllocated()) {
2684 qWarning("QOpenGLTexture::setFormat(): Cannot change format once storage has been allocated");
2685 return;
2686 }
2687
2688 d->format = format;
2689
2690 switch (format) {
2691 case NoFormat:
2692 d->formatClass = NoFormatClass;
2693 break;
2694
2695 case RGBA32F:
2696 case RGBA32U:
2697 case RGBA32I:
2698 d->formatClass = FormatClass_128Bit;
2699 break;
2700
2701 case RGB32F:
2702 case RGB32U:
2703 case RGB32I:
2704 d->formatClass = FormatClass_96Bit;
2705 break;
2706
2707 case RGBA16F:
2708 case RG32F:
2709 case RGBA16U:
2710 case RG32U:
2711 case RGBA16I:
2712 case RG32I:
2713 case RGBA16_UNorm:
2714 case RGBA16_SNorm:
2715 d->formatClass = FormatClass_64Bit;
2716 break;
2717
2718 case RGB16_UNorm:
2719 case RGB16_SNorm:
2720 case RGB16F:
2721 case RGB16U:
2722 case RGB16I:
2723 d->formatClass = FormatClass_48Bit;
2724 break;
2725
2726 case RG16F:
2727 case RG11B10F:
2728 case R32F:
2729 case RGB10A2:
2730 case RGBA8U:
2731 case RG16U:
2732 case R32U:
2733 case RGBA8I:
2734 case RG16I:
2735 case R32I:
2736 case RGBA8_UNorm:
2737 case RG16_UNorm:
2738 case RGBA8_SNorm:
2739 case RG16_SNorm:
2740 case SRGB8_Alpha8:
2741 case RGB9E5:
2742 d->formatClass = FormatClass_32Bit;
2743 break;
2744
2745 case RGB8_UNorm:
2746 case RGB8_SNorm:
2747 case SRGB8:
2748 case RGB8U:
2749 case RGB8I:
2750 d->formatClass = FormatClass_24Bit;
2751 break;
2752
2753 case R16F:
2754 case RG8U:
2755 case R16U:
2756 case RG8I:
2757 case R16I:
2758 case RG8_UNorm:
2759 case R16_UNorm:
2760 case RG8_SNorm:
2761 case R16_SNorm:
2762 d->formatClass = FormatClass_16Bit;
2763 break;
2764
2765 case R8U:
2766 case R8I:
2767 case R8_UNorm:
2768 case R8_SNorm:
2769 d->formatClass = FormatClass_8Bit;
2770 break;
2771
2772 case R_ATI1N_UNorm:
2773 case R_ATI1N_SNorm:
2774 d->formatClass = FormatClass_RGTC1_R;
2775 break;
2776
2777 case RG_ATI2N_UNorm:
2778 case RG_ATI2N_SNorm:
2779 d->formatClass = FormatClass_RGTC2_RG;
2780 break;
2781
2782 case RGB_BP_UNorm:
2783 case SRGB_BP_UNorm:
2784 d->formatClass = FormatClass_BPTC_Unorm;
2785 break;
2786
2789 d->formatClass = FormatClass_BPTC_Float;
2790 break;
2791
2792 case RGB_DXT1:
2793 case SRGB_DXT1:
2794 d->formatClass = FormatClass_S3TC_DXT1_RGB;
2795 break;
2796
2797 case RGBA_DXT1:
2798 case SRGB_Alpha_DXT1:
2799 d->formatClass = FormatClass_S3TC_DXT1_RGBA;
2800 break;
2801
2802 case RGBA_DXT3:
2803 case SRGB_Alpha_DXT3:
2804 d->formatClass = FormatClass_S3TC_DXT3_RGBA;
2805 break;
2806
2807 case RGBA_DXT5:
2808 case SRGB_Alpha_DXT5:
2809 d->formatClass = FormatClass_S3TC_DXT5_RGBA;
2810 break;
2811
2823 case RG3B2:
2824 case R5G6B5:
2825 case RGB5A1:
2826 case RGBA4:
2827 case D16:
2828 case D24:
2829 case D24S8:
2830 case D32:
2831 case D32F:
2832 case D32FS8X24:
2833 case S8:
2834 case DepthFormat:
2835 case AlphaFormat:
2836 case RGBFormat:
2837 case RGBAFormat:
2838 case LuminanceFormat:
2868 d->formatClass = FormatClass_Unique;
2869 break;
2870 }
2871}
2872
2879{
2880 Q_D(const QOpenGLTexture);
2881 return d->format;
2882}
2883
2884static bool isNpot(int width, int height = 1, int depth = 1)
2885{
2886 return width & (width-1) || height & (height-1) || depth & (depth-1);
2887}
2888
2903{
2904 Q_D(QOpenGLTexture);
2905 d->create();
2906 if (isStorageAllocated()) {
2907 qWarning("Cannot resize a texture that already has storage allocated.\n"
2908 "To do so, destroy() the texture and then create() and setSize()");
2909 return;
2910 }
2911
2913 d->setWrapMode(WrapMode::ClampToEdge);
2914
2915 switch (d->target) {
2919 d->dimensions[0] = width;
2921 Q_UNUSED(depth);
2922 break;
2923
2929 d->dimensions[0] = width;
2930 d->dimensions[1] = height;
2931 Q_UNUSED(depth);
2932 break;
2933
2936 if (width != height)
2937 qWarning("QAbstractOpenGLTexture::setSize(): Cube map textures must be square");
2938 d->dimensions[0] = d->dimensions[1] = width;
2939 Q_UNUSED(depth);
2940 break;
2941
2943 d->dimensions[0] = width;
2944 d->dimensions[1] = height;
2945 d->dimensions[2] = depth;
2946 break;
2947 }
2948}
2949
2956{
2957 Q_D(const QOpenGLTexture);
2958 return d->dimensions[0];
2959}
2960
2967{
2968 Q_D(const QOpenGLTexture);
2969 return d->dimensions[1];
2970}
2971
2978{
2979 Q_D(const QOpenGLTexture);
2980 return d->dimensions[2];
2981}
2982
2995{
2996 Q_D(QOpenGLTexture);
2997 d->create();
2998 if (isStorageAllocated()) {
2999 qWarning("Cannot set mip levels on a texture that already has storage allocated.\n"
3000 "To do so, destroy() the texture and then create() and setMipLevels()");
3001 return;
3002 }
3003
3004 switch (d->target) {
3012 d->requestedMipLevels = levels;
3013 break;
3014
3019 qWarning("QAbstractOpenGLTexture::setMipLevels(): This texture target does not support mipmaps");
3020 break;
3021 }
3022}
3023
3032{
3033 Q_D(const QOpenGLTexture);
3034 return isStorageAllocated() ? d->mipLevels : d->requestedMipLevels;
3035}
3036
3044{
3045 Q_D(const QOpenGLTexture);
3046 return d->maximumMipLevelCount();
3047}
3048
3059{
3060 Q_D(QOpenGLTexture);
3061 d->create();
3062 if (isStorageAllocated()) {
3063 qWarning("Cannot set layers on a texture that already has storage allocated.\n"
3064 "To do so, destroy() the texture and then create() and setLayers()");
3065 return;
3066 }
3067
3068 switch (d->target) {
3073 d->layers = layers;
3074 break;
3075
3083 qWarning("Texture target does not support array layers");
3084 break;
3085 }
3086}
3087
3099{
3100 Q_D(const QOpenGLTexture);
3101 return d->layers;
3102}
3103
3111{
3112 Q_D(const QOpenGLTexture);
3113 return d->faces;
3114}
3115
3127{
3128 Q_D(QOpenGLTexture);
3129 d->create();
3130 if (isStorageAllocated()) {
3131 qWarning("Cannot set sample count on a texture that already has storage allocated.\n"
3132 "To do so, destroy() the texture and then create() and setSamples()");
3133 return;
3134 }
3135
3136 switch (d->target) {
3139 d->samples = samples;
3140 break;
3141
3151
3152 qWarning("Texture target does not support multisampling");
3153 break;
3154 }
3155}
3156
3168{
3169 Q_D(const QOpenGLTexture);
3170 return d->samples;
3171}
3172
3189{
3190 Q_D(QOpenGLTexture);
3191 d->create();
3192 if (isStorageAllocated()) {
3193 qWarning("Cannot set sample positions on a texture that already has storage allocated.\n"
3194 "To do so, destroy() the texture and then create() and setFixedSamplePositions()");
3195 return;
3196 }
3197
3198 switch (d->target) {
3201 d->fixedSamplePositions = fixed;
3202 break;
3203
3213
3214 qWarning("Texture target does not support multisampling");
3215 break;
3216 }
3217}
3218
3230{
3231 Q_D(const QOpenGLTexture);
3232 return d->fixedSamplePositions;
3233}
3234
3262{
3263 Q_D(QOpenGLTexture);
3264 if (d->create()) {
3267 d->allocateStorage(pixelFormat, pixelType);
3268 }
3269}
3270
3294{
3295 Q_D(QOpenGLTexture);
3296 if (d->create())
3297 d->allocateStorage(pixelFormat, pixelType);
3298}
3299
3310{
3311 Q_D(const QOpenGLTexture);
3312 return d->storageAllocated;
3313}
3314
3348 TextureFormat viewFormat,
3349 int minimumMipmapLevel, int maximumMipmapLevel,
3350 int minimumLayer, int maximumLayer) const
3351{
3352 Q_D(const QOpenGLTexture);
3353 if (!isStorageAllocated()) {
3354 qWarning("Cannot set create a texture view of a texture that does not have storage allocated.");
3355 return nullptr;
3356 }
3357 Q_ASSERT(maximumMipmapLevel >= minimumMipmapLevel);
3358 Q_ASSERT(maximumLayer >= minimumLayer);
3359 return d->createTextureView(target, viewFormat,
3360 minimumMipmapLevel, maximumMipmapLevel,
3361 minimumLayer, maximumLayer);
3362}
3363
3371{
3372 Q_D(const QOpenGLTexture);
3373 Q_ASSERT(d->textureId);
3374 return d->textureView;
3375}
3376
3393void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace,
3394 PixelFormat sourceFormat, PixelType sourceType,
3395 const void *data, const QOpenGLPixelTransferOptions * const options)
3396{
3397 Q_D(QOpenGLTexture);
3398 Q_ASSERT(d->textureId);
3399 if (!isStorageAllocated()) {
3400 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3401 "To do so call allocateStorage() before this function");
3402 return;
3403 }
3404 d->setData(mipLevel, layer, 1, cubeFace, sourceFormat, sourceType, data, options);
3405}
3406
3414void QOpenGLTexture::setData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions * const options)
3415{
3416 Q_D(QOpenGLTexture);
3417 Q_ASSERT(d->textureId);
3418 if (!isStorageAllocated()) {
3419 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3420 "To do so call allocateStorage() before this function");
3421 return;
3422 }
3423 d->setData(mipLevel, layer, layerCount, cubeFace, sourceFormat, sourceType, data, options);
3424}
3425
3430void QOpenGLTexture::setData(int mipLevel, int layer,
3431 PixelFormat sourceFormat, PixelType sourceType,
3432 const void *data, const QOpenGLPixelTransferOptions * const options)
3433{
3434 Q_D(QOpenGLTexture);
3435 Q_ASSERT(d->textureId);
3436 d->setData(mipLevel, layer, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
3437}
3438
3443void QOpenGLTexture::setData(int mipLevel,
3444 PixelFormat sourceFormat, PixelType sourceType,
3445 const void *data, const QOpenGLPixelTransferOptions * const options)
3446{
3447 Q_D(QOpenGLTexture);
3448 Q_ASSERT(d->textureId);
3449 d->setData(mipLevel, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
3450}
3451
3456void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType,
3457 const void *data, const QOpenGLPixelTransferOptions * const options)
3458{
3459 Q_D(QOpenGLTexture);
3460 Q_ASSERT(d->textureId);
3461 d->setData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
3462}
3463
3477void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3478 int width, int height, int depth,
3479 PixelFormat sourceFormat, PixelType sourceType,
3480 const void *data, const QOpenGLPixelTransferOptions * const options)
3481{
3482 Q_D(QOpenGLTexture);
3483 Q_ASSERT(d->textureId);
3484 d->setData(xOffset, yOffset, zOffset,
3485 width, height, depth,
3486 0, 0, 1,
3488 sourceType, data, options);
3489}
3490
3505void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3506 int width, int height, int depth,
3507 int mipLevel,
3508 PixelFormat sourceFormat, PixelType sourceType,
3509 const void *data, const QOpenGLPixelTransferOptions * const options)
3510{
3511 Q_D(QOpenGLTexture);
3512 Q_ASSERT(d->textureId);
3513 d->setData(xOffset, yOffset, zOffset,
3514 width, height, depth,
3515 mipLevel, 0, 1,
3517 sourceType, data, options);
3518}
3519
3534void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3535 int width, int height, int depth,
3536 int mipLevel, int layer,
3537 PixelFormat sourceFormat, PixelType sourceType,
3538 const void *data, const QOpenGLPixelTransferOptions * const options)
3539{
3540 Q_D(QOpenGLTexture);
3541 Q_ASSERT(d->textureId);
3542 d->setData(xOffset, yOffset, zOffset,
3543 width, height, depth,
3544 mipLevel, layer, 1,
3546 sourceType, data, options);
3547}
3548
3564void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3565 int width, int height, int depth,
3566 int mipLevel, int layer,
3568 PixelFormat sourceFormat, PixelType sourceType,
3569 const void *data, const QOpenGLPixelTransferOptions * const options)
3570{
3571 Q_D(QOpenGLTexture);
3572 Q_ASSERT(d->textureId);
3573 d->setData(xOffset, yOffset, zOffset,
3574 width, height, depth,
3575 mipLevel, layer, 1,
3576 face, sourceFormat,
3577 sourceType, data, options);
3578}
3579
3595void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
3596 int width, int height, int depth,
3597 int mipLevel, int layer,
3598 CubeMapFace face, int layerCount,
3599 PixelFormat sourceFormat, PixelType sourceType,
3600 const void *data, const QOpenGLPixelTransferOptions * const options)
3601{
3602 Q_D(QOpenGLTexture);
3603 Q_ASSERT(d->textureId);
3604 d->setData(xOffset, yOffset, zOffset,
3605 width, height, depth,
3606 mipLevel, layer, layerCount,
3607 face, sourceFormat,
3608 sourceType, data, options);
3609}
3610
3622{
3624 if (!context) {
3625 qWarning("QOpenGLTexture::setData() requires a valid current context");
3626 return;
3627 }
3628
3629 if (image.isNull()) {
3630 qWarning("QOpenGLTexture::setData() tried to set a null image");
3631 return;
3632 }
3633
3634 QImage glImage = image.convertToFormat(QImage::Format_RGBA8888);
3635 if (glImage.isNull()) {
3636 qWarning("QOpenGLTexture::setData() failed to convert image");
3637 return;
3638 }
3639
3640 if (context->isOpenGLES() && context->format().majorVersion() < 3)
3642 else
3644
3645 setSize(image.width(), image.height());
3646 setMipLevels(genMipMaps == GenerateMipMaps ? maximumMipLevels() : 1);
3648
3649 // Upload pixel data and generate mipmaps
3650 QOpenGLPixelTransferOptions uploadOptions;
3651 uploadOptions.setAlignment(1);
3652 setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, glImage.constBits(), &uploadOptions);
3653}
3654
3665void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
3666 int dataSize, const void *data,
3667 const QOpenGLPixelTransferOptions * const options)
3668{
3669 Q_D(QOpenGLTexture);
3670 Q_ASSERT(d->textureId);
3671 if (!isStorageAllocated()) {
3672 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3673 "To do so call allocateStorage() before this function");
3674 return;
3675 }
3676 d->setCompressedData(mipLevel, layer, 1, cubeFace, dataSize, data, options);
3677}
3678
3686void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, int dataSize, const void *data, const QOpenGLPixelTransferOptions * const options)
3687{
3688 Q_D(QOpenGLTexture);
3689 Q_ASSERT(d->textureId);
3690 if (!isStorageAllocated()) {
3691 qWarning("Cannot set data on a texture that does not have storage allocated.\n"
3692 "To do so call allocateStorage() before this function");
3693 return;
3694 }
3695 d->setCompressedData(mipLevel, layer, layerCount, cubeFace, dataSize, data, options);
3696}
3697
3701void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int dataSize, const void *data,
3702 const QOpenGLPixelTransferOptions * const options)
3703{
3704 Q_D(QOpenGLTexture);
3705 Q_ASSERT(d->textureId);
3706 d->setCompressedData(mipLevel, layer, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
3707}
3708
3712void QOpenGLTexture::setCompressedData(int mipLevel, int dataSize, const void *data,
3713 const QOpenGLPixelTransferOptions * const options)
3714{
3715 Q_D(QOpenGLTexture);
3716 Q_ASSERT(d->textureId);
3717 d->setCompressedData(mipLevel, 0, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
3718}
3719
3724 const QOpenGLPixelTransferOptions * const options)
3725{
3726 Q_D(QOpenGLTexture);
3727 Q_ASSERT(d->textureId);
3728 d->setCompressedData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
3729}
3730
3736{
3738 if (!ctx) {
3739 qWarning("QOpenGLTexture::hasFeature() requires a valid current context");
3740 return false;
3741 }
3742
3743 QSurfaceFormat f = ctx->format();
3744
3745 bool supported = false;
3746
3747#if !QT_CONFIG(opengles2)
3748 if (!ctx->isOpenGLES()) {
3749 switch (feature) {
3751 supported = f.version() >= qMakePair(4, 3)
3752 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage_multisample"));
3753 break;
3754
3755 case TextureBuffer:
3756 supported = f.version() >= qMakePair(3, 0)
3757 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_buffer_object"));
3758 break;
3759
3760 case StencilTexturing:
3761 supported = f.version() >= qMakePair(4, 3)
3762 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_stencil_texturing"));
3763 break;
3764
3765 case ImmutableStorage:
3766 supported = f.version() >= qMakePair(4, 2)
3767 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage"))
3768 || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_storage"));
3769 break;
3770
3772 supported = f.version() >= qMakePair(4, 0)
3773 || ctx->hasExtension(QByteArrayLiteral("ARB_texture_cube_map_array"));
3774 break;
3775
3776 case Swizzle:
3777 supported = f.version() >= qMakePair(3, 3)
3778 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_swizzle"));
3779 break;
3780
3781 case TextureMultisample:
3782 supported = f.version() >= qMakePair(3, 2)
3783 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_multisample"));
3784 break;
3785
3786 case TextureArrays:
3787 supported = f.version() >= qMakePair(3, 0)
3788 || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_array"));
3789 break;
3790
3791 case TextureRectangle:
3792 supported = f.version() >= qMakePair(2, 1)
3793 || ctx->hasExtension(QByteArrayLiteral("ARB_texture_rectangle"));
3794 break;
3795
3796 case Texture3D:
3797 supported = f.version() >= qMakePair(1, 3);
3798 break;
3799
3801 supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
3802 break;
3803
3804 case NPOTTextures:
3805 case NPOTTextureRepeat:
3806 supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
3807 break;
3808
3809 case Texture1D:
3810 supported = f.version() >= qMakePair(1, 1);
3811 break;
3812
3814 // GL 1.4 and GL_ARB_shadow alone support only LEQUAL and GEQUAL;
3815 // since we're talking about history anyhow avoid to be extra pedantic
3816 // in the feature set, and simply claim supported if we have the full set of operators
3817 // (which has been added into 1.5 / GL_EXT_shadow_funcs).
3818 supported = f.version() >= qMakePair(1, 5)
3819 || (ctx->hasExtension(QByteArrayLiteral("GL_ARB_shadow"))
3820 && ctx->hasExtension(QByteArrayLiteral("GL_EXT_shadow_funcs")));
3821 break;
3822
3823 case TextureMipMapLevel:
3824 supported = f.version() >= qMakePair(1, 2);
3825 break;
3826
3827 case MaxFeatureFlag:
3828 break;
3829 }
3830 }
3831
3832 if (ctx->isOpenGLES())
3833#endif
3834 {
3835 const char *renderer = reinterpret_cast<const char *>(ctx->functions()->glGetString(GL_RENDERER));
3836 switch (feature) {
3837 case ImmutableStorage:
3838 supported = (f.version() >= qMakePair(3, 0) || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_storage")))
3839 && !(renderer && strstr(renderer, "Mali")); // do not use on Mali: QTBUG-45106
3840 break;
3841
3843 supported = f.version() >= qMakePair(3, 1);
3844 break;
3845
3846 case TextureRectangle:
3847 break;
3848
3849 case TextureArrays:
3850 supported = f.version() >= qMakePair(3, 0);
3851 break;
3852
3853 case Texture3D:
3854 supported = f.version() >= qMakePair(3, 0)
3855 || ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
3856 break;
3857
3858 case TextureMultisample:
3859 supported = f.version() >= qMakePair(3, 1);
3860 break;
3861
3862 case TextureBuffer:
3863 break;
3864
3866 break;
3867
3868 case Swizzle:
3869 supported = f.version() >= qMakePair(3, 0);
3870 break;
3871
3872 case StencilTexturing:
3873 break;
3874
3876 supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
3877 break;
3878
3879 case NPOTTextures:
3880 case NPOTTextureRepeat:
3881 supported = f.version() >= qMakePair(3,0)
3882 || ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"))
3883 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
3884 break;
3885
3886 case Texture1D:
3887 break;
3888
3890 supported = f.version() >= qMakePair(3, 0)
3891 || ctx->hasExtension(QByteArrayLiteral("GL_EXT_shadow_samplers"));
3892 break;
3893
3894 case TextureMipMapLevel:
3895 supported = f.version() >= qMakePair(3, 0);
3896 break;
3897
3898 case MaxFeatureFlag:
3899 break;
3900 }
3901 }
3902
3903 return supported;
3904}
3905
3913{
3914 Q_D(QOpenGLTexture);
3915 d->create();
3916 if (!d->features.testFlag(TextureMipMapLevel)) {
3917 qWarning("QOpenGLTexture::setMipBaseLevel: requires OpenGL >= 1.2 or OpenGL ES >= 3.0");
3918 return;
3919 }
3920 Q_ASSERT(d->textureId);
3921 Q_ASSERT(d->texFuncs);
3922 Q_ASSERT(baseLevel <= d->maxLevel);
3923 d->baseLevel = baseLevel;
3924 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
3925}
3926
3934{
3935 Q_D(const QOpenGLTexture);
3936 return d->baseLevel;
3937}
3938
3946{
3947 Q_D(QOpenGLTexture);
3948 d->create();
3949 if (!d->features.testFlag(TextureMipMapLevel)) {
3950 qWarning("QOpenGLTexture::setMipMaxLevel: requires OpenGL >= 1.2 or OpenGL ES >= 3.0");
3951 return;
3952 }
3953 Q_ASSERT(d->textureId);
3954 Q_ASSERT(d->texFuncs);
3955 Q_ASSERT(d->baseLevel <= maxLevel);
3956 d->maxLevel = maxLevel;
3957 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
3958}
3959
3966{
3967 Q_D(const QOpenGLTexture);
3968 return d->maxLevel;
3969}
3970
3978void QOpenGLTexture::setMipLevelRange(int baseLevel, int maxLevel)
3979{
3980 Q_D(QOpenGLTexture);
3981 d->create();
3982 if (!d->features.testFlag(TextureMipMapLevel)) {
3983 qWarning("QOpenGLTexture::setMipLevelRange: requires OpenGL >= 1.2 or OpenGL ES >= 3.0");
3984 return;
3985 }
3986 Q_ASSERT(d->textureId);
3987 Q_ASSERT(d->texFuncs);
3988 Q_ASSERT(baseLevel <= maxLevel);
3989 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
3990 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
3991}
3992
3998QPair<int, int> QOpenGLTexture::mipLevelRange() const
3999{
4000 Q_D(const QOpenGLTexture);
4001 return qMakePair(d->baseLevel, d->maxLevel);
4002}
4003
4015{
4016 Q_D(QOpenGLTexture);
4017 d->autoGenerateMipMaps = enabled;
4018}
4019
4026{
4027 Q_D(const QOpenGLTexture);
4028 return d->autoGenerateMipMaps;
4029}
4030
4042{
4043 Q_D(QOpenGLTexture);
4044 Q_ASSERT(d->texFuncs);
4045 Q_ASSERT(d->textureId);
4046 if (isCompressedFormat(d->format)) {
4048 if (ctx->isOpenGLES())
4049 return;
4050 }
4051 d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget);
4052}
4053
4066void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel)
4067{
4068 Q_D(QOpenGLTexture);
4069 Q_ASSERT(d->texFuncs);
4070 Q_ASSERT(d->textureId);
4071 if (isCompressedFormat(d->format)) {
4073 if (ctx->isOpenGLES())
4074 return;
4075 }
4076 int oldBaseLevel;
4077 if (resetBaseLevel)
4078 oldBaseLevel = mipBaseLevel();
4079 setMipBaseLevel(baseLevel);
4080 d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget);
4081 if (resetBaseLevel)
4082 setMipBaseLevel(oldBaseLevel);
4083}
4084
4098{
4099#if !defined(Q_OS_MAC) && !QT_CONFIG(opengles2)
4100 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4101 Q_D(QOpenGLTexture);
4102 d->create();
4103 Q_ASSERT(d->texFuncs);
4104 Q_ASSERT(d->textureId);
4105 if (!d->features.testFlag(Swizzle)) {
4106 qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
4107 return;
4108 }
4109 d->swizzleMask[component - SwizzleRed] = value;
4110 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, component, value);
4111 return;
4112 }
4113#else
4115 Q_UNUSED(value);
4116#endif
4117 qWarning("QOpenGLTexture: Texture swizzling is not supported");
4118}
4119
4127{
4128#if !defined(Q_OS_MAC) && !QT_CONFIG(opengles2)
4129 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4130 Q_D(QOpenGLTexture);
4131 d->create();
4132 Q_ASSERT(d->texFuncs);
4133 Q_ASSERT(d->textureId);
4134 if (!d->features.testFlag(Swizzle)) {
4135 qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
4136 return;
4137 }
4138 GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
4139 d->swizzleMask[0] = r;
4140 d->swizzleMask[1] = g;
4141 d->swizzleMask[2] = b;
4142 d->swizzleMask[3] = a;
4143 d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
4144 return;
4145 }
4146#else
4147 Q_UNUSED(r);
4148 Q_UNUSED(g);
4149 Q_UNUSED(b);
4150 Q_UNUSED(a);
4151#endif
4152 qWarning("QOpenGLTexture: Texture swizzling is not supported");
4153}
4154
4163
4187{
4188#if !defined(Q_OS_MAC) && !QT_CONFIG(opengles2)
4189 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4190 Q_D(QOpenGLTexture);
4191 d->create();
4192 Q_ASSERT(d->texFuncs);
4193 Q_ASSERT(d->textureId);
4194 if (!d->features.testFlag(StencilTexturing)) {
4195 qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3 or GL_ARB_stencil_texturing");
4196 return;
4197 }
4198 d->depthStencilMode = mode;
4199 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, mode);
4200 return;
4201 }
4202#else
4203 Q_UNUSED(mode);
4204#endif
4205 qWarning("QOpenGLTexture: DepthStencil Mode is not supported");
4206}
4207
4215{
4216 Q_D(const QOpenGLTexture);
4217 return d->depthStencilMode;
4218}
4219
4247{
4248 Q_D(QOpenGLTexture);
4249 d->create();
4250 if (!d->features.testFlag(TextureComparisonOperators)) {
4251 qWarning("QOpenGLTexture::setComparisonFunction: requires OpenGL >= 1.5 or OpenGL ES >= 3.0");
4252 return;
4253 }
4254 d->comparisonFunction = function;
4255 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_COMPARE_FUNC, function);
4256}
4257
4267{
4268 Q_D(const QOpenGLTexture);
4269 return d->comparisonFunction;
4270}
4271
4290{
4291 Q_D(QOpenGLTexture);
4292 d->create();
4293 if (!d->features.testFlag(TextureComparisonOperators)) {
4294 qWarning("QOpenGLTexture::setComparisonMode: requires OpenGL >= 1.5 or OpenGL ES >= 3.0");
4295 return;
4296 }
4297 d->comparisonMode = mode;
4298 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_COMPARE_MODE, mode);
4299}
4300
4310{
4311 Q_D(const QOpenGLTexture);
4312 return d->comparisonMode;
4313}
4314
4321{
4322 Q_D(QOpenGLTexture);
4323 d->create();
4324 Q_ASSERT(d->texFuncs);
4325 Q_ASSERT(d->textureId);
4326 d->minFilter = filter;
4327 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, filter);
4328}
4329
4336{
4337 Q_D(const QOpenGLTexture);
4338 return d->minFilter;
4339}
4340
4347{
4348 Q_D(QOpenGLTexture);
4349 d->create();
4350 Q_ASSERT(d->texFuncs);
4351 Q_ASSERT(d->textureId);
4352 d->magFilter = filter;
4353 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, filter);
4354}
4355
4362{
4363 Q_D(const QOpenGLTexture);
4364 return d->magFilter;
4365}
4366
4374 QOpenGLTexture::Filter magnificationFilter)
4375{
4376 Q_D(QOpenGLTexture);
4377 d->create();
4378 Q_ASSERT(d->texFuncs);
4379 Q_ASSERT(d->textureId);
4380 d->minFilter = minificationFilter;
4381 d->magFilter = magnificationFilter;
4382 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, minificationFilter);
4383 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, magnificationFilter);
4384}
4385
4391QPair<QOpenGLTexture::Filter, QOpenGLTexture::Filter> QOpenGLTexture::minMagFilters() const
4392{
4393 Q_D(const QOpenGLTexture);
4394 return QPair<QOpenGLTexture::Filter, QOpenGLTexture::Filter>(d->minFilter, d->magFilter);
4395}
4396
4404{
4405 Q_D(QOpenGLTexture);
4406 d->create();
4407 Q_ASSERT(d->texFuncs);
4408 Q_ASSERT(d->textureId);
4409 if (!d->features.testFlag(AnisotropicFiltering)) {
4410 qWarning("QOpenGLTexture::setMaximumAnisotropy() requires GL_EXT_texture_filter_anisotropic");
4411 return;
4412 }
4413 d->maxAnisotropy = anisotropy;
4414 d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
4415}
4416
4424{
4425 Q_D(const QOpenGLTexture);
4426 return d->maxAnisotropy;
4427}
4428
4435{
4436 Q_D(QOpenGLTexture);
4437 d->create();
4438 Q_ASSERT(d->texFuncs);
4439 Q_ASSERT(d->textureId);
4440 d->setWrapMode(mode);
4441}
4442
4448{
4449 Q_D(QOpenGLTexture);
4450 d->create();
4451 Q_ASSERT(d->texFuncs);
4452 Q_ASSERT(d->textureId);
4453 d->setWrapMode(direction, mode);
4454}
4455
4466
4474{
4475 setBorderColor(static_cast<float>(color.redF()), static_cast<float>(color.greenF()),
4476 static_cast<float>(color.blueF()), static_cast<float>(color.alphaF()));
4477}
4478
4484void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
4485{
4486#if !QT_CONFIG(opengles2)
4487 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4488 Q_D(QOpenGLTexture);
4489 d->create();
4490 Q_ASSERT(d->texFuncs);
4491 Q_ASSERT(d->textureId);
4492 float values[4];
4493 values[0] = r;
4494 values[1] = g;
4495 values[2] = b;
4496 values[3] = a;
4497 d->borderColor.clear();
4498 for (int i = 0; i < 4; ++i)
4499 d->borderColor.append(QVariant(values[i]));
4500 d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
4501 return;
4502 }
4503#else
4504 Q_UNUSED(r);
4505 Q_UNUSED(g);
4506 Q_UNUSED(b);
4507 Q_UNUSED(a);
4508#endif
4509 qWarning("QOpenGLTexture: Border color is not supported");
4510}
4511
4517void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
4518{
4519#if !QT_CONFIG(opengles2)
4520 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4521 Q_D(QOpenGLTexture);
4522 d->create();
4523 Q_ASSERT(d->texFuncs);
4524 Q_ASSERT(d->textureId);
4525 int values[4];
4526 values[0] = r;
4527 values[1] = g;
4528 values[2] = b;
4529 values[3] = a;
4530 d->borderColor.clear();
4531 for (int i = 0; i < 4; ++i)
4532 d->borderColor.append(QVariant(values[i]));
4533 d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
4534 return;
4535 }
4536#else
4537 Q_UNUSED(r);
4538 Q_UNUSED(g);
4539 Q_UNUSED(b);
4540 Q_UNUSED(a);
4541#endif
4542 qWarning("QOpenGLTexture: Border color is not supported");
4543
4544 // TODO Handle case of using glTextureParameterIiv() based on format
4545}
4546
4553{
4554#if !QT_CONFIG(opengles2)
4555 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4556 Q_D(QOpenGLTexture);
4557 d->create();
4558 Q_ASSERT(d->texFuncs);
4559 Q_ASSERT(d->textureId);
4560 int values[4];
4561 values[0] = int(r);
4562 values[1] = int(g);
4563 values[2] = int(b);
4564 values[3] = int(a);
4565 d->borderColor.clear();
4566 for (int i = 0; i < 4; ++i)
4567 d->borderColor.append(QVariant(values[i]));
4568 d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
4569 return;
4570 }
4571#else
4572 Q_UNUSED(r);
4573 Q_UNUSED(g);
4574 Q_UNUSED(b);
4575 Q_UNUSED(a);
4576#endif
4577 qWarning("QOpenGLTexture: Border color is not supported");
4578
4579 // TODO Handle case of using glTextureParameterIuiv() based on format
4580}
4581
4588{
4589 Q_D(const QOpenGLTexture);
4590 QColor c(0.0f, 0.0f, 0.0f, 0.0f);
4591 if (!d->borderColor.isEmpty()) {
4592 c.setRedF(d->borderColor.at(0).toFloat());
4593 c.setGreenF(d->borderColor.at(1).toFloat());
4594 c.setBlueF(d->borderColor.at(2).toFloat());
4595 c.setAlphaF(d->borderColor.at(3).toFloat());
4596 }
4597 return c;
4598}
4599
4607{
4608 Q_D(const QOpenGLTexture);
4610 if (d->borderColor.isEmpty()) {
4611 for (int i = 0; i < 4; ++i)
4612 border[i] = 0.0f;
4613 } else {
4614 for (int i = 0; i < 4; ++i)
4615 border[i] = d->borderColor.at(i).toFloat();
4616 }
4617}
4618
4626{
4627 Q_D(const QOpenGLTexture);
4629 if (d->borderColor.isEmpty()) {
4630 for (int i = 0; i < 4; ++i)
4631 border[i] = 0;
4632 } else {
4633 for (int i = 0; i < 4; ++i)
4634 border[i] = d->borderColor.at(i).toInt();
4635 }
4636}
4637
4644void QOpenGLTexture::borderColor(unsigned int *border) const
4645{
4646 Q_D(const QOpenGLTexture);
4648 if (d->borderColor.isEmpty()) {
4649 for (int i = 0; i < 4; ++i)
4650 border[i] = 0;
4651 } else {
4652 for (int i = 0; i < 4; ++i)
4653 border[i] = d->borderColor.at(i).toUInt();
4654 }
4655}
4656
4665{
4666#if !QT_CONFIG(opengles2)
4667 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4668 Q_D(QOpenGLTexture);
4669 d->create();
4670 Q_ASSERT(d->texFuncs);
4671 Q_ASSERT(d->textureId);
4672 Q_ASSERT(value < d->maxLevelOfDetail);
4673 d->minLevelOfDetail = value;
4674 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, value);
4675 return;
4676 }
4677#else
4678 Q_UNUSED(value);
4679#endif
4680 qWarning("QOpenGLTexture: Detail level is not supported");
4681}
4682
4689{
4690 Q_D(const QOpenGLTexture);
4691 return d->minLevelOfDetail;
4692}
4693
4702{
4703#if !QT_CONFIG(opengles2)
4704 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4705 Q_D(QOpenGLTexture);
4706 d->create();
4707 Q_ASSERT(d->texFuncs);
4708 Q_ASSERT(d->textureId);
4709 Q_ASSERT(value > d->minLevelOfDetail);
4710 d->maxLevelOfDetail = value;
4711 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, value);
4712 return;
4713 }
4714#else
4715 Q_UNUSED(value);
4716#endif
4717 qWarning("QOpenGLTexture: Detail level is not supported");
4718}
4719
4726{
4727 Q_D(const QOpenGLTexture);
4728 return d->maxLevelOfDetail;
4729}
4730
4738{
4739#if !QT_CONFIG(opengles2)
4740 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4741 Q_D(QOpenGLTexture);
4742 d->create();
4743 Q_ASSERT(d->texFuncs);
4744 Q_ASSERT(d->textureId);
4745 Q_ASSERT(min < max);
4746 d->minLevelOfDetail = min;
4747 d->maxLevelOfDetail = max;
4748 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, min);
4749 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, max);
4750 return;
4751 }
4752#else
4753 Q_UNUSED(min);
4754 Q_UNUSED(max);
4755#endif
4756 qWarning("QOpenGLTexture: Detail level is not supported");
4757}
4758
4764QPair<float, float> QOpenGLTexture::levelOfDetailRange() const
4765{
4766 Q_D(const QOpenGLTexture);
4767 return qMakePair(d->minLevelOfDetail, d->maxLevelOfDetail);
4768}
4769
4780{
4781#if !QT_CONFIG(opengles2)
4782 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
4783 Q_D(QOpenGLTexture);
4784 d->create();
4785 Q_ASSERT(d->texFuncs);
4786 Q_ASSERT(d->textureId);
4787 d->levelOfDetailBias = bias;
4788 d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_LOD_BIAS, bias);
4789 return;
4790 }
4791#else
4792 Q_UNUSED(bias);
4793#endif
4794 qWarning("QOpenGLTexture: Detail level is not supported");
4795}
4796
4803{
4804 Q_D(const QOpenGLTexture);
4805 return d->levelOfDetailBias;
4806}
4807
4808#ifndef QT_NO_DEBUG_STREAM
4810{
4811 QDebugStateSaver saver(debug);
4812 debug.nospace();
4813 debug << "QOpenGLTexture(";
4814 if (t) {
4815 const QOpenGLTexturePrivate *d = t->d_ptr.data();
4816 debug << d->target << ", bindingTarget=" << d->bindingTarget
4817 << ", size=[" << d->dimensions[0]
4818 << ", " << d->dimensions[1];
4819 if (d->target == QOpenGLTexture::Target3D)
4820 debug << ", " << d->dimensions[2];
4821 debug << "], format=" << d->format << ", formatClass=" << d->formatClass;
4822 if (t->isCreated())
4823 debug << ", textureId=" << d->textureId;
4824 if (t->isBound())
4825 debug << ", [bound]";
4826 if (t->isTextureView())
4827 debug << ", [view]";
4828 if (d->fixedSamplePositions)
4829 debug << ", [fixedSamplePositions]";
4830 debug << ", mipLevels=" << d->requestedMipLevels << ", layers=" << d->layers
4831 << ", faces=" << d->faces << ", samples=" << d->samples
4832 << ", depthStencilMode=" << d->depthStencilMode << ", comparisonFunction="
4833 << d->comparisonFunction << ", comparisonMode=" << d->comparisonMode
4834 << ", features=" << d->features << ", minificationFilter=" << d->minFilter
4835 << ", magnificationFilter=" << d->magFilter << ", wrapMode=" << d->wrapModes[0];
4836 } else {
4837 debug << '0';
4838 }
4839 debug << ')';
4840 return debug;
4841}
4842#endif // QT_NO_DEBUG_STREAM
4843
4845
4846#include "moc_qopengltexture.cpp"
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtCore
\inmodule QtCore
\inmodule QtGui
Definition qimage.h:37
@ Format_RGBA8888
Definition qimage.h:59
QScopedPointer< QObjectData > d_ptr
Definition qobject.h:373
\inmodule QtGui
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
static bool areSharing(QOpenGLContext *first, QOpenGLContext *second)
Returns true if the first and second contexts are sharing OpenGL resources.
The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.
void glGenTextures(GLsizei n, GLuint *textures)
Convenience function that calls glGenTextures(n, textures).
void glBindTexture(GLenum target, GLuint texture)
Convenience function that calls glBindTexture(target, texture).
void glDeleteTextures(GLsizei n, const GLuint *textures)
Convenience function that calls glDeleteTextures(n, textures).
void glGetIntegerv(GLenum pname, GLint *params)
Convenience function that calls glGetIntegerv(pname, params).
void setAlignment(int alignment)
Sets the alignment requirements for each pixel row.
void glTextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height)
void glTextureView(GLuint texture, GLenum target, GLuint origTexture, GLenum internalFormat, GLuint minLevel, GLuint numLevels, GLuint minLayer, GLuint numLayers)
void glCompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits, const QOpenGLPixelTransferOptions *const options=nullptr)
void glTextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
void glTextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
void glActiveTexture(GLenum texture)
void glTextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width)
void glTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
void glTextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
void glTextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth)
void glTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
void glCompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits, const QOpenGLPixelTransferOptions *const options=nullptr)
void glCompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits, const QOpenGLPixelTransferOptions *const options=nullptr)
void glTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, const QOpenGLPixelTransferOptions *const options=nullptr)
void glCompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits, const QOpenGLPixelTransferOptions *const options=nullptr)
void glTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
void glTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels, const QOpenGLPixelTransferOptions *const options=nullptr)
void glCompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits, const QOpenGLPixelTransferOptions *const options=nullptr)
void glTextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
void glCompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits, const QOpenGLPixelTransferOptions *const options=nullptr)
void glTextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
void glTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels, const QOpenGLPixelTransferOptions *const options=nullptr)
QOpenGLTexture::BindingTarget bindingTarget
QOpenGLTexture::SwizzleValue swizzleMask[4]
QOpenGLTexture::WrapMode wrapMode(QOpenGLTexture::CoordinateDirection direction) const
void allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
QOpenGLTexture::Filter minFilter
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
QOpenGLTexture::Filter magFilter
QOpenGLTexturePrivate(QOpenGLTexture::Target textureTarget, QOpenGLTexture *qq)
QOpenGLTexture::WrapMode wrapModes[3]
QOpenGLTexture::Target target
void allocateMutableStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
void setWrapMode(QOpenGLTexture::WrapMode mode)
int maximumMipLevelCount() const
QOpenGLTexture::DepthStencilMode depthStencilMode
QOpenGLTexture::Features features
QOpenGLTexture * createTextureView(QOpenGLTexture::Target target, QOpenGLTexture::TextureFormat viewFormat, int minimumMipmapLevel, int maximumMipmapLevel, int minimumLayer, int maximumLayer) const
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
QOpenGLTexture::TextureFormat format
QOpenGLTexture::TextureFormatClass formatClass
\inmodule QtGui
int width() const
Returns the width of a 1D, 2D or 3D texture.
TextureFormat
This enum defines the possible texture formats.
void release()
Unbinds this texture from the currently active texture unit.
int depth() const
Returns the depth of a 3D texture.
bool isBound() const
Returns true if this texture is bound to the corresponding target of the currently active texture uni...
void setSwizzleMask(SwizzleComponent component, SwizzleValue value)
GLSL shaders are able to reorder the components of the vec4 returned by texture functions.
void setMipLevels(int levels)
For texture targets that support mipmaps, this function sets the requested number of mipmap levels to...
static bool hasFeature(Feature feature)
Returns true if your OpenGL implementation and version supports the texture feature feature.
void setMaximumLevelOfDetail(float value)
Sets the maximum level of detail to value.
float maximumLevelOfDetail() const
Returns the maximum level of detail parameter.
Filter
This enum defines the filtering parameters for a QOpenGLTexture object.
WrapMode wrapMode(CoordinateDirection direction) const
Returns the wrap mode for the texture dimension direction.
bool isAutoMipMapGenerationEnabled() const
Returns whether auto mipmap generation is enabled for this texture object.
void setLevelofDetailBias(float bias)
Sets the level of detail bias to bias.
void setFormat(TextureFormat format)
Sets the format of this texture object to format.
void setWrapMode(WrapMode mode)
Sets the wrap (or repeat mode) for all texture dimensions to mode.
TextureFormat format() const
Returns the format of this texture object.
MipMapGeneration
This enum defines the options to control mipmap generation.
int faces() const
Returns the number of faces for this texture.
void setMipMaxLevel(int maxLevel)
Sets the maximum mipmap level used for all texture lookups with this texture to maxLevel.
int mipBaseLevel() const
Returns the mipmap base level used for all texture lookups with this texture.
WrapMode
This enum defines the possible texture coordinate wrapping modes.
void setMipLevelRange(int baseLevel, int maxLevel)
Sets the range of mipmap levels that can be used for texture lookups with this texture to range from ...
void setMinMagFilters(Filter minificationFilter, Filter magnificationFilter)
Sets the minification filter to minificationFilter and the magnification filter to magnificationFilte...
DepthStencilMode depthStencilMode() const
Returns the depth stencil mode for textures using a combined depth/stencil format.
int samples() const
Returns the number of multisample sample points for this texture.
ComparisonMode comparisonMode() const
void setComparisonMode(ComparisonMode mode)
bool isStorageAllocated() const
Returns true if server-side storage for this texture as been allocated.
QPair< Filter, Filter > minMagFilters() const
Returns the current minification and magnification filters.
void setMinificationFilter(Filter filter)
Sets the filter used for minification to filter.
bool isCreated() const
Returns true if the underlying OpenGL texture object has been created.
SwizzleValue
This enum defines the possible mask values for texture swizzling.
QPair< int, int > mipLevelRange() const
Returns the range of mipmap levels that can be used for texture lookups with this texture.
void setAutoMipMapGenerationEnabled(bool enabled)
If enabled is true, enables automatic mipmap generation for this texture object to occur whenever the...
void setMipBaseLevel(int baseLevel)
Sets the base mipmap level used for all texture lookups with this texture to baseLevel.
QOpenGLTexture(Target target)
Creates a QOpenGLTexture object that can later be bound to target.
void destroy()
Destroys the underlying OpenGL texture object.
void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace, int dataSize, const void *data, const QOpenGLPixelTransferOptions *const options=nullptr)
Uploads compressed pixel data to mipLevel, array layer, and cubeFace.
float levelofDetailBias() const
Returns the level of detail bias parameter.
QColor borderColor() const
Returns the borderColor of this texture.
void setLevelOfDetailRange(float min, float max)
Sets the minimum level of detail parameters to min and the maximum level to max.
void setComparisonFunction(ComparisonFunction function)
bool isFixedSamplePositions() const
Returns whether this texture uses a fixed pattern of multisample samples.
void setMaximumAnisotropy(float anisotropy)
If your OpenGL implementation supports the GL_EXT_texture_filter_anisotropic extension this function ...
CubeMapFace
This enum defines the possible CubeMap faces.
BindingTarget
This enum defines the possible binding targets of texture units.
@ BindingTarget2DMultisampleArray
Filter magnificationFilter() const
Returns the magnification filter.
Filter minificationFilter() const
Returns the minification filter.
void setMinimumLevelOfDetail(float value)
Sets the minimum level of detail to value.
PixelType
This enum defines the possible pixel data types for a pixel transfer operation.
void setFixedSamplePositions(bool fixed)
Sets whether the sample positions and number of samples used with a multisample capable texture targe...
Target
This enum defines the texture target of a QOpenGLTexture object.
int height() const
Returns the height of a 2D or 3D texture.
bool create()
Creates the underlying OpenGL texture object.
void allocateStorage()
Allocates server-side storage for this texture object taking into account, the format,...
QPair< float, float > levelOfDetailRange() const
Returns the minimum and maximum level of detail parameters.
int mipLevels() const
Returns the number of mipmap levels for this texture.
void setLayers(int layers)
Sets the number of array layers to allocate storage for.
Target target() const
Returns the binding target of this texture.
static GLuint boundTextureId(BindingTarget target)
Returns the textureId of the texture that is bound to the target of the currently active texture unit...
void setMagnificationFilter(Filter filter)
Sets the magnification filter to filter.
float maximumAnisotropy() const
Returns the maximum level of anisotropy to be accounted for when performing texture lookups.
void bind()
Binds this texture to the currently active texture unit ready for rendering.
SwizzleValue swizzleMask(SwizzleComponent component) const
Returns the swizzle mask for texture component.
float minimumLevelOfDetail() const
Returns the minimum level of detail parameter.
PixelFormat
This enum defines the possible client-side pixel formats for a pixel transfer operation.
void setBorderColor(const QColor &color)
Sets the border color of the texture to color.
int mipMaxLevel() const
Returns the mipmap maximum level used for all texture lookups with this texture.
GLuint textureId() const
Returns the name of the underlying OpenGL texture object or 0 if it has not yet been created.
int maximumMipLevels() const
Returns the maximum number of mipmap levels that this texture can have given the current dimensions.
void setData(int mipLevel, int layer, CubeMapFace cubeFace, PixelFormat sourceFormat, PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions *const options=nullptr)
Uploads pixel data for this texture object mipLevel, array layer, and cubeFace.
void setDepthStencilMode(DepthStencilMode mode)
If using a texture that has a combined depth/stencil format this function sets which component of the...
void setSize(int width, int height=1, int depth=1)
Sets the dimensions of this texture object to width, height, and depth.
ComparisonFunction comparisonFunction() const
QOpenGLTexture * createTextureView(Target target, TextureFormat viewFormat, int minimumMipmapLevel, int maximumMipmapLevel, int minimumLayer, int maximumLayer) const
Attempts to create a texture view onto this texture.
SwizzleComponent
This enum defines the texture color components that can be assigned a swizzle mask.
Feature
This enum defines the OpenGL texture-related features that can be tested for.
TextureUnitReset
This enum defines options ot control texture unit activation.
int layers() const
Returns the number of array layers for this texture.
CoordinateDirection
This enum defines the possible texture coordinate directions.
void setSamples(int samples)
Sets the number of samples to allocate storage for when rendering to a multisample capable texture ta...
void generateMipMaps()
Generates mipmaps for this texture object from mipmap level 0.
bool isTextureView() const
Returns true if this texture object is actually a view onto another texture object.
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
QPair< int, int > version() const
Returns a QPair<int, int> representing the OpenGL version.
\inmodule QtCore
Definition qvariant.h:65
EGLContext ctx
static VulkanServerBufferGlFunctions * funcs
#define this
Definition dialogs.cpp:9
direction
Combined button and popup list for selecting options.
Definition image.cpp:4
static void * context
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
const EGLAttrib EGLOutputLayerEXT * layers
EGLOutputLayerEXT layer
#define qWarning
Definition qlogging.h:166
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
#define GL_TEXTURE_MAX_ANISOTROPY_EXT
GLenum GLsizei GLsizei GLint * values
[15]
GLboolean GLboolean GLboolean b
GLenum GLsizeiptr const void GLsizei faceIndex
typedef GLint(GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC)(GLuint program
GLint GLenum GLsizei GLsizei GLsizei depth
GLsizei samples
GLenum mode
GLenum GLuint GLint level
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLboolean r
[2]
GLenum GLsizei dataSize
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLenum GLsizei GLsizei GLsizei GLint border
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLenum face
GLfloat GLfloat f
GLsizei levels
GLint GLsizei width
GLuint color
[2]
GLenum target
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLboolean GLboolean g
GLint GLsizei GLsizei GLenum format
GLsizei GLenum internalFormat
#define GL_TEXTURE_COMPARE_FUNC
Definition qopenglext.h:338
GLboolean reset
#define GL_TEXTURE0
Definition qopenglext.h:129
#define GL_DEPTH_STENCIL_TEXTURE_MODE
#define GL_TEXTURE_WRAP_R
Definition qopenglext.h:87
const GLubyte * c
GLfloat bias
#define GL_TEXTURE_BASE_LEVEL
Definition qopenglext.h:103
#define GL_TEXTURE_LOD_BIAS
Definition qopenglext.h:333
#define GL_TEXTURE_MAX_LEVEL
Definition qopenglext.h:104
#define GL_ACTIVE_TEXTURE
Definition qopenglext.h:161
#define GL_TEXTURE_SWIZZLE_RGBA
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
#define GL_TEXTURE_MAX_LOD
Definition qopenglext.h:102
#define GL_TEXTURE_MIN_LOD
Definition qopenglext.h:101
#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)
QDebug operator<<(QDebug debug, const QOpenGLTexture *t)
QT_BEGIN_NAMESPACE constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
Definition qpair.h:19
static qreal component(const QPointF &point, unsigned int i)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define GLuint
#define Q_UNUSED(x)
unsigned int uint
Definition qtypes.h:34
#define enabled
QObject::connect nullptr
QQuickView * view
[0]
QSvgRenderer * renderer
[0]