#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;
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):
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):
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)
{ }
}
}
+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
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.
*/
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);
void operator>>(const LexicalConverter &, BlendFactor &);
void operator<<(LexicalConverter &, BlendFactor);
+void operator>>(const LexicalConverter &, ColorWriteMask &);
+void operator<<(LexicalConverter &, ColorWriteMask);
+
} // namespace GL
} // namespace Msp
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;