]> git.tdb.fi Git - libs/gl.git/commitdiff
Add color write mask to blend state
authorMikko Rasa <tdb@tdb.fi>
Fri, 1 Oct 2021 09:48:01 +0000 (12:48 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 1 Oct 2021 09:48:01 +0000 (12:48 +0300)
source/core/blend.cpp
source/core/blend.h
source/core/pipelinestate.cpp

index 324440d32e9362ad39c33c3e7afafeb878aed37b..8ceb23829a76894e978dfad03a1531c3421c215e 100644 (file)
@@ -1,6 +1,7 @@
 #include <msp/gl/extensions/ext_blend_minmax.h>
 #include <msp/gl/extensions/ext_blend_subtract.h>
 #include <msp/strings/format.h>
+#include <msp/strings/utils.h>
 #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<int>(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
index ad7ba241bd1b1028e7e1bea45b5477f6b66245f6..a1180050163b31dbd009acd1987d27c8507fb5b3 100644 (file)
@@ -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<ColorWriteMask>(static_cast<int>(m1)|static_cast<int>(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
 
index 97f353dcee8b572c835e1ac5569ca9769489b246..262dd26b596b95fb600aea40d5995d0fe08fd56e 100644 (file)
@@ -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;