Added a new texture wrap mode "clampzero", which outputs transparent black (or opaque black for textures without an alpha channel) rather than the texture's edge colors, when it's drawn or sampled from outside of its regular texture coordinate range.

This commit is contained in:
Alex Szpakowski
2015-11-30 02:22:20 -04:00
parent 2c4e713114
commit 4c82c96369
9 changed files with 43 additions and 32 deletions
+1
View File
@@ -182,6 +182,7 @@ StringMap<Graphics::LineJoin, Graphics::LINE_JOIN_MAX_ENUM> Graphics::lineJoins(
StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM>::Entry Graphics::supportEntries[] =
{
{ "multicanvasformats", SUPPORT_MULTI_CANVAS_FORMATS },
{ "clampzero", SUPPORT_CLAMP_ZERO },
};
StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM> Graphics::support(Graphics::supportEntries, sizeof(Graphics::supportEntries));
+1
View File
@@ -99,6 +99,7 @@ public:
enum Support
{
SUPPORT_MULTI_CANVAS_FORMATS,
SUPPORT_CLAMP_ZERO,
SUPPORT_MAX_ENUM
};
+7 -6
View File
@@ -114,18 +114,19 @@ bool Texture::getConstant(WrapMode in, const char *&out)
StringMap<Texture::FilterMode, Texture::FILTER_MAX_ENUM>::Entry Texture::filterModeEntries[] =
{
{ "linear", Texture::FILTER_LINEAR },
{ "nearest", Texture::FILTER_NEAREST },
{ "none", Texture::FILTER_NONE },
{ "linear", FILTER_LINEAR },
{ "nearest", FILTER_NEAREST },
{ "none", FILTER_NONE },
};
StringMap<Texture::FilterMode, Texture::FILTER_MAX_ENUM> Texture::filterModes(Texture::filterModeEntries, sizeof(Texture::filterModeEntries));
StringMap<Texture::WrapMode, Texture::WRAP_MAX_ENUM>::Entry Texture::wrapModeEntries[] =
{
{ "clamp", Texture::WRAP_CLAMP },
{ "repeat", Texture::WRAP_REPEAT },
{ "mirroredrepeat", Texture::WRAP_MIRRORED_REPEAT },
{ "clamp", WRAP_CLAMP },
{ "clampzero", WRAP_CLAMP_ZERO },
{ "repeat", WRAP_REPEAT },
{ "mirroredrepeat", WRAP_MIRRORED_REPEAT },
};
StringMap<Texture::WrapMode, Texture::WRAP_MAX_ENUM> Texture::wrapModes(Texture::wrapModeEntries, sizeof(Texture::wrapModeEntries));
+1
View File
@@ -43,6 +43,7 @@ public:
enum WrapMode
{
WRAP_CLAMP,
WRAP_CLAMP_ZERO,
WRAP_REPEAT,
WRAP_MIRRORED_REPEAT,
WRAP_MAX_ENUM
+1 -10
View File
@@ -407,9 +407,6 @@ void Canvas::startGrab(const std::vector<Canvas *> &canvases)
if (canvases.size() > 0)
{
if (!isMultiCanvasSupported())
throw love::Exception("Multi-canvas rendering is not supported on this system.");
if ((int) canvases.size() + 1 > gl.getMaxRenderTargets())
throw love::Exception("This system can't simultaneously render to %d canvases.", canvases.size()+1);
@@ -804,15 +801,9 @@ bool Canvas::isSupported()
return GLAD_ES_VERSION_2_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object || GLAD_EXT_framebuffer_object;
}
bool Canvas::isMultiCanvasSupported()
{
// system must support at least 4 simultaneous active canvases.
return gl.getMaxRenderTargets() >= 4;
}
bool Canvas::isMultiFormatMultiCanvasSupported()
{
return isMultiCanvasSupported() && (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object);
return gl.getMaxRenderTargets() > 1 && (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object);
}
bool Canvas::supportedFormats[] = {false};
-1
View File
@@ -118,7 +118,6 @@ public:
}
static bool isSupported();
static bool isMultiCanvasSupported();
static bool isMultiFormatMultiCanvasSupported();
static bool isFormatSupported(Format format);
+2
View File
@@ -1491,6 +1491,8 @@ bool Graphics::isSupported(Support feature) const
{
case SUPPORT_MULTI_CANVAS_FORMATS:
return Canvas::isMultiFormatMultiCanvasSupported();
case SUPPORT_CLAMP_ZERO:
return gl.isClampZeroTextureWrapSupported();
default:
return false;
}
+26 -15
View File
@@ -602,24 +602,35 @@ void OpenGL::setTextureFilter(graphics::Texture::Filter &f)
f.anisotropy = 1.0f;
}
GLint OpenGL::getGLWrapMode(Texture::WrapMode wmode)
{
if (wmode == Texture::WRAP_CLAMP_ZERO && !isClampZeroTextureWrapSupported())
wmode = Texture::WRAP_CLAMP;
switch (wmode)
{
case Texture::WRAP_CLAMP:
default:
return GL_CLAMP_TO_EDGE;
case Texture::WRAP_CLAMP_ZERO:
return GL_CLAMP_TO_BORDER;
case Texture::WRAP_REPEAT:
return GL_REPEAT;
case Texture::WRAP_MIRRORED_REPEAT:
return GL_MIRRORED_REPEAT;
}
}
void OpenGL::setTextureWrap(const graphics::Texture::Wrap &w)
{
auto glWrapMode = [](Texture::WrapMode wmode) -> GLint
{
switch (wmode)
{
case Texture::WRAP_CLAMP:
default:
return GL_CLAMP_TO_EDGE;
case Texture::WRAP_REPEAT:
return GL_REPEAT;
case Texture::WRAP_MIRRORED_REPEAT:
return GL_MIRRORED_REPEAT;
}
};
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getGLWrapMode(w.s));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getGLWrapMode(w.t));
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapMode(w.s));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapMode(w.t));
bool OpenGL::isClampZeroTextureWrapSupported() const
{
return GLAD_VERSION_1_3 || GLAD_EXT_texture_border_clamp || GLAD_NV_texture_border_clamp;
}
int OpenGL::getMaxTextureSize() const
+4
View File
@@ -312,6 +312,8 @@ public:
**/
void setTextureWrap(const graphics::Texture::Wrap &w);
bool isClampZeroTextureWrapSupported() const;
/**
* Returns the maximum supported width or height of a texture.
**/
@@ -354,6 +356,8 @@ private:
void initMatrices();
void createDefaultTexture();
GLint getGLWrapMode(Texture::WrapMode wmode);
bool contextInitialized;
float maxAnisotropy;