fill out stencil implementation

This commit is contained in:
cxgeorge 2001-10-13 22:25:39 +00:00
parent b9498d9d50
commit 7ec27f1d55
8 changed files with 198 additions and 86 deletions

View File

@ -284,9 +284,8 @@ call_glLightModelTwoSide(GLboolean twoside)
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void GLGraphicsStateGuardian:: INLINE void GLGraphicsStateGuardian::
call_glStencilFunc(GLenum func) { call_glStencilFunc(GLenum func,GLint ref,GLuint mask) {
if (_stencil_func != func) {
_stencil_func = func;
#ifdef GSG_VERBOSE #ifdef GSG_VERBOSE
glgsg_cat.debug() << "glStencilFunc("; glgsg_cat.debug() << "glStencilFunc(";
switch (func) { switch (func) {
@ -318,10 +317,9 @@ call_glStencilFunc(GLenum func) {
glgsg_cat.debug(false) << "unknown, "; glgsg_cat.debug(false) << "unknown, ";
break; break;
} }
glgsg_cat.debug(false) << "1, 1)" << endl; glgsg_cat.debug(false) << ref << mask << ")\n";
#endif #endif
glStencilFunc(func, 1, 1); glStencilFunc(func, ref, mask);
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -330,11 +328,9 @@ call_glStencilFunc(GLenum func) {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void GLGraphicsStateGuardian:: INLINE void GLGraphicsStateGuardian::
call_glStencilOp(GLenum op) { call_glStencilOp(GLenum fail,GLenum zfail,GLenum zpass) {
if (_stencil_op != op) {
_stencil_op = op;
#ifdef GSG_VERBOSE #ifdef GSG_VERBOSE
glgsg_cat.debug() << "glStencilOp(GL_KEEP, GL_KEEP, "; glgsg_cat.debug() << "glStencilOp(fail, zfail, ";
switch (op) { switch (op) {
case GL_KEEP: case GL_KEEP:
glgsg_cat.debug(false) << "GL_KEEP)"; glgsg_cat.debug(false) << "GL_KEEP)";
@ -360,8 +356,7 @@ call_glStencilOp(GLenum op) {
} }
glgsg_cat.debug(false) << endl; glgsg_cat.debug(false) << endl;
#endif #endif
glStencilOp(GL_KEEP, GL_KEEP, op); glStencilOp(fail,zfail,zpass);
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -3101,16 +3101,16 @@ issue_depth_write(const DepthWriteTransition *attrib) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void GLGraphicsStateGuardian:: void GLGraphicsStateGuardian::
issue_stencil(const StencilTransition *attrib) { issue_stencil(const StencilTransition *attrib) {
// activate();
StencilProperty::Mode mode = attrib->get_mode(); StencilProperty::Mode mode = attrib->get_mode();
if (mode == StencilProperty::M_none) { if (mode == StencilProperty::M_none) {
enable_stencil_test(false); enable_stencil_test(false);
} else { } else {
enable_stencil_test(true); enable_stencil_test(true);
call_glStencilFunc(get_stencil_func_type(mode)); call_glStencilFunc(get_stencil_func_type(mode),attrib->get_reference_value(),attrib->get_func_mask());
call_glStencilOp(get_stencil_action_type(attrib->get_action())); 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(); report_errors();
} }
@ -4099,6 +4099,7 @@ get_depth_func_type(DepthTestProperty::Mode m) const
GLenum GLGraphicsStateGuardian:: GLenum GLGraphicsStateGuardian::
get_stencil_func_type(StencilProperty::Mode m) const get_stencil_func_type(StencilProperty::Mode m) const
{ {
// TODO: should do this with a table, not a switch
switch(m) { switch(m) {
case StencilProperty::M_never: return GL_NEVER; case StencilProperty::M_never: return GL_NEVER;
case StencilProperty::M_less: return GL_LESS; case StencilProperty::M_less: return GL_LESS;
@ -4124,13 +4125,22 @@ get_stencil_func_type(StencilProperty::Mode m) const
GLenum GLGraphicsStateGuardian:: GLenum GLGraphicsStateGuardian::
get_stencil_action_type(StencilProperty::Action a) const get_stencil_action_type(StencilProperty::Action a) const
{ {
// TODO: should do this with a table, not a switch
switch(a) { switch(a) {
case StencilProperty::A_keep: return GL_KEEP; case StencilProperty::A_keep: return GL_KEEP;
case StencilProperty::A_zero: return GL_ZERO; case StencilProperty::A_zero: return GL_ZERO;
case StencilProperty::A_replace: return GL_REPLACE; case StencilProperty::A_replace: return GL_REPLACE;
case StencilProperty::A_increment: return GL_INCR; case StencilProperty::A_increment_clamp: return GL_INCR;
case StencilProperty::A_decrement: return GL_DECR; case StencilProperty::A_decrement_clamp: return GL_DECR;
case StencilProperty::A_invert: return GL_INVERT; 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() glgsg_cat.error()
<< "Invalid StencilProperty::Action value" << endl; << "Invalid StencilProperty::Action value" << endl;

View File

@ -201,8 +201,8 @@ protected:
INLINE void call_glLightModelAmbient(const Colorf& color); INLINE void call_glLightModelAmbient(const Colorf& color);
INLINE void call_glLightModelLocal(GLboolean local); INLINE void call_glLightModelLocal(GLboolean local);
INLINE void call_glLightModelTwoSide(GLboolean twoside); INLINE void call_glLightModelTwoSide(GLboolean twoside);
INLINE void call_glStencilFunc(GLenum func); INLINE void call_glStencilFunc(GLenum func,GLint refval,GLuint mask);
INLINE void call_glStencilOp(GLenum op); INLINE void call_glStencilOp(GLenum fail,GLenum zfail,GLenum pass);
INLINE void call_glClipPlane(GLenum plane, const double equation[4]); INLINE void call_glClipPlane(GLenum plane, const double equation[4]);
INLINE void call_glLineWidth(GLfloat width); INLINE void call_glLineWidth(GLfloat width);
INLINE void call_glPointSize(GLfloat size); INLINE void call_glPointSize(GLfloat size);

View File

@ -22,52 +22,19 @@
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE StencilProperty:: 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), _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 // Function: StencilProperty::compare_to
// Access: Public // Access: Public
@ -75,8 +42,17 @@ get_action() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE int StencilProperty:: INLINE int StencilProperty::
compare_to(const StencilProperty &other) const { compare_to(const StencilProperty &other) const {
if (_mode != other._mode) {
return (int)_mode - (int)other._mode; #define CMPVAL(VAL) \
} if (VAL != other.VAL) {return (int)VAL - (int)other.VAL;}
return (int)_action - (int)other._action;
CMPVAL(_mode);
CMPVAL(_pass_action);
CMPVAL(_fail_action);
CMPVAL(_zfail_action);
CMPVAL(_refval);
CMPVAL(_funcmask);
CMPVAL(_writemask);
return 0;
} }

View File

@ -67,9 +67,15 @@ operator << (ostream &out, StencilProperty::Action action) {
case StencilProperty::A_increment: case StencilProperty::A_increment:
return out << "increment"; return out << "increment";
case StencilProperty::A_increment_clamp:
return out << "increment_clamp";
case StencilProperty::A_decrement: case StencilProperty::A_decrement:
return out << "decrement"; return out << "decrement";
case StencilProperty::A_decrement_clamp:
return out << "decrement_clamp";
case StencilProperty::A_invert: case StencilProperty::A_invert:
return out << "invert"; return out << "invert";
} }
@ -86,6 +92,7 @@ void StencilProperty::
output(ostream &out) const { output(ostream &out) const {
out << _mode; out << _mode;
if (_mode != M_none) { if (_mode != M_none) {
out << ":" << _action; out << ":" << _pass_action << ":" << _fail_action << ":" << _zfail_action
<< ":" << _refval << ": 0x" << (void*)_funcmask << ": 0x" << (void*)_writemask;
} }
} }

View File

@ -40,30 +40,60 @@ public:
M_always // Always draw. M_always // Always draw.
}; };
enum Action { // What to do to the stencil when the above test fails. enum Action {
A_keep, A_keep,
A_zero, A_zero,
A_replace, A_replace,
A_increment, A_increment, // incr maxval will wrap around to 0
A_decrement, 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 A_invert
}; };
public: 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 void set_mode(Mode mode) { _mode = mode; };
INLINE Mode get_mode() const; INLINE Mode get_mode() const { return _mode; };
INLINE void set_action(Action action); INLINE void set_pass_action(Action action) { _pass_action = action; };
INLINE Action get_action() const; 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; INLINE int compare_to(const StencilProperty &other) const;
void output(ostream &out) const; void output(ostream &out) const;
private: private:
Mode _mode; Mode _mode;
Action _action; Action _pass_action,_fail_action,_zfail_action;
unsigned long _refval,_funcmask,_writemask;
}; };
ostream &operator << (ostream &out, StencilProperty::Mode mode); ostream &operator << (ostream &out, StencilProperty::Mode mode);

View File

@ -22,9 +22,10 @@
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE StencilTransition:: INLINE StencilTransition::
StencilTransition(StencilProperty::Mode mode, StencilTransition(StencilProperty::Mode mode, StencilProperty::Action pass_action,
StencilProperty::Action action) : StencilProperty::Action fail_action, StencilProperty::Action zfail_action,
_value(mode, 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: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void StencilTransition:: INLINE void StencilTransition::
set_action(StencilProperty::Action action) { set_pass_action(StencilProperty::Action action) {
_value.set_action(action); _value.set_pass_action(action);
state_changed(); 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 // Function: StencilTransition::get_action
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE StencilProperty::Action StencilTransition:: INLINE StencilProperty::Action StencilTransition::
get_action() const { get_pass_action() const {
return _value.get_action(); 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();
}

View File

@ -38,13 +38,37 @@
class EXPCL_PANDA StencilTransition : public OnTransition { class EXPCL_PANDA StencilTransition : public OnTransition {
public: public:
INLINE StencilTransition(StencilProperty::Mode mode = StencilProperty::M_none, 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 void set_mode(StencilProperty::Mode mode);
INLINE StencilProperty::Mode get_mode() const; INLINE StencilProperty::Mode get_mode() const;
INLINE void set_action(StencilProperty::Action action); INLINE void set_pass_action(StencilProperty::Action action);
INLINE StencilProperty::Action get_action() const; 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_copy() const;
virtual NodeTransition *make_initial() const; virtual NodeTransition *make_initial() const;