diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 808262e27..eeaeeff88 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -700,7 +700,7 @@ void Graphics::restoreState(const DisplayState &s) setShader(s.shader.get()); setRenderTargets(s.renderTargets); - setStencilState(s.stencil.action, s.stencil.compare, s.stencil.value, s.stencil.readMask, s.stencil.writeMask); + setStencilState(s.stencil); setDepthMode(s.depthTest, s.depthWrite); setColorMask(s.colorMask); @@ -776,7 +776,7 @@ void Graphics::restoreStateChecked(const DisplayState &s) setRenderTargets(s.renderTargets); if (!(s.stencil == cur.stencil)) - setStencilState(s.stencil.action, s.stencil.compare, s.stencil.value, s.stencil.readMask, s.stencil.writeMask); + setStencilState(s.stencil); if (s.depthTest != cur.depthTest || s.depthWrite != cur.depthWrite) setDepthMode(s.depthTest, s.depthWrite); @@ -1311,8 +1311,7 @@ bool Graphics::getScissor(Rect &rect) const void Graphics::setStencilMode(StencilMode mode, int value) { - StencilState s = computeStencilState(mode, value); - setStencilState(s.action, s.compare, s.value, s.readMask, s.writeMask); + setStencilState(computeStencilState(mode, value)); if (mode == STENCIL_MODE_DRAW) setColorMask({ false, false, false, false }); else @@ -1321,8 +1320,7 @@ void Graphics::setStencilMode(StencilMode mode, int value) void Graphics::setStencilMode() { - StencilState s = computeStencilState(STENCIL_MODE_OFF, 0); - setStencilState(s.action, s.compare, s.value, s.readMask, s.writeMask); + setStencilState(computeStencilState(STENCIL_MODE_OFF, 0)); setColorMask({ true, true, true, true }); } @@ -1336,17 +1334,14 @@ StencilMode Graphics::getStencilMode(int &value) const void Graphics::setStencilState() { - setStencilState(STENCIL_KEEP, COMPARE_ALWAYS, 0, LOVE_UINT32_MAX, LOVE_UINT32_MAX); + StencilState s; + setStencilState(s); } -void Graphics::getStencilState(StencilAction &action, CompareMode &compare, int &value, uint32 &readmask, uint32 &writemask) const +const StencilState &Graphics::getStencilState() const { const DisplayState &state = states.back(); - action = state.stencil.action; - compare = state.stencil.compare; - value = state.stencil.value; - readmask = state.stencil.readMask; - writemask = state.stencil.writeMask; + return state.stencil; } void Graphics::setDepthMode() diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 61800a72f..38dec2568 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -617,9 +617,9 @@ class Graphics : public Module void setStencilMode(); StencilMode getStencilMode(int &value) const; - virtual void setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) = 0; + virtual void setStencilState(const StencilState &state) = 0; void setStencilState(); - void getStencilState(StencilAction &action, CompareMode &compare, int &value, uint32 &readmask, uint32 &writemask) const; + const StencilState &getStencilState() const; virtual void setDepthMode(CompareMode compare, bool write) = 0; void setDepthMode(); diff --git a/src/modules/graphics/metal/Graphics.h b/src/modules/graphics/metal/Graphics.h index 936be0792..1d910eb5e 100644 --- a/src/modules/graphics/metal/Graphics.h +++ b/src/modules/graphics/metal/Graphics.h @@ -96,7 +96,7 @@ class Graphics final : public love::graphics::Graphics void setScissor(const Rect &rect) override; void setScissor() override; - void setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) override; + void setStencilState(const StencilState &s) override; void setDepthMode(CompareMode compare, bool write) override; diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index daffad45e..2cf4e91f4 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -1760,11 +1760,11 @@ static inline void advanceVertexOffsets(const VertexAttributes &attributes, Buff } } -void Graphics::setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) +void Graphics::setStencilState(const StencilState &s) { DisplayState &state = states.back(); - if (action != STENCIL_KEEP) + if (s.action != STENCIL_KEEP) { const auto &rts = state.renderTargets; love::graphics::Texture *dstexture = rts.depthStencil.texture.get(); @@ -1777,11 +1777,7 @@ static inline void advanceVertexOffsets(const VertexAttributes &attributes, Buff flushBatchedDraws(); - state.stencil.action = action; - state.stencil.compare = compare; - state.stencil.value = value; - state.stencil.readMask = readmask; - state.stencil.writeMask = writemask; + state.stencil = s; dirtyRenderState |= STATEBIT_STENCIL; } diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 728918aa6..b56ed1cee 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -1434,11 +1434,11 @@ void Graphics::setScissor() gl.setEnableState(OpenGL::ENABLE_SCISSOR_TEST, false); } -void Graphics::setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) +void Graphics::setStencilState(const StencilState &s) { DisplayState &state = states.back(); - if (action != STENCIL_KEEP) + if (s.action != STENCIL_KEEP) { const auto &rts = state.renderTargets; love::graphics::Texture *dstexture = rts.depthStencil.texture.get(); @@ -1451,13 +1451,13 @@ void Graphics::setStencilState(StencilAction action, CompareMode compare, int va flushBatchedDraws(); - bool enablestencil = action != STENCIL_KEEP || compare != COMPARE_ALWAYS; + bool enablestencil = s.action != STENCIL_KEEP || s.compare != COMPARE_ALWAYS; if (enablestencil != gl.isStateEnabled(OpenGL::ENABLE_STENCIL_TEST)) gl.setEnableState(OpenGL::ENABLE_STENCIL_TEST, enablestencil); GLenum glaction = GL_KEEP; - switch (action) + switch (s.action) { case STENCIL_KEEP: glaction = GL_KEEP; @@ -1496,22 +1496,18 @@ void Graphics::setStencilState(StencilAction action, CompareMode compare, int va * setStencilState(STENCIL_KEEP, COMPARE_GREATER, 4) will make it pass if the * stencil buffer has a value greater than 4. **/ - GLenum glcompare = OpenGL::getGLCompareMode(getReversedCompareMode(compare)); + GLenum glcompare = OpenGL::getGLCompareMode(getReversedCompareMode(s.compare)); if (enablestencil) { - glStencilFunc(glcompare, value, readmask); + glStencilFunc(glcompare, s.value, s.readMask); glStencilOp(GL_KEEP, GL_KEEP, glaction); } - if (writemask != gl.getStencilWriteMask()) - gl.setStencilWriteMask(writemask); + if (s.writeMask != gl.getStencilWriteMask()) + gl.setStencilWriteMask(s.writeMask); - state.stencil.action = action; - state.stencil.compare = compare; - state.stencil.value = value; - state.stencil.readMask = readmask; - state.stencil.writeMask = writemask; + state.stencil = s; } void Graphics::setDepthMode(CompareMode compare, bool write) diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index ee8a940cb..894b52e21 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -92,7 +92,7 @@ class Graphics final : public love::graphics::Graphics void setScissor(const Rect &rect) override; void setScissor() override; - void setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) override; + void setStencilState(const StencilState &s) override; void setDepthMode(CompareMode compare, bool write) override; diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index ff4b9aef2..399e9b4e8 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -1001,9 +1001,9 @@ void Graphics::setScissor() vkCmdSetScissor(commandBuffers.at(currentFrame), 0, 1, &scissor); } -void Graphics::setStencilState(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) +void Graphics::setStencilState(const StencilState &s) { - if (action != STENCIL_KEEP) + if (s.action != STENCIL_KEEP) { const auto& rts = states.back().renderTargets; auto dsTexture = rts.depthStencil.texture.get(); @@ -1016,23 +1016,19 @@ void Graphics::setStencilState(StencilAction action, CompareMode compare, int va flushBatchedDraws(); - vkCmdSetStencilWriteMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, writemask); + vkCmdSetStencilWriteMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, s.writeMask); - vkCmdSetStencilCompareMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, readmask); - vkCmdSetStencilReference(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, value); + vkCmdSetStencilCompareMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, s.readMask); + vkCmdSetStencilReference(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, s.value); if (optionalDeviceExtensions.extendedDynamicState) vkCmdSetStencilOpEXT( commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, - VK_STENCIL_OP_KEEP, Vulkan::getStencilOp(action), - VK_STENCIL_OP_KEEP, Vulkan::getCompareOp(getReversedCompareMode(compare))); - - states.back().stencil.action = action; - states.back().stencil.compare = compare; - states.back().stencil.value = value; - states.back().stencil.readMask = readmask; - states.back().stencil.writeMask = writemask; + VK_STENCIL_OP_KEEP, Vulkan::getStencilOp(s.action), + VK_STENCIL_OP_KEEP, Vulkan::getCompareOp(getReversedCompareMode(s.compare))); + + states.back().stencil = s; } void Graphics::setDepthMode(CompareMode compare, bool write) diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index 89d1ba8b0..a7c9f9ffd 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -293,7 +293,7 @@ class Graphics final : public love::graphics::Graphics void setColor(Colorf c) override; void setScissor(const Rect &rect) override; void setScissor() override; - void setStencilState(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) override; + void setStencilState(const StencilState &s) override; void setDepthMode(CompareMode compare, bool write) override; void setFrontFaceWinding(Winding winding) override; void setColorMask(ColorChannelMask mask) override; diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index 3f5558ab4..6ff392c71 100644 --- a/src/modules/graphics/wrap_Graphics.cpp +++ b/src/modules/graphics/wrap_Graphics.cpp @@ -645,48 +645,41 @@ int w_setStencilState(lua_State *L) return 0; } - StencilAction action = STENCIL_KEEP; + StencilState s; + const char *actionstr = luaL_checkstring(L, 1); - if (!getConstant(actionstr, action)) - return luax_enumerror(L, "stencil draw action", getConstants(action), actionstr); + if (!getConstant(actionstr, s.action)) + return luax_enumerror(L, "stencil draw action", getConstants(s.action), actionstr); - CompareMode compare = COMPARE_ALWAYS; const char *comparestr = luaL_checkstring(L, 2); - if (!getConstant(comparestr, compare)) - return luax_enumerror(L, "compare mode", getConstants(compare), comparestr); - - int value = (int) luaL_optinteger(L, 3, 0); + if (!getConstant(comparestr, s.compare)) + return luax_enumerror(L, "compare mode", getConstants(s.compare), comparestr); - uint32 readmask = (uint32) luaL_optnumber(L, 4, LOVE_UINT32_MAX); - uint32 writemask = (uint32) luaL_optnumber(L, 5, LOVE_UINT32_MAX); + s.value = (int) luaL_optinteger(L, 3, 0); + s.readMask = (uint32) luaL_optnumber(L, 4, LOVE_UINT32_MAX); + s.writeMask = (uint32) luaL_optnumber(L, 5, LOVE_UINT32_MAX); - luax_catchexcept(L, [&](){ instance()->setStencilState(action, compare, value, readmask, writemask); }); + luax_catchexcept(L, [&](){ instance()->setStencilState(s); }); return 0; } int w_getStencilState(lua_State *L) { - StencilAction action = STENCIL_KEEP; - CompareMode compare = COMPARE_ALWAYS; - int value = 1; - uint32 readmask = LOVE_UINT32_MAX; - uint32 writemask = LOVE_UINT32_MAX; - - instance()->getStencilState(action, compare, value, readmask, writemask); + const StencilState &s = instance()->getStencilState(); const char *actionstr; - if (!getConstant(action, actionstr)) + if (!getConstant(s.action, actionstr)) return luaL_error(L, "Unknown stencil draw action."); const char *comparestr; - if (!getConstant(compare, comparestr)) + if (!getConstant(s.compare, comparestr)) return luaL_error(L, "Unknown compare mode."); lua_pushstring(L, actionstr); lua_pushstring(L, comparestr); - lua_pushinteger(L, value); - lua_pushnumber(L, readmask); - lua_pushnumber(L, writemask); + lua_pushinteger(L, s.value); + lua_pushnumber(L, s.readMask); + lua_pushnumber(L, s.writeMask); return 5; }