Browse Source

Add support for depth-offset in .egg files

rdb 16 years ago
parent
commit
c4cfc0b8a0

+ 17 - 0
panda/src/egg/eggGroup.cxx

@@ -566,6 +566,23 @@ determine_visibility_mode() {
   return EggGroupNode::determine_visibility_mode();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggGroup::determine_depth_offset
+//       Access: Published, Virtual
+//  Description: Walks back up the hierarchy, looking for an EggGroup
+//               or EggPrimitive or some such object at this level or
+//               above this group that has a depth_offset specified.
+//               Returns a valid EggRenderMode pointer if one is found,
+//               or NULL otherwise.
+////////////////////////////////////////////////////////////////////
+EggRenderMode *EggGroup::
+determine_depth_offset() {
+  if (has_depth_offset()) {
+    return this;
+  }
+  return EggGroupNode::determine_depth_offset();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggGroup::determine_draw_order
 //       Access: Published, Virtual

+ 1 - 0
panda/src/egg/eggGroup.h

@@ -154,6 +154,7 @@ PUBLISHED:
   virtual EggRenderMode *determine_depth_write_mode();
   virtual EggRenderMode *determine_depth_test_mode();
   virtual EggRenderMode *determine_visibility_mode();
+  virtual EggRenderMode *determine_depth_offset();
   virtual EggRenderMode *determine_draw_order();
   virtual EggRenderMode *determine_bin();
   virtual bool determine_indexed();

+ 18 - 0
panda/src/egg/eggNode.cxx

@@ -158,6 +158,24 @@ determine_visibility_mode() {
   return _parent->determine_visibility_mode();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggNode::determine_depth_offset
+//       Access: Public, Virtual
+//  Description: Walks back up the hierarchy, looking for an EggGroup
+//               or EggPrimitive or some such object at this level or
+//               above this node that has a depth_offset specified.
+//               Returns a valid EggRenderMode pointer if one is found,
+//               or NULL otherwise.
+////////////////////////////////////////////////////////////////////
+EggRenderMode *EggNode::
+determine_depth_offset() {
+  if (_parent == (EggGroupNode *)NULL) {
+    // Too bad; we're done.
+    return (EggRenderMode *)NULL;
+  }
+  return _parent->determine_depth_offset();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggNode::determine_draw_order
 //       Access: Public, Virtual

+ 1 - 0
panda/src/egg/eggNode.h

@@ -75,6 +75,7 @@ PUBLISHED:
   virtual EggRenderMode *determine_depth_write_mode();
   virtual EggRenderMode *determine_depth_test_mode();
   virtual EggRenderMode *determine_visibility_mode();
+  virtual EggRenderMode *determine_depth_offset();
   virtual EggRenderMode *determine_draw_order();
   virtual EggRenderMode *determine_bin();
   virtual bool determine_indexed();

+ 27 - 0
panda/src/egg/eggPrimitive.cxx

@@ -141,6 +141,33 @@ determine_visibility_mode() {
   return result;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggPrimitive::determine_depth_offset
+//       Access: Published, Virtual
+//  Description: Walks back up the hierarchy, looking for an EggGroup
+//               or EggPrimitive or some such object at this level or
+//               above this primitive that has a depth_offset specified.
+//               Returns a valid EggRenderMode pointer if one is found,
+//               or NULL otherwise.
+////////////////////////////////////////////////////////////////////
+EggRenderMode *EggPrimitive::
+determine_depth_offset() {
+  if (has_depth_offset()) {
+    return this;
+  }
+
+  EggRenderMode *result = EggNode::determine_depth_offset();
+  if (result == (EggRenderMode *)NULL) {
+    int num_textures = get_num_textures();
+    for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
+      if (get_texture(i)->has_depth_offset()) {
+        result = get_texture(i);
+      }
+    }
+  }
+  return result;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggPrimitive::determine_draw_order
 //       Access: Published, Virtual

+ 1 - 0
panda/src/egg/eggPrimitive.h

@@ -80,6 +80,7 @@ PUBLISHED:
   virtual EggRenderMode *determine_depth_write_mode();
   virtual EggRenderMode *determine_depth_test_mode();
   virtual EggRenderMode *determine_visibility_mode();
+  virtual EggRenderMode *determine_depth_offset();
   virtual EggRenderMode *determine_draw_order();
   virtual EggRenderMode *determine_bin();
 

+ 48 - 0
panda/src/egg/eggRenderMode.I

@@ -131,6 +131,54 @@ get_alpha_mode() const {
   return _alpha_mode;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggRenderMode::set_depth_offset
+//       Access: Public
+//  Description: Sets the "depth-offset" flag associated with this
+//               object.  This adds or subtracts an offset bias
+//               into the depth buffer. See also DepthOffsetAttrib
+//               and NodePath::set_depth_offset().
+////////////////////////////////////////////////////////////////////
+INLINE void EggRenderMode::
+set_depth_offset(int order) {
+  _depth_offset = order;
+  _has_depth_offset = true;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggRenderMode::get_depth_offset
+//       Access: Public
+//  Description: Returns the "depth-offset" flag as set for this
+//               particular object.  See set_depth_offset().
+////////////////////////////////////////////////////////////////////
+INLINE int EggRenderMode::
+get_depth_offset() const {
+  return _depth_offset;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggRenderMode::has_depth_offset
+//       Access: Public
+//  Description: Returns true if the depth-offset flag has been set for
+//               this particular object.  See set_depth_offset().
+////////////////////////////////////////////////////////////////////
+INLINE bool EggRenderMode::
+has_depth_offset() const {
+  return _has_depth_offset;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggRenderMode::clear_depth_offset
+//       Access: Public
+//  Description: Removes the depth-offset flag from this particular
+//               object.  See set_depth_offset().
+////////////////////////////////////////////////////////////////////
+INLINE void EggRenderMode::
+clear_depth_offset() {
+  _has_depth_offset = false;
+}
+
 
 ////////////////////////////////////////////////////////////////////
 //     Function: EggRenderMode::set_draw_order

+ 23 - 0
panda/src/egg/eggRenderMode.cxx

@@ -30,6 +30,8 @@ EggRenderMode() {
   _depth_write_mode = DWM_unspecified;
   _depth_test_mode = DTM_unspecified;
   _visibility_mode = VM_unspecified;
+  _depth_offset = 0;
+  _has_depth_offset = false;
   _draw_order = 0;
   _has_draw_order = false;
 }
@@ -45,6 +47,8 @@ operator = (const EggRenderMode &copy) {
   _depth_write_mode = copy._depth_write_mode;
   _depth_test_mode = copy._depth_test_mode;
   _visibility_mode = copy._visibility_mode;
+  _depth_offset = copy._depth_offset;
+  _has_depth_offset = copy._has_depth_offset;
   _draw_order = copy._draw_order;
   _has_draw_order = copy._has_draw_order;
   return *this;
@@ -74,6 +78,10 @@ write(ostream &out, int indent_level) const {
     indent(out, indent_level)
       << "<Scalar> visibility { " << get_visibility_mode() << " }\n";
   }
+  if (has_depth_offset()) {
+    indent(out, indent_level)
+      << "<Scalar> depth-offset { " << get_depth_offset() << " }\n";
+  }
   if (has_draw_order()) {
     indent(out, indent_level)
       << "<Scalar> draw-order { " << get_draw_order() << " }\n";
@@ -95,10 +103,17 @@ operator == (const EggRenderMode &other) const {
       _depth_write_mode != other._depth_write_mode ||
       _depth_test_mode != other._depth_test_mode ||
       _visibility_mode != other._visibility_mode ||
+      _has_depth_offset != other._has_depth_offset ||
       _has_draw_order != other._has_draw_order) {
     return false;
   }
 
+  if (_has_depth_offset) {
+    if (_depth_offset != other._depth_offset) {
+      return false;
+    }
+  }
+
   if (_has_draw_order) {
     if (_draw_order != other._draw_order) {
       return false;
@@ -132,10 +147,18 @@ operator < (const EggRenderMode &other) const {
     return (int)_visibility_mode < (int)other._visibility_mode;
   }
 
+  if (_has_depth_offset != other._has_depth_offset) {
+    return (int)_has_depth_offset < (int)other._has_depth_offset;
+  }
   if (_has_draw_order != other._has_draw_order) {
     return (int)_has_draw_order < (int)other._has_draw_order;
   }
 
+  if (_has_depth_offset) {
+    if (_depth_offset != other._depth_offset) {
+      return _depth_offset < other._depth_offset;
+    }
+  }
   if (_has_draw_order) {
     if (_draw_order != other._draw_order) {
       return _draw_order < other._draw_order;

+ 7 - 0
panda/src/egg/eggRenderMode.h

@@ -77,6 +77,11 @@ PUBLISHED:
   INLINE void set_visibility_mode(VisibilityMode mode);
   INLINE VisibilityMode get_visibility_mode() const;
 
+  INLINE void set_depth_offset(int bias);
+  INLINE int get_depth_offset() const;
+  INLINE bool has_depth_offset() const;
+  INLINE void clear_depth_offset();
+
   INLINE void set_draw_order(int order);
   INLINE int get_draw_order() const;
   INLINE bool has_draw_order() const;
@@ -102,6 +107,8 @@ private:
   DepthWriteMode _depth_write_mode;
   DepthTestMode _depth_test_mode;
   VisibilityMode _visibility_mode;
+  int _depth_offset;
+  bool _has_depth_offset;
   int _draw_order;
   bool _has_draw_order;
   string _bin;

+ 12 - 0
panda/src/egg/parser.yxx

@@ -666,6 +666,9 @@ texture_body:
       texture->set_visibility_mode(m);
     }
 
+  } else if (cmp_nocase_uh(name, "depth_offset") == 0) {
+    texture->set_depth_offset((int)value);
+
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
     texture->set_draw_order((int)value);
 
@@ -1268,6 +1271,9 @@ group_body:
       group->set_visibility_mode(m);
     }
 
+  } else if (cmp_nocase_uh(name, "depth_offset") == 0) {
+    group->set_depth_offset(ulong_value);
+
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
     group->set_draw_order(ulong_value);
 
@@ -2004,6 +2010,8 @@ primitive_body:
       primitive->set_visibility_mode(m);
     }
 
+  } else if (cmp_nocase_uh(name, "depth_offset") == 0) {
+    primitive->set_depth_offset((int)value);
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
     primitive->set_draw_order((int)value);
   } else if (cmp_nocase_uh(name, "bin") == 0) {
@@ -2095,6 +2103,8 @@ nurbs_surface_body:
       primitive->set_visibility_mode(m);
     }
 
+  } else if (cmp_nocase_uh(name, "depth_offset") == 0) {
+    primitive->set_depth_offset((int)value);
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
     primitive->set_draw_order((int)value);
   } else if (cmp_nocase_uh(name, "bin") == 0) {
@@ -2169,6 +2179,8 @@ nurbs_curve_body:
       primitive->set_visibility_mode(m);
     }
 
+  } else if (cmp_nocase_uh(name, "depth_offset") == 0) {
+    primitive->set_depth_offset((int)value);
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
     primitive->set_draw_order((int)value);
   } else if (cmp_nocase_uh(name, "bin") == 0) {

+ 11 - 0
panda/src/egg2pg/eggRenderState.cxx

@@ -29,6 +29,7 @@
 #include "transparencyAttrib.h"
 #include "depthWriteAttrib.h"
 #include "depthTestAttrib.h"
+#include "depthOffsetAttrib.h"
 #include "texMatrixAttrib.h"
 #include "renderModeAttrib.h"
 #include "material.h"
@@ -59,6 +60,8 @@ fill_state(EggPrimitive *egg_prim) {
   bool binary_alpha_only = true;  // true if all alpha sources are binary alpha.
   bool has_draw_order = false;
   int draw_order = 0;
+  bool has_depth_offset = false;
+  int depth_offset = 0;
   bool has_bin = false;
   string bin;
 
@@ -84,6 +87,11 @@ fill_state(EggPrimitive *egg_prim) {
     has_draw_order = true;
     draw_order = render_mode->get_draw_order();
   }
+  render_mode = egg_prim->determine_depth_offset();
+  if (render_mode != (EggRenderMode *)NULL) {
+    has_depth_offset = true;
+    depth_offset = render_mode->get_depth_offset();
+  }
   render_mode = egg_prim->determine_bin();
   if (render_mode != (EggRenderMode *)NULL) {
     has_bin = true;
@@ -398,6 +406,9 @@ fill_state(EggPrimitive *egg_prim) {
   } else if (has_draw_order) {
     add_attrib(CullBinAttrib::make("fixed", draw_order));
   }
+  if (has_depth_offset) {
+    add_attrib(DepthOffsetAttrib::make(depth_offset));
+  }
  
 
   if (egg_prim->get_bface_flag()) {