diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index f8ffd5e5b..6c23bd3c4 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -82,6 +82,16 @@ bool Graphics::getConstant(BlendMode in, const char *&out) return blendModes.find(in, out); } +bool Graphics::getConstant(const char *in, BlendAlpha &out) +{ + return blendAlphaModes.find(in, out); +} + +bool Graphics::getConstant(BlendAlpha in, const char *&out) +{ + return blendAlphaModes.find(in, out); +} + bool Graphics::getConstant(const char *in, LineStyle &out) { return lineStyles.find(in, out); @@ -172,16 +182,24 @@ StringMap Graphics::drawModes(Graph StringMap::Entry Graphics::blendModeEntries[] = { - { "alpha", BLEND_ALPHA }, - { "add", BLEND_ADD }, + { "alpha", BLEND_ALPHA }, + { "add", BLEND_ADD }, { "subtract", BLEND_SUBTRACT }, { "multiply", BLEND_MULTIPLY }, - { "screen", BLEND_SCREEN }, - { "replace", BLEND_REPLACE }, + { "screen", BLEND_SCREEN }, + { "replace", BLEND_REPLACE }, }; StringMap Graphics::blendModes(Graphics::blendModeEntries, sizeof(Graphics::blendModeEntries)); +StringMap::Entry Graphics::blendAlphaEntries[] = +{ + { "alphamultiply", BLENDALPHA_MULTIPLY }, + { "premultiplied", BLENDALPHA_PREMULTIPLIED }, +}; + +StringMap Graphics::blendAlphaModes(Graphics::blendAlphaEntries, sizeof(Graphics::blendAlphaEntries)); + StringMap::Entry Graphics::lineStyleEntries[] = { { "smooth", LINE_SMOOTH }, diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index d1d0b6b36..583822c5f 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -81,6 +81,13 @@ public: BLEND_MAX_ENUM }; + enum BlendAlpha + { + BLENDALPHA_MULTIPLY, + BLENDALPHA_PREMULTIPLIED, + BLENDALPHA_MAX_ENUM + }; + enum LineStyle { LINE_ROUGH, @@ -255,6 +262,9 @@ public: static bool getConstant(const char *in, BlendMode &out); static bool getConstant(BlendMode in, const char *&out); + static bool getConstant(const char *in, BlendAlpha &out); + static bool getConstant(BlendAlpha in, const char *&out); + static bool getConstant(const char *in, LineStyle &out); static bool getConstant(LineStyle in, const char *&out); @@ -287,6 +297,9 @@ private: static StringMap::Entry blendModeEntries[]; static StringMap blendModes; + static StringMap::Entry blendAlphaEntries[]; + static StringMap blendAlphaModes; + static StringMap::Entry lineStyleEntries[]; static StringMap lineStyles; diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 1aee88a4c..8339b0457 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -106,7 +106,7 @@ void Graphics::restoreState(const DisplayState &s) setColor(s.color); setBackgroundColor(s.backgroundColor); - setBlendMode(s.blendMode, s.blendMultiplyAlpha); + setBlendMode(s.blendMode, s.blendAlphaMode); setLineWidth(s.lineWidth); setLineStyle(s.lineStyle); @@ -141,8 +141,8 @@ void Graphics::restoreStateChecked(const DisplayState &s) setBackgroundColor(s.backgroundColor); - if (s.blendMode != cur.blendMode || s.blendMultiplyAlpha != cur.blendMultiplyAlpha) - setBlendMode(s.blendMode, s.blendMultiplyAlpha); + if (s.blendMode != cur.blendMode || s.blendAlphaMode != cur.blendAlphaMode) + setBlendMode(s.blendMode, s.blendAlphaMode); // These are just simple assignments. setLineWidth(s.lineWidth); @@ -1057,7 +1057,7 @@ Graphics::ColorMask Graphics::getColorMask() const return states.back().colorMask; } -void Graphics::setBlendMode(BlendMode mode, bool multiplyalpha) +void Graphics::setBlendMode(BlendMode mode, BlendAlpha alphamode) { GLenum func = GL_FUNC_ADD; GLenum srcRGB = GL_ONE; @@ -1094,19 +1094,19 @@ void Graphics::setBlendMode(BlendMode mode, bool multiplyalpha) } // We can only do alpha-multiplication when srcRGB would have been unmodified. - if (srcRGB == GL_ONE && multiplyalpha) + if (srcRGB == GL_ONE && alphamode == BLENDALPHA_MULTIPLY) srcRGB = GL_SRC_ALPHA; glBlendEquation(func); glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA); states.back().blendMode = mode; - states.back().blendMultiplyAlpha = multiplyalpha; + states.back().blendAlphaMode = alphamode; } -Graphics::BlendMode Graphics::getBlendMode(bool &multiplyalpha) const +Graphics::BlendMode Graphics::getBlendMode(BlendAlpha &alphamode) const { - multiplyalpha = states.back().blendMultiplyAlpha; + alphamode = states.back().blendAlphaMode; return states.back().blendMode; } diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index a984f971c..3fab27735 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -243,12 +243,12 @@ public: /** * Sets the current blend mode. **/ - void setBlendMode(BlendMode mode, bool multiplyalpha); + void setBlendMode(BlendMode mode, BlendAlpha alphamode); /** * Gets the current blend mode. **/ - BlendMode getBlendMode(bool &multiplyalpha) const; + BlendMode getBlendMode(BlendAlpha &alphamode) const; /** * Sets the default filter for images, canvases, and fonts. @@ -478,7 +478,7 @@ private: Colorf backgroundColor = Colorf(0.0, 0.0, 0.0, 255.0); BlendMode blendMode = BLEND_ALPHA; - bool blendMultiplyAlpha = true; + BlendAlpha blendAlphaMode = BLENDALPHA_MULTIPLY; float lineWidth = 1.0f; LineStyle lineStyle = LINE_SMOOTH; diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 5c8914e2e..b3a888d19 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -1042,25 +1042,34 @@ int w_setBlendMode(lua_State *L) if (!Graphics::getConstant(str, mode)) return luaL_error(L, "Invalid blend mode: %s", str); - bool multiplyalpha = luax_optboolean(L, 2, true); + Graphics::BlendAlpha alphamode = Graphics::BLENDALPHA_MULTIPLY; + if (!lua_isnoneornil(L, 2)) + { + const char *alphastr = luaL_checkstring(L, 2); + if (!Graphics::getConstant(alphastr, alphamode)) + return luaL_error(L, "Invalid blend alpha mode: %s", alphastr); + } - luax_catchexcept(L, [&](){ instance()->setBlendMode(mode, multiplyalpha); }); + luax_catchexcept(L, [&](){ instance()->setBlendMode(mode, alphamode); }); return 0; } int w_getBlendMode(lua_State *L) { const char *str; - Graphics::BlendMode mode; - bool multiplyalpha = false; + const char *alphastr; - luax_catchexcept(L, [&](){ mode = instance()->getBlendMode(multiplyalpha); }); + Graphics::BlendAlpha alphamode; + Graphics::BlendMode mode = instance()->getBlendMode(alphamode); if (!Graphics::getConstant(mode, str)) return luaL_error(L, "Unknown blend mode"); + if (!Graphics::getConstant(alphamode, alphastr)) + return luaL_error(L, "Unknown blend alpha mode"); + lua_pushstring(L, str); - lua_pushboolean(L, multiplyalpha); + lua_pushstring(L, alphastr); return 2; }