]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/stenciltest.cpp
Redesign depth and stencil test and blend state management
[libs/gl.git] / source / core / stenciltest.cpp
diff --git a/source/core/stenciltest.cpp b/source/core/stenciltest.cpp
new file mode 100644 (file)
index 0000000..7076f4d
--- /dev/null
@@ -0,0 +1,98 @@
+#include <stdexcept>
+#include <msp/strings/format.h>
+#include "stenciltest.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+StencilTest::StencilTest():
+       enabled(false),
+       compare(ALWAYS),
+       stencil_fail_op(KEEP),
+       depth_fail_op(KEEP),
+       depth_pass_op(KEEP),
+       reference(0)
+{ }
+
+
+StencilTest::Loader::Loader(StencilTest &st):
+       ObjectLoader<StencilTest>(st)
+{
+       add("compare", &Loader::compare);
+       add("actions", &Loader::actions);
+       add("reference", &StencilTest::reference);
+}
+
+void StencilTest::Loader::compare(Predicate c)
+{
+       obj.enabled = true;
+       obj.compare = c;
+}
+
+void StencilTest::Loader::actions(StencilOp sf, StencilOp df, StencilOp dp)
+{
+       obj.stencil_fail_op = sf;
+       obj.depth_fail_op = df;
+       obj.depth_pass_op = dp;
+}
+
+
+GLenum get_gl_stencil_op(StencilOp op)
+{
+       switch(op)
+       {
+       case KEEP: return GL_KEEP;
+       case SET_ZERO: return GL_ZERO;
+       case REPLACE: return GL_REPLACE;
+       case INCR: return GL_INCR;
+       case DECR: return GL_DECR;
+       case INVERT: return GL_INVERT;
+       case INCR_WRAP: return GL_INCR_WRAP;
+       case DECR_WRAP: return GL_DECR_WRAP;
+       default: throw invalid_argument("get_gl_stencil_op");
+       }
+}
+
+void operator>>(const LexicalConverter &conv, StencilOp &op)
+{
+       const string &str = conv.get();
+       if(str=="KEEP")
+               op = KEEP;
+       else if(str=="SET_ZERO")
+               op = SET_ZERO;
+       else if(str=="REPLACE")
+               op = REPLACE;
+       else if(str=="INCR")
+               op = INCR;
+       else if(str=="DECR")
+               op = DECR;
+       else if(str=="INVERT")
+               op = INVERT;
+       else if(str=="INCR_WRAP")
+               op = INCR_WRAP;
+       else if(str=="DECR_WRAP")
+               op = DECR_WRAP;
+       else
+               throw lexical_error(format("conversion of '%s' to StencilOp", str));
+}
+
+void operator<<(LexicalConverter &conv, StencilOp op)
+{
+       switch(op)
+       {
+       case KEEP: conv.result("KEEP"); break;
+       case SET_ZERO: conv.result("SET_ZERO"); break;
+       case REPLACE: conv.result("REPLACE"); break;
+       case INCR: conv.result("INCR"); break;
+       case DECR: conv.result("DECR"); break;
+       case INVERT: conv.result("INVERT"); break;
+       case INCR_WRAP: conv.result("INCR_WRAP"); break;
+       case DECR_WRAP: conv.result("DECR_WRAP"); break;
+       default: conv.result(format("StencilOp(%#x)", static_cast<int>(op)));
+       }
+}
+
+} // namespace GL
+} // namespace Msp