浏览代码

automatically premunge on load

David Rose 18 年之前
父节点
当前提交
c7fb9cd0ab

+ 0 - 5
panda/src/display/graphicsEngine.cxx

@@ -1727,11 +1727,6 @@ do_add_gsg(GraphicsStateGuardian *gsg, GraphicsPipe *pipe,
   gsg->_pipe = pipe;
   gsg->_pipe = pipe;
   gsg->_engine = this;
   gsg->_engine = this;
 
 
-  // If there was no global GSG previously, this becomes the one.
-  if (GraphicsStateGuardian::get_global_gsg() == NULL) {
-    gsg->make_global_gsg();
-  }
-
   WindowRenderer *draw = 
   WindowRenderer *draw = 
     get_window_renderer(threading_model.get_draw_name(),
     get_window_renderer(threading_model.get_draw_name(),
                         threading_model.get_draw_stage());
                         threading_model.get_draw_stage());

+ 3 - 32
panda/src/display/graphicsStateGuardian.I

@@ -166,7 +166,7 @@ get_threading_model() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::prefers_triangle_strips
 //     Function: GraphicsStateGuardian::prefers_triangle_strips
-//       Access: Published
+//       Access: Published, Virtual
 //  Description: Returns true if this GSG strongly prefers triangle
 //  Description: Returns true if this GSG strongly prefers triangle
 //               strips to individual triangles (such as SGI), or
 //               strips to individual triangles (such as SGI), or
 //               false if it prefers to minimize the number of
 //               false if it prefers to minimize the number of
@@ -180,7 +180,7 @@ prefers_triangle_strips() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_max_vertices_per_array
 //     Function: GraphicsStateGuardian::get_max_vertices_per_array
-//       Access: Published
+//       Access: Published, Virtual
 //  Description: Returns the maximum number of vertices that should be
 //  Description: Returns the maximum number of vertices that should be
 //               put into any one GeomVertexData object for use with
 //               put into any one GeomVertexData object for use with
 //               this GSG.
 //               this GSG.
@@ -192,7 +192,7 @@ get_max_vertices_per_array() const {
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_max_vertices_per_primitive
 //     Function: GraphicsStateGuardian::get_max_vertices_per_primitive
-//       Access: Published
+//       Access: Published, Virtual
 //  Description: Returns the maximum number of vertex indices that
 //  Description: Returns the maximum number of vertex indices that
 //               should be put into any one GeomPrimitive object for
 //               should be put into any one GeomPrimitive object for
 //               use with this GSG.
 //               use with this GSG.
@@ -648,35 +648,6 @@ get_coordinate_system() const {
   return _coordinate_system;
   return _coordinate_system;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::make_global_gsg
-//       Access: Published
-//  Description: Marks this particular GraphicsStateGuardian as the
-//               "global" GSG, which is used for optimization hints by
-//               operations like NodePath::flatten_strong().
-////////////////////////////////////////////////////////////////////
-INLINE void GraphicsStateGuardian::
-make_global_gsg() {
-  _global_gsg = this;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::get_global_gsg
-//       Access: Published, Static
-//  Description: Returns the "global" GSG, which is to say, the
-//               GraphicsStateGuardian object that has most recently
-//               had make_global_gsg() called for it.  It may return
-//               NULL if there is no such GSG.
-//
-//               This object should be used for optimization hints
-//               where appropriate, for instance by operations like
-//               NodePath::flatten_strong().
-////////////////////////////////////////////////////////////////////
-INLINE GraphicsStateGuardian *GraphicsStateGuardian::
-get_global_gsg() {
-  return _global_gsg;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::reset_if_new
 //     Function: GraphicsStateGuardian::reset_if_new
 //       Access: Public
 //       Access: Public

+ 1 - 4
panda/src/display/graphicsStateGuardian.cxx

@@ -71,7 +71,6 @@ PStatCollector GraphicsStateGuardian::_clear_pcollector("Draw:Clear");
 PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush");
 PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush");
 
 
 PT(TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage = NULL;
 PT(TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage = NULL;
-GraphicsStateGuardian *GraphicsStateGuardian::_global_gsg = NULL;
 
 
 TypeHandle GraphicsStateGuardian::_type_handle;
 TypeHandle GraphicsStateGuardian::_type_handle;
 
 
@@ -185,9 +184,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 GraphicsStateGuardian::
 GraphicsStateGuardian::
 ~GraphicsStateGuardian() {
 ~GraphicsStateGuardian() {
-  if (_global_gsg == this) {
-    _global_gsg = NULL;
-  }
+  remove_gsg(this);
 
 
   if (_stencil_render_states) {
   if (_stencil_render_states) {
     delete _stencil_render_states;
     delete _stencil_render_states;

+ 3 - 6
panda/src/display/graphicsStateGuardian.h

@@ -98,9 +98,9 @@ PUBLISHED:
   INLINE GraphicsEngine *get_engine() const;
   INLINE GraphicsEngine *get_engine() const;
   INLINE const GraphicsThreadingModel &get_threading_model() const;
   INLINE const GraphicsThreadingModel &get_threading_model() const;
 
 
-  INLINE bool prefers_triangle_strips() const;
-  INLINE int get_max_vertices_per_array() const;
-  INLINE int get_max_vertices_per_primitive() const;
+  virtual INLINE bool prefers_triangle_strips() const;
+  virtual INLINE int get_max_vertices_per_array() const;
+  virtual INLINE int get_max_vertices_per_primitive() const;
 
 
   INLINE int get_max_texture_stages() const;
   INLINE int get_max_texture_stages() const;
   INLINE int get_max_texture_dimension() const;
   INLINE int get_max_texture_dimension() const;
@@ -149,9 +149,6 @@ PUBLISHED:
   INLINE CoordinateSystem get_coordinate_system() const;
   INLINE CoordinateSystem get_coordinate_system() const;
   virtual CoordinateSystem get_internal_coordinate_system() const;
   virtual CoordinateSystem get_internal_coordinate_system() const;
 
 
-  INLINE void make_global_gsg();
-  INLINE static GraphicsStateGuardian *get_global_gsg();
-
   virtual PreparedGraphicsObjects *get_prepared_objects();
   virtual PreparedGraphicsObjects *get_prepared_objects();
 
 
 public:
 public:

+ 4 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1167,6 +1167,10 @@ reset() {
   }
   }
 
 
 #endif
 #endif
+
+  // Now that the GSG has been initialized, make it available for
+  // optimizations.
+  add_gsg(this);
 }
 }
 
 
 
 

+ 88 - 0
panda/src/gsgbase/graphicsStateGuardianBase.cxx

@@ -17,5 +17,93 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
 #include "graphicsStateGuardianBase.h"
 #include "graphicsStateGuardianBase.h"
+#include "mutexHolder.h"
 
 
+GraphicsStateGuardianBase::GSGs GraphicsStateGuardianBase::_gsgs;
+GraphicsStateGuardianBase *GraphicsStateGuardianBase::_default_gsg;
 TypeHandle GraphicsStateGuardianBase::_type_handle;
 TypeHandle GraphicsStateGuardianBase::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardianBase::get_default_gsg
+//       Access: Published, Static
+//  Description: Returns a pointer to the "default" GSG.  This is
+//               typically the first GSG created in an application; in
+//               a single-window application, it will be the only GSG.
+//               This GSG is used to determine default optimization
+//               choices for loaded geometry.
+//
+//               The return value may be NULL if a GSG has not been
+//               created.
+////////////////////////////////////////////////////////////////////
+GraphicsStateGuardianBase *GraphicsStateGuardianBase::
+get_default_gsg() {
+  MutexHolder holder(_lock);
+  return _default_gsg;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardianBase::set_default_gsg
+//       Access: Published, Static
+//  Description: Specifies a particular GSG to use as the "default"
+//               GSG.  See get_default_gsg().
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardianBase::
+set_default_gsg(GraphicsStateGuardianBase *default_gsg) {
+  MutexHolder holder(_lock);
+  if (find(_gsgs.begin(), _gsgs.end(), default_gsg) == _gsgs.end()) {
+    // The specified GSG doesn't exist or it has already destructed.
+    nassertv(false);
+    return;
+  }
+
+  _default_gsg = default_gsg;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardianBase::add_gsg
+//       Access: Public, Static
+//  Description: Called by a GSG after it has been initialized, to add
+//               a new GSG to the available list.
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardianBase::
+add_gsg(GraphicsStateGuardianBase *gsg) {
+  MutexHolder holder(_lock);
+
+  if (find(_gsgs.begin(), _gsgs.end(), gsg) != _gsgs.end()) {
+    // Already on the list.
+    return;
+  }
+
+  _gsgs.push_back(gsg);
+
+  if (_default_gsg == (GraphicsStateGuardianBase *)NULL) {
+    _default_gsg = gsg;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardianBase::remove_gsg
+//       Access: Public, Static
+//  Description: Called by a GSG destructor to remove a GSG from the
+//               available list.
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardianBase::
+remove_gsg(GraphicsStateGuardianBase *gsg) {
+  MutexHolder holder(_lock);
+
+  GSGs::iterator gi = find(_gsgs.begin(), _gsgs.end(), gsg);
+  if (gi == _gsgs.end()) {
+    // Already removed, or never added.
+    return;
+  }
+
+  _gsgs.erase(gi);
+
+  if (_default_gsg == gsg) {
+    if (_gsgs.empty()) {
+      _default_gsg = *_gsgs.begin();
+    } else {
+      _default_gsg = NULL;
+    }
+  }
+}

+ 19 - 2
panda/src/gsgbase/graphicsStateGuardianBase.h

@@ -23,6 +23,7 @@
 
 
 #include "typedWritableReferenceCount.h"
 #include "typedWritableReferenceCount.h"
 #include "luse.h"
 #include "luse.h"
+#include "pmutex.h"
 
 
 // A handful of forward references.
 // A handful of forward references.
 
 
@@ -111,6 +112,10 @@ class Lens;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA GraphicsStateGuardianBase : public TypedWritableReferenceCount {
 class EXPCL_PANDA GraphicsStateGuardianBase : public TypedWritableReferenceCount {
 PUBLISHED:
 PUBLISHED:
+  virtual bool prefers_triangle_strips() const=0;
+  virtual int get_max_vertices_per_array() const=0;
+  virtual int get_max_vertices_per_primitive() const=0;
+
   virtual bool get_supports_multisample() const=0;
   virtual bool get_supports_multisample() const=0;
   virtual int get_supported_geom_rendering() const=0;
   virtual int get_supported_geom_rendering() const=0;
   virtual bool get_supports_occlusion_query() const=0;
   virtual bool get_supports_occlusion_query() const=0;
@@ -203,11 +208,23 @@ public:
                           int light_id) { }
                           int light_id) { }
 
 
 PUBLISHED:
 PUBLISHED:
+  static GraphicsStateGuardianBase *get_default_gsg();
+  static void set_default_gsg(GraphicsStateGuardianBase *default_gsg);
+
+public:
+  static void add_gsg(GraphicsStateGuardianBase *gsg);
+  static void remove_gsg(GraphicsStateGuardianBase *gsg);
+
+private:
+  typedef pvector<GraphicsStateGuardianBase *> GSGs;
+  static GSGs _gsgs;
+  static GraphicsStateGuardianBase *_default_gsg;
+  static Mutex _lock;
+
+public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {
     return _type_handle;
     return _type_handle;
   }
   }
-
-public:
   static void init_type() {
   static void init_type() {
     TypedWritableReferenceCount::init_type();
     TypedWritableReferenceCount::init_type();
     register_type(_type_handle, "GraphicsStateGuardianBase",
     register_type(_type_handle, "GraphicsStateGuardianBase",

+ 1 - 0
panda/src/pgraph/geomTransformer.cxx

@@ -30,6 +30,7 @@
 #include "vector_int.h"
 #include "vector_int.h"
 #include "userVertexTransform.h"
 #include "userVertexTransform.h"
 #include "geomMunger.h"
 #include "geomMunger.h"
+#include "config_pgraph.h"
 
 
 static PStatCollector apply_vertex_collector("*:Flatten:apply:vertex");
 static PStatCollector apply_vertex_collector("*:Flatten:apply:vertex");
 static PStatCollector apply_texcoord_collector("*:Flatten:apply:texcoord");
 static PStatCollector apply_texcoord_collector("*:Flatten:apply:texcoord");

+ 8 - 1
panda/src/pgraph/loader.cxx

@@ -29,6 +29,8 @@
 #include "string_utils.h"
 #include "string_utils.h"
 #include "bamCache.h"
 #include "bamCache.h"
 #include "bamCacheRecord.h"
 #include "bamCacheRecord.h"
+#include "sceneGraphReducer.h"
+#include "renderState.h"
 
 
 bool Loader::_file_types_loaded = false;
 bool Loader::_file_types_loaded = false;
 TypeHandle Loader::_type_handle;
 TypeHandle Loader::_type_handle;
@@ -215,7 +217,10 @@ load_file(const Filename &filename, const LoaderOptions &options) const {
             loader_cat.info()
             loader_cat.info()
               << "Model " << path << " found in disk cache.\n";
               << "Model " << path << " found in disk cache.\n";
           }
           }
-          return DCAST(PandaNode, record->extract_data());
+          PT(PandaNode) result = DCAST(PandaNode, record->extract_data());
+          SceneGraphReducer sgr;
+          sgr.premunge(result, RenderState::make_empty());
+          return result;
         }
         }
       }
       }
     }
     }
@@ -228,6 +233,8 @@ load_file(const Filename &filename, const LoaderOptions &options) const {
           cache->store(record);
           cache->store(record);
         }
         }
         
         
+        SceneGraphReducer sgr;
+        sgr.premunge(result, RenderState::make_empty());
         return result;
         return result;
       }
       }
     }
     }

+ 2 - 2
panda/src/pgraph/nodePath.cxx

@@ -5593,8 +5593,8 @@ premunge_scene(GraphicsStateGuardianBase *gsg) {
     state = get_parent().get_net_state();
     state = get_parent().get_net_state();
   }
   }
 
 
-  SceneGraphReducer gr;
-  gr.premunge(node(), gsg, state);
+  SceneGraphReducer gr(gsg);
+  gr.premunge(node(), state);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 1 - 1
panda/src/pgraph/nodePath.h

@@ -793,7 +793,7 @@ PUBLISHED:
   // Miscellaneous
   // Miscellaneous
   bool verify_complete(Thread *current_thread = Thread::get_current_thread()) const;
   bool verify_complete(Thread *current_thread = Thread::get_current_thread()) const;
 
 
-  void premunge_scene(GraphicsStateGuardianBase *gsg);
+  void premunge_scene(GraphicsStateGuardianBase *gsg = NULL);
   void prepare_scene(GraphicsStateGuardianBase *gsg);
   void prepare_scene(GraphicsStateGuardianBase *gsg);
 
 
   void show_bounds();
   void show_bounds();

+ 22 - 21
panda/src/pgraph/sceneGraphReducer.I

@@ -23,9 +23,10 @@
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE SceneGraphReducer::
 INLINE SceneGraphReducer::
-SceneGraphReducer() :
+SceneGraphReducer(GraphicsStateGuardianBase *gsg) :
   _combine_radius(0.0f)
   _combine_radius(0.0f)
 {
 {
+  set_gsg(gsg);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -37,6 +38,19 @@ INLINE SceneGraphReducer::
 ~SceneGraphReducer() {
 ~SceneGraphReducer() {
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: SceneGraphReducer::get_gsg
+//       Access: Published
+//  Description: Returns the particular GraphicsStateGuardian that
+//               this object will attempt to optimize to. 
+//               See set_gsg().
+////////////////////////////////////////////////////////////////////
+INLINE GraphicsStateGuardianBase *SceneGraphReducer::
+get_gsg() const {
+  return _gsg;
+}
+
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: SceneGraphReducer::set_combine_radius
 //     Function: SceneGraphReducer::set_combine_radius
 //       Access: Published
 //       Access: Published
@@ -145,34 +159,21 @@ make_nonindexed(PandaNode *root, int nonindexed_bits) {
   return r_make_nonindexed(root, nonindexed_bits);
   return r_make_nonindexed(root, nonindexed_bits);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: SceneGraphReducer::unify
-//       Access: Published
-//  Description: Calls unify() on every GeomNode at this level and
-//               below.  This attempts to reduce the total number of
-//               individual Geoms and GeomPrimitives by combining
-//               these objects wherever possible.  See
-//               GeomNode::unify().
-////////////////////////////////////////////////////////////////////
-INLINE void SceneGraphReducer::
-unify(PandaNode *root) {
-  PStatTimer timer(_unify_collector);
-  r_unify(root);
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: SceneGraphReducer::premunge
 //     Function: SceneGraphReducer::premunge
 //       Access: Published
 //       Access: Published
 //  Description: Walks the scene graph rooted at this node and below,
 //  Description: Walks the scene graph rooted at this node and below,
 //               and uses the indicated GSG to premunge every Geom
 //               and uses the indicated GSG to premunge every Geom
 //               found to optimize it for eventual rendering on the
 //               found to optimize it for eventual rendering on the
-//               indicated GSG.
+//               indicated GSG.  If there is no GSG indicated for the
+//               SceneGraphReducer, this is a no-op.
 //
 //
 //               This operation will also apply to stashed children.
 //               This operation will also apply to stashed children.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void SceneGraphReducer::
 INLINE void SceneGraphReducer::
-premunge(PandaNode *root, GraphicsStateGuardianBase *gsg,
-         const RenderState *initial_state) {
-  PStatTimer timer(_premunge_collector);
-  r_premunge(root, gsg, initial_state);
+premunge(PandaNode *root, const RenderState *initial_state) {
+  if (_gsg != (GraphicsStateGuardianBase *)NULL) {
+    PStatTimer timer(_premunge_collector);
+    r_premunge(root, initial_state);
+  }
 }
 }

+ 66 - 8
panda/src/pgraph/sceneGraphReducer.cxx

@@ -33,6 +33,46 @@ PStatCollector SceneGraphReducer::_make_nonindexed_collector("*:Flatten:make non
 PStatCollector SceneGraphReducer::_unify_collector("*:Flatten:unify");
 PStatCollector SceneGraphReducer::_unify_collector("*:Flatten:unify");
 PStatCollector SceneGraphReducer::_premunge_collector("*:Premunge");
 PStatCollector SceneGraphReducer::_premunge_collector("*:Premunge");
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: SceneGraphReducer::set_gsg
+//       Access: Published
+//  Description: Specifies the particular GraphicsStateGuardian that
+//               this object will attempt to optimize to.  The GSG may
+//               specify parameters such as maximum number of vertices
+//               per vertex data, max number of vertices per
+//               primitive, and whether triangle strips are preferred.
+//               It also affects the types of vertex column data that
+//               is created by premunge().
+////////////////////////////////////////////////////////////////////
+void SceneGraphReducer::
+set_gsg(GraphicsStateGuardianBase *gsg) {
+  if (gsg != (GraphicsStateGuardianBase *)NULL) {
+    _gsg = gsg;
+  } else {
+    _gsg = GraphicsStateGuardianBase::get_default_gsg();
+  }
+
+  if (_gsg != (GraphicsStateGuardianBase *)NULL) {
+    _transformer.set_max_collect_vertices(_gsg->get_max_vertices_per_array());
+  } else {
+    _transformer.set_max_collect_vertices(max_collect_vertices);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: SceneGraphReducer::clear_gsg
+//       Access: Published
+//  Description: Specifies that no particular GraphicsStateGuardian
+//               will be used to guide the optimization.  The
+//               SceneGraphReducer will instead use config variables
+//               such as max-collect-vertices and max-collect-indices.
+////////////////////////////////////////////////////////////////////
+void SceneGraphReducer::
+clear_gsg() {
+  _gsg = NULL;
+  _transformer.set_max_collect_vertices(max_collect_vertices);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: SceneGraphReducer::flatten
 //     Function: SceneGraphReducer::flatten
 //       Access: Published
 //       Access: Published
@@ -87,6 +127,25 @@ flatten(PandaNode *root, int combine_siblings_bits) {
   return num_total_nodes;
   return num_total_nodes;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: SceneGraphReducer::unify
+//       Access: Published
+//  Description: Calls unify() on every GeomNode at this level and
+//               below.  This attempts to reduce the total number of
+//               individual Geoms and GeomPrimitives by combining
+//               these objects wherever possible.  See
+//               GeomNode::unify().
+////////////////////////////////////////////////////////////////////
+void SceneGraphReducer::
+unify(PandaNode *root) {
+  PStatTimer timer(_unify_collector);
+  if (_gsg != (GraphicsStateGuardianBase *)NULL) {
+    r_unify(root, _gsg->get_max_vertices_per_primitive());
+  } else {
+    r_unify(root, max_collect_indices);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: SceneGraphReducer::r_apply_attribs
 //     Function: SceneGraphReducer::r_apply_attribs
 //       Access: Protected
 //       Access: Protected
@@ -727,16 +786,16 @@ r_make_nonindexed(PandaNode *node, int nonindexed_bits) {
 //  Description: The recursive implementation of unify().
 //  Description: The recursive implementation of unify().
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void SceneGraphReducer::
 void SceneGraphReducer::
-r_unify(PandaNode *node) {
+r_unify(PandaNode *node, int max_indices) {
   if (node->is_geom_node()) {
   if (node->is_geom_node()) {
     GeomNode *geom_node = DCAST(GeomNode, node);
     GeomNode *geom_node = DCAST(GeomNode, node);
-    geom_node->unify(max_collect_indices);
+    geom_node->unify(max_indices);
   }
   }
 
 
   PandaNode::Children children = node->get_children();
   PandaNode::Children children = node->get_children();
   int num_children = children.get_num_children();
   int num_children = children.get_num_children();
   for (int i = 0; i < num_children; ++i) {
   for (int i = 0; i < num_children; ++i) {
-    r_unify(children.get_child(i));
+    r_unify(children.get_child(i), max_indices);
   }
   }
 }
 }
 
 
@@ -746,25 +805,24 @@ r_unify(PandaNode *node) {
 //  Description: The recursive implementation of premunge().
 //  Description: The recursive implementation of premunge().
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void SceneGraphReducer::
 void SceneGraphReducer::
-r_premunge(PandaNode *node, GraphicsStateGuardianBase *gsg,
-           const RenderState *state) {
+r_premunge(PandaNode *node, const RenderState *state) {
   CPT(RenderState) next_state = state->compose(node->get_state());
   CPT(RenderState) next_state = state->compose(node->get_state());
 
 
   if (node->is_geom_node()) {
   if (node->is_geom_node()) {
     GeomNode *geom_node = DCAST(GeomNode, node);
     GeomNode *geom_node = DCAST(GeomNode, node);
-    geom_node->do_premunge(gsg, next_state, _transformer);
+    geom_node->do_premunge(_gsg, next_state, _transformer);
   }
   }
 
 
   int i;
   int i;
   PandaNode::Children children = node->get_children();
   PandaNode::Children children = node->get_children();
   int num_children = children.get_num_children();
   int num_children = children.get_num_children();
   for (i = 0; i < num_children; ++i) {
   for (i = 0; i < num_children; ++i) {
-    r_premunge(children.get_child(i), gsg, next_state);
+    r_premunge(children.get_child(i), next_state);
   }
   }
 
 
   PandaNode::Stashed stashed = node->get_stashed();
   PandaNode::Stashed stashed = node->get_stashed();
   int num_stashed = stashed.get_num_stashed();
   int num_stashed = stashed.get_num_stashed();
   for (i = 0; i < num_stashed; ++i) {
   for (i = 0; i < num_stashed; ++i) {
-    r_premunge(stashed.get_stashed(i), gsg, next_state);
+    r_premunge(stashed.get_stashed(i), next_state);
   }
   }
 }
 }

+ 11 - 7
panda/src/pgraph/sceneGraphReducer.h

@@ -29,6 +29,7 @@
 #include "pStatTimer.h"
 #include "pStatTimer.h"
 #include "typedObject.h"
 #include "typedObject.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
+#include "graphicsStateGuardianBase.h"
 
 
 class PandaNode;
 class PandaNode;
 
 
@@ -45,7 +46,7 @@ class PandaNode;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA SceneGraphReducer {
 class EXPCL_PANDA SceneGraphReducer {
 PUBLISHED:
 PUBLISHED:
-  INLINE SceneGraphReducer();
+  INLINE SceneGraphReducer(GraphicsStateGuardianBase *gsg = NULL);
   INLINE ~SceneGraphReducer();
   INLINE ~SceneGraphReducer();
 
 
   enum AttribTypes {
   enum AttribTypes {
@@ -121,6 +122,10 @@ PUBLISHED:
     MN_avoid_dynamic   = 0x004,
     MN_avoid_dynamic   = 0x004,
   };
   };
 
 
+  void set_gsg(GraphicsStateGuardianBase *gsg);
+  void clear_gsg();
+  INLINE GraphicsStateGuardianBase *get_gsg() const;
+
   INLINE void set_combine_radius(float combine_radius);
   INLINE void set_combine_radius(float combine_radius);
   INLINE float get_combine_radius() const;
   INLINE float get_combine_radius() const;
 
 
@@ -132,10 +137,9 @@ PUBLISHED:
 
 
   INLINE int collect_vertex_data(PandaNode *root, int collect_bits = ~0);
   INLINE int collect_vertex_data(PandaNode *root, int collect_bits = ~0);
   INLINE int make_nonindexed(PandaNode *root, int nonindexed_bits = ~0);
   INLINE int make_nonindexed(PandaNode *root, int nonindexed_bits = ~0);
-  INLINE void unify(PandaNode *root);
+  void unify(PandaNode *root);
 
 
-  INLINE void premunge(PandaNode *root, GraphicsStateGuardianBase *gsg,
-                       const RenderState *initial_state);
+  INLINE void premunge(PandaNode *root, const RenderState *initial_state);
 
 
 protected:
 protected:
   void r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
   void r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
@@ -165,12 +169,12 @@ protected:
   int r_collect_vertex_data(PandaNode *node, int collect_bits,
   int r_collect_vertex_data(PandaNode *node, int collect_bits,
                             GeomTransformer &transformer);
                             GeomTransformer &transformer);
   int r_make_nonindexed(PandaNode *node, int collect_bits);
   int r_make_nonindexed(PandaNode *node, int collect_bits);
-  void r_unify(PandaNode *node);
+  void r_unify(PandaNode *node, int max_indices);
 
 
-  void r_premunge(PandaNode *node, GraphicsStateGuardianBase *gsg,
-                  const RenderState *state);
+  void r_premunge(PandaNode *node, const RenderState *state);
 
 
 private:
 private:
+  PT(GraphicsStateGuardianBase) _gsg;
   float _combine_radius;
   float _combine_radius;
   GeomTransformer _transformer;
   GeomTransformer _transformer;