diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index 29138447..1be64a6f 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -1,5 +1,4 @@ #include "DirectGLES.h" -#include "MG_Util/ShaderTranspiler/Types.h" #include "Utils.h" #include "Managers.h" #include @@ -150,25 +149,22 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_External::GLES::glViewport( MG_State::pGLContext->GetViewport().x(), MG_State::pGLContext->GetViewport().y(), MG_State::pGLContext->GetViewport().z(), MG_State::pGLContext->GetViewport().w()); - if (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::DepthTest)) { - MG_External::GLES::glEnable(GL_DEPTH_TEST); - } else { - MG_External::GLES::glDisable(GL_DEPTH_TEST); - } - if (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::Blend)) { - MG_External::GLES::glEnable(GL_BLEND); - } else { - MG_External::GLES::glDisable(GL_BLEND); - } - if (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::CullFace)) { - MG_External::GLES::glEnable(GL_CULL_FACE); - } else { - MG_External::GLES::glDisable(GL_CULL_FACE); - } +#define SYNC_CAPABILITY(cap_mg, cap_gl) \ + if (MG_State::pGLContext->IsCapabilityEnabled(cap_mg)) { \ + MG_External::GLES::glEnable(cap_gl); \ + } else { \ + MG_External::GLES::glDisable(cap_gl); \ + } + SYNC_CAPABILITY(CapabilityInput::Blend, GL_BLEND); + SYNC_CAPABILITY(CapabilityInput::DepthTest, GL_DEPTH_TEST); + SYNC_CAPABILITY(CapabilityInput::ScissorTest, GL_SCISSOR_TEST); + SYNC_CAPABILITY(CapabilityInput::CullFace, GL_CULL_FACE); + +#undef SYNC_CAPABILITY const auto& ToGLBoolean = [](Bool b) -> GLboolean { return b ? GL_TRUE : GL_FALSE; }; - { + { // Blend func BlendFactor srcRGB, dstRGB, srcAlpha, dstAlpha; MG_State::pGLContext->GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); @@ -177,26 +173,26 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Util::ConvertBlendFactorToGLEnum(srcAlpha), MG_Util::ConvertBlendFactorToGLEnum(dstAlpha)); } - { + { // Blend equation DepthTestFunc df = MG_State::pGLContext->GetDepthFunc(); MG_External::GLES::glDepthFunc(MG_Util::ConvertDepthTestFuncToGLEnum(df)); MG_External::GLES::glDepthMask(MG_State::pGLContext->GetDepthMask() ? GL_TRUE : GL_FALSE); } - { + { // Color mask BoolVec4 colorMask = MG_State::pGLContext->GetColorMask(); MG_External::GLES::glColorMask(ToGLBoolean(colorMask.x()), ToGLBoolean(colorMask.y()), ToGLBoolean(colorMask.z()), ToGLBoolean(colorMask.w())); } - { + { // Clear values const FloatVec4& clearCol = MG_State::pGLContext->GetClearColor(); MG_External::GLES::glClearColor(clearCol.x(), clearCol.y(), clearCol.z(), clearCol.w()); MG_External::GLES::glClearDepthf(MG_State::pGLContext->GetClearDepth()); } - { + { // Pixel store params { PixelStoreParam p = PixelStoreParam::UnpackAlignment; GLint v = MG_State::pGLContext->GetPixelStoreParam(p); @@ -209,16 +205,15 @@ namespace MobileGL::MG_Backend::DirectGLES { } } - if (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::CullFace)) { - MG_External::GLES::glEnable(GL_CULL_FACE); - } else { - MG_External::GLES::glDisable(GL_CULL_FACE); - } - - { + { // Cull face mode CullFaceMode cfm = MG_State::pGLContext->GetCullFaceMode(); MG_External::GLES::glCullFace(MG_Util::ConvertCullFaceModeToGLEnum(cfm)); } + + { // Scissor box + const IntVec4& scissorBox = MG_State::pGLContext->GetScissorBox(); + MG_External::GLES::glScissor(scissorBox.x(), scissorBox.y(), scissorBox.z(), scissorBox.w()); + } } } // namespace RenderStateImpl diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index 51d256bc..72a5a796 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -285,7 +285,6 @@ namespace MobileGL::MG_Backend::DirectGLES { } { // Update sampler parameters; TODO: always use sampler objects in backend - const auto& samplerObject = stateTextureObject->GetSamplerObject(); if (samplerObject) { MG_External::GLES::glTexParameteri( diff --git a/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp b/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp index 2bdca0ec..a6332553 100644 --- a/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp +++ b/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp @@ -44,7 +44,14 @@ namespace MobileGL { } void Scissor_State(GLint x, GLint y, GLsizei width, GLsizei height) { - // TODO: implement + if (width < 0 || height < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, MakeShared("MG_Impl/GLImpl", "Scissor_State", + "Width abd height must be non-negative.")); + return; + } + + MG_State::pGLContext->SetScissorBox(IntVec4(x, y, width, height)); } void SampleCoverage_State(GLfloat value, GLboolean invert) { diff --git a/MobileGL/MG_State/GLState/Core.cpp b/MobileGL/MG_State/GLState/Core.cpp index ac04c5ac..68f3827b 100644 --- a/MobileGL/MG_State/GLState/Core.cpp +++ b/MobileGL/MG_State/GLState/Core.cpp @@ -293,6 +293,14 @@ namespace MobileGL { return m_renderState.GetCullFaceMode(); } + void GLContext::SetScissorBox(IntVec4 box) { + m_renderState.SetScissorBox(box); + } + + const IntVec4& GLContext::GetScissorBox() const { + return m_renderState.GetScissorBox(); + } + // Framebuffer Vector GLContext::GenFramebufferNames(Uint number) { return m_framebufferState.GenerateNames(number); diff --git a/MobileGL/MG_State/GLState/Core.h b/MobileGL/MG_State/GLState/Core.h index 3facafea..1f175c5f 100644 --- a/MobileGL/MG_State/GLState/Core.h +++ b/MobileGL/MG_State/GLState/Core.h @@ -92,6 +92,8 @@ namespace MobileGL { Int GetPixelStoreParam(PixelStoreParam param) const; void SetCullFaceMode(CullFaceMode mode); CullFaceMode GetCullFaceMode() const; + void SetScissorBox(IntVec4 box); // x, y, width, height + const IntVec4& GetScissorBox() const; // x, y, width, height // Framebuffer Vector GenFramebufferNames(Uint number); diff --git a/MobileGL/MG_State/GLState/RenderState/RenderState.cpp b/MobileGL/MG_State/GLState/RenderState/RenderState.cpp index 03e4acf4..cfbb6477 100644 --- a/MobileGL/MG_State/GLState/RenderState/RenderState.cpp +++ b/MobileGL/MG_State/GLState/RenderState/RenderState.cpp @@ -39,6 +39,9 @@ namespace MobileGL { case CapabilityInput::CullFace: m_cullFaceEnabled = enabled; break; + case CapabilityInput::ScissorTest: + m_scissorTestEnabled = enabled; + break; default: // not supported currently break; } @@ -52,6 +55,8 @@ namespace MobileGL { return m_depthTestEnabled; case CapabilityInput::CullFace: return m_cullFaceEnabled; + case CapabilityInput::ScissorTest: + return m_scissorTestEnabled; default: return false; } @@ -134,6 +139,15 @@ namespace MobileGL { CullFaceMode RenderState::GetCullFaceMode() const { return m_cullFaceMode; } + + // --------------------- Scissor --------------------- + void RenderState::SetScissorBox(IntVec4 box) { + m_scissorBox = box; + } + + const IntVec4& RenderState::GetScissorBox() const { + return m_scissorBox; + } } // namespace GLState } // namespace MG_State } // namespace MobileGL diff --git a/MobileGL/MG_State/GLState/RenderState/RenderState.h b/MobileGL/MG_State/GLState/RenderState/RenderState.h index dd62c60a..7d6ae130 100644 --- a/MobileGL/MG_State/GLState/RenderState/RenderState.h +++ b/MobileGL/MG_State/GLState/RenderState/RenderState.h @@ -1,5 +1,6 @@ #pragma once #include "MG_Util/Math/VectorTypes.h" +#include "MG_Util/Types.h" #include namespace MobileGL { @@ -151,6 +152,10 @@ namespace MobileGL { void SetCullFaceMode(CullFaceMode mode); CullFaceMode GetCullFaceMode() const; + // Scissor + void SetScissorBox(IntVec4 box); // x, y, width, height + const IntVec4& GetScissorBox() const; // x, y, width, height + private: // Rasterization IntVec4 m_viewport = IntVec4(0, 0, 0, 0); // x, y, width, height @@ -180,6 +185,10 @@ namespace MobileGL { // Cull Face Bool m_cullFaceEnabled = false; CullFaceMode m_cullFaceMode = CullFaceMode::Back; + + // Scissor + Bool m_scissorTestEnabled = false; + IntVec4 m_scissorBox = IntVec4(0, 0, 0, 0); // x, y, width, height }; } // namespace GLState } // namespace MG_State