]> git.tdb.fi Git - libs/gl.git/blob - source/core/stenciltest.cpp
Redesign depth and stencil test and blend state management
[libs/gl.git] / source / core / stenciltest.cpp
1 #include <stdexcept>
2 #include <msp/strings/format.h>
3 #include "stenciltest.h"
4
5 using namespace std;
6
7 namespace Msp {
8 namespace GL {
9
10 StencilTest::StencilTest():
11         enabled(false),
12         compare(ALWAYS),
13         stencil_fail_op(KEEP),
14         depth_fail_op(KEEP),
15         depth_pass_op(KEEP),
16         reference(0)
17 { }
18
19
20 StencilTest::Loader::Loader(StencilTest &st):
21         ObjectLoader<StencilTest>(st)
22 {
23         add("compare", &Loader::compare);
24         add("actions", &Loader::actions);
25         add("reference", &StencilTest::reference);
26 }
27
28 void StencilTest::Loader::compare(Predicate c)
29 {
30         obj.enabled = true;
31         obj.compare = c;
32 }
33
34 void StencilTest::Loader::actions(StencilOp sf, StencilOp df, StencilOp dp)
35 {
36         obj.stencil_fail_op = sf;
37         obj.depth_fail_op = df;
38         obj.depth_pass_op = dp;
39 }
40
41
42 GLenum get_gl_stencil_op(StencilOp op)
43 {
44         switch(op)
45         {
46         case KEEP: return GL_KEEP;
47         case SET_ZERO: return GL_ZERO;
48         case REPLACE: return GL_REPLACE;
49         case INCR: return GL_INCR;
50         case DECR: return GL_DECR;
51         case INVERT: return GL_INVERT;
52         case INCR_WRAP: return GL_INCR_WRAP;
53         case DECR_WRAP: return GL_DECR_WRAP;
54         default: throw invalid_argument("get_gl_stencil_op");
55         }
56 }
57
58 void operator>>(const LexicalConverter &conv, StencilOp &op)
59 {
60         const string &str = conv.get();
61         if(str=="KEEP")
62                 op = KEEP;
63         else if(str=="SET_ZERO")
64                 op = SET_ZERO;
65         else if(str=="REPLACE")
66                 op = REPLACE;
67         else if(str=="INCR")
68                 op = INCR;
69         else if(str=="DECR")
70                 op = DECR;
71         else if(str=="INVERT")
72                 op = INVERT;
73         else if(str=="INCR_WRAP")
74                 op = INCR_WRAP;
75         else if(str=="DECR_WRAP")
76                 op = DECR_WRAP;
77         else
78                 throw lexical_error(format("conversion of '%s' to StencilOp", str));
79 }
80
81 void operator<<(LexicalConverter &conv, StencilOp op)
82 {
83         switch(op)
84         {
85         case KEEP: conv.result("KEEP"); break;
86         case SET_ZERO: conv.result("SET_ZERO"); break;
87         case REPLACE: conv.result("REPLACE"); break;
88         case INCR: conv.result("INCR"); break;
89         case DECR: conv.result("DECR"); break;
90         case INVERT: conv.result("INVERT"); break;
91         case INCR_WRAP: conv.result("INCR_WRAP"); break;
92         case DECR_WRAP: conv.result("DECR_WRAP"); break;
93         default: conv.result(format("StencilOp(%#x)", static_cast<int>(op)));
94         }
95 }
96
97 } // namespace GL
98 } // namespace Msp