| /**************************************************************************** |
| ** |
| ** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB). |
| ** Copyright (C) 2020 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtGui module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qopengltexture.h" |
| #include "qopengltexture_p.h" |
| #include "qopengltexturehelper_p.h" |
| #include "qopenglfunctions.h" |
| #include <QtGui/qcolor.h> |
| #include <QtGui/qopenglcontext.h> |
| #include <QtCore/qdebug.h> |
| #include <private/qobject_p.h> |
| #include <private/qopenglcontext_p.h> |
| |
| QT_BEGIN_NAMESPACE |
| |
| //this is to work around GL_TEXTURE_WRAP_R_OES which also has 0x8072 as value |
| #if !defined(GL_TEXTURE_WRAP_R) |
| #define GL_TEXTURE_WRAP_R 0x8072 |
| #endif |
| |
| QOpenGLTexturePrivate::QOpenGLTexturePrivate(QOpenGLTexture::Target textureTarget, |
| QOpenGLTexture *qq) |
| : q_ptr(qq), |
| context(nullptr), |
| target(textureTarget), |
| textureId(0), |
| format(QOpenGLTexture::NoFormat), |
| formatClass(QOpenGLTexture::NoFormatClass), |
| requestedMipLevels(1), |
| mipLevels(-1), |
| layers(1), |
| faces(1), |
| samples(0), |
| fixedSamplePositions(true), |
| baseLevel(0), |
| maxLevel(1000), |
| depthStencilMode(QOpenGLTexture::DepthMode), |
| comparisonFunction(QOpenGLTexture::CompareLessEqual), |
| comparisonMode(QOpenGLTexture::CompareNone), |
| minFilter(QOpenGLTexture::Nearest), |
| magFilter(QOpenGLTexture::Nearest), |
| maxAnisotropy(1.0f), |
| minLevelOfDetail(-1000.0f), |
| maxLevelOfDetail(1000.0f), |
| levelOfDetailBias(0.0f), |
| textureView(false), |
| autoGenerateMipMaps(true), |
| storageAllocated(false), |
| texFuncs(nullptr), |
| functions(nullptr) |
| { |
| dimensions[0] = dimensions[1] = dimensions[2] = 1; |
| |
| switch (target) { |
| case QOpenGLTexture::Target1D: |
| bindingTarget = QOpenGLTexture::BindingTarget1D; |
| break; |
| case QOpenGLTexture::Target1DArray: |
| bindingTarget = QOpenGLTexture::BindingTarget1DArray; |
| break; |
| case QOpenGLTexture::Target2D: |
| bindingTarget = QOpenGLTexture::BindingTarget2D; |
| break; |
| case QOpenGLTexture::Target2DArray: |
| bindingTarget = QOpenGLTexture::BindingTarget2DArray; |
| break; |
| case QOpenGLTexture::Target3D: |
| bindingTarget = QOpenGLTexture::BindingTarget3D; |
| break; |
| case QOpenGLTexture::TargetCubeMap: |
| bindingTarget = QOpenGLTexture::BindingTargetCubeMap; |
| faces = 6; |
| break; |
| case QOpenGLTexture::TargetCubeMapArray: |
| bindingTarget = QOpenGLTexture::BindingTargetCubeMapArray; |
| faces = 6; |
| break; |
| case QOpenGLTexture::Target2DMultisample: |
| bindingTarget = QOpenGLTexture::BindingTarget2DMultisample; |
| break; |
| case QOpenGLTexture::Target2DMultisampleArray: |
| bindingTarget = QOpenGLTexture::BindingTarget2DMultisampleArray; |
| break; |
| case QOpenGLTexture::TargetRectangle: |
| bindingTarget = QOpenGLTexture::BindingTargetRectangle; |
| break; |
| case QOpenGLTexture::TargetBuffer: |
| bindingTarget = QOpenGLTexture::BindingTargetBuffer; |
| break; |
| } |
| |
| swizzleMask[0] = QOpenGLTexture::RedValue; |
| swizzleMask[1] = QOpenGLTexture::GreenValue; |
| swizzleMask[2] = QOpenGLTexture::BlueValue; |
| swizzleMask[3] = QOpenGLTexture::AlphaValue; |
| |
| wrapModes[0] = wrapModes[1] = wrapModes[2] = target == QOpenGLTexture::TargetRectangle |
| ? QOpenGLTexture::ClampToEdge : QOpenGLTexture::Repeat; |
| } |
| |
| QOpenGLTexturePrivate::~QOpenGLTexturePrivate() |
| { |
| destroy(); |
| } |
| |
| void QOpenGLTexturePrivate::initializeOpenGLFunctions() |
| { |
| // If we already have a functions object, there is nothing to do |
| if (texFuncs) |
| return; |
| |
| // See if the context already has a suitable resource we can use. |
| // If not create a functions object and add it to the context in case |
| // others wish to use it too |
| texFuncs = context->textureFunctions(); |
| if (!texFuncs) { |
| texFuncs = new QOpenGLTextureHelper(context); |
| context->setTextureFunctions(texFuncs); |
| } |
| } |
| |
| bool QOpenGLTexturePrivate::create() |
| { |
| if (textureId != 0) |
| return true; |
| |
| QOpenGLContext *ctx = QOpenGLContext::currentContext(); |
| if (!ctx) { |
| qWarning("Requires a valid current OpenGL context.\n" |
| "Texture has not been created"); |
| return false; |
| } |
| context = ctx; |
| functions = ctx->functions(); |
| |
| // Resolve any functions we will need based upon context version and create the texture |
| initializeOpenGLFunctions(); |
| |
| // What features do we have? |
| QOpenGLTexture::Feature feature = QOpenGLTexture::ImmutableStorage; |
| while (feature != QOpenGLTexture::MaxFeatureFlag) { |
| if (QOpenGLTexture::hasFeature(feature)) |
| features |= feature; |
| feature = static_cast<QOpenGLTexture::Feature>(feature << 1); |
| } |
| |
| functions->glGenTextures(1, &textureId); |
| return textureId != 0; |
| } |
| |
| void QOpenGLTexturePrivate::destroy() |
| { |
| if (!textureId) { |
| // not created or already destroyed |
| return; |
| } |
| QOpenGLContext *currentContext = QOpenGLContext::currentContext(); |
| if (!currentContext) { |
| qWarning("QOpenGLTexturePrivate::destroy() called without a current context.\n" |
| "Texture has not been destroyed"); |
| return; |
| } |
| if (!QOpenGLContext::areSharing(currentContext, context)) { |
| |
| qWarning("QOpenGLTexturePrivate::destroy() called but texture context %p" |
| " is not shared with current context %p.\n" |
| "Texture has not been destroyed", |
| static_cast<const void *>(context), |
| static_cast<const void *>(currentContext)); |
| return; |
| } |
| |
| functions->glDeleteTextures(1, &textureId); |
| |
| context = nullptr; |
| functions = nullptr; |
| textureId = 0; |
| format = QOpenGLTexture::NoFormat; |
| formatClass = QOpenGLTexture::NoFormatClass; |
| requestedMipLevels = 1; |
| mipLevels = -1; |
| layers = 1; |
| faces = 1; |
| samples = 0; |
| fixedSamplePositions = true, |
| baseLevel = 0; |
| maxLevel = 1000; |
| depthStencilMode = QOpenGLTexture::DepthMode; |
| minFilter = QOpenGLTexture::Nearest; |
| magFilter = QOpenGLTexture::Nearest; |
| maxAnisotropy = 1.0f; |
| minLevelOfDetail = -1000.0f; |
| maxLevelOfDetail = 1000.0f; |
| levelOfDetailBias = 0.0f; |
| textureView = false; |
| autoGenerateMipMaps = true; |
| storageAllocated = false; |
| texFuncs = nullptr; |
| |
| swizzleMask[0] = QOpenGLTexture::RedValue; |
| swizzleMask[1] = QOpenGLTexture::GreenValue; |
| swizzleMask[2] = QOpenGLTexture::BlueValue; |
| swizzleMask[3] = QOpenGLTexture::AlphaValue; |
| |
| wrapModes[0] = wrapModes[1] = wrapModes[2] = target == QOpenGLTexture::TargetRectangle |
| ? QOpenGLTexture::ClampToEdge : QOpenGLTexture::Repeat; |
| } |
| |
| void QOpenGLTexturePrivate::bind() |
| { |
| functions->glBindTexture(target, textureId); |
| } |
| |
| void QOpenGLTexturePrivate::bind(uint unit, QOpenGLTexture::TextureUnitReset reset) |
| { |
| GLint oldTextureUnit = 0; |
| if (reset == QOpenGLTexture::ResetTextureUnit) |
| functions->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit); |
| |
| texFuncs->glActiveTexture(GL_TEXTURE0 + unit); |
| functions->glBindTexture(target, textureId); |
| |
| if (reset == QOpenGLTexture::ResetTextureUnit) |
| texFuncs->glActiveTexture(GL_TEXTURE0 + oldTextureUnit); |
| } |
| |
| void QOpenGLTexturePrivate::release() |
| { |
| functions->glBindTexture(target, 0); |
| } |
| |
| void QOpenGLTexturePrivate::release(uint unit, QOpenGLTexture::TextureUnitReset reset) |
| { |
| GLint oldTextureUnit = 0; |
| if (reset == QOpenGLTexture::ResetTextureUnit) |
| functions->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit); |
| |
| texFuncs->glActiveTexture(GL_TEXTURE0 + unit); |
| functions->glBindTexture(target, 0); |
| |
| if (reset == QOpenGLTexture::ResetTextureUnit) |
| texFuncs->glActiveTexture(GL_TEXTURE0 + oldTextureUnit); |
| } |
| |
| bool QOpenGLTexturePrivate::isBound() const |
| { |
| GLint boundTextureId = 0; |
| functions->glGetIntegerv(bindingTarget, &boundTextureId); |
| return (static_cast<GLuint>(boundTextureId) == textureId); |
| } |
| |
| bool QOpenGLTexturePrivate::isBound(uint unit) const |
| { |
| GLint oldTextureUnit = 0; |
| functions->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit); |
| |
| GLint boundTextureId = 0; |
| texFuncs->glActiveTexture(GL_TEXTURE0 + unit); |
| functions->glGetIntegerv(bindingTarget, &boundTextureId); |
| bool result = (static_cast<GLuint>(boundTextureId) == textureId); |
| |
| texFuncs->glActiveTexture(GL_TEXTURE0 + oldTextureUnit); |
| return result; |
| } |
| |
| int QOpenGLTexturePrivate::evaluateMipLevels() const |
| { |
| switch (target) { |
| case QOpenGLTexture::Target1D: |
| case QOpenGLTexture::Target1DArray: |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::Target2DArray: |
| case QOpenGLTexture::Target3D: |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetCubeMapArray: |
| return qMin(maximumMipLevelCount(), qMax(1, requestedMipLevels)); |
| |
| case QOpenGLTexture::TargetRectangle: |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| case QOpenGLTexture::TargetBuffer: |
| default: |
| return 1; |
| } |
| } |
| |
| static bool isSizedTextureFormat(QOpenGLTexture::TextureFormat internalFormat) |
| { |
| switch (internalFormat) { |
| case QOpenGLTexture::NoFormat: |
| return false; |
| |
| case QOpenGLTexture::R8_UNorm: |
| case QOpenGLTexture::RG8_UNorm: |
| case QOpenGLTexture::RGB8_UNorm: |
| case QOpenGLTexture::RGBA8_UNorm: |
| case QOpenGLTexture::R16_UNorm: |
| case QOpenGLTexture::RG16_UNorm: |
| case QOpenGLTexture::RGB16_UNorm: |
| case QOpenGLTexture::RGBA16_UNorm: |
| case QOpenGLTexture::R8_SNorm: |
| case QOpenGLTexture::RG8_SNorm: |
| case QOpenGLTexture::RGB8_SNorm: |
| case QOpenGLTexture::RGBA8_SNorm: |
| case QOpenGLTexture::R16_SNorm: |
| case QOpenGLTexture::RG16_SNorm: |
| case QOpenGLTexture::RGB16_SNorm: |
| case QOpenGLTexture::RGBA16_SNorm: |
| case QOpenGLTexture::R8U: |
| case QOpenGLTexture::RG8U: |
| case QOpenGLTexture::RGB8U: |
| case QOpenGLTexture::RGBA8U: |
| case QOpenGLTexture::R16U: |
| case QOpenGLTexture::RG16U: |
| case QOpenGLTexture::RGB16U: |
| case QOpenGLTexture::RGBA16U: |
| case QOpenGLTexture::R32U: |
| case QOpenGLTexture::RG32U: |
| case QOpenGLTexture::RGB32U: |
| case QOpenGLTexture::RGBA32U: |
| case QOpenGLTexture::R8I: |
| case QOpenGLTexture::RG8I: |
| case QOpenGLTexture::RGB8I: |
| case QOpenGLTexture::RGBA8I: |
| case QOpenGLTexture::R16I: |
| case QOpenGLTexture::RG16I: |
| case QOpenGLTexture::RGB16I: |
| case QOpenGLTexture::RGBA16I: |
| case QOpenGLTexture::R32I: |
| case QOpenGLTexture::RG32I: |
| case QOpenGLTexture::RGB32I: |
| case QOpenGLTexture::RGBA32I: |
| case QOpenGLTexture::R16F: |
| case QOpenGLTexture::RG16F: |
| case QOpenGLTexture::RGB16F: |
| case QOpenGLTexture::RGBA16F: |
| case QOpenGLTexture::R32F: |
| case QOpenGLTexture::RG32F: |
| case QOpenGLTexture::RGB32F: |
| case QOpenGLTexture::RGBA32F: |
| case QOpenGLTexture::RGB9E5: |
| case QOpenGLTexture::RG11B10F: |
| case QOpenGLTexture::RG3B2: |
| case QOpenGLTexture::R5G6B5: |
| case QOpenGLTexture::RGB5A1: |
| case QOpenGLTexture::RGBA4: |
| case QOpenGLTexture::RGB10A2: |
| |
| case QOpenGLTexture::D16: |
| case QOpenGLTexture::D24: |
| case QOpenGLTexture::D32: |
| case QOpenGLTexture::D32F: |
| |
| case QOpenGLTexture::D24S8: |
| case QOpenGLTexture::D32FS8X24: |
| |
| case QOpenGLTexture::S8: |
| |
| case QOpenGLTexture::RGB_DXT1: |
| case QOpenGLTexture::RGBA_DXT1: |
| case QOpenGLTexture::RGBA_DXT3: |
| case QOpenGLTexture::RGBA_DXT5: |
| case QOpenGLTexture::R_ATI1N_UNorm: |
| case QOpenGLTexture::R_ATI1N_SNorm: |
| case QOpenGLTexture::RG_ATI2N_UNorm: |
| case QOpenGLTexture::RG_ATI2N_SNorm: |
| case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT: |
| case QOpenGLTexture::RGB_BP_SIGNED_FLOAT: |
| case QOpenGLTexture::RGB_BP_UNorm: |
| case QOpenGLTexture::SRGB8: |
| case QOpenGLTexture::SRGB8_Alpha8: |
| case QOpenGLTexture::SRGB_DXT1: |
| case QOpenGLTexture::SRGB_Alpha_DXT1: |
| case QOpenGLTexture::SRGB_Alpha_DXT3: |
| case QOpenGLTexture::SRGB_Alpha_DXT5: |
| case QOpenGLTexture::SRGB_BP_UNorm: |
| case QOpenGLTexture::R11_EAC_UNorm: |
| case QOpenGLTexture::R11_EAC_SNorm: |
| case QOpenGLTexture::RG11_EAC_UNorm: |
| case QOpenGLTexture::RG11_EAC_SNorm: |
| case QOpenGLTexture::RGB8_ETC2: |
| case QOpenGLTexture::SRGB8_ETC2: |
| case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: |
| case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: |
| case QOpenGLTexture::RGBA8_ETC2_EAC: |
| case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: |
| case QOpenGLTexture::RGBA_ASTC_4x4: |
| case QOpenGLTexture::RGBA_ASTC_5x4: |
| case QOpenGLTexture::RGBA_ASTC_5x5: |
| case QOpenGLTexture::RGBA_ASTC_6x5: |
| case QOpenGLTexture::RGBA_ASTC_6x6: |
| case QOpenGLTexture::RGBA_ASTC_8x5: |
| case QOpenGLTexture::RGBA_ASTC_8x6: |
| case QOpenGLTexture::RGBA_ASTC_8x8: |
| case QOpenGLTexture::RGBA_ASTC_10x5: |
| case QOpenGLTexture::RGBA_ASTC_10x6: |
| case QOpenGLTexture::RGBA_ASTC_10x8: |
| case QOpenGLTexture::RGBA_ASTC_10x10: |
| case QOpenGLTexture::RGBA_ASTC_12x10: |
| case QOpenGLTexture::RGBA_ASTC_12x12: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_4x4: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x4: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x8: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x8: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x10: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x10: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x12: |
| return true; |
| |
| case QOpenGLTexture::RGB8_ETC1: |
| return false; |
| |
| case QOpenGLTexture::DepthFormat: |
| case QOpenGLTexture::AlphaFormat: |
| |
| case QOpenGLTexture::RGBFormat: |
| case QOpenGLTexture::RGBAFormat: |
| |
| case QOpenGLTexture::LuminanceFormat: |
| |
| case QOpenGLTexture::LuminanceAlphaFormat: |
| return false; |
| } |
| |
| Q_UNREACHABLE(); |
| return false; |
| } |
| |
| static bool isTextureTargetMultisample(QOpenGLTexture::Target target) |
| { |
| switch (target) { |
| case QOpenGLTexture::Target1D: |
| case QOpenGLTexture::Target1DArray: |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::Target2DArray: |
| case QOpenGLTexture::Target3D: |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetCubeMapArray: |
| return false; |
| |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| return true; |
| |
| case QOpenGLTexture::TargetRectangle: |
| case QOpenGLTexture::TargetBuffer: |
| return false; |
| } |
| |
| Q_UNREACHABLE(); |
| return false; |
| } |
| |
| bool QOpenGLTexturePrivate::isUsingImmutableStorage() const |
| { |
| // Use immutable storage whenever possible, falling back to mutable |
| // Note that if multisample textures are not supported at all, we'll still fail into |
| // the mutable storage allocation |
| return isSizedTextureFormat(format) |
| && (isTextureTargetMultisample(target) |
| ? features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage) |
| : features.testFlag(QOpenGLTexture::ImmutableStorage)); |
| } |
| |
| void QOpenGLTexturePrivate::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType) |
| { |
| // Resolve the actual number of mipmap levels we can use |
| mipLevels = evaluateMipLevels(); |
| |
| if (isUsingImmutableStorage()) |
| allocateImmutableStorage(); |
| else |
| allocateMutableStorage(pixelFormat, pixelType); |
| } |
| |
| static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpenGLTexture::TextureFormat internalFormat) |
| { |
| switch (internalFormat) { |
| case QOpenGLTexture::NoFormat: |
| return QOpenGLTexture::NoSourceFormat; |
| |
| case QOpenGLTexture::R8_UNorm: |
| return QOpenGLTexture::Red; |
| |
| case QOpenGLTexture::RG8_UNorm: |
| return QOpenGLTexture::RG; |
| |
| case QOpenGLTexture::RGB8_UNorm: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::RGBA8_UNorm: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::R16_UNorm: |
| return QOpenGLTexture::Red; |
| |
| case QOpenGLTexture::RG16_UNorm: |
| return QOpenGLTexture::RG; |
| |
| case QOpenGLTexture::RGB16_UNorm: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::RGBA16_UNorm: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::R8_SNorm: |
| return QOpenGLTexture::Red; |
| |
| case QOpenGLTexture::RG8_SNorm: |
| return QOpenGLTexture::RG; |
| |
| case QOpenGLTexture::RGB8_SNorm: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::RGBA8_SNorm: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::R16_SNorm: |
| return QOpenGLTexture::Red; |
| |
| case QOpenGLTexture::RG16_SNorm: |
| return QOpenGLTexture::RG; |
| |
| case QOpenGLTexture::RGB16_SNorm: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::RGBA16_SNorm: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::R8U: |
| return QOpenGLTexture::Red_Integer; |
| |
| case QOpenGLTexture::RG8U: |
| return QOpenGLTexture::RG_Integer; |
| |
| case QOpenGLTexture::RGB8U: |
| return QOpenGLTexture::RGB_Integer; |
| |
| case QOpenGLTexture::RGBA8U: |
| return QOpenGLTexture::RGBA_Integer; |
| |
| case QOpenGLTexture::R16U: |
| return QOpenGLTexture::Red_Integer; |
| |
| case QOpenGLTexture::RG16U: |
| return QOpenGLTexture::RG_Integer; |
| |
| case QOpenGLTexture::RGB16U: |
| return QOpenGLTexture::RGB_Integer; |
| |
| case QOpenGLTexture::RGBA16U: |
| return QOpenGLTexture::RGBA_Integer; |
| |
| case QOpenGLTexture::R32U: |
| return QOpenGLTexture::Red_Integer; |
| |
| case QOpenGLTexture::RG32U: |
| return QOpenGLTexture::RG_Integer; |
| |
| case QOpenGLTexture::RGB32U: |
| return QOpenGLTexture::RGB_Integer; |
| |
| case QOpenGLTexture::RGBA32U: |
| return QOpenGLTexture::RGBA_Integer; |
| |
| case QOpenGLTexture::R8I: |
| return QOpenGLTexture::Red_Integer; |
| |
| case QOpenGLTexture::RG8I: |
| return QOpenGLTexture::RG_Integer; |
| |
| case QOpenGLTexture::RGB8I: |
| return QOpenGLTexture::RGB_Integer; |
| |
| case QOpenGLTexture::RGBA8I: |
| return QOpenGLTexture::RGBA_Integer; |
| |
| case QOpenGLTexture::R16I: |
| return QOpenGLTexture::Red_Integer; |
| |
| case QOpenGLTexture::RG16I: |
| return QOpenGLTexture::RG_Integer; |
| |
| case QOpenGLTexture::RGB16I: |
| return QOpenGLTexture::RGB_Integer; |
| |
| case QOpenGLTexture::RGBA16I: |
| return QOpenGLTexture::RGBA_Integer; |
| |
| case QOpenGLTexture::R32I: |
| return QOpenGLTexture::Red_Integer; |
| |
| case QOpenGLTexture::RG32I: |
| return QOpenGLTexture::RG_Integer; |
| |
| case QOpenGLTexture::RGB32I: |
| return QOpenGLTexture::RGB_Integer; |
| |
| case QOpenGLTexture::RGBA32I: |
| return QOpenGLTexture::RGBA_Integer; |
| |
| case QOpenGLTexture::R16F: |
| return QOpenGLTexture::Red; |
| |
| case QOpenGLTexture::RG16F: |
| return QOpenGLTexture::RG; |
| |
| case QOpenGLTexture::RGB16F: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::RGBA16F: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::R32F: |
| return QOpenGLTexture::Red; |
| |
| case QOpenGLTexture::RG32F: |
| return QOpenGLTexture::RG; |
| |
| case QOpenGLTexture::RGB32F: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::RGBA32F: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::RGB9E5: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::RG11B10F: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::RG3B2: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::R5G6B5: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::RGB5A1: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::RGBA4: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::RGB10A2: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::D16: |
| case QOpenGLTexture::D24: |
| case QOpenGLTexture::D32: |
| case QOpenGLTexture::D32F: |
| return QOpenGLTexture::Depth; |
| |
| case QOpenGLTexture::D24S8: |
| case QOpenGLTexture::D32FS8X24: |
| return QOpenGLTexture::DepthStencil; |
| |
| case QOpenGLTexture::S8: |
| return QOpenGLTexture::Stencil; |
| |
| case QOpenGLTexture::RGB_DXT1: |
| case QOpenGLTexture::RGBA_DXT1: |
| case QOpenGLTexture::RGBA_DXT3: |
| case QOpenGLTexture::RGBA_DXT5: |
| case QOpenGLTexture::R_ATI1N_UNorm: |
| case QOpenGLTexture::R_ATI1N_SNorm: |
| case QOpenGLTexture::RG_ATI2N_UNorm: |
| case QOpenGLTexture::RG_ATI2N_SNorm: |
| case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT: |
| case QOpenGLTexture::RGB_BP_SIGNED_FLOAT: |
| case QOpenGLTexture::RGB_BP_UNorm: |
| case QOpenGLTexture::SRGB8: |
| case QOpenGLTexture::SRGB8_Alpha8: |
| case QOpenGLTexture::SRGB_DXT1: |
| case QOpenGLTexture::SRGB_Alpha_DXT1: |
| case QOpenGLTexture::SRGB_Alpha_DXT3: |
| case QOpenGLTexture::SRGB_Alpha_DXT5: |
| case QOpenGLTexture::SRGB_BP_UNorm: |
| case QOpenGLTexture::RGB8_ETC1: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::R11_EAC_UNorm: |
| case QOpenGLTexture::R11_EAC_SNorm: |
| return QOpenGLTexture::Red; |
| |
| case QOpenGLTexture::RG11_EAC_UNorm: |
| case QOpenGLTexture::RG11_EAC_SNorm: |
| return QOpenGLTexture::RG; |
| |
| case QOpenGLTexture::RGB8_ETC2: |
| case QOpenGLTexture::SRGB8_ETC2: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: |
| case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::RGBA8_ETC2_EAC: |
| case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::RGBA_ASTC_4x4: |
| case QOpenGLTexture::RGBA_ASTC_5x4: |
| case QOpenGLTexture::RGBA_ASTC_5x5: |
| case QOpenGLTexture::RGBA_ASTC_6x5: |
| case QOpenGLTexture::RGBA_ASTC_6x6: |
| case QOpenGLTexture::RGBA_ASTC_8x5: |
| case QOpenGLTexture::RGBA_ASTC_8x6: |
| case QOpenGLTexture::RGBA_ASTC_8x8: |
| case QOpenGLTexture::RGBA_ASTC_10x5: |
| case QOpenGLTexture::RGBA_ASTC_10x6: |
| case QOpenGLTexture::RGBA_ASTC_10x8: |
| case QOpenGLTexture::RGBA_ASTC_10x10: |
| case QOpenGLTexture::RGBA_ASTC_12x10: |
| case QOpenGLTexture::RGBA_ASTC_12x12: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_4x4: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x4: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x8: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x8: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x10: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x10: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x12: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::DepthFormat: |
| return QOpenGLTexture::Depth; |
| |
| case QOpenGLTexture::AlphaFormat: |
| return QOpenGLTexture::Alpha; |
| |
| case QOpenGLTexture::RGBFormat: |
| return QOpenGLTexture::RGB; |
| |
| case QOpenGLTexture::RGBAFormat: |
| return QOpenGLTexture::RGBA; |
| |
| case QOpenGLTexture::LuminanceFormat: |
| return QOpenGLTexture::Luminance; |
| |
| case QOpenGLTexture::LuminanceAlphaFormat: |
| return QOpenGLTexture::LuminanceAlpha; |
| } |
| |
| Q_UNREACHABLE(); |
| return QOpenGLTexture::NoSourceFormat; |
| } |
| |
| static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTexture::TextureFormat internalFormat) |
| { |
| switch (internalFormat) { |
| case QOpenGLTexture::NoFormat: |
| return QOpenGLTexture::NoPixelType; |
| |
| case QOpenGLTexture::R8_UNorm: |
| case QOpenGLTexture::RG8_UNorm: |
| case QOpenGLTexture::RGB8_UNorm: |
| case QOpenGLTexture::RGBA8_UNorm: |
| case QOpenGLTexture::R16_UNorm: |
| case QOpenGLTexture::RG16_UNorm: |
| case QOpenGLTexture::RGB16_UNorm: |
| case QOpenGLTexture::RGBA16_UNorm: |
| return QOpenGLTexture::UInt8; |
| |
| case QOpenGLTexture::R8_SNorm: |
| case QOpenGLTexture::RG8_SNorm: |
| case QOpenGLTexture::RGB8_SNorm: |
| case QOpenGLTexture::RGBA8_SNorm: |
| case QOpenGLTexture::R16_SNorm: |
| case QOpenGLTexture::RG16_SNorm: |
| case QOpenGLTexture::RGB16_SNorm: |
| case QOpenGLTexture::RGBA16_SNorm: |
| return QOpenGLTexture::Int8; |
| |
| case QOpenGLTexture::R8U: |
| case QOpenGLTexture::RG8U: |
| case QOpenGLTexture::RGB8U: |
| case QOpenGLTexture::RGBA8U: |
| case QOpenGLTexture::R16U: |
| case QOpenGLTexture::RG16U: |
| case QOpenGLTexture::RGB16U: |
| case QOpenGLTexture::RGBA16U: |
| case QOpenGLTexture::R32U: |
| case QOpenGLTexture::RG32U: |
| case QOpenGLTexture::RGB32U: |
| case QOpenGLTexture::RGBA32U: |
| return QOpenGLTexture::UInt8; |
| |
| case QOpenGLTexture::R8I: |
| case QOpenGLTexture::RG8I: |
| case QOpenGLTexture::RGB8I: |
| case QOpenGLTexture::RGBA8I: |
| case QOpenGLTexture::R16I: |
| case QOpenGLTexture::RG16I: |
| case QOpenGLTexture::RGB16I: |
| case QOpenGLTexture::RGBA16I: |
| case QOpenGLTexture::R32I: |
| case QOpenGLTexture::RG32I: |
| case QOpenGLTexture::RGB32I: |
| case QOpenGLTexture::RGBA32I: |
| return QOpenGLTexture::Int8; |
| |
| case QOpenGLTexture::R16F: |
| case QOpenGLTexture::RG16F: |
| case QOpenGLTexture::RGB16F: |
| case QOpenGLTexture::RGBA16F: |
| return QOpenGLTexture::Float16; |
| |
| case QOpenGLTexture::R32F: |
| case QOpenGLTexture::RG32F: |
| case QOpenGLTexture::RGB32F: |
| case QOpenGLTexture::RGBA32F: |
| return QOpenGLTexture::Float32; |
| |
| case QOpenGLTexture::RGB9E5: |
| return QOpenGLTexture::UInt16_RGB5A1_Rev; |
| |
| case QOpenGLTexture::RG11B10F: |
| return QOpenGLTexture::UInt32_RG11B10F; |
| |
| case QOpenGLTexture::RG3B2: |
| return QOpenGLTexture::UInt8_RG3B2; |
| |
| case QOpenGLTexture::R5G6B5: |
| return QOpenGLTexture::UInt16_R5G6B5; |
| |
| case QOpenGLTexture::RGB5A1: |
| return QOpenGLTexture::UInt16_RGB5A1; |
| |
| case QOpenGLTexture::RGBA4: |
| return QOpenGLTexture::UInt16_RGBA4; |
| |
| case QOpenGLTexture::RGB10A2: |
| return QOpenGLTexture::UInt32_RGB10A2; |
| |
| case QOpenGLTexture::D16: |
| return QOpenGLTexture::UInt16; |
| |
| case QOpenGLTexture::D24: |
| case QOpenGLTexture::D32: |
| return QOpenGLTexture::UInt32; |
| |
| case QOpenGLTexture::D32F: |
| return QOpenGLTexture::Float32; |
| |
| case QOpenGLTexture::D24S8: |
| return QOpenGLTexture::UInt32_D24S8; |
| |
| case QOpenGLTexture::D32FS8X24: |
| return QOpenGLTexture::Float32_D32_UInt32_S8_X24; |
| |
| case QOpenGLTexture::S8: |
| return QOpenGLTexture::UInt8; |
| |
| case QOpenGLTexture::RGB_DXT1: |
| case QOpenGLTexture::RGBA_DXT1: |
| case QOpenGLTexture::RGBA_DXT3: |
| case QOpenGLTexture::RGBA_DXT5: |
| case QOpenGLTexture::R_ATI1N_UNorm: |
| case QOpenGLTexture::R_ATI1N_SNorm: |
| case QOpenGLTexture::RG_ATI2N_UNorm: |
| case QOpenGLTexture::RG_ATI2N_SNorm: |
| case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT: |
| case QOpenGLTexture::RGB_BP_SIGNED_FLOAT: |
| case QOpenGLTexture::RGB_BP_UNorm: |
| case QOpenGLTexture::SRGB8: |
| case QOpenGLTexture::SRGB8_Alpha8: |
| case QOpenGLTexture::SRGB_DXT1: |
| case QOpenGLTexture::SRGB_Alpha_DXT1: |
| case QOpenGLTexture::SRGB_Alpha_DXT3: |
| case QOpenGLTexture::SRGB_Alpha_DXT5: |
| case QOpenGLTexture::SRGB_BP_UNorm: |
| case QOpenGLTexture::R11_EAC_UNorm: |
| case QOpenGLTexture::R11_EAC_SNorm: |
| case QOpenGLTexture::RG11_EAC_UNorm: |
| case QOpenGLTexture::RG11_EAC_SNorm: |
| case QOpenGLTexture::RGB8_ETC2: |
| case QOpenGLTexture::SRGB8_ETC2: |
| case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: |
| case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: |
| case QOpenGLTexture::RGBA8_ETC2_EAC: |
| case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: |
| case QOpenGLTexture::RGB8_ETC1: |
| case QOpenGLTexture::RGBA_ASTC_4x4: |
| case QOpenGLTexture::RGBA_ASTC_5x4: |
| case QOpenGLTexture::RGBA_ASTC_5x5: |
| case QOpenGLTexture::RGBA_ASTC_6x5: |
| case QOpenGLTexture::RGBA_ASTC_6x6: |
| case QOpenGLTexture::RGBA_ASTC_8x5: |
| case QOpenGLTexture::RGBA_ASTC_8x6: |
| case QOpenGLTexture::RGBA_ASTC_8x8: |
| case QOpenGLTexture::RGBA_ASTC_10x5: |
| case QOpenGLTexture::RGBA_ASTC_10x6: |
| case QOpenGLTexture::RGBA_ASTC_10x8: |
| case QOpenGLTexture::RGBA_ASTC_10x10: |
| case QOpenGLTexture::RGBA_ASTC_12x10: |
| case QOpenGLTexture::RGBA_ASTC_12x12: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_4x4: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x4: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x8: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x8: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x10: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x10: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x12: |
| return QOpenGLTexture::UInt8; |
| |
| case QOpenGLTexture::DepthFormat: |
| return QOpenGLTexture::UInt32; |
| |
| case QOpenGLTexture::AlphaFormat: |
| case QOpenGLTexture::RGBFormat: |
| case QOpenGLTexture::RGBAFormat: |
| case QOpenGLTexture::LuminanceFormat: |
| case QOpenGLTexture::LuminanceAlphaFormat: |
| return QOpenGLTexture::UInt8; |
| } |
| |
| Q_UNREACHABLE(); |
| return QOpenGLTexture::NoPixelType; |
| } |
| |
| static bool isCompressedFormat(QOpenGLTexture::TextureFormat internalFormat) |
| { |
| switch (internalFormat) { |
| case QOpenGLTexture::NoFormat: |
| |
| case QOpenGLTexture::R8_UNorm: |
| case QOpenGLTexture::RG8_UNorm: |
| case QOpenGLTexture::RGB8_UNorm: |
| case QOpenGLTexture::RGBA8_UNorm: |
| case QOpenGLTexture::R16_UNorm: |
| case QOpenGLTexture::RG16_UNorm: |
| case QOpenGLTexture::RGB16_UNorm: |
| case QOpenGLTexture::RGBA16_UNorm: |
| case QOpenGLTexture::R8_SNorm: |
| case QOpenGLTexture::RG8_SNorm: |
| case QOpenGLTexture::RGB8_SNorm: |
| case QOpenGLTexture::RGBA8_SNorm: |
| case QOpenGLTexture::R16_SNorm: |
| case QOpenGLTexture::RG16_SNorm: |
| case QOpenGLTexture::RGB16_SNorm: |
| case QOpenGLTexture::RGBA16_SNorm: |
| case QOpenGLTexture::R8U: |
| case QOpenGLTexture::RG8U: |
| case QOpenGLTexture::RGB8U: |
| case QOpenGLTexture::RGBA8U: |
| case QOpenGLTexture::R16U: |
| case QOpenGLTexture::RG16U: |
| case QOpenGLTexture::RGB16U: |
| case QOpenGLTexture::RGBA16U: |
| case QOpenGLTexture::R32U: |
| case QOpenGLTexture::RG32U: |
| case QOpenGLTexture::RGB32U: |
| case QOpenGLTexture::RGBA32U: |
| case QOpenGLTexture::R8I: |
| case QOpenGLTexture::RG8I: |
| case QOpenGLTexture::RGB8I: |
| case QOpenGLTexture::RGBA8I: |
| case QOpenGLTexture::R16I: |
| case QOpenGLTexture::RG16I: |
| case QOpenGLTexture::RGB16I: |
| case QOpenGLTexture::RGBA16I: |
| case QOpenGLTexture::R32I: |
| case QOpenGLTexture::RG32I: |
| case QOpenGLTexture::RGB32I: |
| case QOpenGLTexture::RGBA32I: |
| case QOpenGLTexture::R16F: |
| case QOpenGLTexture::RG16F: |
| case QOpenGLTexture::RGB16F: |
| case QOpenGLTexture::RGBA16F: |
| case QOpenGLTexture::R32F: |
| case QOpenGLTexture::RG32F: |
| case QOpenGLTexture::RGB32F: |
| case QOpenGLTexture::RGBA32F: |
| case QOpenGLTexture::RGB9E5: |
| case QOpenGLTexture::RG11B10F: |
| case QOpenGLTexture::RG3B2: |
| case QOpenGLTexture::R5G6B5: |
| case QOpenGLTexture::RGB5A1: |
| case QOpenGLTexture::RGBA4: |
| case QOpenGLTexture::RGB10A2: |
| |
| case QOpenGLTexture::D16: |
| case QOpenGLTexture::D24: |
| case QOpenGLTexture::D32: |
| case QOpenGLTexture::D32F: |
| |
| case QOpenGLTexture::D24S8: |
| case QOpenGLTexture::D32FS8X24: |
| |
| case QOpenGLTexture::S8: |
| return false; |
| |
| case QOpenGLTexture::RGB_DXT1: |
| case QOpenGLTexture::RGBA_DXT1: |
| case QOpenGLTexture::RGBA_DXT3: |
| case QOpenGLTexture::RGBA_DXT5: |
| case QOpenGLTexture::R_ATI1N_UNorm: |
| case QOpenGLTexture::R_ATI1N_SNorm: |
| case QOpenGLTexture::RG_ATI2N_UNorm: |
| case QOpenGLTexture::RG_ATI2N_SNorm: |
| case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT: |
| case QOpenGLTexture::RGB_BP_SIGNED_FLOAT: |
| case QOpenGLTexture::RGB_BP_UNorm: |
| case QOpenGLTexture::SRGB8: |
| case QOpenGLTexture::SRGB8_Alpha8: |
| case QOpenGLTexture::SRGB_DXT1: |
| case QOpenGLTexture::SRGB_Alpha_DXT1: |
| case QOpenGLTexture::SRGB_Alpha_DXT3: |
| case QOpenGLTexture::SRGB_Alpha_DXT5: |
| case QOpenGLTexture::SRGB_BP_UNorm: |
| case QOpenGLTexture::R11_EAC_UNorm: |
| case QOpenGLTexture::R11_EAC_SNorm: |
| case QOpenGLTexture::RG11_EAC_UNorm: |
| case QOpenGLTexture::RG11_EAC_SNorm: |
| case QOpenGLTexture::RGB8_ETC2: |
| case QOpenGLTexture::SRGB8_ETC2: |
| case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: |
| case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: |
| case QOpenGLTexture::RGBA8_ETC2_EAC: |
| case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: |
| case QOpenGLTexture::RGB8_ETC1: |
| case QOpenGLTexture::RGBA_ASTC_4x4: |
| case QOpenGLTexture::RGBA_ASTC_5x4: |
| case QOpenGLTexture::RGBA_ASTC_5x5: |
| case QOpenGLTexture::RGBA_ASTC_6x5: |
| case QOpenGLTexture::RGBA_ASTC_6x6: |
| case QOpenGLTexture::RGBA_ASTC_8x5: |
| case QOpenGLTexture::RGBA_ASTC_8x6: |
| case QOpenGLTexture::RGBA_ASTC_8x8: |
| case QOpenGLTexture::RGBA_ASTC_10x5: |
| case QOpenGLTexture::RGBA_ASTC_10x6: |
| case QOpenGLTexture::RGBA_ASTC_10x8: |
| case QOpenGLTexture::RGBA_ASTC_10x10: |
| case QOpenGLTexture::RGBA_ASTC_12x10: |
| case QOpenGLTexture::RGBA_ASTC_12x12: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_4x4: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x4: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x8: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x8: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x10: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x10: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x12: |
| return true; |
| |
| case QOpenGLTexture::DepthFormat: |
| case QOpenGLTexture::AlphaFormat: |
| case QOpenGLTexture::RGBFormat: |
| case QOpenGLTexture::RGBAFormat: |
| case QOpenGLTexture::LuminanceFormat: |
| case QOpenGLTexture::LuminanceAlphaFormat: |
| return false; |
| } |
| |
| Q_UNREACHABLE(); |
| return false; |
| } |
| |
| void QOpenGLTexturePrivate::allocateMutableStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType) |
| { |
| // There is no way to allocate mutable storage for compressed textures in in |
| // versions older than OpenGL 3.1 and OpenGL ES 3.0, because the older specs |
| // do not mandate accepting null data pointers for glCompressedTexImage*D, |
| // unlike glTexImage*D (which in turn does not accept compressed formats). |
| if (isCompressedFormat(format)) { |
| storageAllocated = true; |
| return; |
| } |
| |
| switch (target) { |
| case QOpenGLTexture::TargetBuffer: |
| // Buffer textures get their storage from an external OpenGL buffer |
| qWarning("Buffer textures do not allocate storage"); |
| return; |
| |
| case QOpenGLTexture::Target1D: |
| if (features.testFlag(QOpenGLTexture::Texture1D)) { |
| for (int level = 0; level < mipLevels; ++level) |
| texFuncs->glTextureImage1D(textureId, target, bindingTarget, level, format, |
| mipLevelSize(level, dimensions[0]), |
| 0, |
| pixelFormat, pixelType, nullptr); |
| } else { |
| qWarning("1D textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::Target1DArray: |
| if (features.testFlag(QOpenGLTexture::Texture1D) |
| && features.testFlag(QOpenGLTexture::TextureArrays)) { |
| for (int level = 0; level < mipLevels; ++level) |
| texFuncs->glTextureImage2D(textureId, target, bindingTarget, level, format, |
| mipLevelSize(level, dimensions[0]), |
| layers, |
| 0, |
| pixelFormat, pixelType, nullptr); |
| } else { |
| qWarning("1D array textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::TargetRectangle: |
| for (int level = 0; level < mipLevels; ++level) |
| texFuncs->glTextureImage2D(textureId, target, bindingTarget, level, format, |
| mipLevelSize(level, dimensions[0]), |
| mipLevelSize(level, dimensions[1]), |
| 0, |
| pixelFormat, pixelType, nullptr); |
| break; |
| |
| case QOpenGLTexture::TargetCubeMap: { |
| // Cubemaps are the odd one out. We have to allocate storage for each |
| // face and miplevel using the special cubemap face targets rather than |
| // GL_TARGET_CUBEMAP. |
| const QOpenGLTexture::CubeMapFace faceTargets[] = { |
| QOpenGLTexture::CubeMapPositiveX, QOpenGLTexture::CubeMapNegativeX, |
| QOpenGLTexture::CubeMapPositiveY, QOpenGLTexture::CubeMapNegativeY, |
| QOpenGLTexture::CubeMapPositiveZ, QOpenGLTexture::CubeMapNegativeZ |
| }; |
| |
| for (int faceTarget = 0; faceTarget < 6; ++faceTarget) { |
| for (int level = 0; level < mipLevels; ++level) { |
| texFuncs->glTextureImage2D(textureId, faceTargets[faceTarget], bindingTarget, |
| level, format, |
| mipLevelSize(level, dimensions[0]), |
| mipLevelSize(level, dimensions[1]), |
| 0, |
| pixelFormat, pixelType, nullptr); |
| } |
| } |
| break; |
| } |
| |
| case QOpenGLTexture::Target2DArray: |
| if (features.testFlag(QOpenGLTexture::TextureArrays)) { |
| for (int level = 0; level < mipLevels; ++level) |
| texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format, |
| mipLevelSize(level, dimensions[0]), |
| mipLevelSize(level, dimensions[1]), |
| layers, |
| 0, |
| pixelFormat, pixelType, nullptr); |
| } else { |
| qWarning("Array textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::TargetCubeMapArray: |
| // Cubemap arrays must specify number of layer-faces (6 * layers) as depth parameter |
| if (features.testFlag(QOpenGLTexture::TextureCubeMapArrays)) { |
| for (int level = 0; level < mipLevels; ++level) |
| texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format, |
| mipLevelSize(level, dimensions[0]), |
| mipLevelSize(level, dimensions[1]), |
| 6 * layers, |
| 0, |
| pixelFormat, pixelType, nullptr); |
| } else { |
| qWarning("Cubemap Array textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::Target3D: |
| if (features.testFlag(QOpenGLTexture::Texture3D)) { |
| for (int level = 0; level < mipLevels; ++level) |
| texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format, |
| mipLevelSize(level, dimensions[0]), |
| mipLevelSize(level, dimensions[1]), |
| mipLevelSize(level, dimensions[2]), |
| 0, |
| pixelFormat, pixelType, nullptr); |
| } else { |
| qWarning("3D textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::Target2DMultisample: |
| if (features.testFlag(QOpenGLTexture::TextureMultisample)) { |
| texFuncs->glTextureImage2DMultisample(textureId, target, bindingTarget, samples, format, |
| dimensions[0], dimensions[1], |
| fixedSamplePositions); |
| } else { |
| qWarning("Multisample textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::Target2DMultisampleArray: |
| if (features.testFlag(QOpenGLTexture::TextureMultisample) |
| && features.testFlag(QOpenGLTexture::TextureArrays)) { |
| texFuncs->glTextureImage3DMultisample(textureId, target, bindingTarget, samples, format, |
| dimensions[0], dimensions[1], layers, |
| fixedSamplePositions); |
| } else { |
| qWarning("Multisample array textures are not supported"); |
| return; |
| } |
| break; |
| } |
| |
| storageAllocated = true; |
| } |
| |
| void QOpenGLTexturePrivate::allocateImmutableStorage() |
| { |
| switch (target) { |
| case QOpenGLTexture::TargetBuffer: |
| // Buffer textures get their storage from an external OpenGL buffer |
| qWarning("Buffer textures do not allocate storage"); |
| return; |
| |
| case QOpenGLTexture::Target1D: |
| if (features.testFlag(QOpenGLTexture::Texture1D)) { |
| texFuncs->glTextureStorage1D(textureId, target, bindingTarget, mipLevels, format, |
| dimensions[0]); |
| } else { |
| qWarning("1D textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::Target1DArray: |
| if (features.testFlag(QOpenGLTexture::Texture1D) |
| && features.testFlag(QOpenGLTexture::TextureArrays)) { |
| texFuncs->glTextureStorage2D(textureId, target, bindingTarget, mipLevels, format, |
| dimensions[0], layers); |
| } else { |
| qWarning("1D array textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetRectangle: |
| texFuncs->glTextureStorage2D(textureId, target, bindingTarget, mipLevels, format, |
| dimensions[0], dimensions[1]); |
| break; |
| |
| case QOpenGLTexture::Target2DArray: |
| if (features.testFlag(QOpenGLTexture::TextureArrays)) { |
| texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format, |
| dimensions[0], dimensions[1], layers); |
| } else { |
| qWarning("Array textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::TargetCubeMapArray: |
| // Cubemap arrays must specify number of layer-faces (6 * layers) as depth parameter |
| if (features.testFlag(QOpenGLTexture::TextureCubeMapArrays)) { |
| texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format, |
| dimensions[0], dimensions[1], 6 * layers); |
| } else { |
| qWarning("Cubemap Array textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::Target3D: |
| if (features.testFlag(QOpenGLTexture::Texture3D)) { |
| texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format, |
| dimensions[0], dimensions[1], dimensions[2]); |
| } else { |
| qWarning("3D textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::Target2DMultisample: |
| if (features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage)) { |
| texFuncs->glTextureStorage2DMultisample(textureId, target, bindingTarget, samples, format, |
| dimensions[0], dimensions[1], |
| fixedSamplePositions); |
| } else { |
| qWarning("Multisample textures are not supported"); |
| return; |
| } |
| break; |
| |
| case QOpenGLTexture::Target2DMultisampleArray: |
| if (features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage) |
| && features.testFlag(QOpenGLTexture::TextureArrays)) { |
| texFuncs->glTextureStorage3DMultisample(textureId, target, bindingTarget, samples, format, |
| dimensions[0], dimensions[1], layers, |
| fixedSamplePositions); |
| } else { |
| qWarning("Multisample array textures are not supported"); |
| return; |
| } |
| break; |
| } |
| |
| storageAllocated = true; |
| } |
| |
| void QOpenGLTexturePrivate::setData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, |
| QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, |
| const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| switch (target) { |
| case QOpenGLTexture::Target1D: |
| Q_UNUSED(layer); |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(layerCount); |
| texFuncs->glTextureSubImage1D(textureId, target, bindingTarget, mipLevel, |
| 0, mipLevelSize( mipLevel, dimensions[0] ), |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::Target1DArray: |
| Q_UNUSED(cubeFace); |
| texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel, |
| 0, layer, |
| mipLevelSize(mipLevel, dimensions[0]), |
| layerCount, |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::Target2D: |
| Q_UNUSED(layer); |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(layerCount); |
| texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel, |
| 0, 0, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::Target2DArray: |
| Q_UNUSED(cubeFace); |
| texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, |
| 0, 0, layer, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| layerCount, |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::Target3D: |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(layerCount); |
| texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, |
| 0, 0, layer, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| mipLevelSize(mipLevel, dimensions[2]), |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::TargetCubeMap: |
| Q_UNUSED(layer); |
| Q_UNUSED(layerCount); |
| texFuncs->glTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel, |
| 0, 0, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::TargetCubeMapArray: { |
| int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX; |
| int layerFace = 6 * layer + faceIndex; |
| texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, |
| 0, 0, layerFace, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| layerCount, |
| sourceFormat, sourceType, data, options); |
| break; |
| } |
| |
| case QOpenGLTexture::TargetRectangle: |
| Q_UNUSED(mipLevel); |
| Q_UNUSED(layer); |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(layerCount); |
| texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, 0, |
| 0, 0, |
| dimensions[0], |
| dimensions[1], |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| case QOpenGLTexture::TargetBuffer: |
| // We don't upload pixel data for these targets |
| qWarning("QOpenGLTexture::setData(): Texture target does not support pixel data upload"); |
| break; |
| } |
| |
| // If requested perform automatic mip map generation |
| if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) { |
| Q_Q(QOpenGLTexture); |
| q->generateMipMaps(); |
| } |
| } |
| |
| void QOpenGLTexturePrivate::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) |
| { |
| switch (target) { |
| case QOpenGLTexture::Target1D: |
| Q_UNUSED(layer); |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(layerCount); |
| Q_UNUSED(yOffset); |
| Q_UNUSED(zOffset); |
| Q_UNUSED(height); |
| Q_UNUSED(depth); |
| texFuncs->glTextureSubImage1D(textureId, target, bindingTarget, mipLevel, |
| xOffset, width, |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::Target1DArray: |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(yOffset); |
| Q_UNUSED(zOffset); |
| Q_UNUSED(height); |
| Q_UNUSED(depth); |
| texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel, |
| xOffset, layer, |
| width, |
| layerCount, |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::Target2D: |
| Q_UNUSED(layer); |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(layerCount); |
| Q_UNUSED(zOffset); |
| Q_UNUSED(depth); |
| texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel, |
| xOffset, yOffset, |
| width, height, |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::Target2DArray: |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(zOffset); |
| Q_UNUSED(depth); |
| texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, |
| xOffset, yOffset, layer, |
| width, height, layerCount, |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::Target3D: |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(layerCount); |
| texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, |
| xOffset, yOffset, zOffset, |
| width, height, depth, |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::TargetCubeMap: |
| Q_UNUSED(layer); |
| Q_UNUSED(layerCount); |
| Q_UNUSED(zOffset); |
| Q_UNUSED(depth); |
| texFuncs->glTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel, |
| xOffset, yOffset, |
| width, height, |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::TargetCubeMapArray: { |
| Q_UNUSED(zOffset); |
| Q_UNUSED(depth); |
| int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX; |
| int layerFace = 6 * layer + faceIndex; |
| texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, |
| xOffset, yOffset, layerFace, |
| width, height, |
| layerCount, |
| sourceFormat, sourceType, data, options); |
| break; |
| } |
| |
| case QOpenGLTexture::TargetRectangle: |
| Q_UNUSED(mipLevel); |
| Q_UNUSED(layer); |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(layerCount); |
| Q_UNUSED(zOffset); |
| Q_UNUSED(depth); |
| texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, 0, |
| xOffset, yOffset, |
| width, height, |
| sourceFormat, sourceType, data, options); |
| break; |
| |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| case QOpenGLTexture::TargetBuffer: |
| // We don't upload pixel data for these targets |
| qWarning("QOpenGLTexture::setData(): Texture target does not support pixel data upload"); |
| break; |
| } |
| |
| // If requested perform automatic mip map generation |
| if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) { |
| Q_Q(QOpenGLTexture); |
| q->generateMipMaps(); |
| } |
| } |
| |
| |
| void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, int layerCount, |
| QOpenGLTexture::CubeMapFace cubeFace, |
| int dataSize, const void *data, |
| const QOpenGLPixelTransferOptions * const options) |
| { |
| if (!isCompressedFormat(format)) { |
| qWarning("Cannot set compressed data for non-compressed format 0x%x", format); |
| return; |
| } |
| |
| const bool needsFullSpec = !isUsingImmutableStorage(); // was allocateStorage() a no-op? |
| |
| switch (target) { |
| case QOpenGLTexture::Target1D: |
| Q_UNUSED(layer); |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(layerCount); |
| if (needsFullSpec) { |
| texFuncs->glCompressedTextureImage1D(textureId, target, bindingTarget, mipLevel, |
| format, |
| mipLevelSize(mipLevel, dimensions[0]), |
| 0, dataSize, data, options); |
| } else { |
| texFuncs->glCompressedTextureSubImage1D(textureId, target, bindingTarget, mipLevel, |
| 0, mipLevelSize( mipLevel, dimensions[0] ), |
| format, dataSize, data, options); |
| } |
| break; |
| |
| case QOpenGLTexture::Target1DArray: |
| Q_UNUSED(cubeFace); |
| if (!needsFullSpec) { |
| texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel, |
| 0, layer, |
| mipLevelSize(mipLevel, dimensions[0]), |
| layerCount, |
| format, dataSize, data, options); |
| } |
| break; |
| |
| case QOpenGLTexture::Target2D: |
| Q_UNUSED(layer); |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(layerCount); |
| if (needsFullSpec) { |
| texFuncs->glCompressedTextureImage2D(textureId, target, bindingTarget, mipLevel, |
| format, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| 0, dataSize, data, options); |
| } else { |
| texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel, |
| 0, 0, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| format, dataSize, data, options); |
| } |
| break; |
| |
| case QOpenGLTexture::Target2DArray: |
| Q_UNUSED(cubeFace); |
| if (!needsFullSpec) { |
| texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, |
| 0, 0, layer, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| layerCount, |
| format, dataSize, data, options); |
| } |
| break; |
| |
| case QOpenGLTexture::Target3D: |
| Q_UNUSED(cubeFace); |
| Q_UNUSED(layerCount); |
| if (needsFullSpec) { |
| texFuncs->glCompressedTextureImage3D(textureId, target, bindingTarget, mipLevel, |
| format, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| mipLevelSize(mipLevel, dimensions[2]), |
| 0, dataSize, data, options); |
| } else { |
| texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, |
| 0, 0, layer, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| mipLevelSize(mipLevel, dimensions[2]), |
| format, dataSize, data, options); |
| } |
| break; |
| |
| case QOpenGLTexture::TargetCubeMap: |
| Q_UNUSED(layer); |
| Q_UNUSED(layerCount); |
| if (needsFullSpec) { |
| texFuncs->glCompressedTextureImage2D(textureId, cubeFace, bindingTarget, mipLevel, |
| format, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| 0, dataSize, data, options); |
| } else { |
| texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel, |
| 0, 0, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| format, dataSize, data, options); |
| } |
| break; |
| |
| case QOpenGLTexture::TargetCubeMapArray: { |
| int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX; |
| int layerFace = 6 * layer + faceIndex; |
| if (!needsFullSpec) { |
| texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, |
| 0, 0, layerFace, |
| mipLevelSize(mipLevel, dimensions[0]), |
| mipLevelSize(mipLevel, dimensions[1]), |
| layerCount, |
| format, dataSize, data, options); |
| } |
| break; |
| } |
| |
| case QOpenGLTexture::TargetRectangle: |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| case QOpenGLTexture::TargetBuffer: |
| // We don't upload pixel data for these targets |
| qWarning("QOpenGLTexture::setCompressedData(): Texture target does not support pixel data upload"); |
| break; |
| } |
| |
| // If requested perform automatic mip map generation |
| if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) { |
| Q_Q(QOpenGLTexture); |
| q->generateMipMaps(); |
| } |
| } |
| |
| void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::WrapMode mode) |
| { |
| switch (target) { |
| case QOpenGLTexture::Target1D: |
| case QOpenGLTexture::Target1DArray: |
| case QOpenGLTexture::TargetBuffer: |
| wrapModes[0] = mode; |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode); |
| break; |
| |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::Target2DArray: |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetCubeMapArray: |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| case QOpenGLTexture::TargetRectangle: |
| wrapModes[0] = wrapModes[1] = mode; |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode); |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode); |
| break; |
| |
| case QOpenGLTexture::Target3D: |
| wrapModes[0] = wrapModes[1] = wrapModes[2] = mode; |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode); |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode); |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_R, mode); |
| break; |
| } |
| } |
| |
| void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::CoordinateDirection direction, QOpenGLTexture::WrapMode mode) |
| { |
| switch (target) { |
| case QOpenGLTexture::Target1D: |
| case QOpenGLTexture::Target1DArray: |
| case QOpenGLTexture::TargetBuffer: |
| switch (direction) { |
| case QOpenGLTexture::DirectionS: |
| wrapModes[0] = mode; |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode); |
| break; |
| |
| case QOpenGLTexture::DirectionT: |
| case QOpenGLTexture::DirectionR: |
| qWarning("QOpenGLTexture::setWrapMode() direction not valid for this texture target"); |
| break; |
| } |
| break; |
| |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::Target2DArray: |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetCubeMapArray: |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| case QOpenGLTexture::TargetRectangle: |
| switch (direction) { |
| case QOpenGLTexture::DirectionS: |
| wrapModes[0] = mode; |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode); |
| break; |
| |
| case QOpenGLTexture::DirectionT: |
| wrapModes[1] = mode; |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode); |
| break; |
| |
| case QOpenGLTexture::DirectionR: |
| qWarning("QOpenGLTexture::setWrapMode() direction not valid for this texture target"); |
| break; |
| } |
| break; |
| |
| case QOpenGLTexture::Target3D: |
| switch (direction) { |
| case QOpenGLTexture::DirectionS: |
| wrapModes[0] = mode; |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode); |
| break; |
| |
| case QOpenGLTexture::DirectionT: |
| wrapModes[1] = mode; |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode); |
| break; |
| |
| case QOpenGLTexture::DirectionR: |
| wrapModes[2] = mode; |
| texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode); |
| break; |
| } |
| break; |
| } |
| } |
| |
| QOpenGLTexture::WrapMode QOpenGLTexturePrivate::wrapMode(QOpenGLTexture::CoordinateDirection direction) const |
| { |
| switch (target) { |
| case QOpenGLTexture::Target1D: |
| case QOpenGLTexture::Target1DArray: |
| case QOpenGLTexture::TargetBuffer: |
| switch (direction) { |
| case QOpenGLTexture::DirectionS: |
| return wrapModes[0]; |
| |
| case QOpenGLTexture::DirectionT: |
| case QOpenGLTexture::DirectionR: |
| qWarning("QOpenGLTexture::wrapMode() direction not valid for this texture target"); |
| return QOpenGLTexture::Repeat; |
| } |
| break; |
| |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::Target2DArray: |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetCubeMapArray: |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| case QOpenGLTexture::TargetRectangle: |
| switch (direction) { |
| case QOpenGLTexture::DirectionS: |
| return wrapModes[0]; |
| |
| case QOpenGLTexture::DirectionT: |
| return wrapModes[1]; |
| |
| case QOpenGLTexture::DirectionR: |
| qWarning("QOpenGLTexture::wrapMode() direction not valid for this texture target"); |
| return QOpenGLTexture::Repeat; |
| } |
| break; |
| |
| case QOpenGLTexture::Target3D: |
| switch (direction) { |
| case QOpenGLTexture::DirectionS: |
| return wrapModes[0]; |
| |
| case QOpenGLTexture::DirectionT: |
| return wrapModes[1]; |
| |
| case QOpenGLTexture::DirectionR: |
| return wrapModes[2]; |
| } |
| break; |
| } |
| // Should never get here |
| Q_ASSERT(false); |
| return QOpenGLTexture::Repeat; |
| } |
| |
| QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target viewTarget, |
| QOpenGLTexture::TextureFormat viewFormat, |
| int minimumMipmapLevel, int maximumMipmapLevel, |
| int minimumLayer, int maximumLayer) const |
| { |
| // Do sanity checks - see http://www.opengl.org/wiki/GLAPI/glTextureView |
| |
| // Check the targets are compatible |
| bool viewTargetCompatible = false; |
| switch (target) { |
| case QOpenGLTexture::Target1D: |
| case QOpenGLTexture::Target1DArray: |
| viewTargetCompatible = (viewTarget == QOpenGLTexture::Target1D |
| || viewTarget == QOpenGLTexture::Target1DArray); |
| break; |
| |
| |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::Target2DArray: |
| viewTargetCompatible = (viewTarget == QOpenGLTexture::Target2D |
| || viewTarget == QOpenGLTexture::Target2DArray); |
| break; |
| |
| case QOpenGLTexture::Target3D: |
| viewTargetCompatible = (viewTarget == QOpenGLTexture::Target3D); |
| break; |
| |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetCubeMapArray: |
| viewTargetCompatible = (viewTarget == QOpenGLTexture::TargetCubeMap |
| || viewTarget == QOpenGLTexture::Target2D |
| || viewTarget == QOpenGLTexture::Target2DArray |
| || viewTarget == QOpenGLTexture::TargetCubeMapArray); |
| break; |
| |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| viewTargetCompatible = (viewTarget == QOpenGLTexture::Target2DMultisample |
| || viewTarget == QOpenGLTexture::Target2DMultisampleArray); |
| break; |
| |
| case QOpenGLTexture::TargetRectangle: |
| viewTargetCompatible = (viewTarget == QOpenGLTexture::TargetRectangle); |
| break; |
| |
| case QOpenGLTexture::TargetBuffer: |
| // Cannot be used with texture views |
| break; |
| } |
| |
| if (!viewTargetCompatible) { |
| qWarning("QOpenGLTexture::createTextureView(): Incompatible source and view targets"); |
| return nullptr; |
| } |
| |
| // Check the formats are compatible |
| bool viewFormatCompatible = false; |
| switch (formatClass) { |
| case QOpenGLTexture::NoFormatClass: |
| break; |
| |
| case QOpenGLTexture::FormatClass_128Bit: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA32F |
| || viewFormat == QOpenGLTexture::RGBA32U |
| || viewFormat == QOpenGLTexture::RGBA32I); |
| break; |
| |
| case QOpenGLTexture::FormatClass_96Bit: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB32F |
| || viewFormat == QOpenGLTexture::RGB32U |
| || viewFormat == QOpenGLTexture::RGB32I); |
| break; |
| |
| case QOpenGLTexture::FormatClass_64Bit: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA16F |
| || viewFormat == QOpenGLTexture::RG32F |
| || viewFormat == QOpenGLTexture::RGBA16U |
| || viewFormat == QOpenGLTexture::RG32U |
| || viewFormat == QOpenGLTexture::RGBA16I |
| || viewFormat == QOpenGLTexture::RG32I |
| || viewFormat == QOpenGLTexture::RGBA16_UNorm |
| || viewFormat == QOpenGLTexture::RGBA16_SNorm); |
| break; |
| |
| case QOpenGLTexture::FormatClass_48Bit: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB16_UNorm |
| || viewFormat == QOpenGLTexture::RGB16_SNorm |
| || viewFormat == QOpenGLTexture::RGB16F |
| || viewFormat == QOpenGLTexture::RGB16U |
| || viewFormat == QOpenGLTexture::RGB16I); |
| break; |
| |
| case QOpenGLTexture::FormatClass_32Bit: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RG16F |
| || viewFormat == QOpenGLTexture::RG11B10F |
| || viewFormat == QOpenGLTexture::R32F |
| || viewFormat == QOpenGLTexture::RGB10A2 |
| || viewFormat == QOpenGLTexture::RGBA8U |
| || viewFormat == QOpenGLTexture::RG16U |
| || viewFormat == QOpenGLTexture::R32U |
| || viewFormat == QOpenGLTexture::RGBA8I |
| || viewFormat == QOpenGLTexture::RG16I |
| || viewFormat == QOpenGLTexture::R32I |
| || viewFormat == QOpenGLTexture::RGBA8_UNorm |
| || viewFormat == QOpenGLTexture::RG16_UNorm |
| || viewFormat == QOpenGLTexture::RGBA8_SNorm |
| || viewFormat == QOpenGLTexture::RG16_SNorm |
| || viewFormat == QOpenGLTexture::SRGB8_Alpha8 |
| || viewFormat == QOpenGLTexture::RGB9E5); |
| break; |
| |
| case QOpenGLTexture::FormatClass_24Bit: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB8_UNorm |
| || viewFormat == QOpenGLTexture::RGB8_SNorm |
| || viewFormat == QOpenGLTexture::SRGB8 |
| || viewFormat == QOpenGLTexture::RGB8U |
| || viewFormat == QOpenGLTexture::RGB8I); |
| break; |
| |
| case QOpenGLTexture::FormatClass_16Bit: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::R16F |
| || viewFormat == QOpenGLTexture::RG8U |
| || viewFormat == QOpenGLTexture::R16U |
| || viewFormat == QOpenGLTexture::RG8I |
| || viewFormat == QOpenGLTexture::R16I |
| || viewFormat == QOpenGLTexture::RG8_UNorm |
| || viewFormat == QOpenGLTexture::R16_UNorm |
| || viewFormat == QOpenGLTexture::RG8_SNorm |
| || viewFormat == QOpenGLTexture::R16_SNorm); |
| break; |
| |
| case QOpenGLTexture::FormatClass_8Bit: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::R8U |
| || viewFormat == QOpenGLTexture::R8I |
| || viewFormat == QOpenGLTexture::R8_UNorm |
| || viewFormat == QOpenGLTexture::R8_SNorm); |
| break; |
| |
| case QOpenGLTexture::FormatClass_RGTC1_R: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::R_ATI1N_UNorm |
| || viewFormat == QOpenGLTexture::R_ATI1N_SNorm); |
| break; |
| |
| case QOpenGLTexture::FormatClass_RGTC2_RG: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RG_ATI2N_UNorm |
| || viewFormat == QOpenGLTexture::RG_ATI2N_SNorm); |
| break; |
| |
| case QOpenGLTexture::FormatClass_BPTC_Unorm: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB_BP_UNorm |
| || viewFormat == QOpenGLTexture::SRGB_BP_UNorm); |
| break; |
| |
| case QOpenGLTexture::FormatClass_BPTC_Float: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT |
| || viewFormat == QOpenGLTexture::RGB_BP_SIGNED_FLOAT); |
| break; |
| |
| case QOpenGLTexture::FormatClass_S3TC_DXT1_RGB: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RGB_DXT1 |
| || viewFormat == QOpenGLTexture::SRGB_DXT1); |
| break; |
| |
| case QOpenGLTexture::FormatClass_S3TC_DXT1_RGBA: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA_DXT1 |
| || viewFormat == QOpenGLTexture::SRGB_Alpha_DXT1); |
| break; |
| |
| case QOpenGLTexture::FormatClass_S3TC_DXT3_RGBA: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA_DXT3 |
| || viewFormat == QOpenGLTexture::SRGB_Alpha_DXT3); |
| break; |
| |
| case QOpenGLTexture::FormatClass_S3TC_DXT5_RGBA: |
| viewFormatCompatible = (viewFormat == QOpenGLTexture::RGBA_DXT5 |
| || viewFormat == QOpenGLTexture::SRGB_Alpha_DXT5); |
| break; |
| |
| case QOpenGLTexture::FormatClass_Unique: |
| viewFormatCompatible = (viewFormat == format); |
| break; |
| } |
| |
| if (!viewFormatCompatible) { |
| qWarning("QOpenGLTexture::createTextureView(): Incompatible source and view formats"); |
| return nullptr; |
| } |
| |
| |
| // Create a view |
| QOpenGLTexture *view = new QOpenGLTexture(viewTarget); |
| view->setFormat(viewFormat); |
| view->create(); |
| view->d_ptr->textureView = true; |
| texFuncs->glTextureView(view->textureId(), viewTarget, textureId, viewFormat, |
| minimumMipmapLevel, maximumMipmapLevel - minimumMipmapLevel + 1, |
| minimumLayer, maximumLayer - minimumLayer + 1); |
| return view; |
| } |
| |
| |
| /*! |
| \class QOpenGLTexture |
| \inmodule QtGui |
| \since 5.2 |
| \wrapper |
| \brief The QOpenGLTexture class encapsulates an OpenGL texture object. |
| |
| QOpenGLTexture makes it easy to work with OpenGL textures and the myriad features |
| and targets that they offer depending upon the capabilities of your OpenGL implementation. |
| |
| The typical usage pattern for QOpenGLTexture is |
| \list |
| \li Instantiate the object specifying the texture target type |
| \li Set properties that affect the storage requirements e.g. storage format, dimensions |
| \li Allocate the server-side storage |
| \li Optionally upload pixel data |
| \li Optionally set any additional properties e.g. filtering and border options |
| \li Render with texture or render to texture |
| \endlist |
| |
| In the common case of simply using a QImage as the source of texture pixel data |
| most of the above steps are performed automatically. |
| |
| \code |
| // Prepare texture |
| QOpenGLTexture *texture = new QOpenGLTexture(QImage(fileName).mirrored()); |
| texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); |
| texture->setMagnificationFilter(QOpenGLTexture::Linear); |
| ... |
| // Render with texture |
| texture->bind(); |
| glDrawArrays(...); |
| \endcode |
| |
| Note that the QImage is mirrored vertically to account for the fact that |
| OpenGL and QImage use opposite directions for the y axis. Another option |
| would be to transform your texture coordinates. |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::Filter |
| This enum defines the filtering parameters for a QOpenGLTexture object. |
| \value Nearest Equivalent to GL_NEAREST |
| \value Linear Equivalent to GL_LINEAR |
| \value NearestMipMapNearest Equivalent to GL_NEAREST_MIPMAP_NEAREST |
| \value NearestMipMapLinear Equivalent to GL_NEAREST_MIPMAP_LINEAR |
| \value LinearMipMapNearest Equivalent to GL_LINEAR_MIPMAP_NEAREST |
| \value LinearMipMapLinear Equivalent to GL_LINEAR_MIPMAP_LINEAR |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::Target |
| This enum defines the texture target of a QOpenGLTexture object. |
| For more information on creating array textures, see \l{Array Texture}. |
| |
| \value Target1D A 1-dimensional texture. |
| Equivalent to GL_TEXTURE_1D. |
| \value Target1DArray An array of 1-dimensional textures. |
| Equivalent to GL_TEXTURE_1D_ARRAY |
| \value Target2D A 2-dimensional texture. |
| Equivalent to GL_TEXTURE_2D |
| \value Target2DArray An array of 2-dimensional textures. |
| Equivalent to GL_TEXTURE_2D_ARRAY |
| \value Target3D A 3-dimensional texture. |
| Equivalent to GL_TEXTURE_3D |
| \value TargetCubeMap A cubemap texture. |
| Equivalent to GL_TEXTURE_CUBE_MAP |
| \value TargetCubeMapArray An array of cubemap textures. |
| Equivalent to GL_TEXTURE_CUBE_MAP_ARRAY |
| \value Target2DMultisample A 2-dimensional texture with multisample support. |
| Equivalent to GL_TEXTURE_2D_MULTISAMPLE |
| \value Target2DMultisampleArray An array of 2-dimensional textures with multisample support. |
| Equivalent to GL_TEXTURE_2D_MULTISAMPLE_ARRAY |
| \value TargetRectangle A rectangular 2-dimensional texture. |
| Equivalent to GL_TEXTURE_RECTANGLE |
| \value TargetBuffer A texture with data from an OpenGL buffer object. |
| Equivalent to GL_TEXTURE_BUFFER |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::BindingTarget |
| This enum defines the possible binding targets of texture units. |
| |
| \value BindingTarget1D Equivalent to GL_TEXTURE_BINDING_1D |
| \value BindingTarget1DArray Equivalent to GL_TEXTURE_BINDING_1D_ARRAY |
| \value BindingTarget2D Equivalent to GL_TEXTURE_BINDING_2D |
| \value BindingTarget2DArray Equivalent to GL_TEXTURE_BINDING_2D_ARRAY |
| \value BindingTarget3D Equivalent to GL_TEXTURE_BINDING_3D |
| \value BindingTargetCubeMap Equivalent to GL_TEXTURE_BINDING_CUBE_MAP |
| \value BindingTargetCubeMapArray Equivalent to GL_TEXTURE_BINDING_CUBE_MAP_ARRAY |
| \value BindingTarget2DMultisample Equivalent to GL_TEXTURE_BINDING_2D_MULTISAMPLE |
| \value BindingTarget2DMultisampleArray Equivalent to GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY |
| \value BindingTargetRectangle Equivalent to GL_TEXTURE_BINDING_RECTANGLE |
| \value BindingTargetBuffer Equivalent to GL_TEXTURE_BINDING_BUFFER |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::MipMapGeneration |
| This enum defines the options to control mipmap generation. |
| |
| \value GenerateMipMaps Mipmaps should be generated |
| \value DontGenerateMipMaps Mipmaps should not be generated |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::TextureUnitReset |
| This enum defines options ot control texture unit activation. |
| |
| \value ResetTextureUnit The previous active texture unit will be reset |
| \value DontResetTextureUnit The previous active texture unit will not be rest |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::TextureFormat |
| This enum defines the possible texture formats. Depending upon your OpenGL |
| implementation only a subset of these may be supported. |
| |
| \value NoFormat Equivalent to GL_NONE |
| |
| \value R8_UNorm Equivalent to GL_R8 |
| \value RG8_UNorm Equivalent to GL_RG8 |
| \value RGB8_UNorm Equivalent to GL_RGB8 |
| \value RGBA8_UNorm Equivalent to GL_RGBA8 |
| |
| \value R16_UNorm Equivalent to GL_R16 |
| \value RG16_UNorm Equivalent to GL_RG16 |
| \value RGB16_UNorm Equivalent to GL_RGB16 |
| \value RGBA16_UNorm Equivalent to GL_RGBA16 |
| |
| \value R8_SNorm Equivalent to GL_R8_SNORM |
| \value RG8_SNorm Equivalent to GL_RG8_SNORM |
| \value RGB8_SNorm Equivalent to GL_RGB8_SNORM |
| \value RGBA8_SNorm Equivalent to GL_RGBA8_SNORM |
| |
| \value R16_SNorm Equivalent to GL_R16_SNORM |
| \value RG16_SNorm Equivalent to GL_RG16_SNORM |
| \value RGB16_SNorm Equivalent to GL_RGB16_SNORM |
| \value RGBA16_SNorm Equivalent to GL_RGBA16_SNORM |
| |
| \value R8U Equivalent to GL_R8UI |
| \value RG8U Equivalent to GL_RG8UI |
| \value RGB8U Equivalent to GL_RGB8UI |
| \value RGBA8U Equivalent to GL_RGBA8UI |
| |
| \value R16U Equivalent to GL_R16UI |
| \value RG16U Equivalent to GL_RG16UI |
| \value RGB16U Equivalent to GL_RGB16UI |
| \value RGBA16U Equivalent to GL_RGBA16UI |
| |
| \value R32U Equivalent to GL_R32UI |
| \value RG32U Equivalent to GL_RG32UI |
| \value RGB32U Equivalent to GL_RGB32UI |
| \value RGBA32U Equivalent to GL_RGBA32UI |
| |
| \value R8I Equivalent to GL_R8I |
| \value RG8I Equivalent to GL_RG8I |
| \value RGB8I Equivalent to GL_RGB8I |
| \value RGBA8I Equivalent to GL_RGBA8I |
| |
| \value R16I Equivalent to GL_R16I |
| \value RG16I Equivalent to GL_RG16I |
| \value RGB16I Equivalent to GL_RGB16I |
| \value RGBA16I Equivalent to GL_RGBA16I |
| |
| \value R32I Equivalent to GL_R32I |
| \value RG32I Equivalent to GL_RG32I |
| \value RGB32I Equivalent to GL_RGB32I |
| \value RGBA32I Equivalent to GL_RGBA32I |
| |
| \value R16F Equivalent to GL_R16F |
| \value RG16F Equivalent to GL_RG16F |
| \value RGB16F Equivalent to GL_RGB16F |
| \value RGBA16F Equivalent to GL_RGBA16F |
| |
| \value R32F Equivalent to GL_R32F |
| \value RG32F Equivalent to GL_RG32F |
| \value RGB32F Equivalent to GL_RGB32F |
| \value RGBA32F Equivalent to GL_RGBA32F |
| |
| \value RGB9E5 Equivalent to GL_RGB9_E5 |
| \value RG11B10F Equivalent to GL_R11F_G11F_B10F |
| \value RG3B2 Equivalent to GL_R3_G3_B2 |
| \value R5G6B5 Equivalent to GL_RGB565 |
| \value RGB5A1 Equivalent to GL_RGB5_A1 |
| \value RGBA4 Equivalent to GL_RGBA4 |
| \value RGB10A2 Equivalent to GL_RGB10_A2UI |
| |
| \value D16 Equivalent to GL_DEPTH_COMPONENT16 |
| \value D24 Equivalent to GL_DEPTH_COMPONENT24 |
| \value D24S8 Equivalent to GL_DEPTH24_STENCIL8 |
| \value D32 Equivalent to GL_DEPTH_COMPONENT32 |
| \value D32F Equivalent to GL_DEPTH_COMPONENT32F |
| \value D32FS8X24 Equivalent to GL_DEPTH32F_STENCIL8 |
| \value S8 Equivalent to GL_STENCIL_INDEX8. Introduced in Qt 5.4 |
| |
| \value RGB_DXT1 Equivalent to GL_COMPRESSED_RGB_S3TC_DXT1_EXT |
| \value RGBA_DXT1 Equivalent to GL_COMPRESSED_RGBA_S3TC_DXT1_EXT |
| \value RGBA_DXT3 Equivalent to GL_COMPRESSED_RGBA_S3TC_DXT3_EXT |
| \value RGBA_DXT5 Equivalent to GL_COMPRESSED_RGBA_S3TC_DXT5_EXT |
| \value R_ATI1N_UNorm Equivalent to GL_COMPRESSED_RED_RGTC1 |
| \value R_ATI1N_SNorm Equivalent to GL_COMPRESSED_SIGNED_RED_RGTC1 |
| \value RG_ATI2N_UNorm Equivalent to GL_COMPRESSED_RG_RGTC2 |
| \value RG_ATI2N_SNorm Equivalent to GL_COMPRESSED_SIGNED_RG_RGTC2 |
| \value RGB_BP_UNSIGNED_FLOAT Equivalent to GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB |
| \value RGB_BP_SIGNED_FLOAT Equivalent to GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB |
| \value RGB_BP_UNorm Equivalent to GL_COMPRESSED_RGBA_BPTC_UNORM_ARB |
| \value R11_EAC_UNorm Equivalent to GL_COMPRESSED_R11_EAC |
| \value R11_EAC_SNorm Equivalent to GL_COMPRESSED_SIGNED_R11_EAC |
| \value RG11_EAC_UNorm Equivalent to GL_COMPRESSED_RG11_EAC |
| \value RG11_EAC_SNorm Equivalent to GL_COMPRESSED_SIGNED_RG11_EAC |
| \value RGB8_ETC2 Equivalent to GL_COMPRESSED_RGB8_ETC2 |
| \value SRGB8_ETC2 Equivalent to GL_COMPRESSED_SRGB8_ETC2 |
| \value RGB8_PunchThrough_Alpha1_ETC2 Equivalent to GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 |
| \value SRGB8_PunchThrough_Alpha1_ETC2 Equivalent to GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 |
| \value RGBA8_ETC2_EAC Equivalent to GL_COMPRESSED_RGBA8_ETC2_EAC |
| \value SRGB8_Alpha8_ETC2_EAC Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC |
| \value RGB8_ETC1 Equivalent to GL_ETC1_RGB8_OES |
| \value RGBA_ASTC_4x4 Equivalent to GL_COMPRESSED_RGBA_ASTC_4x4_KHR |
| \value RGBA_ASTC_5x4 Equivalent to GL_COMPRESSED_RGBA_ASTC_5x4_KHR |
| \value RGBA_ASTC_5x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_5x5_KHR |
| \value RGBA_ASTC_6x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_6x5_KHR |
| \value RGBA_ASTC_6x6 Equivalent to GL_COMPRESSED_RGBA_ASTC_6x6_KHR |
| \value RGBA_ASTC_8x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_8x5_KHR |
| \value RGBA_ASTC_8x6 Equivalent to GL_COMPRESSED_RGBA_ASTC_8x6_KHR |
| \value RGBA_ASTC_8x8 Equivalent to GL_COMPRESSED_RGBA_ASTC_8x8_KHR |
| \value RGBA_ASTC_10x5 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x5_KHR |
| \value RGBA_ASTC_10x6 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x6_KHR |
| \value RGBA_ASTC_10x8 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x8_KHR |
| \value RGBA_ASTC_10x10 Equivalent to GL_COMPRESSED_RGBA_ASTC_10x10_KHR |
| \value RGBA_ASTC_12x10 Equivalent to GL_COMPRESSED_RGBA_ASTC_12x10_KHR |
| \value RGBA_ASTC_12x12 Equivalent to GL_COMPRESSED_RGBA_ASTC_12x12_KHR |
| \value SRGB8_Alpha8_ASTC_4x4 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR |
| \value SRGB8_Alpha8_ASTC_5x4 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR |
| \value SRGB8_Alpha8_ASTC_5x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR |
| \value SRGB8_Alpha8_ASTC_6x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR |
| \value SRGB8_Alpha8_ASTC_6x6 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR |
| \value SRGB8_Alpha8_ASTC_8x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR |
| \value SRGB8_Alpha8_ASTC_8x6 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR |
| \value SRGB8_Alpha8_ASTC_8x8 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR |
| \value SRGB8_Alpha8_ASTC_10x5 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR |
| \value SRGB8_Alpha8_ASTC_10x6 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR |
| \value SRGB8_Alpha8_ASTC_10x8 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR |
| \value SRGB8_Alpha8_ASTC_10x10 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR |
| \value SRGB8_Alpha8_ASTC_12x10 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR |
| \value SRGB8_Alpha8_ASTC_12x12 Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR |
| |
| \value SRGB8 Equivalent to GL_SRGB8 |
| \value SRGB8_Alpha8 Equivalent to GL_SRGB8_ALPHA8 |
| \value SRGB_DXT1 Equivalent to GL_COMPRESSED_SRGB_S3TC_DXT1_EXT |
| \value SRGB_Alpha_DXT1 Equivalent to GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT |
| \value SRGB_Alpha_DXT3 Equivalent to GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT |
| \value SRGB_Alpha_DXT5 Equivalent to GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT |
| \value SRGB_BP_UNorm Equivalent to GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB |
| |
| \value DepthFormat Equivalent to GL_DEPTH_COMPONENT (only OpenGL ES 3 or ES 2 with OES_depth_texture) |
| \value AlphaFormat Equivalent to GL_ALPHA (OpenGL ES 2 only) |
| \value RGBFormat Equivalent to GL_RGB (OpenGL ES 2 only) |
| \value RGBAFormat Equivalent to GL_RGBA (OpenGL ES 2 only) |
| \value LuminanceFormat Equivalent to GL_LUMINANCE (OpenGL ES 2 only) |
| \value LuminanceAlphaFormat Equivalent to GL_LUMINANCE_ALPHA (OpenGL ES 2 only) |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::CubeMapFace |
| This enum defines the possible CubeMap faces. |
| |
| \value CubeMapPositiveX Equivalent to GL_TEXTURE_CUBE_MAP_POSITIVE_X |
| \value CubeMapNegativeX Equivalent to GL_TEXTURE_CUBE_MAP_NEGATIVE_X |
| \value CubeMapPositiveY Equivalent to GL_TEXTURE_CUBE_MAP_POSITIVE_Y |
| \value CubeMapNegativeY Equivalent to GL_TEXTURE_CUBE_MAP_NEGATIVE_Y |
| \value CubeMapPositiveZ Equivalent to GL_TEXTURE_CUBE_MAP_POSITIVE_Z |
| \value CubeMapNegativeZ Equivalent to GL_TEXTURE_CUBE_MAP_NEGATIVE_Z |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::PixelFormat |
| This enum defines the possible client-side pixel formats for a pixel |
| transfer operation. |
| |
| \value NoSourceFormat Equivalent to GL_NONE |
| \value Red Equivalent to GL_RED |
| \value RG Equivalent to GL_RG |
| \value RGB Equivalent to GL_RGB |
| \value BGR Equivalent to GL_BGR |
| \value RGBA Equivalent to GL_RGBA |
| \value BGRA Equivalent to GL_BGRA |
| \value Red_Integer Equivalent to GL_RED_INTEGER |
| \value RG_Integer Equivalent to GL_RG_INTEGER |
| \value RGB_Integer Equivalent to GL_RGB_INTEGER |
| \value BGR_Integer Equivalent to GL_BGR_INTEGER |
| \value RGBA_Integer Equivalent to GL_RGBA_INTEGER |
| \value BGRA_Integer Equivalent to GL_BGRA_INTEGER |
| \value Stencil Equivalent to GL_STENCIL_INDEX. Introduced in Qt 5.4 |
| \value Depth Equivalent to GL_DEPTH_COMPONENT |
| \value DepthStencil Equivalent to GL_DEPTH_STENCIL |
| \value Alpha Equivalent to GL_ALPHA (OpenGL ES 2 only) |
| \value Luminance Equivalent to GL_LUMINANCE (OpenGL ES 2 only) |
| \value LuminanceAlpha Equivalent to GL_LUMINANCE_ALPHA (OpenGL ES 2 only) |
| |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::PixelType |
| This enum defines the possible pixel data types for a pixel transfer operation |
| |
| \value NoPixelType Equivalent to GL_NONE |
| \value Int8 Equivalent to GL_BYTE |
| \value UInt8 Equivalent to GL_UNSIGNED_BYTE |
| \value Int16 Equivalent to GL_SHORT |
| \value UInt16 Equivalent to GL_UNSIGNED_SHORT |
| \value Int32 Equivalent to GL_INT |
| \value UInt32 Equivalent to GL_UNSIGNED_INT |
| \value Float16 Equivalent to GL_HALF_FLOAT |
| \value Float16OES Equivalent to GL_HALF_FLOAT_OES |
| \value Float32 Equivalent to GL_FLOAT |
| \value UInt32_RGB9_E5 Equivalent to GL_UNSIGNED_INT_5_9_9_9_REV |
| \value UInt32_RG11B10F Equivalent to GL_UNSIGNED_INT_10F_11F_11F_REV |
| \value UInt8_RG3B2 Equivalent to GL_UNSIGNED_BYTE_3_3_2 |
| \value UInt8_RG3B2_Rev Equivalent to GL_UNSIGNED_BYTE_2_3_3_REV |
| \value UInt16_RGB5A1 Equivalent to GL_UNSIGNED_SHORT_5_5_5_1 |
| \value UInt16_RGB5A1_Rev Equivalent to GL_UNSIGNED_SHORT_1_5_5_5_REV |
| \value UInt16_R5G6B5 Equivalent to GL_UNSIGNED_SHORT_5_6_5 |
| \value UInt16_R5G6B5_Rev Equivalent to GL_UNSIGNED_SHORT_5_6_5_REV |
| \value UInt16_RGBA4 Equivalent to GL_UNSIGNED_SHORT_4_4_4_4 |
| \value UInt16_RGBA4_Rev Equivalent to GL_UNSIGNED_SHORT_4_4_4_4_REV |
| \value UInt32_RGBA8 Equivalent to GL_UNSIGNED_INT_8_8_8_8 |
| \value UInt32_RGBA8_Rev Equivalent to GL_UNSIGNED_INT_8_8_8_8_REV |
| \value UInt32_RGB10A2 Equivalent to GL_UNSIGNED_INT_10_10_10_2 |
| \value UInt32_RGB10A2_Rev Equivalent to GL_UNSIGNED_INT_2_10_10_10_REV |
| \value UInt32_D24S8 Equivalent to GL_UNSIGNED_INT_24_8. Introduced in Qt 5.4 |
| \value Float32_D32_UInt32_S8_X24 Equivalent to GL_FLOAT_32_UNSIGNED_INT_24_8_REV. Introduced in Qt 5.4 |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::Feature |
| This enum defines the OpenGL texture-related features that can be tested for. |
| |
| \value ImmutableStorage Support for immutable texture storage |
| \value ImmutableMultisampleStorage Support for immutable texture storage with |
| multisample targets |
| \value TextureRectangle Support for the GL_TEXTURE_RECTANGLE target |
| \value TextureArrays Support for texture targets with array layers |
| \value Texture3D Support for the 3 dimensional texture target |
| \value TextureMultisample Support for texture targets that have multisample capabilities |
| \value TextureBuffer Support for textures that use OpenGL buffer objects |
| as their data source |
| \value TextureCubeMapArrays Support for cubemap array texture target |
| \value Swizzle Support for texture component swizzle masks |
| \value StencilTexturing Support for stencil texturing (i.e. looking up depth or stencil |
| components of a combined depth/stencil format texture in GLSL shaders). |
| \value AnisotropicFiltering Support for anisotropic texture filtering |
| \value NPOTTextures Basic support for non-power-of-two textures |
| \value NPOTTextureRepeat Full support for non-power-of-two textures including texture |
| repeat modes |
| \value Texture1D Support for the 1 dimensional texture target |
| \value TextureComparisonOperators Support for texture comparison operators |
| \value TextureMipMapLevel Support for setting the base and maximum mipmap levels |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::SwizzleComponent |
| This enum defines the texture color components that can be assigned a swizzle mask. |
| |
| \value SwizzleRed The red component. Equivalent to GL_TEXTURE_SWIZZLE_R |
| \value SwizzleGreen The green component. Equivalent to GL_TEXTURE_SWIZZLE_G |
| \value SwizzleBlue The blue component. Equivalent to GL_TEXTURE_SWIZZLE_B |
| \value SwizzleAlpha The alpha component. Equivalent to GL_TEXTURE_SWIZZLE_A |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::SwizzleValue |
| This enum defines the possible mask values for texture swizzling. |
| |
| \value RedValue Maps the component to the red channel. Equivalent to GL_RED |
| \value GreenValue Maps the component to the green channel. Equivalent to GL_GREEN |
| \value BlueValue Maps the component to the blue channel. Equivalent to GL_BLUE |
| \value AlphaValue Maps the component to the alpha channel. Equivalent to GL_ALPHA |
| \value ZeroValue Maps the component to a fixed value of 0. Equivalent to GL_ZERO |
| \value OneValue Maps the component to a fixed value of 1. Equivalent to GL_ONE |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::WrapMode |
| This enum defines the possible texture coordinate wrapping modes. |
| |
| \value Repeat Texture coordinate is repeated. Equivalent to GL_REPEAT |
| \value MirroredRepeat Texture coordinate is reflected about 0 and 1. Equivalent to GL_MIRRORED_REPEAT |
| \value ClampToEdge Clamps the texture coordinates to [0,1]. Equivalent to GL_CLAMP_TO_EDGE |
| \value ClampToBorder As for ClampToEdge but also blends samples at 0 and 1 with a |
| fixed border color. Equivalent to GL_CLAMP_TO_BORDER |
| */ |
| |
| /*! |
| \enum QOpenGLTexture::CoordinateDirection |
| This enum defines the possible texture coordinate directions |
| |
| \value DirectionS The horizontal direction. Equivalent to GL_TEXTURE_WRAP_S |
| \value DirectionT The vertical direction. Equivalent to GL_TEXTURE_WRAP_T |
| \value DirectionR The depth direction. Equivalent to GL_TEXTURE_WRAP_R |
| */ |
| |
| /*! |
| Creates a QOpenGLTexture object that can later be bound to \a target. |
| |
| This does not create the underlying OpenGL texture object. Therefore, |
| construction using this constructor does not require a valid current |
| OpenGL context. |
| */ |
| QOpenGLTexture::QOpenGLTexture(Target target) |
| : d_ptr(new QOpenGLTexturePrivate(target, this)) |
| { |
| } |
| |
| /*! |
| Creates a QOpenGLTexture object that can later be bound to the 2D texture |
| target and contains the pixel data contained in \a image. If you wish |
| to have a chain of mipmaps generated then set \a genMipMaps to \c true (this |
| is the default). |
| |
| This does create the underlying OpenGL texture object. Therefore, |
| construction using this constructor does require a valid current |
| OpenGL context. |
| */ |
| QOpenGLTexture::QOpenGLTexture(const QImage& image, MipMapGeneration genMipMaps) |
| : QOpenGLTexture(QOpenGLTexture::Target2D) |
| { |
| setData(image, genMipMaps); |
| } |
| |
| QOpenGLTexture::~QOpenGLTexture() |
| { |
| } |
| |
| /*! |
| Returns the binding target of this texture. |
| |
| \since 5.4 |
| */ |
| QOpenGLTexture::Target QOpenGLTexture::target() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->target; |
| } |
| |
| /*! |
| Creates the underlying OpenGL texture object. This requires a current valid |
| OpenGL context. If the texture object already exists, this function does |
| nothing. |
| |
| Once the texture object is created you can obtain the object |
| name from the textureId() function. This may be useful if you wish to make |
| some raw OpenGL calls related to this texture. |
| |
| Normally it should not be necessary to call this function directly as all |
| functions that set properties of the texture object implicitly call create() |
| on your behalf. |
| |
| Returns \c true if the creation succeeded, otherwise returns \c false. |
| |
| \sa destroy(), isCreated(), textureId() |
| */ |
| bool QOpenGLTexture::create() |
| { |
| Q_D(QOpenGLTexture); |
| return d->create(); |
| } |
| |
| /*! |
| Destroys the underlying OpenGL texture object. This requires a current valid |
| OpenGL context. |
| |
| \sa create(), isCreated(), textureId() |
| */ |
| void QOpenGLTexture::destroy() |
| { |
| Q_D(QOpenGLTexture); |
| return d->destroy(); |
| } |
| |
| /*! |
| Returns \c true if the underlying OpenGL texture object has been created. |
| |
| \sa create(), destroy(), textureId() |
| */ |
| bool QOpenGLTexture::isCreated() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->textureId != 0; |
| } |
| |
| /*! |
| Returns the name of the underlying OpenGL texture object or 0 if it has |
| not yet been created. |
| |
| \sa create(), destroy(), isCreated() |
| */ |
| GLuint QOpenGLTexture::textureId() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->textureId; |
| } |
| |
| /*! |
| Binds this texture to the currently active texture unit ready for |
| rendering. Note that you do not need to bind QOpenGLTexture objects |
| in order to modify them as the implementation makes use of the |
| EXT_direct_state_access extension where available and simulates it |
| where it is not. |
| |
| \sa release() |
| */ |
| void QOpenGLTexture::bind() |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->bind(); |
| } |
| |
| /*! |
| Binds this texture to texture unit \a unit ready for |
| rendering. Note that you do not need to bind QOpenGLTexture objects |
| in order to modify them as the implementation makes use of the |
| EXT_direct_state_access extension where available and simulates it |
| where it is not. |
| |
| If parameter \a reset is \c true then this function will restore |
| the active unit to the texture unit that was active upon entry. |
| |
| \sa release() |
| */ |
| void QOpenGLTexture::bind(uint unit, TextureUnitReset reset) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->bind(unit, reset); |
| } |
| |
| /*! |
| Unbinds this texture from the currently active texture unit. |
| |
| \sa bind() |
| */ |
| void QOpenGLTexture::release() |
| { |
| Q_D(QOpenGLTexture); |
| d->release(); |
| } |
| |
| /*! |
| Unbinds this texture from texture unit \a unit. |
| |
| If parameter \a reset is \c true then this function |
| will restore the active unit to the texture unit that was active |
| upon entry. |
| */ |
| void QOpenGLTexture::release(uint unit, TextureUnitReset reset) |
| { |
| Q_D(QOpenGLTexture); |
| d->release(unit, reset); |
| } |
| |
| /*! |
| Returns \c true if this texture is bound to the corresponding target |
| of the currently active texture unit. |
| |
| \sa bind(), release() |
| */ |
| bool QOpenGLTexture::isBound() const |
| { |
| Q_D(const QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| return d->isBound(); |
| } |
| |
| /*! |
| Returns \c true if this texture is bound to the corresponding target |
| of texture unit \a unit. |
| |
| \sa bind(), release() |
| */ |
| bool QOpenGLTexture::isBound(uint unit) |
| { |
| Q_D(const QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| return d->isBound(unit); |
| } |
| |
| /*! |
| Returns the textureId of the texture that is bound to the \a target |
| of the currently active texture unit. |
| */ |
| GLuint QOpenGLTexture::boundTextureId(BindingTarget target) |
| { |
| QOpenGLContext *ctx = QOpenGLContext::currentContext(); |
| if (!ctx) { |
| qWarning("QOpenGLTexture::boundTextureId() requires a valid current context"); |
| return 0; |
| } |
| |
| GLint textureId = 0; |
| ctx->functions()->glGetIntegerv(target, &textureId); |
| return static_cast<GLuint>(textureId); |
| } |
| |
| /*! |
| Returns the textureId of the texture that is bound to the \a target |
| of the texture unit \a unit. |
| */ |
| GLuint QOpenGLTexture::boundTextureId(uint unit, BindingTarget target) |
| { |
| QOpenGLContext *ctx = QOpenGLContext::currentContext(); |
| if (!ctx) { |
| qWarning("QOpenGLTexture::boundTextureId() requires a valid current context"); |
| return 0; |
| } |
| |
| QOpenGLFunctions *funcs = ctx->functions(); |
| funcs->initializeOpenGLFunctions(); |
| |
| GLint oldTextureUnit = 0; |
| funcs->glGetIntegerv(GL_ACTIVE_TEXTURE, &oldTextureUnit); |
| |
| funcs->glActiveTexture(unit); |
| GLint textureId = 0; |
| funcs->glGetIntegerv(target, &textureId); |
| funcs->glActiveTexture(oldTextureUnit); |
| |
| return static_cast<GLuint>(textureId); |
| } |
| |
| /*! |
| Sets the format of this texture object to \a format. This function |
| must be called before texture storage is allocated. |
| |
| Note that all formats may not be supported. The exact set of supported |
| formats is dependent upon your OpenGL implementation and version. |
| |
| \sa format(), allocateStorage() |
| */ |
| void QOpenGLTexture::setFormat(TextureFormat format) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| if (isStorageAllocated()) { |
| qWarning("QOpenGLTexture::setFormat(): Cannot change format once storage has been allocated"); |
| return; |
| } |
| |
| d->format = format; |
| |
| switch (format) { |
| case NoFormat: |
| d->formatClass = NoFormatClass; |
| break; |
| |
| case RGBA32F: |
| case RGBA32U: |
| case RGBA32I: |
| d->formatClass = FormatClass_128Bit; |
| break; |
| |
| case RGB32F: |
| case RGB32U: |
| case RGB32I: |
| d->formatClass = FormatClass_96Bit; |
| break; |
| |
| case RGBA16F: |
| case RG32F: |
| case RGBA16U: |
| case RG32U: |
| case RGBA16I: |
| case RG32I: |
| case RGBA16_UNorm: |
| case RGBA16_SNorm: |
| d->formatClass = FormatClass_64Bit; |
| break; |
| |
| case RGB16_UNorm: |
| case RGB16_SNorm: |
| case RGB16F: |
| case RGB16U: |
| case RGB16I: |
| d->formatClass = FormatClass_48Bit; |
| break; |
| |
| case RG16F: |
| case RG11B10F: |
| case R32F: |
| case RGB10A2: |
| case RGBA8U: |
| case RG16U: |
| case R32U: |
| case RGBA8I: |
| case RG16I: |
| case R32I: |
| case RGBA8_UNorm: |
| case RG16_UNorm: |
| case RGBA8_SNorm: |
| case RG16_SNorm: |
| case SRGB8_Alpha8: |
| case RGB9E5: |
| d->formatClass = FormatClass_32Bit; |
| break; |
| |
| case RGB8_UNorm: |
| case RGB8_SNorm: |
| case SRGB8: |
| case RGB8U: |
| case RGB8I: |
| d->formatClass = FormatClass_24Bit; |
| break; |
| |
| case R16F: |
| case RG8U: |
| case R16U: |
| case RG8I: |
| case R16I: |
| case RG8_UNorm: |
| case R16_UNorm: |
| case RG8_SNorm: |
| case R16_SNorm: |
| d->formatClass = FormatClass_16Bit; |
| break; |
| |
| case R8U: |
| case R8I: |
| case R8_UNorm: |
| case R8_SNorm: |
| d->formatClass = FormatClass_8Bit; |
| break; |
| |
| case R_ATI1N_UNorm: |
| case R_ATI1N_SNorm: |
| d->formatClass = FormatClass_RGTC1_R; |
| break; |
| |
| case RG_ATI2N_UNorm: |
| case RG_ATI2N_SNorm: |
| d->formatClass = FormatClass_RGTC2_RG; |
| break; |
| |
| case RGB_BP_UNorm: |
| case SRGB_BP_UNorm: |
| d->formatClass = FormatClass_BPTC_Unorm; |
| break; |
| |
| case RGB_BP_UNSIGNED_FLOAT: |
| case RGB_BP_SIGNED_FLOAT: |
| d->formatClass = FormatClass_BPTC_Float; |
| break; |
| |
| case RGB_DXT1: |
| case SRGB_DXT1: |
| d->formatClass = FormatClass_S3TC_DXT1_RGB; |
| break; |
| |
| case RGBA_DXT1: |
| case SRGB_Alpha_DXT1: |
| d->formatClass = FormatClass_S3TC_DXT1_RGBA; |
| break; |
| |
| case RGBA_DXT3: |
| case SRGB_Alpha_DXT3: |
| d->formatClass = FormatClass_S3TC_DXT3_RGBA; |
| break; |
| |
| case RGBA_DXT5: |
| case SRGB_Alpha_DXT5: |
| d->formatClass = FormatClass_S3TC_DXT5_RGBA; |
| break; |
| |
| case QOpenGLTexture::R11_EAC_UNorm: |
| case QOpenGLTexture::R11_EAC_SNorm: |
| case QOpenGLTexture::RG11_EAC_UNorm: |
| case QOpenGLTexture::RG11_EAC_SNorm: |
| case QOpenGLTexture::RGB8_ETC2: |
| case QOpenGLTexture::SRGB8_ETC2: |
| case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: |
| case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: |
| case QOpenGLTexture::RGBA8_ETC2_EAC: |
| case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: |
| case QOpenGLTexture::RGB8_ETC1: |
| case RG3B2: |
| case R5G6B5: |
| case RGB5A1: |
| case RGBA4: |
| case D16: |
| case D24: |
| case D24S8: |
| case D32: |
| case D32F: |
| case D32FS8X24: |
| case S8: |
| case DepthFormat: |
| case AlphaFormat: |
| case RGBFormat: |
| case RGBAFormat: |
| case LuminanceFormat: |
| case LuminanceAlphaFormat: |
| case QOpenGLTexture::RGBA_ASTC_4x4: |
| case QOpenGLTexture::RGBA_ASTC_5x4: |
| case QOpenGLTexture::RGBA_ASTC_5x5: |
| case QOpenGLTexture::RGBA_ASTC_6x5: |
| case QOpenGLTexture::RGBA_ASTC_6x6: |
| case QOpenGLTexture::RGBA_ASTC_8x5: |
| case QOpenGLTexture::RGBA_ASTC_8x6: |
| case QOpenGLTexture::RGBA_ASTC_8x8: |
| case QOpenGLTexture::RGBA_ASTC_10x5: |
| case QOpenGLTexture::RGBA_ASTC_10x6: |
| case QOpenGLTexture::RGBA_ASTC_10x8: |
| case QOpenGLTexture::RGBA_ASTC_10x10: |
| case QOpenGLTexture::RGBA_ASTC_12x10: |
| case QOpenGLTexture::RGBA_ASTC_12x12: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_4x4: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x4: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_5x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_6x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_8x8: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x5: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x6: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x8: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_10x10: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x10: |
| case QOpenGLTexture::SRGB8_Alpha8_ASTC_12x12: |
| d->formatClass = FormatClass_Unique; |
| break; |
| } |
| } |
| |
| /*! |
| Returns the format of this texture object. |
| |
| \sa setFormat() |
| */ |
| QOpenGLTexture::TextureFormat QOpenGLTexture::format() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->format; |
| } |
| |
| static bool isNpot(int width, int height = 1, int depth = 1) |
| { |
| return width & (width-1) || height & (height-1) || depth & (depth-1); |
| } |
| |
| /*! |
| Sets the dimensions of this texture object to \a width, |
| \a height, and \a depth. The default for each dimension is 1. |
| The maximum allowable texture size is dependent upon your OpenGL |
| implementation. Allocating storage for a texture less than the |
| maximum size can still fail if your system is low on resources. |
| |
| If a non-power-of-two \a width, \a height or \a depth is provided and your |
| OpenGL implementation doesn't have support for repeating non-power-of-two |
| textures, then the wrap mode is automatically set to ClampToEdge. |
| |
| \sa width(), height(), depth() |
| */ |
| void QOpenGLTexture::setSize(int width, int height, int depth) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| if (isStorageAllocated()) { |
| qWarning("Cannot resize a texture that already has storage allocated.\n" |
| "To do so, destroy() the texture and then create() and setSize()"); |
| return; |
| } |
| |
| if (isNpot(width, height, depth) && !hasFeature(Feature::NPOTTextureRepeat) && d->target != Target::TargetRectangle) |
| d->setWrapMode(WrapMode::ClampToEdge); |
| |
| switch (d->target) { |
| case QOpenGLTexture::Target1D: |
| case QOpenGLTexture::Target1DArray: |
| case QOpenGLTexture::TargetBuffer: |
| d->dimensions[0] = width; |
| Q_UNUSED(height); |
| Q_UNUSED(depth); |
| break; |
| |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::Target2DArray: |
| case QOpenGLTexture::TargetRectangle: |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| d->dimensions[0] = width; |
| d->dimensions[1] = height; |
| Q_UNUSED(depth); |
| break; |
| |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetCubeMapArray: |
| if (width != height) |
| qWarning("QAbstractOpenGLTexture::setSize(): Cube map textures must be square"); |
| d->dimensions[0] = d->dimensions[1] = width; |
| Q_UNUSED(depth); |
| break; |
| |
| case QOpenGLTexture::Target3D: |
| d->dimensions[0] = width; |
| d->dimensions[1] = height; |
| d->dimensions[2] = depth; |
| break; |
| } |
| } |
| |
| /*! |
| Returns the width of a 1D, 2D or 3D texture. |
| |
| \sa height(), depth(), setSize() |
| */ |
| int QOpenGLTexture::width() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->dimensions[0]; |
| } |
| |
| /*! |
| Returns the height of a 2D or 3D texture. |
| |
| \sa width(), depth(), setSize() |
| */ |
| int QOpenGLTexture::height() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->dimensions[1]; |
| } |
| |
| /*! |
| Returns the depth of a 3D texture. |
| |
| \sa width(), height(), setSize() |
| */ |
| int QOpenGLTexture::depth() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->dimensions[2]; |
| } |
| |
| /*! |
| For texture targets that support mipmaps, this function |
| sets the requested number of mipmap \a levels to allocate storage |
| for. This function should be called before storage is allocated |
| for the texture. |
| |
| If the texture target does not support mipmaps this function |
| has no effect. |
| |
| \sa mipLevels(), maximumMipLevels(), isStorageAllocated() |
| */ |
| void QOpenGLTexture::setMipLevels(int levels) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| if (isStorageAllocated()) { |
| qWarning("Cannot set mip levels on a texture that already has storage allocated.\n" |
| "To do so, destroy() the texture and then create() and setMipLevels()"); |
| return; |
| } |
| |
| switch (d->target) { |
| case QOpenGLTexture::Target1D: |
| case QOpenGLTexture::Target1DArray: |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::Target2DArray: |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetCubeMapArray: |
| case QOpenGLTexture::Target3D: |
| d->requestedMipLevels = levels; |
| break; |
| |
| case QOpenGLTexture::TargetBuffer: |
| case QOpenGLTexture::TargetRectangle: |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| qWarning("QAbstractOpenGLTexture::setMipLevels(): This texture target does not support mipmaps"); |
| break; |
| } |
| } |
| |
| /*! |
| Returns the number of mipmap levels for this texture. If storage |
| has not yet been allocated for this texture it returns the |
| requested number of mipmap levels. |
| |
| \sa setMipLevels(), maximumMipLevels(), isStorageAllocated() |
| */ |
| int QOpenGLTexture::mipLevels() const |
| { |
| Q_D(const QOpenGLTexture); |
| return isStorageAllocated() ? d->mipLevels : d->requestedMipLevels; |
| } |
| |
| /*! |
| Returns the maximum number of mipmap levels that this texture |
| can have given the current dimensions. |
| |
| \sa setMipLevels(), mipLevels(), setSize() |
| */ |
| int QOpenGLTexture::maximumMipLevels() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->maximumMipLevelCount(); |
| } |
| |
| /*! |
| Sets the number of array \a layers to allocate storage for. This |
| function should be called before storage is allocated for the texture. |
| |
| For targets that do not support array layers this function has |
| no effect. |
| |
| \sa layers(), isStorageAllocated() |
| */ |
| void QOpenGLTexture::setLayers(int layers) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| if (isStorageAllocated()) { |
| qWarning("Cannot set layers on a texture that already has storage allocated.\n" |
| "To do so, destroy() the texture and then create() and setLayers()"); |
| return; |
| } |
| |
| switch (d->target) { |
| case QOpenGLTexture::Target1DArray: |
| case QOpenGLTexture::Target2DArray: |
| case QOpenGLTexture::TargetCubeMapArray: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| d->layers = layers; |
| break; |
| |
| case QOpenGLTexture::Target1D: |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::Target3D: |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetBuffer: |
| case QOpenGLTexture::TargetRectangle: |
| case QOpenGLTexture::Target2DMultisample: |
| qWarning("Texture target does not support array layers"); |
| break; |
| } |
| } |
| |
| /*! |
| Returns the number of array layers for this texture. If |
| storage has not yet been allocated for this texture then |
| this function returns the requested number of array layers. |
| |
| For texture targets that do not support array layers this |
| will return 1. |
| |
| \sa setLayers(), isStorageAllocated() |
| */ |
| int QOpenGLTexture::layers() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->layers; |
| } |
| |
| /*! |
| Returns the number of faces for this texture. For cubemap |
| and cubemap array type targets this will be 6. |
| |
| For non-cubemap type targets this will return 1. |
| */ |
| int QOpenGLTexture::faces() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->faces; |
| } |
| |
| /*! |
| Sets the number of \a samples to allocate storage for when rendering to |
| a multisample capable texture target. This function should |
| be called before storage is allocated for the texture. |
| |
| For targets that do not support multisampling this function has |
| no effect. |
| |
| \sa samples(), isStorageAllocated() |
| */ |
| void QOpenGLTexture::setSamples(int samples) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| if (isStorageAllocated()) { |
| qWarning("Cannot set sample count on a texture that already has storage allocated.\n" |
| "To do so, destroy() the texture and then create() and setSamples()"); |
| return; |
| } |
| |
| switch (d->target) { |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| d->samples = samples; |
| break; |
| |
| case QOpenGLTexture::Target1D: |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::Target3D: |
| case QOpenGLTexture::Target1DArray: |
| case QOpenGLTexture::Target2DArray: |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetCubeMapArray: |
| case QOpenGLTexture::TargetBuffer: |
| case QOpenGLTexture::TargetRectangle: |
| |
| qWarning("Texture target does not support multisampling"); |
| break; |
| } |
| } |
| |
| /*! |
| Returns the number of multisample sample points for this texture. |
| If storage has not yet been allocated for this texture then |
| this function returns the requested number of samples. |
| |
| For texture targets that do not support multisampling this |
| will return 0. |
| |
| \sa setSamples(), isStorageAllocated() |
| */ |
| int QOpenGLTexture::samples() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->samples; |
| } |
| |
| /*! |
| Sets whether the sample positions and number of samples used with |
| a multisample capable texture target to \a fixed. If set to \c true |
| the sample positions and number of samples used are the same for |
| all texels in the image and will not depend upon the image size or |
| internal format. This function should be called before storage is allocated |
| for the texture. |
| |
| For targets that do not support multisampling this function has |
| no effect. |
| |
| The default value is \c true. |
| |
| \sa isFixedSamplePositions(), isStorageAllocated() |
| */ |
| void QOpenGLTexture::setFixedSamplePositions(bool fixed) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| if (isStorageAllocated()) { |
| qWarning("Cannot set sample positions on a texture that already has storage allocated.\n" |
| "To do so, destroy() the texture and then create() and setFixedSamplePositions()"); |
| return; |
| } |
| |
| switch (d->target) { |
| case QOpenGLTexture::Target2DMultisample: |
| case QOpenGLTexture::Target2DMultisampleArray: |
| d->fixedSamplePositions = fixed; |
| break; |
| |
| case QOpenGLTexture::Target1D: |
| case QOpenGLTexture::Target2D: |
| case QOpenGLTexture::Target3D: |
| case QOpenGLTexture::Target1DArray: |
| case QOpenGLTexture::Target2DArray: |
| case QOpenGLTexture::TargetCubeMap: |
| case QOpenGLTexture::TargetCubeMapArray: |
| case QOpenGLTexture::TargetBuffer: |
| case QOpenGLTexture::TargetRectangle: |
| |
| qWarning("Texture target does not support multisampling"); |
| break; |
| } |
| } |
| |
| /*! |
| Returns whether this texture uses a fixed pattern of multisample |
| samples. If storage has not yet been allocated for this texture then |
| this function returns the requested fixed sample position setting. |
| |
| For texture targets that do not support multisampling this |
| will return \c true. |
| |
| \sa setFixedSamplePositions(), isStorageAllocated() |
| */ |
| bool QOpenGLTexture::isFixedSamplePositions() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->fixedSamplePositions; |
| } |
| |
| /*! |
| Allocates server-side storage for this texture object taking |
| into account, the format, dimensions, mipmap levels, array |
| layers and cubemap faces. |
| |
| Once storage has been allocated it is no longer possible to change |
| these properties. |
| |
| If supported QOpenGLTexture makes use of immutable texture |
| storage. |
| |
| Once storage has been allocated for the texture then pixel data |
| can be uploaded via one of the setData() overloads. |
| |
| \note If immutable texture storage is not available, |
| then a default pixel format and pixel type will be used to |
| create the mutable storage. You can use the other |
| allocateStorage() overload to specify exactly the pixel format |
| and the pixel type to use when allocating mutable storage; |
| this is particulary useful under certain OpenGL ES implementations |
| (notably, OpenGL ES 2), where the pixel format and the pixel type |
| used at allocation time must perfectly match the format |
| and the type passed to any subsequent setData() call. |
| |
| \sa isStorageAllocated(), setData() |
| */ |
| void QOpenGLTexture::allocateStorage() |
| { |
| Q_D(QOpenGLTexture); |
| if (d->create()) { |
| const QOpenGLTexture::PixelFormat pixelFormat = pixelFormatCompatibleWithInternalFormat(d->format); |
| const QOpenGLTexture::PixelType pixelType = pixelTypeCompatibleWithInternalFormat(d->format); |
| d->allocateStorage(pixelFormat, pixelType); |
| } |
| } |
| |
| /*! |
| \since 5.5 |
| |
| Allocates server-side storage for this texture object taking |
| into account, the format, dimensions, mipmap levels, array |
| layers and cubemap faces. |
| |
| Once storage has been allocated it is no longer possible to change |
| these properties. |
| |
| If supported QOpenGLTexture makes use of immutable texture |
| storage. However, if immutable texture storage is not available, |
| then the specified \a pixelFormat and \a pixelType will be used |
| to allocate mutable storage; note that in certain OpenGL implementations |
| (notably, OpenGL ES 2) they must perfectly match the format |
| and the type passed to any subsequent setData() call. |
| |
| Once storage has been allocated for the texture then pixel data |
| can be uploaded via one of the setData() overloads. |
| |
| \sa isStorageAllocated(), setData() |
| */ |
| void QOpenGLTexture::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType) |
| { |
| Q_D(QOpenGLTexture); |
| if (d->create()) |
| d->allocateStorage(pixelFormat, pixelType); |
| } |
| |
| /*! |
| Returns \c true if server-side storage for this texture as been |
| allocated. |
| |
| The texture format, dimensions, mipmap levels and array layers |
| cannot be altered once storage ihas been allocated. |
| |
| \sa allocateStorage(), setSize(), setMipLevels(), setLayers(), setFormat() |
| */ |
| bool QOpenGLTexture::isStorageAllocated() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->storageAllocated; |
| } |
| |
| /*! |
| Attempts to create a texture view onto this texture. A texture |
| view is somewhat analogous to a view in SQL in that it presents |
| a restricted or reinterpreted view of the original data. Texture |
| views do not allocate any more server-side storage, insted relying |
| on the storage buffer of the source texture. |
| |
| Texture views are only available when using immutable storage. For |
| more information on texture views see |
| http://www.opengl.org/wiki/Texture_Storage#Texture_views. |
| |
| The \a target argument specifies the target to use for the view. |
| Only some targets can be used depending upon the target of the original |
| target. For e.g. a view onto a Target1DArray texture can specify |
| either Target1DArray or Target1D but for the latter the number of |
| array layers specified with \a minimumLayer and \a maximumLayer must |
| be exactly 1. |
| |
| Simpliar constraints apply for the \a viewFormat. See the above link |
| and the specification for more details. |
| |
| The \a minimumMipmapLevel, \a maximumMipmapLevel, \a minimumLayer, |
| and \a maximumLayer arguments serve to restrict the parts of the |
| texture accessible by the texture view. |
| |
| If creation of the texture view fails this function will return |
| 0. If the function succeeds it will return a pointer to a new |
| QOpenGLTexture object that will return \c true from its isTextureView() |
| function. |
| |
| \sa isTextureView() |
| */ |
| QOpenGLTexture *QOpenGLTexture::createTextureView(Target target, |
| TextureFormat viewFormat, |
| int minimumMipmapLevel, int maximumMipmapLevel, |
| int minimumLayer, int maximumLayer) const |
| { |
| Q_D(const QOpenGLTexture); |
| if (!isStorageAllocated()) { |
| qWarning("Cannot set create a texture view of a texture that does not have storage allocated."); |
| return nullptr; |
| } |
| Q_ASSERT(maximumMipmapLevel >= minimumMipmapLevel); |
| Q_ASSERT(maximumLayer >= minimumLayer); |
| return d->createTextureView(target, viewFormat, |
| minimumMipmapLevel, maximumMipmapLevel, |
| minimumLayer, maximumLayer); |
| } |
| |
| /*! |
| Returns \c true if this texture object is actually a view onto another |
| texture object. |
| |
| \sa createTextureView() |
| */ |
| bool QOpenGLTexture::isTextureView() const |
| { |
| Q_D(const QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| return d->textureView; |
| } |
| |
| /*! |
| Uploads pixel \a data for this texture object \a mipLevel, array \a layer, and \a cubeFace. |
| Storage must have been allocated before uploading pixel data. Some overloads of setData() |
| will set appropriate dimensions, mipmap levels, and array layers and then allocate storage |
| for you if they have enough information to do so. This will be noted in the function |
| documentation. |
| |
| The structure of the pixel data pointed to by \a data is specified by \a sourceFormat |
| and \a sourceType. The pixel data upload can optionally be controlled by \a options. |
| |
| If using a compressed format() then you should use setCompressedData() instead of this |
| function. |
| |
| \since 5.3 |
| \sa setCompressedData() |
| */ |
| void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace, |
| PixelFormat sourceFormat, PixelType sourceType, |
| const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| if (!isStorageAllocated()) { |
| qWarning("Cannot set data on a texture that does not have storage allocated.\n" |
| "To do so call allocateStorage() before this function"); |
| return; |
| } |
| d->setData(mipLevel, layer, 1, cubeFace, sourceFormat, sourceType, data, options); |
| } |
| |
| /*! |
| \since 5.9 |
| \overload |
| |
| Parameter \a layerCount is the number of layers in a texture array |
| that are being uploaded/populated by this call. |
| */ |
| void QOpenGLTexture::setData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| if (!isStorageAllocated()) { |
| qWarning("Cannot set data on a texture that does not have storage allocated.\n" |
| "To do so call allocateStorage() before this function"); |
| return; |
| } |
| d->setData(mipLevel, layer, layerCount, cubeFace, sourceFormat, sourceType, data, options); |
| } |
| |
| /*! |
| \since 5.3 |
| \overload |
| */ |
| void QOpenGLTexture::setData(int mipLevel, int layer, |
| PixelFormat sourceFormat, PixelType sourceType, |
| const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setData(mipLevel, layer, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options); |
| } |
| |
| /*! |
| \since 5.3 |
| \overload |
| */ |
| void QOpenGLTexture::setData(int mipLevel, |
| PixelFormat sourceFormat, PixelType sourceType, |
| const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setData(mipLevel, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options); |
| } |
| |
| /*! |
| \since 5.3 |
| \overload |
| */ |
| void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType, |
| const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options); |
| } |
| |
| /*! |
| \since 5.14 |
| \overload |
| |
| This overload is to be used to update a part of the texture. Parameters \a |
| xOffset, \a yOffset, \a zOffset specify the texel offsets within the |
| texture. Parameters \a width, \a height and \a depth specify the dimensions |
| of the sub image. |
| |
| The structure of the pixel data pointed to by \a data is specified by \a |
| sourceFormat and \a sourceType. The pixel data upload can optionally be |
| controlled by \a options. |
| */ |
| void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, |
| int width, int height, int depth, |
| PixelFormat sourceFormat, PixelType sourceType, |
| const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setData(xOffset, yOffset, zOffset, |
| width, height, depth, |
| 0, 0, 1, |
| QOpenGLTexture::CubeMapPositiveX, sourceFormat, |
| sourceType, data, options); |
| } |
| |
| /*! |
| \since 5.14 |
| \overload |
| |
| This overload is to be used to update a part of the texture. Parameters \a |
| xOffset, \a yOffset, \a zOffset specify the texel offsets within the |
| texture. Parameters \a width, \a height and \a depth specify the dimensions |
| of the sub image. The mip map level the sub image we want to |
| update is specified with \a mipLevel. |
| |
| The structure of the pixel data pointed to by \a data is specified by \a |
| sourceFormat and \a sourceType. The pixel data upload can optionally be |
| controlled by \a options. |
| */ |
| void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, |
| int width, int height, int depth, |
| int mipLevel, |
| PixelFormat sourceFormat, PixelType sourceType, |
| const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setData(xOffset, yOffset, zOffset, |
| width, height, depth, |
| mipLevel, 0, 1, |
| QOpenGLTexture::CubeMapPositiveX, sourceFormat, |
| sourceType, data, options); |
| } |
| |
| /*! |
| \since 5.14 |
| \overload |
| |
| This overload is to be used to update a part of the texture. Parameters \a |
| xOffset, \a yOffset, \a zOffset specify the texel offsets within the |
| texture. Parameters \a width, \a height and \a depth specify the dimensions |
| of the sub image. The mip map level and layerof the sub image we want to |
| update are specified with \a mipLevel and \a layer. |
| |
| The structure of the pixel data pointed to by \a data is specified by \a |
| sourceFormat and \a sourceType. The pixel data upload can optionally be |
| controlled by \a options. |
| */ |
| void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, |
| int width, int height, int depth, |
| int mipLevel, int layer, |
| PixelFormat sourceFormat, PixelType sourceType, |
| const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setData(xOffset, yOffset, zOffset, |
| width, height, depth, |
| mipLevel, layer, 1, |
| QOpenGLTexture::CubeMapPositiveX, sourceFormat, |
| sourceType, data, options); |
| } |
| |
| /*! |
| \since 5.14 |
| \overload |
| |
| This overload is to be used to update a part of the texture. Parameters \a |
| xOffset, \a yOffset, \a zOffset specify the texel offsets within the |
| texture. Parameters \a width, \a height and \a depth specify the dimensions |
| of the sub image.The mip map level, layer and cube map face of the sub |
| image we want to update are specified with \a mipLevel, \a layer and \a |
| face. |
| |
| The structure of the pixel data pointed to by \a data is specified by \a |
| sourceFormat and \a sourceType. The pixel data upload can optionally be |
| controlled by \a options. |
| */ |
| void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, |
| int width, int height, int depth, |
| int mipLevel, int layer, |
| CubeMapFace face, |
| PixelFormat sourceFormat, PixelType sourceType, |
| const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setData(xOffset, yOffset, zOffset, |
| width, height, depth, |
| mipLevel, layer, 1, |
| face, sourceFormat, |
| sourceType, data, options); |
| } |
| |
| /*! |
| \since 5.14 |
| \overload |
| |
| This overload is to be used to update a part of the texture. Parameters \a |
| xOffset, \a yOffset, \a zOffset specify the texel offsets within the |
| texture. Parameters \a width, \a height and \a depth specify the dimensions |
| of the sub image.The mip map level, starting layer, cube map face and |
| number of layers of the sub image we want to update are specified with \a |
| mipLevel, \a layer, \a face and \a layerCount. |
| |
| The structure of the pixel data pointed to by \a data is specified by \a |
| sourceFormat and \a sourceType. The pixel data upload can optionally be |
| controlled by \a options. |
| */ |
| void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, |
| int width, int height, int depth, |
| int mipLevel, int layer, |
| CubeMapFace face, int layerCount, |
| PixelFormat sourceFormat, PixelType sourceType, |
| const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setData(xOffset, yOffset, zOffset, |
| width, height, depth, |
| mipLevel, layer, layerCount, |
| face, sourceFormat, |
| sourceType, data, options); |
| } |
| |
| #if QT_DEPRECATED_SINCE(5, 3) |
| /*! |
| \obsolete |
| \overload |
| |
| \sa setCompressedData() |
| */ |
| void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace, |
| PixelFormat sourceFormat, PixelType sourceType, |
| void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| if (!isStorageAllocated()) { |
| qWarning("Cannot set data on a texture that does not have storage allocated.\n" |
| "To do so call allocateStorage() before this function"); |
| return; |
| } |
| d->setData(mipLevel, layer, 1, cubeFace, sourceFormat, sourceType, data, options); |
| } |
| |
| /*! |
| \obsolete |
| \overload |
| */ |
| void QOpenGLTexture::setData(int mipLevel, int layer, |
| PixelFormat sourceFormat, PixelType sourceType, |
| void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setData(mipLevel, layer, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options); |
| } |
| |
| /*! |
| \obsolete |
| \overload |
| */ |
| void QOpenGLTexture::setData(int mipLevel, |
| PixelFormat sourceFormat, PixelType sourceType, |
| void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setData(mipLevel, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options); |
| } |
| |
| /*! |
| \obsolete |
| \overload |
| */ |
| void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType, |
| void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options); |
| } |
| #endif |
| |
| /*! |
| This overload of setData() will allocate storage for you. |
| The pixel data is contained in \a image. Mipmaps are generated by default. |
| Set \a genMipMaps to \l DontGenerateMipMaps to turn off mipmap generation. |
| |
| \overload |
| */ |
| void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps) |
| { |
| QOpenGLContext *context = QOpenGLContext::currentContext(); |
| if (!context) { |
| qWarning("QOpenGLTexture::setData() requires a valid current context"); |
| return; |
| } |
| |
| if (image.isNull()) { |
| qWarning("QOpenGLTexture::setData() tried to set a null image"); |
| return; |
| } |
| |
| if (context->isOpenGLES() && context->format().majorVersion() < 3) |
| setFormat(QOpenGLTexture::RGBAFormat); |
| else |
| setFormat(QOpenGLTexture::RGBA8_UNorm); |
| |
| setSize(image.width(), image.height()); |
| setMipLevels(genMipMaps == GenerateMipMaps ? maximumMipLevels() : 1); |
| allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8); |
| |
| // Upload pixel data and generate mipmaps |
| QImage glImage = image.convertToFormat(QImage::Format_RGBA8888); |
| QOpenGLPixelTransferOptions uploadOptions; |
| uploadOptions.setAlignment(1); |
| setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, glImage.constBits(), &uploadOptions); |
| } |
| |
| /*! |
| Uploads compressed pixel \a data to \a mipLevel, array \a layer, and \a cubeFace. |
| The pixel transfer can optionally be controlled with \a options. The \a dataSize |
| argument should specify the size of the data pointed to by \a data. |
| |
| If not using a compressed format() then you should use setData() instead of this |
| function. |
| |
| \since 5.3 |
| */ |
| void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace, |
| int dataSize, const void *data, |
| const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| if (!isStorageAllocated()) { |
| qWarning("Cannot set data on a texture that does not have storage allocated.\n" |
| "To do so call allocateStorage() before this function"); |
| return; |
| } |
| d->setCompressedData(mipLevel, layer, 1, cubeFace, dataSize, data, options); |
| } |
| |
| /*! |
| \since 5.9 |
| \overload |
| |
| Parameter \a layerCount is the number of layers in a texture array |
| that are being uploaded/populated by this call. |
| */ |
| void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, int dataSize, const void *data, const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| if (!isStorageAllocated()) { |
| qWarning("Cannot set data on a texture that does not have storage allocated.\n" |
| "To do so call allocateStorage() before this function"); |
| return; |
| } |
| d->setCompressedData(mipLevel, layer, layerCount, cubeFace, dataSize, data, options); |
| } |
| |
| /*! |
| \overload |
| */ |
| void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int dataSize, const void *data, |
| const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setCompressedData(mipLevel, layer, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options); |
| } |
| |
| /*! |
| \overload |
| */ |
| void QOpenGLTexture::setCompressedData(int mipLevel, int dataSize, const void *data, |
| const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setCompressedData(mipLevel, 0, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options); |
| } |
| |
| /*! |
| \overload |
| */ |
| void QOpenGLTexture::setCompressedData(int dataSize, const void *data, |
| const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setCompressedData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options); |
| } |
| |
| #if QT_DEPRECATED_SINCE(5, 3) |
| /*! |
| \obsolete |
| \overload |
| */ |
| void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace, |
| int dataSize, void *data, |
| const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| if (!isStorageAllocated()) { |
| qWarning("Cannot set data on a texture that does not have storage allocated.\n" |
| "To do so call allocateStorage() before this function"); |
| return; |
| } |
| d->setCompressedData(mipLevel, layer, 1, cubeFace, dataSize, data, options); |
| } |
| |
| /*! |
| \obsolete |
| \overload |
| */ |
| void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int dataSize, void *data, |
| const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setCompressedData(mipLevel, layer, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options); |
| } |
| |
| /*! |
| \obsolete |
| \overload |
| */ |
| void QOpenGLTexture::setCompressedData(int mipLevel, int dataSize, void *data, |
| const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setCompressedData(mipLevel, 0, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options); |
| } |
| |
| /*! |
| \obsolete |
| \overload |
| */ |
| void QOpenGLTexture::setCompressedData(int dataSize, void *data, |
| const QOpenGLPixelTransferOptions * const options) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->textureId); |
| d->setCompressedData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options); |
| } |
| #endif |
| |
| /*! |
| Returns \c true if your OpenGL implementation and version supports the texture |
| feature \a feature. |
| */ |
| bool QOpenGLTexture::hasFeature(Feature feature) |
| { |
| QOpenGLContext *ctx = QOpenGLContext::currentContext(); |
| if (!ctx) { |
| qWarning("QOpenGLTexture::hasFeature() requires a valid current context"); |
| return false; |
| } |
| |
| QSurfaceFormat f = ctx->format(); |
| |
| bool supported = false; |
| |
| #if !defined(QT_OPENGL_ES_2) |
| if (!ctx->isOpenGLES()) { |
| switch (feature) { |
| case ImmutableMultisampleStorage: |
| supported = f.version() >= qMakePair(4, 3) |
| || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage_multisample")); |
| break; |
| |
| case TextureBuffer: |
| supported = f.version() >= qMakePair(3, 0) |
| || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_buffer_object")); |
| break; |
| |
| case StencilTexturing: |
| supported = f.version() >= qMakePair(4, 3) |
| || ctx->hasExtension(QByteArrayLiteral("GL_ARB_stencil_texturing")); |
| break; |
| |
| case ImmutableStorage: |
| supported = f.version() >= qMakePair(4, 2) |
| || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage")) |
| || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_storage")); |
| break; |
| |
| case TextureCubeMapArrays: |
| supported = f.version() >= qMakePair(4, 0) |
| || ctx->hasExtension(QByteArrayLiteral("ARB_texture_cube_map_array")); |
| break; |
| |
| case Swizzle: |
| supported = f.version() >= qMakePair(3, 3) |
| || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_swizzle")); |
| break; |
| |
| case TextureMultisample: |
| supported = f.version() >= qMakePair(3, 2) |
| || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_multisample")); |
| break; |
| |
| case TextureArrays: |
| supported = f.version() >= qMakePair(3, 0) |
| || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_array")); |
| break; |
| |
| case TextureRectangle: |
| supported = f.version() >= qMakePair(2, 1) |
| || ctx->hasExtension(QByteArrayLiteral("ARB_texture_rectangle")); |
| break; |
| |
| case Texture3D: |
| supported = f.version() >= qMakePair(1, 3); |
| break; |
| |
| case AnisotropicFiltering: |
| supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic")); |
| break; |
| |
| case NPOTTextures: |
| case NPOTTextureRepeat: |
| supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two")); |
| break; |
| |
| case Texture1D: |
| supported = f.version() >= qMakePair(1, 1); |
| break; |
| |
| case TextureComparisonOperators: |
| // GL 1.4 and GL_ARB_shadow alone support only LEQUAL and GEQUAL; |
| // since we're talking about history anyhow avoid to be extra pedantic |
| // in the feature set, and simply claim supported if we have the full set of operators |
| // (which has been added into 1.5 / GL_EXT_shadow_funcs). |
| supported = f.version() >= qMakePair(1, 5) |
| || (ctx->hasExtension(QByteArrayLiteral("GL_ARB_shadow")) |
| && ctx->hasExtension(QByteArrayLiteral("GL_EXT_shadow_funcs"))); |
| break; |
| |
| case TextureMipMapLevel: |
| supported = f.version() >= qMakePair(1, 2); |
| break; |
| |
| case MaxFeatureFlag: |
| break; |
| } |
| } |
| |
| if (ctx->isOpenGLES()) |
| #endif |
| { |
| const char *renderer = reinterpret_cast<const char *>(ctx->functions()->glGetString(GL_RENDERER)); |
| switch (feature) { |
| case ImmutableStorage: |
| supported = (f.version() >= qMakePair(3, 0) || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_storage"))) |
| && !(renderer && strstr(renderer, "Mali")); // do not use on Mali: QTBUG-45106 |
| break; |
| |
| case ImmutableMultisampleStorage: |
| supported = f.version() >= qMakePair(3, 1); |
| break; |
| |
| case TextureRectangle: |
| break; |
| |
| case TextureArrays: |
| supported = f.version() >= qMakePair(3, 0); |
| break; |
| |
| case Texture3D: |
| supported = f.version() >= qMakePair(3, 0) |
| || ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D")); |
| break; |
| |
| case TextureMultisample: |
| supported = f.version() >= qMakePair(3, 1); |
| break; |
| |
| case TextureBuffer: |
| break; |
| |
| case TextureCubeMapArrays: |
| break; |
| |
| case Swizzle: |
| supported = f.version() >= qMakePair(3, 0); |
| break; |
| |
| case StencilTexturing: |
| break; |
| |
| case AnisotropicFiltering: |
| supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic")); |
| break; |
| |
| case NPOTTextures: |
| case NPOTTextureRepeat: |
| supported = f.version() >= qMakePair(3,0) |
| || ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot")) |
| || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two")); |
| break; |
| |
| case Texture1D: |
| break; |
| |
| case TextureComparisonOperators: |
| supported = f.version() >= qMakePair(3, 0) |
| || ctx->hasExtension(QByteArrayLiteral("GL_EXT_shadow_samplers")); |
| break; |
| |
| case TextureMipMapLevel: |
| supported = f.version() >= qMakePair(3, 0); |
| break; |
| |
| case MaxFeatureFlag: |
| break; |
| } |
| } |
| |
| return supported; |
| } |
| |
| /*! |
| Sets the base mipmap level used for all texture lookups with this texture to \a baseLevel. |
| |
| \note This function has no effect on Qt built for OpenGL ES 2. |
| \sa mipBaseLevel(), setMipMaxLevel(), setMipLevelRange() |
| */ |
| void QOpenGLTexture::setMipBaseLevel(int baseLevel) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| if (!d->features.testFlag(TextureMipMapLevel)) { |
| qWarning("QOpenGLTexture::setMipBaseLevel: requires OpenGL >= 1.2 or OpenGL ES >= 3.0"); |
| return; |
| } |
| Q_ASSERT(d->textureId); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(baseLevel <= d->maxLevel); |
| d->baseLevel = baseLevel; |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel); |
| } |
| |
| /*! |
| Returns the mipmap base level used for all texture lookups with this texture. |
| The default is 0. |
| |
| \sa setMipBaseLevel(), mipMaxLevel(), mipLevelRange() |
| */ |
| int QOpenGLTexture::mipBaseLevel() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->baseLevel; |
| } |
| |
| /*! |
| Sets the maximum mipmap level used for all texture lookups with this texture to \a maxLevel. |
| |
| \note This function has no effect on Qt built for OpenGL ES 2. |
| \sa mipMaxLevel(), setMipBaseLevel(), setMipLevelRange() |
| */ |
| void QOpenGLTexture::setMipMaxLevel(int maxLevel) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| if (!d->features.testFlag(TextureMipMapLevel)) { |
| qWarning("QOpenGLTexture::setMipMaxLevel: requires OpenGL >= 1.2 or OpenGL ES >= 3.0"); |
| return; |
| } |
| Q_ASSERT(d->textureId); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->baseLevel <= maxLevel); |
| d->maxLevel = maxLevel; |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel); |
| } |
| |
| /*! |
| Returns the mipmap maximum level used for all texture lookups with this texture. |
| |
| \sa setMipMaxLevel(), mipBaseLevel(), mipLevelRange() |
| */ |
| int QOpenGLTexture::mipMaxLevel() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->maxLevel; |
| } |
| |
| /*! |
| Sets the range of mipmap levels that can be used for texture lookups with this texture |
| to range from \a baseLevel to \a maxLevel. |
| |
| \note This function has no effect on Qt built for OpenGL ES 2. |
| \sa setMipBaseLevel(), setMipMaxLevel(), mipLevelRange() |
| */ |
| void QOpenGLTexture::setMipLevelRange(int baseLevel, int maxLevel) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| if (!d->features.testFlag(TextureMipMapLevel)) { |
| qWarning("QOpenGLTexture::setMipLevelRange: requires OpenGL >= 1.2 or OpenGL ES >= 3.0"); |
| return; |
| } |
| Q_ASSERT(d->textureId); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(baseLevel <= maxLevel); |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel); |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel); |
| } |
| |
| /*! |
| Returns the range of mipmap levels that can be used for texture lookups with this texture. |
| |
| \sa mipBaseLevel(), mipMaxLevel() |
| */ |
| QPair<int, int> QOpenGLTexture::mipLevelRange() const |
| { |
| Q_D(const QOpenGLTexture); |
| return qMakePair(d->baseLevel, d->maxLevel); |
| } |
| |
| /*! |
| If \a enabled is \c true, enables automatic mipmap generation for this texture object |
| to occur whenever the level 0 mipmap data is set via setData(). |
| |
| The automatic mipmap generation is enabled by default. |
| |
| \note Mipmap generation is not supported for compressed textures with OpenGL ES 2.0. |
| |
| \sa isAutoMipMapGenerationEnabled(), generateMipMaps() |
| */ |
| void QOpenGLTexture::setAutoMipMapGenerationEnabled(bool enabled) |
| { |
| Q_D(QOpenGLTexture); |
| d->autoGenerateMipMaps = enabled; |
| } |
| |
| /*! |
| Returns whether auto mipmap generation is enabled for this texture object. |
| |
| \sa setAutoMipMapGenerationEnabled(), generateMipMaps() |
| */ |
| bool QOpenGLTexture::isAutoMipMapGenerationEnabled() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->autoGenerateMipMaps; |
| } |
| |
| /*! |
| Generates mipmaps for this texture object from mipmap level 0. If you are |
| using a texture target and filtering option that requires mipmaps and you |
| have disabled automatic mipmap generation then you need to call this function |
| or the overload to create the mipmap chain. |
| |
| \note Mipmap generation is not supported for compressed textures with OpenGL ES. |
| |
| \sa setAutoMipMapGenerationEnabled(), setMipLevels(), mipLevels() |
| */ |
| void QOpenGLTexture::generateMipMaps() |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| if (isCompressedFormat(d->format)) { |
| if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) |
| if (ctx->isOpenGLES()) |
| return; |
| } |
| d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget); |
| } |
| |
| /*! |
| Generates mipmaps for this texture object from mipmap level \a baseLevel. If you are |
| using a texture target and filtering option that requires mipmaps and you |
| have disabled automatic mipmap generation then you need to call this function |
| or the overload to create the mipmap chain. |
| |
| The generation of mipmaps to above \a baseLevel is achieved by setting the mipmap |
| base level to \a baseLevel and then generating the mipmap chain. If \a resetBaseLevel |
| is \c true, then the baseLevel of the texture will be reset to its previous value. |
| |
| \sa setAutoMipMapGenerationEnabled(), setMipLevels(), mipLevels() |
| */ |
| void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel) |
| { |
| Q_D(QOpenGLTexture); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| if (isCompressedFormat(d->format)) { |
| if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) |
| if (ctx->isOpenGLES()) |
| return; |
| } |
| int oldBaseLevel; |
| if (resetBaseLevel) |
| oldBaseLevel = mipBaseLevel(); |
| setMipBaseLevel(baseLevel); |
| d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget); |
| if (resetBaseLevel) |
| setMipBaseLevel(oldBaseLevel); |
| } |
| |
| /*! |
| GLSL shaders are able to reorder the components of the vec4 returned by texture |
| functions. It is also desirable to be able to control this reordering from CPU |
| side code. This is made possible by swizzle masks since OpenGL 3.3. |
| |
| Each component of the texture can be mapped to one of the SwizzleValue options. |
| |
| This function maps \a component to the output \a value. |
| |
| \note This function has no effect on Mac and Qt built for OpenGL ES 2. |
| \sa swizzleMask() |
| */ |
| void QOpenGLTexture::setSwizzleMask(SwizzleComponent component, SwizzleValue value) |
| { |
| #if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2) |
| if (!QOpenGLContext::currentContext()->isOpenGLES()) { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| if (!d->features.testFlag(Swizzle)) { |
| qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3"); |
| return; |
| } |
| d->swizzleMask[component - SwizzleRed] = value; |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, component, value); |
| return; |
| } |
| #else |
| Q_UNUSED(component); |
| Q_UNUSED(value); |
| #endif |
| qWarning("QOpenGLTexture: Texture swizzling is not supported"); |
| } |
| |
| /*! |
| Parameters \a {r}, \a {g}, \a {b}, and \a {a} are values used for setting |
| the colors red, green, blue, and the alpha value. |
| \overload |
| */ |
| void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g, |
| SwizzleValue b, SwizzleValue a) |
| { |
| #if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2) |
| if (!QOpenGLContext::currentContext()->isOpenGLES()) { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| if (!d->features.testFlag(Swizzle)) { |
| qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3"); |
| return; |
| } |
| GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)}; |
| d->swizzleMask[0] = r; |
| d->swizzleMask[1] = g; |
| d->swizzleMask[2] = b; |
| d->swizzleMask[3] = a; |
| d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); |
| return; |
| } |
| #else |
| Q_UNUSED(r); |
| Q_UNUSED(g); |
| Q_UNUSED(b); |
| Q_UNUSED(a); |
| #endif |
| qWarning("QOpenGLTexture: Texture swizzling is not supported"); |
| } |
| |
| /*! |
| Returns the swizzle mask for texture \a component. |
| */ |
| QOpenGLTexture::SwizzleValue QOpenGLTexture::swizzleMask(SwizzleComponent component) const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->swizzleMask[component - SwizzleRed]; |
| } |
| |
| /*! |
| \enum QOpenGLTexture::DepthStencilMode |
| \since 5.4 |
| This enum specifies which component of a depth/stencil texture is |
| accessed when the texture is sampled. |
| |
| \value DepthMode Equivalent to GL_DEPTH_COMPONENT. |
| \value StencilMode Equivalent to GL_STENCIL_INDEX. |
| */ |
| |
| /*! |
| If using a texture that has a combined depth/stencil format this function sets |
| which component of the texture is accessed to \a mode. |
| |
| When the parameter is set to DepthMode, then accessing it from the |
| shader will access the depth component as a single float, as normal. But when |
| the parameter is set to StencilMode, the shader will access the stencil component. |
| |
| \note This function has no effect on Mac and Qt built for OpenGL ES 2. |
| \since 5.4 |
| \sa depthStencilMode() |
| */ |
| void QOpenGLTexture::setDepthStencilMode(QOpenGLTexture::DepthStencilMode mode) |
| { |
| #if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2) |
| if (!QOpenGLContext::currentContext()->isOpenGLES()) { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| if (!d->features.testFlag(StencilTexturing)) { |
| qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3 or GL_ARB_stencil_texturing"); |
| return; |
| } |
| d->depthStencilMode = mode; |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, mode); |
| return; |
| } |
| #else |
| Q_UNUSED(mode); |
| #endif |
| qWarning("QOpenGLTexture: DepthStencil Mode is not supported"); |
| } |
| |
| /*! |
| Returns the depth stencil mode for textures using a combined depth/stencil format. |
| |
| \since 5.4 |
| \sa setDepthStencilMode() |
| */ |
| QOpenGLTexture::DepthStencilMode QOpenGLTexture::depthStencilMode() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->depthStencilMode; |
| } |
| |
| /*! |
| \enum QOpenGLTexture::ComparisonFunction |
| \since 5.5 |
| This enum specifies which comparison operator is used when texture comparison |
| is enabled on this texture. |
| |
| \value CompareLessEqual Equivalent to GL_LEQUAL. |
| \value CompareGreaterEqual Equivalent to GL_GEQUAL. |
| \value CompareLess Equivalent to GL_LESS. |
| \value CompareGreater Equivalent to GL_GREATER. |
| \value CompareEqual Equivalent to GL_EQUAL. |
| \value CommpareNotEqual Equivalent to GL_NOTEQUAL. |
| \value CompareAlways Equivalent to GL_ALWAYS. |
| \value CompareNever Equivalent to GL_NEVER. |
| |
| */ |
| |
| /*! |
| \since 5.5 |
| |
| Sets the texture comparison function on this texture to \a function. The texture |
| comparison function is used by shadow samplers when sampling a depth texture. |
| |
| \sa comparisonFunction() |
| */ |
| void QOpenGLTexture::setComparisonFunction(QOpenGLTexture::ComparisonFunction function) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| if (!d->features.testFlag(TextureComparisonOperators)) { |
| qWarning("QOpenGLTexture::setComparisonFunction: requires OpenGL >= 1.5 or OpenGL ES >= 3.0"); |
| return; |
| } |
| d->comparisonFunction = function; |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_COMPARE_FUNC, function); |
| } |
| |
| /*! |
| \since 5.5 |
| |
| Returns the texture comparison operator set on this texture. By default, a |
| texture has a CompareLessEqual comparison function. |
| |
| \sa setComparisonFunction() |
| */ |
| QOpenGLTexture::ComparisonFunction QOpenGLTexture::comparisonFunction() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->comparisonFunction; |
| } |
| |
| /*! |
| \enum QOpenGLTexture::ComparisonMode |
| \since 5.5 |
| This enum specifies which comparison mode is used when sampling this texture. |
| |
| \value CompareRefToTexture Equivalent to GL_COMPARE_REF_TO_TEXTURE. |
| \value CompareNone Equivalent to GL_NONE. |
| */ |
| |
| /*! |
| \since 5.5 |
| |
| Sets the texture comparison mode on this texture to \a mode. The texture |
| comparison mode is used by shadow samplers when sampling a depth texture. |
| |
| \sa comparisonMode() |
| */ |
| void QOpenGLTexture::setComparisonMode(QOpenGLTexture::ComparisonMode mode) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| if (!d->features.testFlag(TextureComparisonOperators)) { |
| qWarning("QOpenGLTexture::setComparisonMode: requires OpenGL >= 1.5 or OpenGL ES >= 3.0"); |
| return; |
| } |
| d->comparisonMode = mode; |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_COMPARE_MODE, mode); |
| } |
| |
| /*! |
| \since 5.5 |
| |
| Returns the texture comparison mode set on this texture. By default, a |
| texture has a CompareNone comparison mode (i.e. comparisons are disabled). |
| |
| \sa setComparisonMode() |
| */ |
| QOpenGLTexture::ComparisonMode QOpenGLTexture::comparisonMode() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->comparisonMode; |
| } |
| |
| /*! |
| Sets the filter used for minification to \a filter. |
| |
| \sa minificationFilter(), setMagnificationFilter(), setMinMagFilters() |
| */ |
| void QOpenGLTexture::setMinificationFilter(QOpenGLTexture::Filter filter) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| d->minFilter = filter; |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, filter); |
| } |
| |
| /*! |
| Returns the minification filter. |
| |
| \sa setMinificationFilter() |
| */ |
| QOpenGLTexture::Filter QOpenGLTexture::minificationFilter() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->minFilter; |
| } |
| |
| /*! |
| Sets the magnification filter to \a filter. |
| |
| \sa magnificationFilter(), setMinificationFilter(), setMinMagFilters() |
| */ |
| void QOpenGLTexture::setMagnificationFilter(QOpenGLTexture::Filter filter) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| d->magFilter = filter; |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, filter); |
| } |
| |
| /*! |
| Returns the magnification filter. |
| |
| \sa setMagnificationFilter() |
| */ |
| QOpenGLTexture::Filter QOpenGLTexture::magnificationFilter() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->magFilter; |
| } |
| |
| /*! |
| Sets the minification filter to \a minificationFilter and the magnification filter |
| to \a magnificationFilter. |
| |
| \sa minMagFilters(), setMinificationFilter(), setMagnificationFilter() |
| */ |
| void QOpenGLTexture::setMinMagFilters(QOpenGLTexture::Filter minificationFilter, |
| QOpenGLTexture::Filter magnificationFilter) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| d->minFilter = minificationFilter; |
| d->magFilter = magnificationFilter; |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, minificationFilter); |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, magnificationFilter); |
| } |
| |
| /*! |
| Returns the current minification and magnification filters. |
| |
| \sa setMinMagFilters() |
| */ |
| QPair<QOpenGLTexture::Filter, QOpenGLTexture::Filter> QOpenGLTexture::minMagFilters() const |
| { |
| Q_D(const QOpenGLTexture); |
| return QPair<QOpenGLTexture::Filter, QOpenGLTexture::Filter>(d->minFilter, d->magFilter); |
| } |
| |
| /*! |
| If your OpenGL implementation supports the GL_EXT_texture_filter_anisotropic extension |
| this function sets the maximum anisotropy level to \a anisotropy. |
| |
| \sa maximumAnisotropy() |
| */ |
| void QOpenGLTexture::setMaximumAnisotropy(float anisotropy) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| if (!d->features.testFlag(AnisotropicFiltering)) { |
| qWarning("QOpenGLTexture::setMaximumAnisotropy() requires GL_EXT_texture_filter_anisotropic"); |
| return; |
| } |
| d->maxAnisotropy = anisotropy; |
| d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); |
| } |
| |
| /*! |
| Returns the maximum level of anisotropy to be accounted for when performing texture lookups. |
| This requires the GL_EXT_texture_filter_anisotropic extension. |
| |
| \sa setMaximumAnisotropy() |
| */ |
| float QOpenGLTexture::maximumAnisotropy() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->maxAnisotropy; |
| } |
| |
| /*! |
| Sets the wrap (or repeat mode) for all texture dimentions to \a mode. |
| |
| \sa wrapMode() |
| */ |
| void QOpenGLTexture::setWrapMode(QOpenGLTexture::WrapMode mode) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| d->setWrapMode(mode); |
| } |
| |
| /*! |
| Holds the texture dimension \a direction. |
| \overload |
| */ |
| void QOpenGLTexture::setWrapMode(QOpenGLTexture::CoordinateDirection direction, QOpenGLTexture::WrapMode mode) |
| { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| d->setWrapMode(direction, mode); |
| } |
| |
| /*! |
| Returns the wrap mode for the texture dimension \a direction. |
| |
| \sa setWrapMode() |
| */ |
| QOpenGLTexture::WrapMode QOpenGLTexture::wrapMode(QOpenGLTexture::CoordinateDirection direction) const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->wrapMode(direction); |
| } |
| |
| /*! |
| Sets the border color of the texture to \a color. |
| |
| \note This function has no effect on Mac and Qt built for OpenGL ES 2. |
| \sa borderColor() |
| */ |
| void QOpenGLTexture::setBorderColor(QColor color) |
| { |
| setBorderColor(static_cast<float>(color.redF()), static_cast<float>(color.greenF()), |
| static_cast<float>(color.blueF()), static_cast<float>(color.alphaF())); |
| } |
| |
| /*! |
| Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and \a {a} to the |
| alpha value. |
| \overload |
| */ |
| void QOpenGLTexture::setBorderColor(float r, float g, float b, float a) |
| { |
| #if !defined(QT_OPENGL_ES_2) |
| if (!QOpenGLContext::currentContext()->isOpenGLES()) { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| float values[4]; |
| values[0] = r; |
| values[1] = g; |
| values[2] = b; |
| values[3] = a; |
| d->borderColor.clear(); |
| for (int i = 0; i < 4; ++i) |
| d->borderColor.append(QVariant(values[i])); |
| d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values); |
| return; |
| } |
| #else |
| Q_UNUSED(r); |
| Q_UNUSED(g); |
| Q_UNUSED(b); |
| Q_UNUSED(a); |
| #endif |
| qWarning("QOpenGLTexture: Border color is not supported"); |
| } |
| |
| /*! |
| Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and the alpha |
| value to \a {a}. |
| \overload |
| */ |
| void QOpenGLTexture::setBorderColor(int r, int g, int b, int a) |
| { |
| #if !defined(QT_OPENGL_ES_2) |
| if (!QOpenGLContext::currentContext()->isOpenGLES()) { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| int values[4]; |
| values[0] = r; |
| values[1] = g; |
| values[2] = b; |
| values[3] = a; |
| d->borderColor.clear(); |
| for (int i = 0; i < 4; ++i) |
| d->borderColor.append(QVariant(values[i])); |
| d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values); |
| return; |
| } |
| #else |
| Q_UNUSED(r); |
| Q_UNUSED(g); |
| Q_UNUSED(b); |
| Q_UNUSED(a); |
| #endif |
| qWarning("QOpenGLTexture: Border color is not supported"); |
| |
| // TODO Handle case of using glTextureParameterIiv() based on format |
| } |
| |
| /*! |
| Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and the alpha |
| value to \a {a}. |
| \overload |
| */ |
| void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a) |
| { |
| #if !defined(QT_OPENGL_ES_2) |
| if (!QOpenGLContext::currentContext()->isOpenGLES()) { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| int values[4]; |
| values[0] = int(r); |
| values[1] = int(g); |
| values[2] = int(b); |
| values[3] = int(a); |
| d->borderColor.clear(); |
| for (int i = 0; i < 4; ++i) |
| d->borderColor.append(QVariant(values[i])); |
| d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values); |
| return; |
| } |
| #else |
| Q_UNUSED(r); |
| Q_UNUSED(g); |
| Q_UNUSED(b); |
| Q_UNUSED(a); |
| #endif |
| qWarning("QOpenGLTexture: Border color is not supported"); |
| |
| // TODO Handle case of using glTextureParameterIuiv() based on format |
| } |
| |
| /*! |
| Returns the borderColor of this texture. |
| |
| \sa setBorderColor() |
| */ |
| QColor QOpenGLTexture::borderColor() const |
| { |
| Q_D(const QOpenGLTexture); |
| QColor c(0.0f, 0.0f, 0.0f, 0.0f); |
| if (!d->borderColor.isEmpty()) { |
| c.setRedF(d->borderColor.at(0).toFloat()); |
| c.setGreenF(d->borderColor.at(1).toFloat()); |
| c.setBlueF(d->borderColor.at(2).toFloat()); |
| c.setAlphaF(d->borderColor.at(3).toFloat()); |
| } |
| return c; |
| } |
| |
| /*! |
| Writes the texture border color into the first four elements |
| of the array pointed to by \a border. |
| |
| \sa setBorderColor() |
| */ |
| void QOpenGLTexture::borderColor(float *border) const |
| { |
| Q_D(const QOpenGLTexture); |
| Q_ASSERT(border); |
| if (d->borderColor.isEmpty()) { |
| for (int i = 0; i < 4; ++i) |
| border[i] = 0.0f; |
| } else { |
| for (int i = 0; i < 4; ++i) |
| border[i] = d->borderColor.at(i).toFloat(); |
| } |
| } |
| |
| /*! |
| Writes the texture border color into the first four elements |
| of the array pointed to by \a border. |
| |
| \overload |
| */ |
| void QOpenGLTexture::borderColor(int *border) const |
| { |
| Q_D(const QOpenGLTexture); |
| Q_ASSERT(border); |
| if (d->borderColor.isEmpty()) { |
| for (int i = 0; i < 4; ++i) |
| border[i] = 0; |
| } else { |
| for (int i = 0; i < 4; ++i) |
| border[i] = d->borderColor.at(i).toInt(); |
| } |
| } |
| |
| /*! |
| Writes the texture border color into the first four elements |
| of the array pointed to by \a border. |
| |
| \overload |
| */ |
| void QOpenGLTexture::borderColor(unsigned int *border) const |
| { |
| Q_D(const QOpenGLTexture); |
| Q_ASSERT(border); |
| if (d->borderColor.isEmpty()) { |
| for (int i = 0; i < 4; ++i) |
| border[i] = 0; |
| } else { |
| for (int i = 0; i < 4; ++i) |
| border[i] = d->borderColor.at(i).toUInt(); |
| } |
| } |
| |
| /*! |
| Sets the minimum level of detail to \a value. This limits the selection of highest |
| resolution mipmap (lowest mipmap level). The default value is -1000. |
| |
| \note This function has no effect on Qt built for OpenGL ES 2. |
| \sa minimumLevelOfDetail(), setMaximumLevelOfDetail(), setLevelOfDetailRange() |
| */ |
| void QOpenGLTexture::setMinimumLevelOfDetail(float value) |
| { |
| #if !defined(QT_OPENGL_ES_2) |
| if (!QOpenGLContext::currentContext()->isOpenGLES()) { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| Q_ASSERT(value < d->maxLevelOfDetail); |
| d->minLevelOfDetail = value; |
| d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, value); |
| return; |
| } |
| #else |
| Q_UNUSED(value); |
| #endif |
| qWarning("QOpenGLTexture: Detail level is not supported"); |
| } |
| |
| /*! |
| Returns the minimum level of detail parameter. |
| |
| \sa setMinimumLevelOfDetail(), maximumLevelOfDetail(), levelOfDetailRange() |
| */ |
| float QOpenGLTexture::minimumLevelOfDetail() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->minLevelOfDetail; |
| } |
| |
| /*! |
| Sets the maximum level of detail to \a value. This limits the selection of lowest |
| resolution mipmap (highest mipmap level). The default value is 1000. |
| |
| \note This function has no effect on Qt built for OpenGL ES 2. |
| \sa maximumLevelOfDetail(), setMinimumLevelOfDetail(), setLevelOfDetailRange() |
| */ |
| void QOpenGLTexture::setMaximumLevelOfDetail(float value) |
| { |
| #if !defined(QT_OPENGL_ES_2) |
| if (!QOpenGLContext::currentContext()->isOpenGLES()) { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| Q_ASSERT(value > d->minLevelOfDetail); |
| d->maxLevelOfDetail = value; |
| d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, value); |
| return; |
| } |
| #else |
| Q_UNUSED(value); |
| #endif |
| qWarning("QOpenGLTexture: Detail level is not supported"); |
| } |
| |
| /*! |
| Returns the maximum level of detail parameter. |
| |
| \sa setMaximumLevelOfDetail(), minimumLevelOfDetail(), levelOfDetailRange() |
| */ |
| float QOpenGLTexture::maximumLevelOfDetail() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->maxLevelOfDetail; |
| } |
| |
| /*! |
| Sets the minimum level of detail parameters to \a min and the maximum level |
| to \a max. |
| \note This function has no effect on Qt built for OpenGL ES 2. |
| \sa levelOfDetailRange(), setMinimumLevelOfDetail(), setMaximumLevelOfDetail() |
| */ |
| void QOpenGLTexture::setLevelOfDetailRange(float min, float max) |
| { |
| #if !defined(QT_OPENGL_ES_2) |
| if (!QOpenGLContext::currentContext()->isOpenGLES()) { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| Q_ASSERT(min < max); |
| d->minLevelOfDetail = min; |
| d->maxLevelOfDetail = max; |
| d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, min); |
| d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, max); |
| return; |
| } |
| #else |
| Q_UNUSED(min); |
| Q_UNUSED(max); |
| #endif |
| qWarning("QOpenGLTexture: Detail level is not supported"); |
| } |
| |
| /*! |
| Returns the minimum and maximum level of detail parameters. |
| |
| \sa setLevelOfDetailRange(), minimumLevelOfDetail(), maximumLevelOfDetail() |
| */ |
| QPair<float, float> QOpenGLTexture::levelOfDetailRange() const |
| { |
| Q_D(const QOpenGLTexture); |
| return qMakePair(d->minLevelOfDetail, d->maxLevelOfDetail); |
| } |
| |
| /*! |
| Sets the level of detail bias to \a bias. |
| Level of detail bias affects the point at which mipmapping levels change. |
| Increasing values for level of detail bias makes the overall images blurrier |
| or smoother. Decreasing values make the overall images sharper. |
| |
| \note This function has no effect on Qt built for OpenGL ES 2. |
| \sa levelofDetailBias() |
| */ |
| void QOpenGLTexture::setLevelofDetailBias(float bias) |
| { |
| #if !defined(QT_OPENGL_ES_2) |
| if (!QOpenGLContext::currentContext()->isOpenGLES()) { |
| Q_D(QOpenGLTexture); |
| d->create(); |
| Q_ASSERT(d->texFuncs); |
| Q_ASSERT(d->textureId); |
| d->levelOfDetailBias = bias; |
| d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_LOD_BIAS, bias); |
| return; |
| } |
| #else |
| Q_UNUSED(bias); |
| #endif |
| qWarning("QOpenGLTexture: Detail level is not supported"); |
| } |
| |
| /*! |
| Returns the level of detail bias parameter. |
| |
| \sa setLevelofDetailBias() |
| */ |
| float QOpenGLTexture::levelofDetailBias() const |
| { |
| Q_D(const QOpenGLTexture); |
| return d->levelOfDetailBias; |
| } |
| |
| #ifndef QT_NO_DEBUG_STREAM |
| QDebug operator<<(QDebug debug, const QOpenGLTexture *t) |
| { |
| QDebugStateSaver saver(debug); |
| debug.nospace(); |
| debug << "QOpenGLTexture("; |
| if (t) { |
| const QOpenGLTexturePrivate *d = t->d_ptr.data(); |
| debug << d->target << ", bindingTarget=" << d->bindingTarget |
| << ", size=[" << d->dimensions[0] |
| << ", " << d->dimensions[1]; |
| if (d->target == QOpenGLTexture::Target3D) |
| debug << ", " << d->dimensions[2]; |
| debug << "], format=" << d->format << ", formatClass=" << d->formatClass; |
| if (t->isCreated()) |
| debug << ", textureId=" << d->textureId; |
| if (t->isBound()) |
| debug << ", [bound]"; |
| if (t->isTextureView()) |
| debug << ", [view]"; |
| if (d->fixedSamplePositions) |
| debug << ", [fixedSamplePositions]"; |
| debug << ", mipLevels=" << d->requestedMipLevels << ", layers=" << d->layers |
| << ", faces=" << d->faces << ", samples=" << d->samples |
| << ", depthStencilMode=" << d->depthStencilMode << ", comparisonFunction=" |
| << d->comparisonFunction << ", comparisonMode=" << d->comparisonMode |
| << ", features=" << d->features << ", minificationFilter=" << d->minFilter |
| << ", magnificationFilter=" << d->magFilter << ", wrapMode=" << d->wrapModes[0]; |
| } else { |
| debug << '0'; |
| } |
| debug << ')'; |
| return debug; |
| } |
| #endif // QT_NO_DEBUG_STREAM |
| |
| QT_END_NAMESPACE |