diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 0b9229e36..0b96bb05e 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -229,15 +229,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) { #ifndef USING_GLES2 if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) { - // TODO: Make this dynamic - // Logic Ops - if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY) { - // TODO: Fix logic ops. - //glstate.colorLogicOp.enable(); - //glstate.logicOp.set(logicOps[gstate.getLogicOp()]); - } else { - //glstate.colorLogicOp.disable(); - } + renderManager->SetLogicOp(gstate.isLogicOpEnabled(), logicOps[gstate.getLogicOp()]); } #endif } diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index 1fcd63fda..bec22244a 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -405,6 +405,9 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { glDisable(GL_CULL_FACE); glDisable(GL_DITHER); glEnable(GL_SCISSOR_TEST); +#ifndef USING_GLES2 + glDisable(GL_COLOR_LOGIC_OP); +#endif /* #ifndef USING_GLES2 @@ -430,12 +433,14 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { int colorMask = -1; int depthMask = -1; int depthFunc = -1; + int logicOp = -1; GLuint curArrayBuffer = (GLuint)-1; GLuint curElemArrayBuffer = (GLuint)-1; bool depthEnabled = false; bool blendEnabled = false; bool cullEnabled = false; bool ditherEnabled = false; + bool logicEnabled = false; GLuint blendEqColor = (GLuint)-1; GLuint blendEqAlpha = (GLuint)-1; @@ -496,6 +501,22 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { colorMask = c.blend.mask; } break; + case GLRRenderCommand::LOGICOP: +#ifndef USING_GLES2 + if (c.logic.enabled) { + if (!logicEnabled) { + glEnable(GL_COLOR_LOGIC_OP); + logicEnabled = true; + } + if (logicOp != c.logic.logicOp) { + glLogicOp(c.logic.logicOp); + } + } else if (!c.logic.enabled && logicEnabled) { + glDisable(GL_COLOR_LOGIC_OP); + logicEnabled = false; + } +#endif + break; case GLRRenderCommand::CLEAR: glDisable(GL_SCISSOR_TEST); if (c.clear.colorMask != colorMask) { @@ -814,6 +835,9 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); glDisable(GL_CULL_FACE); +#ifndef USING_GLES2 + glDisable(GL_COLOR_LOGIC_OP); +#endif glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } diff --git a/ext/native/thin3d/GLQueueRunner.h b/ext/native/thin3d/GLQueueRunner.h index 22dfbaef8..a4175405f 100644 --- a/ext/native/thin3d/GLQueueRunner.h +++ b/ext/native/thin3d/GLQueueRunner.h @@ -32,6 +32,7 @@ enum class GLRRenderCommand : uint8_t { STENCILOP, BLEND, BLENDCOLOR, + LOGICOP, UNIFORM4I, UNIFORM4F, UNIFORMMATRIX, @@ -55,6 +56,7 @@ enum class GLRRenderCommand : uint8_t { // TODO: Bloated since the biggest struct decides the size. Will need something more efficient (separate structs with shared // type field, smashed right after each other?) +// Also, all GLenums are really only 16 bits. struct GLRRenderData { GLRRenderCommand cmd; union { @@ -71,6 +73,10 @@ struct GLRRenderData { struct { float color[4]; } blendColor; + struct { + GLboolean enabled; + GLenum logicOp; + } logic; struct { GLboolean enabled; GLboolean write; diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index c5d728505..345b8ad6f 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -505,6 +505,16 @@ public: curRenderStep_->commands.push_back(data); } +#ifndef USING_GLES2 + void SetLogicOp(bool enabled, GLenum logicOp) { + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + GLRRenderData data{ GLRRenderCommand::LOGICOP }; + data.logic.enabled = enabled; + data.logic.logicOp = logicOp; + curRenderStep_->commands.push_back(data); + } +#endif + void SetStencilFunc(bool enabled, GLenum func, uint8_t refValue, uint8_t compareMask) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::STENCILFUNC };