]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/blend.cpp
Redesign depth and stencil test and blend state management
[libs/gl.git] / source / core / blend.cpp
index 3327885c74c1ef34b7a5c1d111f22935a8639de0..a5e8f44d2917ffc8c7fc2e48cb784b28b3ec01fd 100644 (file)
@@ -9,61 +9,120 @@ namespace Msp {
 namespace GL {
 
 Blend::Blend():
-       eq(ADD),
+       enabled(false),
+       equation(ADD),
        src_factor(ONE),
-       dst_factor(ZERO)
+       dst_factor(ZERO),
+       constant(0.0f, 0.0f, 0.0f, 0.0f)
 { }
 
 Blend::Blend(BlendFactor sf, BlendFactor df):
-       eq(ADD),
+       enabled(true),
+       equation(ADD),
        src_factor(sf),
-       dst_factor(df)
+       dst_factor(df),
+       constant(0.0f, 0.0f, 0.0f, 0.0f)
 { }
 
 Blend::Blend(BlendEquation e, BlendFactor sf, BlendFactor df):
-       eq(e),
+       enabled(true),
+       equation(e),
        src_factor(sf),
-       dst_factor(df)
+       dst_factor(df),
+       constant(0.0f, 0.0f, 0.0f, 0.0f)
+{ }
+
+
+Blend::Loader::Loader(Blend &b):
+       ObjectLoader<Blend>(b)
 {
-       if(eq==MIN || eq==MAX)
-               static Require _req(EXT_blend_minmax);
-       else if(eq==SUBTRACT || eq==REVERSE_SUBTRACT)
-               static Require _req(EXT_blend_subtract);
+       add("equation", &Loader::equation);
+       add("factors", &Loader::factors);
+       add("constant", &Loader::constant);
 }
 
-void Blend::bind() const
+void Blend::Loader::constant(float r, float g, float b, float a)
 {
-       if(set_current(this))
-       {
-               glEnable(GL_BLEND);
-               if(EXT_blend_minmax)
-                       glBlendEquation(eq);
-               glBlendFunc(src_factor, dst_factor);
-       }
+       obj.constant = Color(r, g, b, a);
 }
 
-void Blend::unbind()
+void Blend::Loader::equation(BlendEquation eq)
 {
-       if(set_current(0))
-               glDisable(GL_BLEND);
+       obj.enabled = true;
+       obj.equation = eq;
 }
 
-const Blend &Blend::alpha()
+void Blend::Loader::factors(BlendFactor sf, BlendFactor df)
 {
-       static Blend blend(SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
-       return blend;
+       obj.enabled = true;
+       obj.src_factor = sf;
+       obj.dst_factor = df;
 }
 
-const Blend &Blend::additive()
+
+GLenum get_gl_blend_equation(BlendEquation eq)
 {
-       static Blend blend(ONE, ONE);
-       return blend;
+       switch(eq)
+       {
+       case ADD: return GL_FUNC_ADD;
+       case SUBTRACT: return GL_FUNC_SUBTRACT;
+       case REVERSE_SUBTRACT: return GL_FUNC_REVERSE_SUBTRACT;
+       case MIN: return GL_MIN;
+       case MAX: return GL_MAX;
+       default: throw invalid_argument("get_gl_blend_equation");
+       }
 }
 
-const Blend &Blend::additive_alpha()
+GLenum get_gl_blend_factor(BlendFactor factor)
 {
-       static Blend blend(SRC_ALPHA, ONE);
-       return blend;
+       switch(factor)
+       {
+       case ZERO: return GL_ZERO;
+       case ONE: return GL_ONE;
+       case SRC_COLOR: return GL_SRC_COLOR;
+       case ONE_MINUS_SRC_COLOR: return GL_ONE_MINUS_SRC_COLOR;
+       case SRC_ALPHA: return GL_SRC_ALPHA;
+       case ONE_MINUS_SRC_ALPHA: return GL_ONE_MINUS_SRC_ALPHA;
+       case DST_COLOR: return GL_DST_COLOR;
+       case ONE_MINUS_DST_COLOR: return GL_ONE_MINUS_DST_COLOR;
+       case DST_ALPHA: return GL_DST_ALPHA;
+       case ONE_MINUS_DST_ALPHA: return GL_ONE_MINUS_DST_ALPHA;
+       case CONSTANT_COLOR: return GL_CONSTANT_COLOR;
+       case ONE_MINUS_CONSTANT_COLOR: return GL_ONE_MINUS_CONSTANT_COLOR;
+       case CONSTANT_ALPHA: return GL_CONSTANT_ALPHA;
+       case ONE_MINUS_CONSTANT_ALPHA: return GL_ONE_MINUS_CONSTANT_ALPHA;
+       default: throw invalid_argument("get_gl_blend_factor");
+       }
+}
+
+void operator>>(const LexicalConverter &conv, BlendEquation &eq)
+{
+       const string &str = conv.get();
+       if(str=="ADD")
+               eq = ADD;
+       else if(str=="SUBTRACT")
+               eq = SUBTRACT;
+       else if(str=="REVERSE_SUBTRACT")
+               eq = REVERSE_SUBTRACT;
+       else if(str=="MIN")
+               eq = MIN;
+       else if(str=="MAX")
+               eq = MAX;
+       else
+               throw lexical_error(format("conversion of '%s' to BlendEquation", str));
+}
+
+void operator<<(LexicalConverter &conv, BlendEquation eq)
+{
+       switch(eq)
+       {
+       case ADD: conv.result("ADD"); break;
+       case SUBTRACT: conv.result("SUBTRACT"); break;
+       case REVERSE_SUBTRACT: conv.result("REVERSE_SUBTRACT"); break;
+       case MIN: conv.result("MIN"); break;
+       case MAX: conv.result("MAX"); break;
+       default: conv.result(format("BlendEquation(%#x)", static_cast<int>(eq)));
+       }
 }
 
 void operator>>(const LexicalConverter &conv, BlendFactor &factor)