Added "lighten" and "darken" blend modes (resolves issue #443).

They perform the equations res.rgba = max(dst.rgba, src.rgba) and res.rgba = min(dst.rgba, src.rgba) respectively.

They only work when the "premultiplied" blend alpha mode is used, and an error occurs otherwise.  They also aren't supported on some non-iOS OpenGL ES 2 systems. Check for support with love.graphics.getSupported().lighten.
This commit is contained in:
Alex Szpakowski
2015-12-31 15:54:02 -04:00
parent 5a98af7e2d
commit b48117544d
3 changed files with 40 additions and 5 deletions
+3
View File
@@ -205,6 +205,8 @@ StringMap<Graphics::BlendMode, Graphics::BLEND_MAX_ENUM>::Entry Graphics::blendM
{ "add", BLEND_ADD },
{ "subtract", BLEND_SUBTRACT },
{ "multiply", BLEND_MULTIPLY },
{ "lighten", BLEND_LIGHTEN },
{ "darken", BLEND_DARKEN },
{ "screen", BLEND_SCREEN },
{ "replace", BLEND_REPLACE },
};
@@ -265,6 +267,7 @@ StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM>::Entry Graphics::suppor
{
{ "multicanvasformats", SUPPORT_MULTI_CANVAS_FORMATS },
{ "clampzero", SUPPORT_CLAMP_ZERO },
{ "lighten", SUPPORT_LIGHTEN },
};
StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM> Graphics::support(Graphics::supportEntries, sizeof(Graphics::supportEntries));
+3
View File
@@ -84,6 +84,8 @@ public:
BLEND_ADD,
BLEND_SUBTRACT,
BLEND_MULTIPLY,
BLEND_LIGHTEN,
BLEND_DARKEN,
BLEND_SCREEN,
BLEND_REPLACE,
BLEND_MAX_ENUM
@@ -138,6 +140,7 @@ public:
{
SUPPORT_MULTI_CANVAS_FORMATS,
SUPPORT_CLAMP_ZERO,
SUPPORT_LIGHTEN,
SUPPORT_MAX_ENUM
};
+34 -5
View File
@@ -1079,6 +1079,28 @@ void Graphics::setBlendMode(BlendMode mode, BlendAlpha alphamode)
GLenum dstRGB = GL_ZERO;
GLenum dstA = GL_ZERO;
if (mode == BLEND_LIGHTEN || mode == BLEND_DARKEN)
{
if (!isSupported(SUPPORT_LIGHTEN))
throw love::Exception("The 'lighten' and 'darken' blend modes are not supported on this system.");
}
if (alphamode != BLENDALPHA_PREMULTIPLIED)
{
const char *modestr = "unknown";
switch (mode)
{
case BLEND_LIGHTEN:
case BLEND_DARKEN:
/*case BLEND_MULTIPLY:*/ // FIXME: Uncomment for 0.11.0
getConstant(mode, modestr);
throw love::Exception("The '%s' blend mode must be used with premultiplied alpha.", modestr);
break;
default:
break;
}
}
switch (mode)
{
case BLEND_ALPHA:
@@ -1096,6 +1118,12 @@ void Graphics::setBlendMode(BlendMode mode, BlendAlpha alphamode)
srcA = GL_ZERO;
dstRGB = dstA = GL_ONE;
break;
case BLEND_LIGHTEN:
func = GL_MAX;
break;
case BLEND_DARKEN:
func = GL_MIN;
break;
case BLEND_SCREEN:
srcRGB = srcA = GL_ONE;
dstRGB = dstA = GL_ONE_MINUS_SRC_COLOR;
@@ -1609,14 +1637,13 @@ Graphics::Stats Graphics::getStats() const
double Graphics::getSystemLimit(SystemLimit limittype) const
{
GLfloat limits[2];
switch (limittype)
{
case Graphics::LIMIT_POINT_SIZE:
{
GLfloat limits[2];
glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, limits);
return (double) limits[1];
}
glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, limits);
return (double) limits[1];
case Graphics::LIMIT_TEXTURE_SIZE:
return (double) gl.getMaxTextureSize();
case Graphics::LIMIT_MULTI_CANVAS:
@@ -1636,6 +1663,8 @@ bool Graphics::isSupported(Support feature) const
return Canvas::isMultiFormatMultiCanvasSupported();
case SUPPORT_CLAMP_ZERO:
return gl.isClampZeroTextureWrapSupported();
case SUPPORT_LIGHTEN:
return GLAD_VERSION_1_4 || GLAD_ES_VERSION_3_0 || GLAD_EXT_blend_minmax;
default:
return false;
}