diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index e7d763f9..2d9b469f 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -530,6 +530,10 @@ namespace MobileGL::MG_Backend::DirectGLES { const CullFaceMode& cfm = parameters.CullFaceModeSetting; g_GLESFuncs.glCullFace(MG_Util::ConvertCullFaceModeToGLEnum(cfm)); } + if (parameters.FrontFaceModeSetting != g_syncedRenderStateParameters.FrontFaceModeSetting) { + const FrontFaceMode& ffm = parameters.FrontFaceModeSetting; + g_GLESFuncs.glFrontFace(MG_Util::ConvertFrontFaceModeToGLEnum(ffm)); + } } { // Scissor box diff --git a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp index 6b5c45ce..ebb96907 100644 --- a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp +++ b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp @@ -305,6 +305,9 @@ namespace MobileGL::MG_Impl::GLImpl { case GL_CULL_FACE_MODE: *params = static_cast(MG_Util::ConvertCullFaceModeToGLEnum(MG_State::pGLContext->GetCullFaceMode())); break; + case GL_FRONT_FACE: + *params = static_cast(MG_Util::ConvertFrontFaceModeToGLEnum(MG_State::pGLContext->GetFrontFaceMode())); + break; case GL_CURRENT_PROGRAM: { const auto& currentProgram = MG_State::pGLContext->GetCurrentProgram(); *params = currentProgram ? (GLint)currentProgram->GetExternalIndex() : 0; diff --git a/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp b/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp index aa7c46f3..a96b8bff 100644 --- a/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp +++ b/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp @@ -154,7 +154,18 @@ namespace MobileGL::MG_Impl::GLImpl { } void FrontFace_State(GLenum mode) { - // TODO: implement + FrontFaceMode frontFaceMode = MG_Util::ConvertGLEnumToFrontFaceMode(mode); + if (frontFaceMode == FrontFaceMode::Unknown) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeUnique("MG_Impl/GLImpl", "FrontFace_State", + "Front face mode enum " + + MG_Util::ConvertFrontFaceModeToString(frontFaceMode) + "(" + + MG_Util::ConvertGLEnumToString(mode) + ") is not supported.")); + return; + } + + MG_State::pGLContext->SetFrontFaceMode(frontFaceMode); } void Enable_State(GLenum cap) { diff --git a/MobileGL/MG_State/GLState/Core.cpp b/MobileGL/MG_State/GLState/Core.cpp index 08043405..a6be59e1 100644 --- a/MobileGL/MG_State/GLState/Core.cpp +++ b/MobileGL/MG_State/GLState/Core.cpp @@ -405,6 +405,14 @@ namespace MobileGL::MG_State { return m_renderState.GetCullFaceMode(); } + void GLContext::SetFrontFaceMode(FrontFaceMode mode) { + m_renderState.SetFrontFaceMode(mode); + } + + FrontFaceMode GLContext::GetFrontFaceMode() const { + return m_renderState.GetFrontFaceMode(); + } + void GLContext::SetScissorBox(IntVec4 box) { m_renderState.SetScissorBox(box); } diff --git a/MobileGL/MG_State/GLState/Core.h b/MobileGL/MG_State/GLState/Core.h index 0347dcac..f074d9ee 100644 --- a/MobileGL/MG_State/GLState/Core.h +++ b/MobileGL/MG_State/GLState/Core.h @@ -134,6 +134,8 @@ namespace MobileGL { PixelStoreParameters GetPixelStoreParameters(Bool isUnpack) const; void SetCullFaceMode(CullFaceMode mode); CullFaceMode GetCullFaceMode() const; + void SetFrontFaceMode(FrontFaceMode mode); + FrontFaceMode GetFrontFaceMode() const; void SetScissorBox(IntVec4 box); // x, y, width, height const IntVec4& GetScissorBox() const; // x, y, width, height diff --git a/MobileGL/MG_State/GLState/RenderState/RenderState.cpp b/MobileGL/MG_State/GLState/RenderState/RenderState.cpp index 1089c932..1df25bc8 100644 --- a/MobileGL/MG_State/GLState/RenderState/RenderState.cpp +++ b/MobileGL/MG_State/GLState/RenderState/RenderState.cpp @@ -349,6 +349,17 @@ namespace MobileGL { return m_parameters.CullFaceModeSetting; } + void RenderState::SetFrontFaceMode(FrontFaceMode mode) { + if (m_parameters.FrontFaceModeSetting == mode) return; + + m_parameters.FrontFaceModeSetting = mode; + ++m_version; + } + + FrontFaceMode RenderState::GetFrontFaceMode() const { + return m_parameters.FrontFaceModeSetting; + } + // --------------------- Scissor --------------------- void RenderState::SetScissorBox(IntVec4 box) { if (m_parameters.ScissorBox == box) return; diff --git a/MobileGL/MG_State/GLState/RenderState/RenderState.h b/MobileGL/MG_State/GLState/RenderState/RenderState.h index ff13aecf..c6101112 100644 --- a/MobileGL/MG_State/GLState/RenderState/RenderState.h +++ b/MobileGL/MG_State/GLState/RenderState/RenderState.h @@ -87,6 +87,13 @@ namespace MobileGL { Unknown = -1 }; + enum class FrontFaceMode { + CounterClockwise, + Clockwise, + FrontFaceModeCount, + Unknown = -1 + }; + enum class CapabilityInput { Blend, ClipDistance0, @@ -171,6 +178,7 @@ namespace MobileGL { // Cull Face Bool CullFaceEnabled = false; CullFaceMode CullFaceModeSetting = CullFaceMode::Back; + FrontFaceMode FrontFaceModeSetting = FrontFaceMode::CounterClockwise; // Scissor Bool ScissorTestEnabled = false; @@ -235,6 +243,8 @@ namespace MobileGL { // Cull Face void SetCullFaceMode(CullFaceMode mode); CullFaceMode GetCullFaceMode() const; + void SetFrontFaceMode(FrontFaceMode mode); + FrontFaceMode GetFrontFaceMode() const; // Scissor void SetScissorBox(IntVec4 box); // x, y, width, height diff --git a/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.cpp b/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.cpp index ef3bd98e..46c104ab 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.cpp @@ -137,6 +137,17 @@ namespace MobileGL { } } + FrontFaceMode ConvertGLEnumToFrontFaceMode(GLenum v) { + switch (v) { + case GL_CCW: + return FrontFaceMode::CounterClockwise; + case GL_CW: + return FrontFaceMode::Clockwise; + default: + return FrontFaceMode::Unknown; + } + } + CapabilityInput ConvertGLEnumToCapabilityInput(GLenum v) { switch (v) { case GL_BLEND: diff --git a/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.h b/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.h index 5ea89cd6..21794a22 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.h +++ b/MobileGL/MG_Util/Converters/GLToMG/RenderStateEnumConverter.h @@ -17,6 +17,7 @@ namespace MobileGL { DepthTestFunc ConvertGLEnumToDepthTestFunc(GLenum value); PixelStoreParam ConvertGLEnumToPixelStoreParam(GLenum value); CullFaceMode ConvertGLEnumToCullFaceMode(GLenum value); + FrontFaceMode ConvertGLEnumToFrontFaceMode(GLenum value); CapabilityInput ConvertGLEnumToCapabilityInput(GLenum value); } // namespace MG_Util } // namespace MobileGL diff --git a/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.cpp index 199a3d2c..19fa100f 100644 --- a/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.cpp @@ -138,6 +138,17 @@ namespace MobileGL { } } + GLenum ConvertFrontFaceModeToGLEnum(FrontFaceMode v) { + switch (v) { + case FrontFaceMode::CounterClockwise: + return GL_CCW; + case FrontFaceMode::Clockwise: + return GL_CW; + default: + return GL_UNKNOWN_MGL; + } + } + GLenum ConvertCapabilityInputToGLEnum(CapabilityInput v) { switch (v) { case CapabilityInput::Blend: diff --git a/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.h b/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.h index 16725373..a857d438 100644 --- a/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.h +++ b/MobileGL/MG_Util/Converters/MGToGL/RenderStateEnumConverter.h @@ -17,6 +17,7 @@ namespace MobileGL { GLenum ConvertDepthTestFuncToGLEnum(DepthTestFunc value); GLenum ConvertPixelStoreParamToGLEnum(PixelStoreParam value); GLenum ConvertCullFaceModeToGLEnum(CullFaceMode value); + GLenum ConvertFrontFaceModeToGLEnum(FrontFaceMode value); GLenum ConvertCapabilityInputToGLEnum(CapabilityInput value); } // namespace MG_Util } // namespace MobileGL diff --git a/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.cpp index f985aa8f..d2b3c3e4 100644 --- a/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.cpp @@ -120,6 +120,17 @@ namespace MobileGL { } } + String ConvertFrontFaceModeToString(FrontFaceMode v) { + switch (v) { + case FrontFaceMode::CounterClockwise: + return "CounterClockwise"; + case FrontFaceMode::Clockwise: + return "Clockwise"; + default: + return "Unknown"; + } + } + String ConvertCapabilityInputToString(CapabilityInput v) { switch (v) { case CapabilityInput::Blend: @@ -197,4 +208,4 @@ namespace MobileGL { } } } // namespace MG_Util -} // namespace MobileGL \ No newline at end of file +} // namespace MobileGL diff --git a/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.h b/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.h index 7d57d0dd..1831d86b 100644 --- a/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.h +++ b/MobileGL/MG_Util/Converters/MGToStr/RenderStateEnumConverter.h @@ -16,6 +16,7 @@ namespace MobileGL { String ConvertDepthTestFuncToString(DepthTestFunc value); String ConvertPixelStoreParamToString(PixelStoreParam value); String ConvertCullFaceModeToString(CullFaceMode value); + String ConvertFrontFaceModeToString(FrontFaceMode value); String ConvertCapabilityInputToString(CapabilityInput value); } // namespace MG_Util -} // namespace MobileGL \ No newline at end of file +} // namespace MobileGL