Browse Source

Add new wrap mode "clampone". Pixels sampled outside of [0, 1] are white (1, 1, 1, 1).

--HG--
branch : minor
Alex Szpakowski 5 years ago
parent
commit
361cefbb05

+ 1 - 0
src/modules/graphics/Texture.cpp

@@ -450,6 +450,7 @@ StringMap<Texture::WrapMode, Texture::WRAP_MAX_ENUM>::Entry Texture::wrapModeEnt
 {
 	{ "clamp", WRAP_CLAMP },
 	{ "clampzero", WRAP_CLAMP_ZERO },
+	{ "clampone", WRAP_CLAMP_ONE },
 	{ "repeat", WRAP_REPEAT },
 	{ "mirroredrepeat", WRAP_MIRRORED_REPEAT },
 };

+ 3 - 0
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<std::string> getConstants(TextureType);

+ 4 - 4
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);

+ 1 - 1
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;

+ 4 - 4
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);

+ 21 - 4
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;
 }

+ 1 - 1
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;