From 361cefbb05e348eb21b0e64aac8f590eadd00f33 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Fri, 27 Dec 2019 13:57:20 -0500 Subject: [PATCH] Add new wrap mode "clampone". Pixels sampled outside of [0, 1] are white (1, 1, 1, 1). --HG-- branch : minor --- src/modules/graphics/Texture.cpp | 1 + src/modules/graphics/Texture.h | 3 +++ src/modules/graphics/opengl/Canvas.cpp | 8 ++++---- src/modules/graphics/opengl/Graphics.cpp | 2 +- src/modules/graphics/opengl/Image.cpp | 8 ++++---- src/modules/graphics/opengl/OpenGL.cpp | 25 ++++++++++++++++++++---- src/modules/graphics/opengl/OpenGL.h | 2 +- 7 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index 547b5eeb1..b8dfedfd7 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -450,6 +450,7 @@ StringMap::Entry Texture::wrapModeEnt { { "clamp", WRAP_CLAMP }, { "clampzero", WRAP_CLAMP_ZERO }, + { "clampone", WRAP_CLAMP_ONE }, { "repeat", WRAP_REPEAT }, { "mirroredrepeat", WRAP_MIRRORED_REPEAT }, }; diff --git a/src/modules/graphics/Texture.h b/src/modules/graphics/Texture.h index 74162d59e..8f0b4a9b7 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -67,6 +67,7 @@ public: { WRAP_CLAMP, WRAP_CLAMP_ZERO, + WRAP_CLAMP_ONE, WRAP_REPEAT, WRAP_MIRRORED_REPEAT, WRAP_MAX_ENUM @@ -153,6 +154,8 @@ public: static int getTotalMipmapCount(int w, int h); static int getTotalMipmapCount(int w, int h, int d); + static bool isClampZeroOrOne(WrapMode w) { return w == WRAP_CLAMP_ZERO || w == WRAP_CLAMP_ONE; } + static bool getConstant(const char *in, TextureType &out); static bool getConstant(TextureType in, const char *&out); static std::vector getConstants(TextureType); diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index 81d379bb2..c53a416a4 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -357,11 +357,11 @@ bool Canvas::setWrap(const Texture::Wrap &w) wrap.s = wrap.t = wrap.r = WRAP_CLAMP; } - if (!gl.isClampZeroTextureWrapSupported()) + if (!gl.isClampZeroOneTextureWrapSupported()) { - if (wrap.s == WRAP_CLAMP_ZERO) wrap.s = WRAP_CLAMP; - if (wrap.t == WRAP_CLAMP_ZERO) wrap.t = WRAP_CLAMP; - if (wrap.r == WRAP_CLAMP_ZERO) wrap.r = WRAP_CLAMP; + if (isClampZeroOrOne(wrap.s)) wrap.s = WRAP_CLAMP; + if (isClampZeroOrOne(wrap.t)) wrap.t = WRAP_CLAMP; + if (isClampZeroOrOne(wrap.r)) wrap.r = WRAP_CLAMP; } gl.bindTextureToUnit(this, 0, false); diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 6a7e17bb6..d7a4e51d3 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -1363,7 +1363,7 @@ void Graphics::getAPIStats(int &shaderswitches) const void Graphics::initCapabilities() { capabilities.features[FEATURE_MULTI_CANVAS_FORMATS] = Canvas::isMultiFormatMultiCanvasSupported(); - capabilities.features[FEATURE_CLAMP_ZERO] = gl.isClampZeroTextureWrapSupported(); + capabilities.features[FEATURE_CLAMP_ZERO] = gl.isClampZeroOneTextureWrapSupported(); capabilities.features[FEATURE_BLENDMINMAX] = GLAD_VERSION_1_4 || GLAD_ES_VERSION_3_0 || GLAD_EXT_blend_minmax; capabilities.features[FEATURE_LIGHTEN] = capabilities.features[FEATURE_BLENDMINMAX]; capabilities.features[FEATURE_FULL_NPOT] = GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot; diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 5ec0496fb..b2c7d9979 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -316,11 +316,11 @@ bool Image::setWrap(const Texture::Wrap &w) wrap.s = wrap.t = wrap.r = WRAP_CLAMP; } - if (!gl.isClampZeroTextureWrapSupported()) + if (!gl.isClampZeroOneTextureWrapSupported()) { - if (wrap.s == WRAP_CLAMP_ZERO) wrap.s = WRAP_CLAMP; - if (wrap.t == WRAP_CLAMP_ZERO) wrap.t = WRAP_CLAMP; - if (wrap.r == WRAP_CLAMP_ZERO) wrap.r = WRAP_CLAMP; + if (isClampZeroOrOne(wrap.s)) wrap.s = WRAP_CLAMP; + if (isClampZeroOrOne(wrap.t)) wrap.t = WRAP_CLAMP; + if (isClampZeroOrOne(wrap.r)) wrap.r = WRAP_CLAMP; } gl.bindTextureToUnit(this, 0, false); diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index ed3c749ab..affbb4d99 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -1061,6 +1061,7 @@ GLint OpenGL::getGLWrapMode(Texture::WrapMode wmode) default: return GL_CLAMP_TO_EDGE; case Texture::WRAP_CLAMP_ZERO: + case Texture::WRAP_CLAMP_ONE: return GL_CLAMP_TO_BORDER; case Texture::WRAP_REPEAT: return GL_REPEAT; @@ -1094,13 +1095,29 @@ GLint OpenGL::getGLCompareMode(CompareMode mode) } } +static bool isClampOne(Texture::WrapMode mode) +{ + return mode == Texture::WRAP_CLAMP_ONE; +} + void OpenGL::setTextureWrap(TextureType target, const graphics::Texture::Wrap &w) { - glTexParameteri(getGLTextureType(target), GL_TEXTURE_WRAP_S, getGLWrapMode(w.s)); - glTexParameteri(getGLTextureType(target), GL_TEXTURE_WRAP_T, getGLWrapMode(w.t)); + GLenum textype = getGLTextureType(target); + + if (Texture::isClampZeroOrOne(w.s) || Texture::isClampZeroOrOne(w.t) || Texture::isClampZeroOrOne(w.r)) + { + GLfloat c[] = {0.0f, 0.0f, 0.0f, 0.0f}; + if (isClampOne(w.s) || isClampOne(w.t) || isClampOne(w.r)) + c[0] = c[1] = c[2] = c[3] = 1.0f; + + glTexParameterfv(textype, GL_TEXTURE_BORDER_COLOR, c); + } + + glTexParameteri(textype, GL_TEXTURE_WRAP_S, getGLWrapMode(w.s)); + glTexParameteri(textype, GL_TEXTURE_WRAP_T, getGLWrapMode(w.t)); if (target == TEXTURE_VOLUME) - glTexParameteri(getGLTextureType(target), GL_TEXTURE_WRAP_R, getGLWrapMode(w.r)); + glTexParameteri(textype, GL_TEXTURE_WRAP_R, getGLWrapMode(w.r)); } bool OpenGL::rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, bool &isSRGB, int width, int height, int depth) @@ -1202,7 +1219,7 @@ bool OpenGL::isTextureTypeSupported(TextureType type) const } } -bool OpenGL::isClampZeroTextureWrapSupported() const +bool OpenGL::isClampZeroOneTextureWrapSupported() const { return GLAD_VERSION_1_3 || GLAD_EXT_texture_border_clamp || GLAD_NV_texture_border_clamp; } diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index 54a35f4c1..f64a665df 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -348,7 +348,7 @@ public: bool rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, bool &isSRGB, int width, int height, int depth = 1); bool isTextureTypeSupported(TextureType type) const; - bool isClampZeroTextureWrapSupported() const; + bool isClampZeroOneTextureWrapSupported() const; bool isPixelShaderHighpSupported() const; bool isInstancingSupported() const; bool isDepthCompareSampleSupported() const;