diff options
Diffstat (limited to 'src/gui/opengl')
-rw-r--r-- | src/gui/opengl/opengl.pri | 1 | ||||
-rw-r--r-- | src/gui/opengl/qopengl.h | 23 | ||||
-rw-r--r-- | src/gui/opengl/qopenglextensions_p.h | 2 | ||||
-rw-r--r-- | src/gui/opengl/qopenglframebufferobject.cpp | 37 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexture.cpp | 384 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexture.h | 12 | ||||
-rw-r--r-- | src/gui/opengl/qopenglversionfunctions.cpp | 16 |
7 files changed, 434 insertions, 41 deletions
diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri index cadba26797..f82401c973 100644 --- a/src/gui/opengl/opengl.pri +++ b/src/gui/opengl/opengl.pri @@ -2,7 +2,6 @@ contains(QT_CONFIG, opengl):CONFIG += opengl contains(QT_CONFIG, opengles2):CONFIG += opengles2 -contains(QT_CONFIG, egl):CONFIG += egl contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) { diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h index ef5ab9aa65..09bb6adf9a 100644 --- a/src/gui/opengl/qopengl.h +++ b/src/gui/opengl/qopengl.h @@ -79,7 +79,28 @@ typedef void* GLeglImageOES; # else // "uncontrolled" ES2 platforms -# include <GLES2/gl2.h> + +// In "es2" builds (QT_OPENGL_ES_2) additional defines indicate if ES +// 3.0 or higher is available. In this case include the corresponding +// header. These are backwards compatible and it should be safe to +// include headers on top of each other, meaning that applications can +// include gl2.h even if gl31.h gets included here. + +// This compile time differentation is important inside Qt because, +// unlike desktop GL, GLES is different when it comes to versioning +// and extensions: Standard functions that are new in a given version +// are always available in a version-specific header and are not +// guaranteed to be dynamically resolvable via eglGetProcAddress (and +// are typically not available as extensions even if they were part of +// an extension for a previous version). + +# if defined(QT_OPENGL_ES_3_1) +# include <GLES3/gl31.h> +# elif defined(QT_OPENGL_ES_3) +# include <GLES3/gl3.h> +# else +# include <GLES2/gl2.h> +#endif /* Some GLES2 implementations (like the one on Harmattan) are missing the diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h index 265771ce1b..065cbb0e57 100644 --- a/src/gui/opengl/qopenglextensions_p.h +++ b/src/gui/opengl/qopenglextensions_p.h @@ -106,8 +106,6 @@ public: OpenGLExtensions openGLExtensions(); bool hasOpenGLExtension(QOpenGLExtensions::OpenGLExtension extension) const; - void initializeGLExtensions(); - GLvoid *glMapBuffer(GLenum target, GLenum access); GLboolean glUnmapBuffer(GLenum target); diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 7d91d2c497..a6feda8732 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -484,7 +484,6 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi initAttachments(ctx, attachment); - funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo); if (valid) { fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc); } else { @@ -968,8 +967,6 @@ bool QOpenGLFramebufferObject::bind() d->valid = d->checkFramebufferStatus(current); else d->initTexture(d->format.textureTarget(), d->format.internalTextureFormat(), d->size, d->format.mipmap()); - if (d->valid && current) - current->d_func()->current_fbo = d->fbo(); return d->valid; } @@ -997,10 +994,8 @@ bool QOpenGLFramebufferObject::release() qWarning("QOpenGLFramebufferObject::release() called from incompatible context"); #endif - if (current) { - current->d_func()->current_fbo = current->defaultFramebufferObject(); - d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->d_func()->current_fbo); - } + if (current) + d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->defaultFramebufferObject()); return true; } @@ -1047,7 +1042,7 @@ GLuint QOpenGLFramebufferObject::takeTexture() GLuint id = 0; if (isValid() && d->texture_guard) { QOpenGLContext *current = QOpenGLContext::currentContext(); - if (current && current->shareGroup() == d->fbo_guard->group() && current->d_func()->current_fbo == d->fbo()) + if (current && current->shareGroup() == d->fbo_guard->group() && isBound()) release(); id = d->texture_guard->id(); // Do not call free() on texture_guard, just null it out. @@ -1163,16 +1158,13 @@ QImage QOpenGLFramebufferObject::toImage() const bool QOpenGLFramebufferObject::bindDefault() { QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext()); - QOpenGLFunctions functions(ctx); - if (ctx) { - ctx->d_func()->current_fbo = ctx->defaultFramebufferObject(); - functions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo); + if (ctx) + ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject()); #ifdef QT_DEBUG - } else { + else qWarning("QOpenGLFramebufferObject::bindDefault() called without current context."); #endif - } return ctx != 0; } @@ -1185,7 +1177,7 @@ bool QOpenGLFramebufferObject::bindDefault() */ bool QOpenGLFramebufferObject::hasOpenGLFramebufferObjects() { - return QOpenGLFunctions(QOpenGLContext::currentContext()).hasOpenGLFeature(QOpenGLFunctions::Framebuffers); + return QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(QOpenGLFunctions::Framebuffers); } /*! @@ -1236,20 +1228,21 @@ void QOpenGLFramebufferObject::setAttachment(QOpenGLFramebufferObject::Attachmen #endif d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo()); d->initAttachments(current, attachment); - if (current->d_func()->current_fbo != d->fbo()) - d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->d_func()->current_fbo); } /*! - Returns \c true if the framebuffer object is currently bound to a context, + Returns \c true if the framebuffer object is currently bound to the current context, otherwise false is returned. */ - bool QOpenGLFramebufferObject::isBound() const { Q_D(const QOpenGLFramebufferObject); - QOpenGLContext *current = QOpenGLContext::currentContext(); - return current ? current->d_func()->current_fbo == d->fbo() : false; + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (!ctx) + return false; + GLint fbo = 0; + ctx->functions()->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo); + return GLuint(fbo) == d->fbo(); } /*! @@ -1355,8 +1348,6 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, extensions.glBlitFramebuffer(sx0, sy0, sx1, sy1, tx0, ty0, tx1, ty1, buffers, filter); - - extensions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo); } QT_END_NAMESPACE diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 6e2e72a3b4..b64956c65c 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -67,7 +67,7 @@ QOpenGLTexturePrivate::QOpenGLTexturePrivate(QOpenGLTexture::Target textureTarge mipLevels(-1), layers(1), faces(1), - samples(1), + samples(0), fixedSamplePositions(true), baseLevel(0), maxLevel(1000), @@ -200,7 +200,7 @@ void QOpenGLTexturePrivate::destroy() mipLevels = -1; layers = 1; faces = 1; - samples = 1; + samples = 0; fixedSamplePositions = true, baseLevel = 0; maxLevel = 1000; @@ -314,8 +314,239 @@ void QOpenGLTexturePrivate::allocateStorage() allocateMutableStorage(); } +static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpenGLTexture::TextureFormat internalFormat) +{ + switch (internalFormat) { + case QOpenGLTexture::NoFormat: + return QOpenGLTexture::NoSourceFormat; + + 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: + 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: + return QOpenGLTexture::RGBA; + + case QOpenGLTexture::DepthFormat: + return QOpenGLTexture::Depth; + + case QOpenGLTexture::AlphaFormat: + return QOpenGLTexture::Alpha; + + case QOpenGLTexture::RGBFormat: + 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: + 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: + return QOpenGLTexture::UInt8; + + case QOpenGLTexture::D16: + case QOpenGLTexture::D24: + case QOpenGLTexture::D32: + case QOpenGLTexture::D32F: + return QOpenGLTexture::UInt8; + + 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: + return QOpenGLTexture::UInt8; + + case QOpenGLTexture::DepthFormat: + case QOpenGLTexture::AlphaFormat: + case QOpenGLTexture::RGBFormat: + case QOpenGLTexture::RGBAFormat: + case QOpenGLTexture::LuminanceFormat: + case QOpenGLTexture::LuminanceAlphaFormat: + return QOpenGLTexture::UInt8; + } + + Q_UNREACHABLE(); + return QOpenGLTexture::NoPixelType; +} + void QOpenGLTexturePrivate::allocateMutableStorage() { + const QOpenGLTexture::PixelFormat pixelFormat = pixelFormatCompatibleWithInternalFormat(format); + const QOpenGLTexture::PixelType pixelType = pixelTypeCompatibleWithInternalFormat(format); + switch (target) { case QOpenGLTexture::TargetBuffer: // Buffer textures get their storage from an external OpenGL buffer @@ -328,7 +559,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage() texFuncs->glTextureImage1D(textureId, target, bindingTarget, level, format, mipLevelSize(level, dimensions[0]), 0, - QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0); + pixelFormat, pixelType, 0); } else { qWarning("1D textures are not supported"); return; @@ -343,7 +574,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage() mipLevelSize(level, dimensions[0]), layers, 0, - QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0); + pixelFormat, pixelType, 0); } else { qWarning("1D array textures are not supported"); return; @@ -357,7 +588,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage() mipLevelSize(level, dimensions[0]), mipLevelSize(level, dimensions[1]), 0, - QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0); + pixelFormat, pixelType, 0); break; case QOpenGLTexture::TargetCubeMap: { @@ -377,7 +608,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage() mipLevelSize(level, dimensions[0]), mipLevelSize(level, dimensions[1]), 0, - QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0); + pixelFormat, pixelType, 0); } } break; @@ -391,7 +622,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage() mipLevelSize(level, dimensions[1]), layers, 0, - QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0); + pixelFormat, pixelType, 0); } else { qWarning("Array textures are not supported"); return; @@ -407,7 +638,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage() mipLevelSize(level, dimensions[1]), 6 * layers, 0, - QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0); + pixelFormat, pixelType, 0); } else { qWarning("Cubemap Array textures are not supported"); return; @@ -422,7 +653,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage() mipLevelSize(level, dimensions[1]), mipLevelSize(level, dimensions[2]), 0, - QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0); + pixelFormat, pixelType, 0); } else { qWarning("3D textures are not supported"); return; @@ -1289,6 +1520,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target \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 @@ -1348,6 +1580,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target \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) @@ -1382,6 +1615,8 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target \value UInt16_RGBA4_Rev Equivalent to GL_UNSIGNED_SHORT_4_4_4_4_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 */ /*! @@ -1483,6 +1718,17 @@ 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. @@ -1820,6 +2066,7 @@ void QOpenGLTexture::setFormat(TextureFormat format) case D32: case D32F: case D32FS8X24: + case S8: case DepthFormat: case AlphaFormat: case RGBFormat: @@ -2063,6 +2310,125 @@ int QOpenGLTexture::faces() const } /*! + 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. diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h index 0c272456f6..ea81f1f8a4 100644 --- a/src/gui/opengl/qopengltexture.h +++ b/src/gui/opengl/qopengltexture.h @@ -100,6 +100,8 @@ public: explicit QOpenGLTexture(const QImage& image, MipMapGeneration genMipMaps = GenerateMipMaps); ~QOpenGLTexture(); + Target target() const; + // Creation and destruction bool create(); void destroy(); @@ -201,6 +203,7 @@ public: D32 = 0x81A7, // GL_DEPTH_COMPONENT32 D32F = 0x8CAC, // GL_DEPTH_COMPONENT32F D32FS8X24 = 0x8CAD, // GL_DEPTH32F_STENCIL8 + S8 = 0x8D48, // GL_STENCIL_INDEX8 // Compressed formats RGB_DXT1 = 0x83F0, // GL_COMPRESSED_RGB_S3TC_DXT1_EXT @@ -272,6 +275,10 @@ public: void setLayers(int layers); int layers() const; int faces() const; + void setSamples(int samples); + int samples() const; + void setFixedSamplePositions(bool fixed); + bool isFixedSamplePositions() const; void allocateStorage(); bool isStorageAllocated() const; @@ -304,6 +311,7 @@ public: BGR_Integer = 0x8D9A, // GL_BGR_INTEGER RGBA_Integer = 0x8D99, // GL_RGBA_INTEGER BGRA_Integer = 0x8D9B, // GL_BGRA_INTEGER + Stencil = 0x1901, // GL_STENCIL_INDEX Depth = 0x1902, // GL_DEPTH_COMPONENT DepthStencil = 0x84F9, // GL_DEPTH_STENCIL Alpha = 0x1906, // GL_ALPHA @@ -333,7 +341,9 @@ public: UInt16_RGBA4 = 0x8033, // GL_UNSIGNED_SHORT_4_4_4_4 UInt16_RGBA4_Rev = 0x8365, // GL_UNSIGNED_SHORT_4_4_4_4_REV UInt32_RGB10A2 = 0x8036, // GL_UNSIGNED_INT_10_10_10_2 - UInt32_RGB10A2_Rev = 0x8368 // GL_UNSIGNED_INT_2_10_10_10_REV + UInt32_RGB10A2_Rev = 0x8368, // GL_UNSIGNED_INT_2_10_10_10_REV + UInt32_D24S8 = 0x84FA, // GL_UNSIGNED_INT_24_8 + Float32_D32_UInt32_S8_X24 = 0x8DAD // GL_FLOAT_32_UNSIGNED_INT_24_8_REV }; // Pixel transfer diff --git a/src/gui/opengl/qopenglversionfunctions.cpp b/src/gui/opengl/qopenglversionfunctions.cpp index 5df7463e8a..010ddaf228 100644 --- a/src/gui/opengl/qopenglversionfunctions.cpp +++ b/src/gui/opengl/qopenglversionfunctions.cpp @@ -227,7 +227,9 @@ QOpenGLFunctions_1_0_CoreBackend::QOpenGLFunctions_1_0_CoreBackend(QOpenGLContex { // OpenGL 1.0 core functions #if defined(Q_OS_WIN) - HMODULE handle = GetModuleHandleA("opengl32.dll"); + HMODULE handle = static_cast<HMODULE>(QOpenGLContext::openGLModuleHandle()); + if (!handle) + handle = GetModuleHandleA("opengl32.dll"); Viewport = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLint , GLint , GLsizei , GLsizei )>(GetProcAddress(handle, "glViewport")); DepthRange = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLdouble , GLdouble )>(GetProcAddress(handle, "glDepthRange")); IsEnabled = reinterpret_cast<GLboolean (QOPENGLF_APIENTRYP)(GLenum )>(GetProcAddress(handle, "glIsEnabled")); @@ -339,7 +341,9 @@ QOpenGLFunctions_1_1_CoreBackend::QOpenGLFunctions_1_1_CoreBackend(QOpenGLContex { // OpenGL 1.1 core functions #if defined(Q_OS_WIN) - HMODULE handle = GetModuleHandleA("opengl32.dll"); + HMODULE handle = static_cast<HMODULE>(QOpenGLContext::openGLModuleHandle()); + if (!handle) + handle = GetModuleHandleA("opengl32.dll"); Indexubv = reinterpret_cast<void (QOPENGLF_APIENTRYP)(const GLubyte *)>(GetProcAddress(handle, "glIndexubv")); Indexub = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLubyte )>(GetProcAddress(handle, "glIndexub")); IsTexture = reinterpret_cast<GLboolean (QOPENGLF_APIENTRYP)(GLuint )>(GetProcAddress(handle, "glIsTexture")); @@ -991,7 +995,9 @@ QOpenGLFunctions_1_0_DeprecatedBackend::QOpenGLFunctions_1_0_DeprecatedBackend(Q { // OpenGL 1.0 deprecated functions #if defined(Q_OS_WIN) - HMODULE handle = GetModuleHandleA("opengl32.dll"); + HMODULE handle = static_cast<HMODULE>(QOpenGLContext::openGLModuleHandle()); + if (!handle) + handle = GetModuleHandleA("opengl32.dll"); Translatef = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLfloat , GLfloat , GLfloat )>(GetProcAddress(handle, "glTranslatef")); Translated = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLdouble , GLdouble , GLdouble )>(GetProcAddress(handle, "glTranslated")); Scalef = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLfloat , GLfloat , GLfloat )>(GetProcAddress(handle, "glScalef")); @@ -1523,7 +1529,9 @@ QOpenGLFunctions_1_1_DeprecatedBackend::QOpenGLFunctions_1_1_DeprecatedBackend(Q { // OpenGL 1.1 deprecated functions #if defined(Q_OS_WIN) - HMODULE handle = GetModuleHandleA("opengl32.dll"); + HMODULE handle = static_cast<HMODULE>(QOpenGLContext::openGLModuleHandle()); + if (!handle) + handle = GetModuleHandleA("opengl32.dll"); PushClientAttrib = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLbitfield )>(GetProcAddress(handle, "glPushClientAttrib")); PopClientAttrib = reinterpret_cast<void (QOPENGLF_APIENTRYP)()>(GetProcAddress(handle, "glPopClientAttrib")); PrioritizeTextures = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *, const GLfloat *)>(GetProcAddress(handle, "glPrioritizeTextures")); |