From 7ec27f1d55c5b13f34147fa1a314c9ba2bb2622f Mon Sep 17 00:00:00 2001 From: cxgeorge <> Date: Sat, 13 Oct 2001 22:25:39 +0000 Subject: [PATCH] fill out stencil implementation --- panda/src/glgsg/glGraphicsStateGuardian.I | 19 ++--- panda/src/glgsg/glGraphicsStateGuardian.cxx | 22 ++++-- panda/src/glgsg/glGraphicsStateGuardian.h | 4 +- panda/src/sgattrib/stencilProperty.I | 68 ++++++----------- panda/src/sgattrib/stencilProperty.cxx | 9 ++- panda/src/sgattrib/stencilProperty.h | 48 +++++++++--- panda/src/sgattrib/stencilTransition.I | 84 +++++++++++++++++++-- panda/src/sgattrib/stencilTransition.h | 30 +++++++- 8 files changed, 198 insertions(+), 86 deletions(-) diff --git a/panda/src/glgsg/glGraphicsStateGuardian.I b/panda/src/glgsg/glGraphicsStateGuardian.I index 392d508576..adb5c58ead 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.I +++ b/panda/src/glgsg/glGraphicsStateGuardian.I @@ -284,9 +284,8 @@ call_glLightModelTwoSide(GLboolean twoside) // Description: //////////////////////////////////////////////////////////////////// INLINE void GLGraphicsStateGuardian:: -call_glStencilFunc(GLenum func) { - if (_stencil_func != func) { - _stencil_func = func; +call_glStencilFunc(GLenum func,GLint ref,GLuint mask) { + #ifdef GSG_VERBOSE glgsg_cat.debug() << "glStencilFunc("; switch (func) { @@ -318,10 +317,9 @@ call_glStencilFunc(GLenum func) { glgsg_cat.debug(false) << "unknown, "; break; } - glgsg_cat.debug(false) << "1, 1)" << endl; + glgsg_cat.debug(false) << ref << mask << ")\n"; #endif - glStencilFunc(func, 1, 1); - } + glStencilFunc(func, ref, mask); } //////////////////////////////////////////////////////////////////// @@ -330,11 +328,9 @@ call_glStencilFunc(GLenum func) { // Description: //////////////////////////////////////////////////////////////////// INLINE void GLGraphicsStateGuardian:: -call_glStencilOp(GLenum op) { - if (_stencil_op != op) { - _stencil_op = op; +call_glStencilOp(GLenum fail,GLenum zfail,GLenum zpass) { #ifdef GSG_VERBOSE - glgsg_cat.debug() << "glStencilOp(GL_KEEP, GL_KEEP, "; + glgsg_cat.debug() << "glStencilOp(fail, zfail, "; switch (op) { case GL_KEEP: glgsg_cat.debug(false) << "GL_KEEP)"; @@ -360,8 +356,7 @@ call_glStencilOp(GLenum op) { } glgsg_cat.debug(false) << endl; #endif - glStencilOp(GL_KEEP, GL_KEEP, op); - } + glStencilOp(fail,zfail,zpass); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/glgsg/glGraphicsStateGuardian.cxx b/panda/src/glgsg/glGraphicsStateGuardian.cxx index 898a212d42..1c3bd5b9a7 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.cxx +++ b/panda/src/glgsg/glGraphicsStateGuardian.cxx @@ -3101,16 +3101,16 @@ issue_depth_write(const DepthWriteTransition *attrib) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: issue_stencil(const StencilTransition *attrib) { - // activate(); - StencilProperty::Mode mode = attrib->get_mode(); if (mode == StencilProperty::M_none) { enable_stencil_test(false); } else { enable_stencil_test(true); - call_glStencilFunc(get_stencil_func_type(mode)); - call_glStencilOp(get_stencil_action_type(attrib->get_action())); + call_glStencilFunc(get_stencil_func_type(mode),attrib->get_reference_value(),attrib->get_func_mask()); + call_glStencilOp(get_stencil_action_type(attrib->get_fail_action()), + get_stencil_action_type(attrib->get_zfail_action()), + get_stencil_action_type(attrib->get_pass_action())); } report_errors(); } @@ -4099,6 +4099,7 @@ get_depth_func_type(DepthTestProperty::Mode m) const GLenum GLGraphicsStateGuardian:: get_stencil_func_type(StencilProperty::Mode m) const { + // TODO: should do this with a table, not a switch switch(m) { case StencilProperty::M_never: return GL_NEVER; case StencilProperty::M_less: return GL_LESS; @@ -4124,13 +4125,22 @@ get_stencil_func_type(StencilProperty::Mode m) const GLenum GLGraphicsStateGuardian:: get_stencil_action_type(StencilProperty::Action a) const { + // TODO: should do this with a table, not a switch switch(a) { case StencilProperty::A_keep: return GL_KEEP; case StencilProperty::A_zero: return GL_ZERO; case StencilProperty::A_replace: return GL_REPLACE; - case StencilProperty::A_increment: return GL_INCR; - case StencilProperty::A_decrement: return GL_DECR; + case StencilProperty::A_increment_clamp: return GL_INCR; + case StencilProperty::A_decrement_clamp: return GL_DECR; case StencilProperty::A_invert: return GL_INVERT; + + case StencilProperty::A_increment: + case StencilProperty::A_decrement: + glgsg_cat.error() + << "wraparound incr/decr StencilProperty::Action not supported by OpenGL\n"; + if(a == StencilProperty::A_increment) + return GL_INCR; + else return GL_DECR; } glgsg_cat.error() << "Invalid StencilProperty::Action value" << endl; diff --git a/panda/src/glgsg/glGraphicsStateGuardian.h b/panda/src/glgsg/glGraphicsStateGuardian.h index 7b1348a542..ae283fb34d 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.h +++ b/panda/src/glgsg/glGraphicsStateGuardian.h @@ -201,8 +201,8 @@ protected: INLINE void call_glLightModelAmbient(const Colorf& color); INLINE void call_glLightModelLocal(GLboolean local); INLINE void call_glLightModelTwoSide(GLboolean twoside); - INLINE void call_glStencilFunc(GLenum func); - INLINE void call_glStencilOp(GLenum op); + INLINE void call_glStencilFunc(GLenum func,GLint refval,GLuint mask); + INLINE void call_glStencilOp(GLenum fail,GLenum zfail,GLenum pass); INLINE void call_glClipPlane(GLenum plane, const double equation[4]); INLINE void call_glLineWidth(GLfloat width); INLINE void call_glPointSize(GLfloat size); diff --git a/panda/src/sgattrib/stencilProperty.I b/panda/src/sgattrib/stencilProperty.I index e25a384049..6d12edd142 100644 --- a/panda/src/sgattrib/stencilProperty.I +++ b/panda/src/sgattrib/stencilProperty.I @@ -22,52 +22,19 @@ // Description: //////////////////////////////////////////////////////////////////// INLINE StencilProperty:: -StencilProperty(StencilProperty::Mode mode, StencilProperty::Action action) : +StencilProperty(StencilProperty::Mode mode, StencilProperty::Action pass_action, + StencilProperty::Action fail_action, StencilProperty::Action zfail_action, + unsigned long refval, unsigned long funcmask, unsigned long writemask) : _mode(mode), - _action(action) + _pass_action(pass_action), + _fail_action(fail_action), + _zfail_action(zfail_action), + _refval(refval), + _funcmask(funcmask), + _writemask(writemask) { } -//////////////////////////////////////////////////////////////////// -// Function: StencilProperty::set_mode -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void StencilProperty:: -set_mode(StencilProperty::Mode mode) { - _mode = mode; -} - -//////////////////////////////////////////////////////////////////// -// Function: StencilProperty::get_mode -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE StencilProperty::Mode StencilProperty:: -get_mode() const { - return _mode; -} - -//////////////////////////////////////////////////////////////////// -// Function: StencilProperty::set_action -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void StencilProperty:: -set_action(StencilProperty::Action action) { - _action = action; -} - -//////////////////////////////////////////////////////////////////// -// Function: StencilProperty::get_action -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE StencilProperty::Action StencilProperty:: -get_action() const { - return _action; -} - //////////////////////////////////////////////////////////////////// // Function: StencilProperty::compare_to // Access: Public @@ -75,8 +42,17 @@ get_action() const { //////////////////////////////////////////////////////////////////// INLINE int StencilProperty:: compare_to(const StencilProperty &other) const { - if (_mode != other._mode) { - return (int)_mode - (int)other._mode; - } - return (int)_action - (int)other._action; + + #define CMPVAL(VAL) \ + if (VAL != other.VAL) {return (int)VAL - (int)other.VAL;} + + CMPVAL(_mode); + CMPVAL(_pass_action); + CMPVAL(_fail_action); + CMPVAL(_zfail_action); + CMPVAL(_refval); + CMPVAL(_funcmask); + CMPVAL(_writemask); + + return 0; } diff --git a/panda/src/sgattrib/stencilProperty.cxx b/panda/src/sgattrib/stencilProperty.cxx index 0e30ca267d..91323bd1b7 100644 --- a/panda/src/sgattrib/stencilProperty.cxx +++ b/panda/src/sgattrib/stencilProperty.cxx @@ -67,9 +67,15 @@ operator << (ostream &out, StencilProperty::Action action) { case StencilProperty::A_increment: return out << "increment"; + case StencilProperty::A_increment_clamp: + return out << "increment_clamp"; + case StencilProperty::A_decrement: return out << "decrement"; + case StencilProperty::A_decrement_clamp: + return out << "decrement_clamp"; + case StencilProperty::A_invert: return out << "invert"; } @@ -86,6 +92,7 @@ void StencilProperty:: output(ostream &out) const { out << _mode; if (_mode != M_none) { - out << ":" << _action; + out << ":" << _pass_action << ":" << _fail_action << ":" << _zfail_action + << ":" << _refval << ": 0x" << (void*)_funcmask << ": 0x" << (void*)_writemask; } } diff --git a/panda/src/sgattrib/stencilProperty.h b/panda/src/sgattrib/stencilProperty.h index 2fcb57076e..b3d925cade 100644 --- a/panda/src/sgattrib/stencilProperty.h +++ b/panda/src/sgattrib/stencilProperty.h @@ -40,30 +40,60 @@ public: M_always // Always draw. }; - enum Action { // What to do to the stencil when the above test fails. + enum Action { A_keep, A_zero, A_replace, - A_increment, - A_decrement, + A_increment, // incr maxval will wrap around to 0 + A_decrement, // decr 0 will wrap around to all 1's + A_increment_clamp, // cap value to max stencil val + A_decrement_clamp, // cap value at zero A_invert }; public: - INLINE StencilProperty(Mode mode, Action action); + INLINE StencilProperty(Mode mode,Action pass_action,Action fail_action,Action zfail_action, + unsigned long refval, unsigned long funcmask, unsigned long writemask); - INLINE void set_mode(Mode mode); - INLINE Mode get_mode() const; + INLINE void set_mode(Mode mode) { _mode = mode; }; + INLINE Mode get_mode() const { return _mode; }; - INLINE void set_action(Action action); - INLINE Action get_action() const; + INLINE void set_pass_action(Action action) { _pass_action = action; }; + INLINE Action get_pass_action() const { return _pass_action; }; + + INLINE void set_fail_action(Action action) { _fail_action = action; }; + INLINE Action get_fail_action() const { return _fail_action; }; + + INLINE void set_zfail_action(Action action) { _zfail_action = action; }; + INLINE Action get_zfail_action() const { return _zfail_action; }; + + INLINE void set_reference_value(unsigned long v) { _refval = v; }; + INLINE unsigned long get_reference_value() const { return _refval; }; + + INLINE void set_func_mask(unsigned long m) { _funcmask = m; }; + INLINE unsigned long get_func_mask() const { return _funcmask; }; + + INLINE void set_write_mask(unsigned long m) { _writemask = m; }; + INLINE unsigned long get_write_mask() const { return _writemask; }; + + INLINE void set_stencil_state(Mode mode, Action pass_action, Action fail_action, Action zfail_action, + unsigned long refval, unsigned long funcmask, unsigned long writemask) { + _mode = mode; + _pass_action = pass_action; + _fail_action = fail_action; + _zfail_action = zfail_action; + _refval = refval; + _funcmask = funcmask; + _writemask = writemask; + }; INLINE int compare_to(const StencilProperty &other) const; void output(ostream &out) const; private: Mode _mode; - Action _action; + Action _pass_action,_fail_action,_zfail_action; + unsigned long _refval,_funcmask,_writemask; }; ostream &operator << (ostream &out, StencilProperty::Mode mode); diff --git a/panda/src/sgattrib/stencilTransition.I b/panda/src/sgattrib/stencilTransition.I index e277dfb282..3ec10db1da 100644 --- a/panda/src/sgattrib/stencilTransition.I +++ b/panda/src/sgattrib/stencilTransition.I @@ -22,9 +22,10 @@ // Description: //////////////////////////////////////////////////////////////////// INLINE StencilTransition:: -StencilTransition(StencilProperty::Mode mode, - StencilProperty::Action action) : - _value(mode, action) +StencilTransition(StencilProperty::Mode mode, StencilProperty::Action pass_action, + StencilProperty::Action fail_action, StencilProperty::Action zfail_action, + unsigned long refval, unsigned long funcmask, unsigned long writemask) : + _value(mode,pass_action,fail_action,zfail_action,refval,funcmask,writemask) { } @@ -55,17 +56,86 @@ get_mode() const { // Description: //////////////////////////////////////////////////////////////////// INLINE void StencilTransition:: -set_action(StencilProperty::Action action) { - _value.set_action(action); +set_pass_action(StencilProperty::Action action) { + _value.set_pass_action(action); state_changed(); } +INLINE void StencilTransition:: +set_fail_action(StencilProperty::Action action) { + _value.set_fail_action(action); + state_changed(); +} + +INLINE void StencilTransition:: +set_zfail_action(StencilProperty::Action action) { + _value.set_zfail_action(action); + state_changed(); +} + +INLINE void StencilTransition:: +set_reference_value(unsigned long v) { + _value.set_reference_value(v); + state_changed(); +} + +INLINE void StencilTransition:: +set_func_mask(unsigned long m) { + _value.set_func_mask(m); + state_changed(); +} + +INLINE void StencilTransition:: +set_write_mask(unsigned long m) { + _value.set_write_mask(m); + state_changed(); +} + +INLINE void StencilTransition:: +set_stencil_state(StencilProperty::Mode mode, StencilProperty::Action pass_action, + StencilProperty::Action fail_action, StencilProperty::Action zfail_action, + unsigned long refval, unsigned long refmask, unsigned long writemask) { + _value.set_stencil_state(mode,pass_action,fail_action,zfail_action, + refval,refmask,writemask); + state_changed(); +} + //////////////////////////////////////////////////////////////////// // Function: StencilTransition::get_action // Access: Public // Description: //////////////////////////////////////////////////////////////////// INLINE StencilProperty::Action StencilTransition:: -get_action() const { - return _value.get_action(); +get_pass_action() const { + return _value.get_pass_action(); } + +INLINE StencilProperty::Action StencilTransition:: +get_fail_action() const { + return _value.get_fail_action(); +} + +INLINE StencilProperty::Action StencilTransition:: +get_zfail_action() const { + return _value.get_zfail_action(); +} + +INLINE unsigned long StencilTransition:: +get_reference_value() const { + return _value.get_reference_value(); +} + +INLINE unsigned long StencilTransition:: +get_func_mask() const { + return _value.get_func_mask(); +} + +INLINE unsigned long StencilTransition:: +get_write_mask() const { + return _value.get_write_mask(); +} + + + + + diff --git a/panda/src/sgattrib/stencilTransition.h b/panda/src/sgattrib/stencilTransition.h index d3b9490d1a..86d7dbc40e 100644 --- a/panda/src/sgattrib/stencilTransition.h +++ b/panda/src/sgattrib/stencilTransition.h @@ -38,13 +38,37 @@ class EXPCL_PANDA StencilTransition : public OnTransition { public: INLINE StencilTransition(StencilProperty::Mode mode = StencilProperty::M_none, - StencilProperty::Action action = StencilProperty::A_keep); + StencilProperty::Action pass_action = StencilProperty::A_replace, + StencilProperty::Action fail_action = StencilProperty::A_keep, + StencilProperty::Action zfail_action = StencilProperty::A_keep, + unsigned long refval = 0, + unsigned long funcmask = 0xFFFFFFFF, + unsigned long writemask = 0xFFFFFFFF); INLINE void set_mode(StencilProperty::Mode mode); INLINE StencilProperty::Mode get_mode() const; - INLINE void set_action(StencilProperty::Action action); - INLINE StencilProperty::Action get_action() const; + INLINE void set_pass_action(StencilProperty::Action action); + INLINE StencilProperty::Action get_pass_action() const; + + INLINE void set_fail_action(StencilProperty::Action action); + INLINE StencilProperty::Action get_fail_action() const; + + INLINE void set_zfail_action(StencilProperty::Action action); + INLINE StencilProperty::Action get_zfail_action() const; + + INLINE void set_reference_value(unsigned long v); + INLINE unsigned long get_reference_value() const; + + INLINE void set_func_mask(unsigned long m); + INLINE unsigned long get_func_mask() const; + + INLINE void set_write_mask(unsigned long m); + INLINE unsigned long get_write_mask() const; + + INLINE void set_stencil_state(StencilProperty::Mode mode, StencilProperty::Action pass_action, + StencilProperty::Action fail_action, StencilProperty::Action zfail_action, + unsigned long refval, unsigned long funcmask, unsigned long writemask); virtual NodeTransition *make_copy() const; virtual NodeTransition *make_initial() const;