From: Mikko Rasa Date: Fri, 1 Oct 2021 09:48:01 +0000 (+0300) Subject: Add color write mask to blend state X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=bae374a3cda6a1b59f36016624ef518bf2676355 Add color write mask to blend state --- diff --git a/source/core/blend.cpp b/source/core/blend.cpp index 324440d3..8ceb2382 100644 --- a/source/core/blend.cpp +++ b/source/core/blend.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "blend.h" using namespace std; @@ -13,7 +14,8 @@ Blend::Blend(): equation(ADD), src_factor(ONE), dst_factor(ZERO), - constant(0.0f, 0.0f, 0.0f, 0.0f) + constant(0.0f, 0.0f, 0.0f, 0.0f), + write_mask(WRITE_ALL) { } Blend::Blend(BlendFactor sf, BlendFactor df): @@ -21,7 +23,8 @@ Blend::Blend(BlendFactor sf, BlendFactor df): equation(ADD), src_factor(sf), dst_factor(df), - constant(0.0f, 0.0f, 0.0f, 0.0f) + constant(0.0f, 0.0f, 0.0f, 0.0f), + write_mask(WRITE_ALL) { } Blend::Blend(BlendEquation e, BlendFactor sf, BlendFactor df): @@ -29,7 +32,8 @@ Blend::Blend(BlendEquation e, BlendFactor sf, BlendFactor df): equation(e), src_factor(sf), dst_factor(df), - constant(0.0f, 0.0f, 0.0f, 0.0f) + constant(0.0f, 0.0f, 0.0f, 0.0f), + write_mask(WRITE_ALL) { } @@ -182,5 +186,47 @@ void operator<<(LexicalConverter &conv, BlendFactor factor) } } +void operator>>(const LexicalConverter &conv, ColorWriteMask &mask) +{ + ColorWriteMask result = WRITE_NONE; + for(const string &p: split(conv.get(), '_')) + { + if(p=="ALL") + result = result|WRITE_ALL; + else if(p=="RED") + result = result|WRITE_RED; + else if(p=="GREEN") + result = result|WRITE_GREEN; + else if(p=="BLUE") + result = result|WRITE_BLUE; + else if(p=="ALPHA") + result = result|WRITE_ALPHA; + else + throw lexical_error(format("conversion of '%s' to ColorWriteMask", conv.get())); + } + mask = result; +} + +void operator<<(LexicalConverter &conv, ColorWriteMask mask) +{ + if(mask==WRITE_ALL) + conv.result("ALL"); + else if(mask&~WRITE_ALL) + conv.result(format("ColorWriteMask(%#x)", static_cast(mask))); + else + { + string result; + if(mask&WRITE_RED) + result = "RED"; + if(mask&WRITE_GREEN) + append(result, "_", "GREEN"); + if(mask&WRITE_BLUE) + append(result, "_", "BLUE"); + if(mask&WRITE_ALPHA) + append(result, "_", "ALPHA"); + conv.result(result); + } +} + } // namespace GL } // namespace Msp diff --git a/source/core/blend.h b/source/core/blend.h index ad7ba241..a1180050 100644 --- a/source/core/blend.h +++ b/source/core/blend.h @@ -35,6 +35,16 @@ enum BlendFactor ONE_MINUS_CONSTANT_ALPHA }; +enum ColorWriteMask +{ + WRITE_NONE = 0, + WRITE_RED = 1, + WRITE_GREEN = 2, + WRITE_BLUE = 4, + WRITE_ALPHA = 8, + WRITE_ALL = 15 +}; + /** Blends incoming fragments with those already in the framebuffer. */ @@ -56,12 +66,17 @@ struct Blend BlendFactor src_factor; BlendFactor dst_factor; Color constant; + ColorWriteMask write_mask; Blend(); Blend(BlendFactor, BlendFactor); Blend(BlendEquation, BlendFactor, BlendFactor); }; + +inline ColorWriteMask operator|(ColorWriteMask m1, ColorWriteMask m2) +{ return static_cast(static_cast(m1)|static_cast(m2)); } + unsigned get_gl_blend_equation(BlendEquation); unsigned get_gl_blend_factor(BlendFactor); @@ -71,6 +86,9 @@ void operator<<(LexicalConverter &, BlendEquation); void operator>>(const LexicalConverter &, BlendFactor &); void operator<<(LexicalConverter &, BlendFactor); +void operator>>(const LexicalConverter &, ColorWriteMask &); +void operator<<(LexicalConverter &, ColorWriteMask); + } // namespace GL } // namespace Msp diff --git a/source/core/pipelinestate.cpp b/source/core/pipelinestate.cpp index 97f353dc..262dd26b 100644 --- a/source/core/pipelinestate.cpp +++ b/source/core/pipelinestate.cpp @@ -322,9 +322,14 @@ void PipelineState::apply(unsigned mask) const glBlendEquation(get_gl_blend_equation(blend->equation)); glBlendFunc(get_gl_blend_factor(blend->src_factor), get_gl_blend_factor(blend->dst_factor)); glBlendColor(blend->constant.r, blend->constant.g, blend->constant.b, blend->constant.a); + ColorWriteMask cw = blend->write_mask; + glColorMask((cw&WRITE_RED)!=0, (cw&WRITE_GREEN)!=0, (cw&WRITE_BLUE)!=0, (cw&WRITE_ALPHA)!=0); } else + { glDisable(GL_BLEND); + glColorMask(true, true, true, true); + } } last_applied = this;