1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSG_STENCIL
15#define OSG_STENCIL 1
16
17#include <osg/StateAttribute>
18
19namespace osg {
20
21#ifndef GL_INCR_WRAP
22#define GL_INCR_WRAP 0x8507
23#define GL_DECR_WRAP 0x8508
24#endif
25
26
27/** Encapsulate OpenGL glStencilFunc/Op/Mask functions.
28*
29*   All functionality except INCR_WRAP and DECR_WRAP is supported by OpenGL 1.1.
30*   INCR_WRAP an DECR_WRAP are available since OpenGL 1.4 or when
31*   GL_EXT_stencil_wrap extension is present.
32*
33*   If INCR_WRAP or DECR_WRAP values are used while they are detected to be not supported,
34*   the INCR or DECR values are sent to OpenGL instead.
35*
36*   OpenGL 2.0 introduced two side stenciling that is available through
37*   osg::StencilTwoSided class.
38*/
39class OSG_EXPORT Stencil : public StateAttribute
40{
41    public :
42
43
44        Stencil();
45
46        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
47        Stencil(const Stencil& stencil,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
48            StateAttribute(stencil,copyop),
49            _func(stencil._func),
50            _funcRef(stencil._funcRef),
51            _funcMask(stencil._funcMask),
52            _sfail(stencil._sfail),
53            _zfail(stencil._zfail),
54            _zpass(stencil._zpass),
55            _writeMask(stencil._writeMask) {}
56
57
58        META_StateAttribute(osg, Stencil, STENCIL);
59
60        /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
61        virtual int compare(const StateAttribute& sa) const
62        {
63            // check the types are equal and then create the rhs variable
64            // used by the COMPARE_StateAttribute_Parameter macros below.
65            COMPARE_StateAttribute_Types(Stencil,sa)
66
67            // compare each parameter in turn against the rhs.
68            COMPARE_StateAttribute_Parameter(_func)
69            COMPARE_StateAttribute_Parameter(_funcRef)
70            COMPARE_StateAttribute_Parameter(_funcMask)
71            COMPARE_StateAttribute_Parameter(_sfail)
72            COMPARE_StateAttribute_Parameter(_zfail)
73            COMPARE_StateAttribute_Parameter(_zpass)
74            COMPARE_StateAttribute_Parameter(_writeMask)
75
76            return 0; // passed all the above comparison macros, must be equal.
77        }
78
79        virtual bool getModeUsage(StateAttribute::ModeUsage& usage) const
80        {
81            usage.usesMode(GL_STENCIL_TEST);
82            return true;
83        }
84
85        enum Function
86        {
87            NEVER = GL_NEVER,
88            LESS = GL_LESS,
89            EQUAL = GL_EQUAL,
90            LEQUAL = GL_LEQUAL,
91            GREATER = GL_GREATER,
92            NOTEQUAL = GL_NOTEQUAL,
93            GEQUAL = GL_GEQUAL,
94            ALWAYS = GL_ALWAYS
95        };
96
97        inline void setFunction(Function func,int ref,unsigned int mask)
98        {
99            _func = func;
100            _funcRef = ref;
101            _funcMask = mask;
102        }
103
104        inline void setFunction(Function func) { _func = func; }
105        inline Function getFunction() const { return _func; }
106
107        inline void setFunctionRef(int ref) { _funcRef=ref; }
108        inline int getFunctionRef() const { return _funcRef; }
109
110        inline void setFunctionMask(unsigned int mask) { _funcMask=mask; }
111        inline unsigned int getFunctionMask() const { return _funcMask; }
112
113
114        enum Operation
115        {
116            KEEP = GL_KEEP,
117            ZERO = GL_ZERO,
118            REPLACE = GL_REPLACE,
119            INCR = GL_INCR,
120            DECR = GL_DECR,
121            INVERT = GL_INVERT,
122            INCR_WRAP = GL_INCR_WRAP,
123            DECR_WRAP = GL_DECR_WRAP
124        };
125
126        /** set the operations to apply when the various stencil and depth
127          * tests fail or pass.  First parameter is to control the operation
128          * when the stencil test fails.  The second parameter is to control the
129          * operation when the stencil test passes, but depth test fails. The
130          * third parameter controls the operation when both the stencil test
131          * and depth pass.  Ordering of parameter is the same as if using
132          * glStencilOp(,,).*/
133        inline void setOperation(Operation sfail, Operation zfail, Operation zpass)
134        {
135            _sfail = sfail;
136            _zfail = zfail;
137            _zpass = zpass;
138        }
139
140        /** set the operation when the stencil test fails.*/
141        inline void setStencilFailOperation(Operation sfail) { _sfail = sfail; }
142
143        /** get the operation when the stencil test fails.*/
144        inline Operation getStencilFailOperation() const { return _sfail; }
145
146        /** set the operation when the stencil test passes but the depth test fails.*/
147        inline void setStencilPassAndDepthFailOperation(Operation zfail) { _zfail=zfail; }
148
149        /** get the operation when the stencil test passes but the depth test fails.*/
150        inline Operation getStencilPassAndDepthFailOperation() const { return _zfail; }
151
152        /** set the operation when both the stencil test and the depth test pass.*/
153        inline void setStencilPassAndDepthPassOperation(Operation zpass) { _zpass=zpass; }
154
155        /** get the operation when both the stencil test and the depth test pass.*/
156        inline Operation getStencilPassAndDepthPassOperation() const { return _zpass; }
157
158
159        inline void setWriteMask(unsigned int mask) { _writeMask = mask; }
160
161        inline unsigned int getWriteMask() const { return _writeMask; }
162
163
164        virtual void apply(State& state) const;
165
166
167    protected:
168
169        virtual ~Stencil();
170
171        Function            _func;
172        int                 _funcRef;
173        unsigned int        _funcMask;
174
175        Operation           _sfail;
176        Operation           _zfail;
177        Operation           _zpass;
178
179        unsigned int        _writeMask;
180
181};
182
183}
184
185#endif
186