From e4d15b41e83d552c64f32541570f9009a6c6ec81 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 14 Jan 2015 00:02:38 +0100 Subject: QOpenGLTexture: introduce texture comparison support Shadow sampling is an old OpenGL feature (hello, OpenGL 1.3!), which was missing from QOpenGLTexture. This commit adds the relevant support. Change-Id: I9f6b552d806a356d24ee08121af6bc9ce684f2b5 Reviewed-by: Sean Harmer --- src/gui/opengl/qopengltexture.cpp | 121 ++++++++++++++++++++++++++++++++++++++ src/gui/opengl/qopengltexture.h | 25 +++++++- src/gui/opengl/qopengltexture_p.h | 2 + 3 files changed, 147 insertions(+), 1 deletion(-) (limited to 'src/gui') diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 5dc1d017f7..903cfb2bf8 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -64,6 +64,8 @@ QOpenGLTexturePrivate::QOpenGLTexturePrivate(QOpenGLTexture::Target textureTarge baseLevel(0), maxLevel(1000), depthStencilMode(QOpenGLTexture::DepthMode), + comparisonFunction(QOpenGLTexture::CompareLessEqual), + comparisonMode(QOpenGLTexture::CompareNone), minFilter(QOpenGLTexture::Nearest), magFilter(QOpenGLTexture::Nearest), maxAnisotropy(1.0f), @@ -3250,6 +3252,16 @@ bool QOpenGLTexture::hasFeature(Feature feature) 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 MaxFeatureFlag: break; } @@ -3311,6 +3323,11 @@ bool QOpenGLTexture::hasFeature(Feature feature) case Texture1D: break; + case TextureComparisonOperators: + supported = f.version() >= qMakePair(3, 0) + || ctx->hasExtension(QByteArrayLiteral("GL_EXT_shadow_samplers")); + break; + case MaxFeatureFlag: break; } @@ -3632,6 +3649,110 @@ QOpenGLTexture::DepthStencilMode QOpenGLTexture::depthStencilMode() const return d->depthStencilMode; } +/*! + \enum 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) +{ +#if !defined(QT_OPENGL_ES_2) + 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); +#else + Q_UNUSED(function); + qWarning("QOpenGLTexture: texture comparison functions are not supported"); +#endif +} + +/*! + \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) +{ +#if !defined(QT_OPENGL_ES_2) + 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); +#else + Q_UNUSED(mode); + qWarning("QOpenGLTexture: texture comparison modes are not supported"); +#endif +} + +/*! + \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. diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h index 1cf5fdc12a..56fdd07f2f 100644 --- a/src/gui/opengl/qopengltexture.h +++ b/src/gui/opengl/qopengltexture.h @@ -346,8 +346,9 @@ public: NPOTTextures = 0x00000800, NPOTTextureRepeat = 0x00001000, Texture1D = 0x00002000, + TextureComparisonOperators = 0x00004000, #ifndef Q_QDOC - MaxFeatureFlag = 0x00004000 + MaxFeatureFlag = 0x00008000 #endif }; Q_DECLARE_FLAGS(Features, Feature) @@ -488,6 +489,28 @@ public: void setDepthStencilMode(DepthStencilMode mode); DepthStencilMode depthStencilMode() const; + enum ComparisonFunction { + CompareLessEqual = 0x0203, // GL_LEQUAL + CompareGreaterEqual = 0x0206, // GL_GEQUAL + CompareLess = 0x0201, // GL_LESS + CompareGreater = 0x0204, // GL_GREATER + CompareEqual = 0x0202, // GL_EQUAL + CommpareNotEqual = 0x0205, // GL_NOTEQUAL + CompareAlways = 0x0207, // GL_ALWAYS + CompareNever = 0x0200 // GL_NEVER + }; + + void setComparisonFunction(ComparisonFunction function); + ComparisonFunction comparisonFunction() const; + + enum ComparisonMode { + CompareRefToTexture = 0x884E, // GL_COMPARE_REF_TO_TEXTURE + CompareNone = 0x0000 // GL_NONE + }; + + void setComparisonMode(ComparisonMode mode); + ComparisonMode comparisonMode() const; + // Sampling Parameters enum Filter { Nearest = 0x2600, // GL_NEAREST diff --git a/src/gui/opengl/qopengltexture_p.h b/src/gui/opengl/qopengltexture_p.h index 3b70010231..bd0396bab9 100644 --- a/src/gui/opengl/qopengltexture_p.h +++ b/src/gui/opengl/qopengltexture_p.h @@ -138,6 +138,8 @@ public: QOpenGLTexture::SwizzleValue swizzleMask[4]; QOpenGLTexture::DepthStencilMode depthStencilMode; + QOpenGLTexture::ComparisonFunction comparisonFunction; + QOpenGLTexture::ComparisonMode comparisonMode; QOpenGLTexture::Filter minFilter; QOpenGLTexture::Filter magFilter; -- cgit v1.2.3