-/* $Id$
-
-This file is part of libmspgl
-Copyright © 2008 Mikko Rasa, Mikkosoft Productions
-Distributed under the LGPL
-*/
-
-#define GL_GLEXT_PROTOTYPES
+#include <msp/gl/extensions/ext_blend_minmax.h>
+#include <msp/gl/extensions/ext_blend_subtract.h>
+#include <msp/strings/format.h>
#include "blend.h"
+using namespace std;
+
namespace Msp {
namespace GL {
-void blend_equation(BlendEquation eq)
+Blend::Blend():
+ eq(ADD),
+ src_factor(ONE),
+ dst_factor(ZERO)
+{ }
+
+Blend::Blend(BlendFactor sf, BlendFactor df):
+ eq(ADD),
+ src_factor(sf),
+ dst_factor(df)
+{ }
+
+Blend::Blend(BlendEquation e, BlendFactor sf, BlendFactor df):
+ eq(e),
+ src_factor(sf),
+ dst_factor(df)
+{
+ if(eq==MIN || eq==MAX)
+ static Require _req(EXT_blend_minmax);
+ else if(eq==SUBTRACT || eq==REVERSE_SUBTRACT)
+ static Require _req(EXT_blend_subtract);
+}
+
+void Blend::bind() const
+{
+ if(set_current(this))
+ {
+ glEnable(GL_BLEND);
+ if(EXT_blend_minmax)
+ glBlendEquation(eq);
+ glBlendFunc(src_factor, dst_factor);
+ }
+}
+
+void Blend::unbind()
+{
+ if(set_current(0))
+ glDisable(GL_BLEND);
+}
+
+const Blend &Blend::alpha()
+{
+ static Blend blend(SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
+ return blend;
+}
+
+const Blend &Blend::additive()
+{
+ static Blend blend(ONE, ONE);
+ return blend;
+}
+
+const Blend &Blend::additive_alpha()
+{
+ static Blend blend(SRC_ALPHA, ONE);
+ return blend;
+}
+
+void operator>>(const LexicalConverter &conv, BlendFactor &factor)
{
- glBlendEquation(eq);
+ const string &str = conv.get();
+ if(str=="ZERO")
+ factor = ZERO;
+ else if(str=="ONE")
+ factor = ONE;
+ else if(str=="SRC_COLOR")
+ factor = SRC_COLOR;
+ else if(str=="ONE_MINUS_SRC_COLOR")
+ factor = ONE_MINUS_SRC_COLOR;
+ else if(str=="SRC_ALPHA")
+ factor = SRC_ALPHA;
+ else if(str=="ONE_MINUS_SRC_ALPHA")
+ factor = ONE_MINUS_SRC_ALPHA;
+ else if(str=="DST_COLOR")
+ factor = DST_COLOR;
+ else if(str=="ONE_MINUS_DST_COLOR")
+ factor = ONE_MINUS_DST_COLOR;
+ else if(str=="DST_ALPHA")
+ factor = DST_ALPHA;
+ else if(str=="ONE_MINUS_DST_ALPHA")
+ factor = ONE_MINUS_DST_ALPHA;
+ else if(str=="CONSTANT_COLOR")
+ factor = CONSTANT_COLOR;
+ else if(str=="ONE_MINUS_CONSTANT_COLOR")
+ factor = ONE_MINUS_CONSTANT_COLOR;
+ else if(str=="CONSTANT_ALPHA")
+ factor = CONSTANT_ALPHA;
+ else if(str=="ONE_MINUS_CONSTANT_ALPHA")
+ factor = ONE_MINUS_CONSTANT_ALPHA;
+ else
+ throw lexical_error(format("conversion of '%s' to BlendFactor", str));
}
-void blend_func(BlendFactor src, BlendFactor dst)
+void operator<<(LexicalConverter &conv, BlendFactor factor)
{
- glBlendFunc(src, dst);
+ switch(factor)
+ {
+ case ZERO: conv.result("ZERO"); break;
+ case ONE: conv.result("ONE"); break;
+ case SRC_COLOR: conv.result("SRC_COLOR"); break;
+ case ONE_MINUS_SRC_COLOR: conv.result("ONE_MINUS_SRC_COLOR"); break;
+ case SRC_ALPHA: conv.result("SRC_ALPHA"); break;
+ case ONE_MINUS_SRC_ALPHA: conv.result("ONE_MINUS_SRC_ALPHA"); break;
+ case DST_COLOR: conv.result("DST_COLOR"); break;
+ case ONE_MINUS_DST_COLOR: conv.result("ONE_MINUS_DST_COLOR"); break;
+ case DST_ALPHA: conv.result("DST_ALPHA"); break;
+ case ONE_MINUS_DST_ALPHA: conv.result("ONE_MINUS_DST_ALPHA"); break;
+ case CONSTANT_COLOR: conv.result("CONSTANT_COLOR"); break;
+ case ONE_MINUS_CONSTANT_COLOR: conv.result("ONE_MINUS_CONSTANT_COLOR"); break;
+ case CONSTANT_ALPHA: conv.result("CONSTANT_ALPHA"); break;
+ case ONE_MINUS_CONSTANT_ALPHA: conv.result("ONE_MINUS_CONSTANT_ALPHA"); break;
+ default: conv.result(format("BlendFactor(%#x)", static_cast<int>(factor)));
+ }
}
} // namespace GL