[Feat] (MG_State/RenderState): Support indexed blend states.

This commit is contained in:
BZLZHH
2026-02-06 00:41:30 +08:00
parent 68bdea41d2
commit a109675f1f
4 changed files with 129 additions and 19 deletions
+18
View File
@@ -244,6 +244,14 @@ namespace MobileGL {
return m_renderState.IsCapabilityEnabled(cap); return m_renderState.IsCapabilityEnabled(cap);
} }
void GLContext::SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled) {
m_renderState.SetCapabilityIndexed(cap, index, enabled);
}
Bool GLContext::IsCapabilityEnabledIndexed(CapabilityInput cap, Uint index) const {
return m_renderState.IsCapabilityEnabledIndexed(cap, index);
}
void GLContext::SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha, void GLContext::SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
BlendFactor dstAlpha) { BlendFactor dstAlpha) {
m_renderState.SetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); m_renderState.SetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha);
@@ -254,6 +262,16 @@ namespace MobileGL {
m_renderState.GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha); m_renderState.GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha);
} }
void GLContext::SetBlendFuncIndexed(Uint index, BlendFactor srcRGB, BlendFactor dstRGB,
BlendFactor srcAlpha, BlendFactor dstAlpha) {
m_renderState.SetBlendFuncIndexed(index, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::GetBlendFuncIndexed(Uint index, BlendFactor& srcRGB, BlendFactor& dstRGB,
BlendFactor& srcAlpha, BlendFactor& dstAlpha) const {
m_renderState.GetBlendFuncIndexed(index, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::SetDepthFunc(DepthTestFunc func) { void GLContext::SetDepthFunc(DepthTestFunc func) {
m_renderState.SetDepthFunc(func); m_renderState.SetDepthFunc(func);
} }
+6
View File
@@ -92,9 +92,15 @@ namespace MobileGL {
const IntVec4& GetViewport() const; // x, y, width, height const IntVec4& GetViewport() const; // x, y, width, height
void SetCapability(CapabilityInput cap, Bool enabled); void SetCapability(CapabilityInput cap, Bool enabled);
Bool IsCapabilityEnabled(CapabilityInput cap) const; Bool IsCapabilityEnabled(CapabilityInput cap) const;
void SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled);
Bool IsCapabilityEnabledIndexed(CapabilityInput cap, Uint index) const;
void SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha, BlendFactor dstAlpha); void SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha, BlendFactor dstAlpha);
void GetBlendFunc(BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha, void GetBlendFunc(BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
BlendFactor& dstAlpha) const; BlendFactor& dstAlpha) const;
void SetBlendFuncIndexed(Uint index, BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
BlendFactor dstAlpha);
void GetBlendFuncIndexed(Uint index, BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
BlendFactor& dstAlpha) const;
void SetDepthFunc(DepthTestFunc func); void SetDepthFunc(DepthTestFunc func);
DepthTestFunc GetDepthFunc() const; DepthTestFunc GetDepthFunc() const;
void SetDepthMask(Bool flag); void SetDepthMask(Bool flag);
@@ -7,6 +7,7 @@
// End of Source File Header // End of Source File Header
#include "RenderState.h" #include "RenderState.h"
#include "MG_Util/Types.h"
namespace MobileGL { namespace MobileGL {
namespace MG_State { namespace MG_State {
@@ -43,10 +44,19 @@ namespace MobileGL {
break; break;
switch (cap) { switch (cap) {
SET_CAPABILITY(Blend, enabled);
SET_CAPABILITY(DepthTest, enabled); SET_CAPABILITY(DepthTest, enabled);
SET_CAPABILITY(CullFace, enabled); SET_CAPABILITY(CullFace, enabled);
SET_CAPABILITY(ScissorTest, enabled); SET_CAPABILITY(ScissorTest, enabled);
case CapabilityInput::Blend: {
Bool stateChanged = false;
for (auto& blendState : m_parameters.BlendStates) {
if (blendState.Enabled == enabled) continue;
blendState.Enabled = enabled;
stateChanged = true;
}
if (stateChanged) ++m_version;
break;
}
default: // not supported currently default: // not supported currently
break; break;
} }
@@ -58,35 +68,100 @@ namespace MobileGL {
case CapabilityInput::capability: \ case CapabilityInput::capability: \
return m_parameters.capability##Enabled; return m_parameters.capability##Enabled;
switch (cap) { switch (cap) {
RETURN_CAPABILITY(Blend);
RETURN_CAPABILITY(DepthTest); RETURN_CAPABILITY(DepthTest);
RETURN_CAPABILITY(CullFace); RETURN_CAPABILITY(CullFace);
RETURN_CAPABILITY(ScissorTest); RETURN_CAPABILITY(ScissorTest);
case CapabilityInput::Blend:
return m_parameters.BlendStates[0].Enabled;
default: default:
return false; return false;
} }
} }
void RenderState::SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled) {
// Only for BlendState currently
if (cap != CapabilityInput::Blend) {
THROW_UNIMPL_EXCEPTION;
return;
}
if (index >= MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) {
MOBILEGL_ASSERT(false, "Blend capability index out of range: %d", index);
return;
}
if (m_parameters.BlendStates[index].Enabled == enabled) return;
m_parameters.BlendStates[index].Enabled = enabled;
++m_version;
}
Bool RenderState::IsCapabilityEnabledIndexed(CapabilityInput cap, Uint index) const {
// Only for BlendState currently
if (cap != CapabilityInput::Blend) {
THROW_UNIMPL_EXCEPTION;
return false;
}
if (index >= MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) {
MOBILEGL_ASSERT(false, "Blend capability index out of range: %d", index);
return false;
}
return m_parameters.BlendStates[index].Enabled;
}
// -------------------- Blending -------------------- // -------------------- Blending --------------------
void RenderState::SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha, void RenderState::SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
BlendFactor dstAlpha) { BlendFactor dstAlpha) {
if (m_parameters.SrcFactorRGB == srcRGB && m_parameters.DstFactorRGB == dstRGB && Bool stateChanged = false;
m_parameters.SrcFactorAlpha == srcAlpha && m_parameters.DstFactorAlpha == dstAlpha) for (auto& blendState : m_parameters.BlendStates) {
return; if (blendState.SrcFactorRGB == srcRGB && blendState.DstFactorRGB == dstRGB &&
blendState.SrcFactorAlpha == srcAlpha && blendState.DstFactorAlpha == dstAlpha) {
m_parameters.SrcFactorRGB = srcRGB; continue;
m_parameters.DstFactorRGB = dstRGB; }
m_parameters.SrcFactorAlpha = srcAlpha; blendState.SrcFactorRGB = srcRGB;
m_parameters.DstFactorAlpha = dstAlpha; blendState.DstFactorRGB = dstRGB;
blendState.SrcFactorAlpha = srcAlpha;
blendState.DstFactorAlpha = dstAlpha;
stateChanged = true;
}
if (!stateChanged) return;
++m_version; ++m_version;
} }
void RenderState::GetBlendFunc(BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha, void RenderState::GetBlendFunc(BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
BlendFactor& dstAlpha) const { BlendFactor& dstAlpha) const {
srcRGB = m_parameters.SrcFactorRGB; srcRGB = m_parameters.BlendStates[0].SrcFactorRGB;
dstRGB = m_parameters.DstFactorRGB; dstRGB = m_parameters.BlendStates[0].DstFactorRGB;
srcAlpha = m_parameters.SrcFactorAlpha; srcAlpha = m_parameters.BlendStates[0].SrcFactorAlpha;
dstAlpha = m_parameters.DstFactorAlpha; dstAlpha = m_parameters.BlendStates[0].DstFactorAlpha;
}
void RenderState::SetBlendFuncIndexed(Uint index, BlendFactor srcRGB, BlendFactor dstRGB,
BlendFactor srcAlpha, BlendFactor dstAlpha) {
if (index >= MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) {
MOBILEGL_ASSERT(false, "Blend function index out of range: %d", index);
return;
}
PerBufferBlendState& blendState = m_parameters.BlendStates[index];
if (blendState.SrcFactorRGB == srcRGB && blendState.DstFactorRGB == dstRGB &&
blendState.SrcFactorAlpha == srcAlpha && blendState.DstFactorAlpha == dstAlpha) {
return;
}
blendState.SrcFactorRGB = srcRGB;
blendState.DstFactorRGB = dstRGB;
blendState.SrcFactorAlpha = srcAlpha;
blendState.DstFactorAlpha = dstAlpha;
++m_version;
}
void RenderState::GetBlendFuncIndexed(Uint index, BlendFactor& srcRGB, BlendFactor& dstRGB,
BlendFactor& srcAlpha, BlendFactor& dstAlpha) const {
if (index >= MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS) {
MOBILEGL_ASSERT(false, "Blend function index out of range: %d", index);
return;
}
srcRGB = m_parameters.BlendStates[index].SrcFactorRGB;
dstRGB = m_parameters.BlendStates[index].DstFactorRGB;
srcAlpha = m_parameters.BlendStates[index].SrcFactorAlpha;
dstAlpha = m_parameters.BlendStates[index].DstFactorAlpha;
} }
// -------------------- Depth -------------------- // -------------------- Depth --------------------
@@ -9,6 +9,7 @@
#pragma once #pragma once
#include <Includes.h> #include <Includes.h>
#include <MG_Util/Math/VectorTypes.h> #include <MG_Util/Math/VectorTypes.h>
#include <MG_State/GLState/FramebufferState/FramebufferObject.h>
namespace MobileGL { namespace MobileGL {
enum class BlendFactor { enum class BlendFactor {
@@ -127,16 +128,20 @@ namespace MobileGL {
Int Alignment = 4; Int Alignment = 4;
}; };
struct PerBufferBlendState {
Bool Enabled = false;
BlendFactor SrcFactorRGB = BlendFactor::One;
BlendFactor DstFactorRGB = BlendFactor::Zero;
BlendFactor SrcFactorAlpha = BlendFactor::One;
BlendFactor DstFactorAlpha = BlendFactor::Zero;
};
struct RenderStateParameters { struct RenderStateParameters {
// Rasterization // Rasterization
IntVec4 Viewport = IntVec4(0, 0, 0, 0); // x, y, width, height IntVec4 Viewport = IntVec4(0, 0, 0, 0); // x, y, width, height
// Blending // Blending
Bool BlendEnabled = false; Array<PerBufferBlendState, MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS> BlendStates;
BlendFactor SrcFactorRGB = BlendFactor::One;
BlendFactor DstFactorRGB = BlendFactor::Zero;
BlendFactor SrcFactorAlpha = BlendFactor::One;
BlendFactor DstFactorAlpha = BlendFactor::Zero;
// Depth // Depth
Bool DepthTestEnabled = false; Bool DepthTestEnabled = false;
@@ -175,11 +180,17 @@ namespace MobileGL {
// Capabilities // Capabilities
void SetCapability(CapabilityInput cap, Bool enabled); void SetCapability(CapabilityInput cap, Bool enabled);
Bool IsCapabilityEnabled(CapabilityInput cap) const; Bool IsCapabilityEnabled(CapabilityInput cap) const;
void SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled);
Bool IsCapabilityEnabledIndexed(CapabilityInput cap, Uint index) const;
// Blending // Blending
void SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha, BlendFactor dstAlpha); void SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha, BlendFactor dstAlpha);
void GetBlendFunc(BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha, void GetBlendFunc(BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
BlendFactor& dstAlpha) const; BlendFactor& dstAlpha) const;
void SetBlendFuncIndexed(Uint index, BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
BlendFactor dstAlpha);
void GetBlendFuncIndexed(Uint index, BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
BlendFactor& dstAlpha) const;
// Depth // Depth
void SetDepthFunc(DepthTestFunc func); void SetDepthFunc(DepthTestFunc func);