[Feat] (...): Implement scissor box in frontend and backend.

This commit is contained in:
BZLZHH
2025-11-01 16:40:38 +08:00
parent 708db4b5eb
commit bcb947235d
7 changed files with 64 additions and 30 deletions
+23 -28
View File
@@ -1,5 +1,4 @@
#include "DirectGLES.h" #include "DirectGLES.h"
#include "MG_Util/ShaderTranspiler/Types.h"
#include "Utils.h" #include "Utils.h"
#include "Managers.h" #include "Managers.h"
#include <MG_State/GLState/Core.h> #include <MG_State/GLState/Core.h>
@@ -150,25 +149,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_External::GLES::glViewport( MG_External::GLES::glViewport(
MG_State::pGLContext->GetViewport().x(), MG_State::pGLContext->GetViewport().y(), MG_State::pGLContext->GetViewport().x(), MG_State::pGLContext->GetViewport().y(),
MG_State::pGLContext->GetViewport().z(), MG_State::pGLContext->GetViewport().w()); MG_State::pGLContext->GetViewport().z(), MG_State::pGLContext->GetViewport().w());
if (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::DepthTest)) { #define SYNC_CAPABILITY(cap_mg, cap_gl) \
MG_External::GLES::glEnable(GL_DEPTH_TEST); if (MG_State::pGLContext->IsCapabilityEnabled(cap_mg)) { \
} else { MG_External::GLES::glEnable(cap_gl); \
MG_External::GLES::glDisable(GL_DEPTH_TEST); } else { \
} MG_External::GLES::glDisable(cap_gl); \
if (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::Blend)) { }
MG_External::GLES::glEnable(GL_BLEND); SYNC_CAPABILITY(CapabilityInput::Blend, GL_BLEND);
} else { SYNC_CAPABILITY(CapabilityInput::DepthTest, GL_DEPTH_TEST);
MG_External::GLES::glDisable(GL_BLEND); SYNC_CAPABILITY(CapabilityInput::ScissorTest, GL_SCISSOR_TEST);
} SYNC_CAPABILITY(CapabilityInput::CullFace, GL_CULL_FACE);
if (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::CullFace)) {
MG_External::GLES::glEnable(GL_CULL_FACE); #undef SYNC_CAPABILITY
} else {
MG_External::GLES::glDisable(GL_CULL_FACE);
}
const auto& ToGLBoolean = [](Bool b) -> GLboolean { return b ? GL_TRUE : GL_FALSE; }; const auto& ToGLBoolean = [](Bool b) -> GLboolean { return b ? GL_TRUE : GL_FALSE; };
{ { // Blend func
BlendFactor srcRGB, dstRGB, srcAlpha, dstAlpha; BlendFactor srcRGB, dstRGB, srcAlpha, dstAlpha;
MG_State::pGLContext->GetBlendFunc(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)); MG_Util::ConvertBlendFactorToGLEnum(srcAlpha), MG_Util::ConvertBlendFactorToGLEnum(dstAlpha));
} }
{ { // Blend equation
DepthTestFunc df = MG_State::pGLContext->GetDepthFunc(); DepthTestFunc df = MG_State::pGLContext->GetDepthFunc();
MG_External::GLES::glDepthFunc(MG_Util::ConvertDepthTestFuncToGLEnum(df)); MG_External::GLES::glDepthFunc(MG_Util::ConvertDepthTestFuncToGLEnum(df));
MG_External::GLES::glDepthMask(MG_State::pGLContext->GetDepthMask() ? GL_TRUE : GL_FALSE); MG_External::GLES::glDepthMask(MG_State::pGLContext->GetDepthMask() ? GL_TRUE : GL_FALSE);
} }
{ { // Color mask
BoolVec4 colorMask = MG_State::pGLContext->GetColorMask(); BoolVec4 colorMask = MG_State::pGLContext->GetColorMask();
MG_External::GLES::glColorMask(ToGLBoolean(colorMask.x()), ToGLBoolean(colorMask.y()), MG_External::GLES::glColorMask(ToGLBoolean(colorMask.x()), ToGLBoolean(colorMask.y()),
ToGLBoolean(colorMask.z()), ToGLBoolean(colorMask.w())); ToGLBoolean(colorMask.z()), ToGLBoolean(colorMask.w()));
} }
{ { // Clear values
const FloatVec4& clearCol = MG_State::pGLContext->GetClearColor(); const FloatVec4& clearCol = MG_State::pGLContext->GetClearColor();
MG_External::GLES::glClearColor(clearCol.x(), clearCol.y(), clearCol.z(), clearCol.w()); MG_External::GLES::glClearColor(clearCol.x(), clearCol.y(), clearCol.z(), clearCol.w());
MG_External::GLES::glClearDepthf(MG_State::pGLContext->GetClearDepth()); MG_External::GLES::glClearDepthf(MG_State::pGLContext->GetClearDepth());
} }
{ { // Pixel store params
{ {
PixelStoreParam p = PixelStoreParam::UnpackAlignment; PixelStoreParam p = PixelStoreParam::UnpackAlignment;
GLint v = MG_State::pGLContext->GetPixelStoreParam(p); GLint v = MG_State::pGLContext->GetPixelStoreParam(p);
@@ -209,16 +205,15 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
} }
if (MG_State::pGLContext->IsCapabilityEnabled(CapabilityInput::CullFace)) { { // Cull face mode
MG_External::GLES::glEnable(GL_CULL_FACE);
} else {
MG_External::GLES::glDisable(GL_CULL_FACE);
}
{
CullFaceMode cfm = MG_State::pGLContext->GetCullFaceMode(); CullFaceMode cfm = MG_State::pGLContext->GetCullFaceMode();
MG_External::GLES::glCullFace(MG_Util::ConvertCullFaceModeToGLEnum(cfm)); 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 } // namespace RenderStateImpl
@@ -285,7 +285,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
{ // Update sampler parameters; TODO: always use sampler objects in backend { // Update sampler parameters; TODO: always use sampler objects in backend
const auto& samplerObject = stateTextureObject->GetSamplerObject(); const auto& samplerObject = stateTextureObject->GetSamplerObject();
if (samplerObject) { if (samplerObject) {
MG_External::GLES::glTexParameteri( MG_External::GLES::glTexParameteri(
@@ -44,7 +44,14 @@ namespace MobileGL {
} }
void Scissor_State(GLint x, GLint y, GLsizei width, GLsizei height) { 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<GenericErrorInfo>("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) { void SampleCoverage_State(GLfloat value, GLboolean invert) {
+8
View File
@@ -293,6 +293,14 @@ namespace MobileGL {
return m_renderState.GetCullFaceMode(); return m_renderState.GetCullFaceMode();
} }
void GLContext::SetScissorBox(IntVec4 box) {
m_renderState.SetScissorBox(box);
}
const IntVec4& GLContext::GetScissorBox() const {
return m_renderState.GetScissorBox();
}
// Framebuffer // Framebuffer
Vector<Uint> GLContext::GenFramebufferNames(Uint number) { Vector<Uint> GLContext::GenFramebufferNames(Uint number) {
return m_framebufferState.GenerateNames(number); return m_framebufferState.GenerateNames(number);
+2
View File
@@ -92,6 +92,8 @@ namespace MobileGL {
Int GetPixelStoreParam(PixelStoreParam param) const; Int GetPixelStoreParam(PixelStoreParam param) const;
void SetCullFaceMode(CullFaceMode mode); void SetCullFaceMode(CullFaceMode mode);
CullFaceMode GetCullFaceMode() const; CullFaceMode GetCullFaceMode() const;
void SetScissorBox(IntVec4 box); // x, y, width, height
const IntVec4& GetScissorBox() const; // x, y, width, height
// Framebuffer // Framebuffer
Vector<Uint> GenFramebufferNames(Uint number); Vector<Uint> GenFramebufferNames(Uint number);
@@ -39,6 +39,9 @@ namespace MobileGL {
case CapabilityInput::CullFace: case CapabilityInput::CullFace:
m_cullFaceEnabled = enabled; m_cullFaceEnabled = enabled;
break; break;
case CapabilityInput::ScissorTest:
m_scissorTestEnabled = enabled;
break;
default: // not supported currently default: // not supported currently
break; break;
} }
@@ -52,6 +55,8 @@ namespace MobileGL {
return m_depthTestEnabled; return m_depthTestEnabled;
case CapabilityInput::CullFace: case CapabilityInput::CullFace:
return m_cullFaceEnabled; return m_cullFaceEnabled;
case CapabilityInput::ScissorTest:
return m_scissorTestEnabled;
default: default:
return false; return false;
} }
@@ -134,6 +139,15 @@ namespace MobileGL {
CullFaceMode RenderState::GetCullFaceMode() const { CullFaceMode RenderState::GetCullFaceMode() const {
return m_cullFaceMode; return m_cullFaceMode;
} }
// --------------------- Scissor ---------------------
void RenderState::SetScissorBox(IntVec4 box) {
m_scissorBox = box;
}
const IntVec4& RenderState::GetScissorBox() const {
return m_scissorBox;
}
} // namespace GLState } // namespace GLState
} // namespace MG_State } // namespace MG_State
} // namespace MobileGL } // namespace MobileGL
@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "MG_Util/Math/VectorTypes.h" #include "MG_Util/Math/VectorTypes.h"
#include "MG_Util/Types.h"
#include <Includes.h> #include <Includes.h>
namespace MobileGL { namespace MobileGL {
@@ -151,6 +152,10 @@ namespace MobileGL {
void SetCullFaceMode(CullFaceMode mode); void SetCullFaceMode(CullFaceMode mode);
CullFaceMode GetCullFaceMode() const; CullFaceMode GetCullFaceMode() const;
// Scissor
void SetScissorBox(IntVec4 box); // x, y, width, height
const IntVec4& GetScissorBox() const; // x, y, width, height
private: private:
// Rasterization // Rasterization
IntVec4 m_viewport = IntVec4(0, 0, 0, 0); // x, y, width, height IntVec4 m_viewport = IntVec4(0, 0, 0, 0); // x, y, width, height
@@ -180,6 +185,10 @@ namespace MobileGL {
// Cull Face // Cull Face
Bool m_cullFaceEnabled = false; Bool m_cullFaceEnabled = false;
CullFaceMode m_cullFaceMode = CullFaceMode::Back; 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 GLState
} // namespace MG_State } // namespace MG_State