Added an optional (true by default) boolean argument to love.graphics.setBlendMode to specify whether alpha should be multiplied with rgb when blending.

Removed the 'premultiplied' blend mode, since setBlendMode("alpha", false) accomplishes the same thing now.

The 'multiply' blend mode is unaffected by the new flag, since fixed-function hardware blending can't do the equivalent of setBlendMode("multiply", true).
This commit is contained in:
Alex Szpakowski
2015-06-24 16:47:10 -03:00
parent ed3f419747
commit 88c8e0c071
5 changed files with 27 additions and 19 deletions
-1
View File
@@ -123,7 +123,6 @@ StringMap<Graphics::BlendMode, Graphics::BLEND_MAX_ENUM>::Entry Graphics::blendM
{ "add", BLEND_ADD },
{ "subtract", BLEND_SUBTRACT },
{ "multiply", BLEND_MULTIPLY },
{ "premultiplied", BLEND_PREMULTIPLIED },
{ "screen", BLEND_SCREEN },
{ "replace", BLEND_REPLACE },
};
-1
View File
@@ -50,7 +50,6 @@ public:
BLEND_ADD,
BLEND_SUBTRACT,
BLEND_MULTIPLY,
BLEND_PREMULTIPLIED,
BLEND_SCREEN,
BLEND_REPLACE,
BLEND_MAX_ENUM
+17 -12
View File
@@ -101,7 +101,7 @@ void Graphics::restoreState(const DisplayState &s)
setColor(s.color);
setBackgroundColor(s.backgroundColor);
setBlendMode(s.blendMode);
setBlendMode(s.blendMode, s.blendMultiplyAlpha);
setLineWidth(s.lineWidth);
setLineStyle(s.lineStyle);
@@ -137,8 +137,8 @@ void Graphics::restoreStateChecked(const DisplayState &s)
if (*(uint32 *) &s.backgroundColor.r != *(uint32 *) &cur.backgroundColor.r)
setBackgroundColor(s.backgroundColor);
if (s.blendMode != cur.blendMode)
setBlendMode(s.blendMode);
if (s.blendMode != cur.blendMode || s.blendMultiplyAlpha != cur.blendMultiplyAlpha)
setBlendMode(s.blendMode, s.blendMultiplyAlpha);
// These are just simple assignments.
setLineWidth(s.lineWidth);
@@ -923,7 +923,7 @@ Graphics::ColorMask Graphics::getColorMask() const
return states.back().colorMask;
}
void Graphics::setBlendMode(Graphics::BlendMode mode)
void Graphics::setBlendMode(BlendMode mode, bool multiplyalpha)
{
GLenum func = GL_FUNC_ADD;
GLenum srcRGB = GL_ONE;
@@ -934,22 +934,18 @@ void Graphics::setBlendMode(Graphics::BlendMode mode)
switch (mode)
{
case BLEND_ALPHA:
srcRGB = GL_SRC_ALPHA;
srcA = GL_ONE;
srcRGB = srcA = GL_ONE;
dstRGB = dstA = GL_ONE_MINUS_SRC_ALPHA;
break;
case BLEND_MULTIPLY:
srcRGB = srcA = GL_DST_COLOR;
dstRGB = dstA = GL_ZERO;
break;
case BLEND_PREMULTIPLIED:
srcRGB = srcA = GL_ONE;
dstRGB = dstA = GL_ONE_MINUS_SRC_ALPHA;
break;
case BLEND_SUBTRACT:
func = GL_FUNC_REVERSE_SUBTRACT;
case BLEND_ADD:
srcRGB = srcA = GL_SRC_ALPHA;
srcRGB = GL_ONE;
srcA = GL_SRC_ALPHA; // FIXME: This isn't correct...
dstRGB = dstA = GL_ONE;
break;
case BLEND_SCREEN:
@@ -963,14 +959,20 @@ void Graphics::setBlendMode(Graphics::BlendMode mode)
break;
}
// We can only do alpha-multiplication when srcRGB would have been unmodified.
if (srcRGB == GL_ONE && multiplyalpha)
srcRGB = GL_SRC_ALPHA;
glBlendEquation(func);
glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA);
states.back().blendMode = mode;
states.back().blendMultiplyAlpha = multiplyalpha;
}
Graphics::BlendMode Graphics::getBlendMode() const
Graphics::BlendMode Graphics::getBlendMode(bool &multiplyalpha) const
{
multiplyalpha = states.back().blendMultiplyAlpha;
return states.back().blendMode;
}
@@ -1493,6 +1495,7 @@ Graphics::DisplayState::DisplayState()
: color(255, 255, 255, 255)
, backgroundColor(0, 0, 0, 255)
, blendMode(BLEND_ALPHA)
, blendMultiplyAlpha(true)
, lineWidth(1.0f)
, lineStyle(LINE_SMOOTH)
, lineJoin(LINE_JOIN_MITER)
@@ -1515,6 +1518,7 @@ Graphics::DisplayState::DisplayState(const DisplayState &other)
: color(other.color)
, backgroundColor(other.backgroundColor)
, blendMode(other.blendMode)
, blendMultiplyAlpha(other.blendMultiplyAlpha)
, lineWidth(other.lineWidth)
, lineStyle(other.lineStyle)
, lineJoin(other.lineJoin)
@@ -1543,6 +1547,7 @@ Graphics::DisplayState &Graphics::DisplayState::operator = (const DisplayState &
color = other.color;
backgroundColor = other.backgroundColor;
blendMode = other.blendMode;
blendMultiplyAlpha = other.blendMultiplyAlpha;
lineWidth = other.lineWidth;
lineStyle = other.lineStyle;
lineJoin = other.lineJoin;
+3 -2
View File
@@ -232,12 +232,12 @@ public:
/**
* Sets the current blend mode.
**/
void setBlendMode(BlendMode mode);
void setBlendMode(BlendMode mode, bool multiplyalpha);
/**
* Gets the current blend mode.
**/
BlendMode getBlendMode() const;
BlendMode getBlendMode(bool &multiplyalpha) const;
/**
* Sets the default filter for images, canvases, and fonts.
@@ -467,6 +467,7 @@ private:
Color backgroundColor;
BlendMode blendMode;
bool blendMultiplyAlpha;
float lineWidth;
LineStyle lineStyle;
@@ -967,7 +967,9 @@ int w_setBlendMode(lua_State *L)
if (!Graphics::getConstant(str, mode))
return luaL_error(L, "Invalid blend mode: %s", str);
luax_catchexcept(L, [&](){ instance()->setBlendMode(mode); });
bool multiplyalpha = luax_optboolean(L, 2, true);
luax_catchexcept(L, [&](){ instance()->setBlendMode(mode, multiplyalpha); });
return 0;
}
@@ -975,14 +977,16 @@ int w_getBlendMode(lua_State *L)
{
const char *str;
Graphics::BlendMode mode;
bool multiplyalpha = false;
luax_catchexcept(L, [&](){ mode = instance()->getBlendMode(); });
luax_catchexcept(L, [&](){ mode = instance()->getBlendMode(multiplyalpha); });
if (!Graphics::getConstant(mode, str))
return luaL_error(L, "Unknown blend mode");
lua_pushstring(L, str);
return 1;
lua_pushboolean(L, multiplyalpha);
return 2;
}
int w_setDefaultFilter(lua_State *L)