From c7fb9cd0ab8488a1f0156f3faf7f020ff234b9a7 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 21 May 2007 22:36:27 +0000 Subject: [PATCH] automatically premunge on load --- panda/src/display/graphicsEngine.cxx | 5 -- panda/src/display/graphicsStateGuardian.I | 35 +------- panda/src/display/graphicsStateGuardian.cxx | 5 +- panda/src/display/graphicsStateGuardian.h | 9 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 4 + .../src/gsgbase/graphicsStateGuardianBase.cxx | 88 +++++++++++++++++++ panda/src/gsgbase/graphicsStateGuardianBase.h | 21 ++++- panda/src/pgraph/geomTransformer.cxx | 1 + panda/src/pgraph/loader.cxx | 9 +- panda/src/pgraph/nodePath.cxx | 4 +- panda/src/pgraph/nodePath.h | 2 +- panda/src/pgraph/sceneGraphReducer.I | 43 ++++----- panda/src/pgraph/sceneGraphReducer.cxx | 74 ++++++++++++++-- panda/src/pgraph/sceneGraphReducer.h | 18 ++-- 14 files changed, 229 insertions(+), 89 deletions(-) diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index d04459348b..e445c1f322 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -1727,11 +1727,6 @@ do_add_gsg(GraphicsStateGuardian *gsg, GraphicsPipe *pipe, gsg->_pipe = pipe; 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 = get_window_renderer(threading_model.get_draw_name(), threading_model.get_draw_stage()); diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index b496408edf..d2bb82073e 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -166,7 +166,7 @@ get_threading_model() const { //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::prefers_triangle_strips -// Access: Published +// Access: Published, Virtual // Description: Returns true if this GSG strongly prefers triangle // strips to individual triangles (such as SGI), or // false if it prefers to minimize the number of @@ -180,7 +180,7 @@ prefers_triangle_strips() const { //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_max_vertices_per_array -// Access: Published +// Access: Published, Virtual // Description: Returns the maximum number of vertices that should be // put into any one GeomVertexData object for use with // this GSG. @@ -192,7 +192,7 @@ get_max_vertices_per_array() const { //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_max_vertices_per_primitive -// Access: Published +// Access: Published, Virtual // Description: Returns the maximum number of vertex indices that // should be put into any one GeomPrimitive object for // use with this GSG. @@ -648,35 +648,6 @@ get_coordinate_system() const { 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 // Access: Public diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 0eb133279d..670a896667 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -71,7 +71,6 @@ PStatCollector GraphicsStateGuardian::_clear_pcollector("Draw:Clear"); PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush"); PT(TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage = NULL; -GraphicsStateGuardian *GraphicsStateGuardian::_global_gsg = NULL; TypeHandle GraphicsStateGuardian::_type_handle; @@ -185,9 +184,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system, //////////////////////////////////////////////////////////////////// GraphicsStateGuardian:: ~GraphicsStateGuardian() { - if (_global_gsg == this) { - _global_gsg = NULL; - } + remove_gsg(this); if (_stencil_render_states) { delete _stencil_render_states; diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 028e93877b..1a8674a256 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -98,9 +98,9 @@ PUBLISHED: INLINE GraphicsEngine *get_engine() 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_dimension() const; @@ -149,9 +149,6 @@ PUBLISHED: INLINE CoordinateSystem get_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(); public: diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 60632b4af1..264079f3fc 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1167,6 +1167,10 @@ reset() { } #endif + + // Now that the GSG has been initialized, make it available for + // optimizations. + add_gsg(this); } diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.cxx b/panda/src/gsgbase/graphicsStateGuardianBase.cxx index cc130c4a6f..e48c9de35d 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.cxx +++ b/panda/src/gsgbase/graphicsStateGuardianBase.cxx @@ -17,5 +17,93 @@ //////////////////////////////////////////////////////////////////// #include "graphicsStateGuardianBase.h" +#include "mutexHolder.h" +GraphicsStateGuardianBase::GSGs GraphicsStateGuardianBase::_gsgs; +GraphicsStateGuardianBase *GraphicsStateGuardianBase::_default_gsg; 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; + } + } +} diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index 91b30f5f04..e915f2f28b 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -23,6 +23,7 @@ #include "typedWritableReferenceCount.h" #include "luse.h" +#include "pmutex.h" // A handful of forward references. @@ -111,6 +112,10 @@ class Lens; //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GraphicsStateGuardianBase : public TypedWritableReferenceCount { 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 int get_supported_geom_rendering() const=0; virtual bool get_supports_occlusion_query() const=0; @@ -203,11 +208,23 @@ public: int light_id) { } 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 GSGs; + static GSGs _gsgs; + static GraphicsStateGuardianBase *_default_gsg; + static Mutex _lock; + +public: static TypeHandle get_class_type() { return _type_handle; } - -public: static void init_type() { TypedWritableReferenceCount::init_type(); register_type(_type_handle, "GraphicsStateGuardianBase", diff --git a/panda/src/pgraph/geomTransformer.cxx b/panda/src/pgraph/geomTransformer.cxx index 9b960e961e..d57b40b715 100644 --- a/panda/src/pgraph/geomTransformer.cxx +++ b/panda/src/pgraph/geomTransformer.cxx @@ -30,6 +30,7 @@ #include "vector_int.h" #include "userVertexTransform.h" #include "geomMunger.h" +#include "config_pgraph.h" static PStatCollector apply_vertex_collector("*:Flatten:apply:vertex"); static PStatCollector apply_texcoord_collector("*:Flatten:apply:texcoord"); diff --git a/panda/src/pgraph/loader.cxx b/panda/src/pgraph/loader.cxx index 80eb0fa6bd..bdcdc1f349 100644 --- a/panda/src/pgraph/loader.cxx +++ b/panda/src/pgraph/loader.cxx @@ -29,6 +29,8 @@ #include "string_utils.h" #include "bamCache.h" #include "bamCacheRecord.h" +#include "sceneGraphReducer.h" +#include "renderState.h" bool Loader::_file_types_loaded = false; TypeHandle Loader::_type_handle; @@ -215,7 +217,10 @@ load_file(const Filename &filename, const LoaderOptions &options) const { loader_cat.info() << "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); } + SceneGraphReducer sgr; + sgr.premunge(result, RenderState::make_empty()); return result; } } diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 39b12e9a6d..8779255e63 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -5593,8 +5593,8 @@ premunge_scene(GraphicsStateGuardianBase *gsg) { state = get_parent().get_net_state(); } - SceneGraphReducer gr; - gr.premunge(node(), gsg, state); + SceneGraphReducer gr(gsg); + gr.premunge(node(), state); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 2b8269a08c..c999676036 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -793,7 +793,7 @@ PUBLISHED: // Miscellaneous 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 show_bounds(); diff --git a/panda/src/pgraph/sceneGraphReducer.I b/panda/src/pgraph/sceneGraphReducer.I index 4ca0c222c7..49782b6171 100644 --- a/panda/src/pgraph/sceneGraphReducer.I +++ b/panda/src/pgraph/sceneGraphReducer.I @@ -23,9 +23,10 @@ // Description: //////////////////////////////////////////////////////////////////// INLINE SceneGraphReducer:: -SceneGraphReducer() : +SceneGraphReducer(GraphicsStateGuardianBase *gsg) : _combine_radius(0.0f) { + set_gsg(gsg); } //////////////////////////////////////////////////////////////////// @@ -37,6 +38,19 @@ INLINE 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 // Access: Published @@ -145,34 +159,21 @@ make_nonindexed(PandaNode *root, int 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 // Access: Published // Description: Walks the scene graph rooted at this node and below, // and uses the indicated GSG to premunge every Geom // 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. //////////////////////////////////////////////////////////////////// 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); + } } diff --git a/panda/src/pgraph/sceneGraphReducer.cxx b/panda/src/pgraph/sceneGraphReducer.cxx index 07bd05d1c6..cf60eb2ca2 100644 --- a/panda/src/pgraph/sceneGraphReducer.cxx +++ b/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::_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 // Access: Published @@ -87,6 +127,25 @@ flatten(PandaNode *root, int combine_siblings_bits) { 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 // Access: Protected @@ -727,16 +786,16 @@ r_make_nonindexed(PandaNode *node, int nonindexed_bits) { // Description: The recursive implementation of unify(). //////////////////////////////////////////////////////////////////// void SceneGraphReducer:: -r_unify(PandaNode *node) { +r_unify(PandaNode *node, int max_indices) { if (node->is_geom_node()) { GeomNode *geom_node = DCAST(GeomNode, node); - geom_node->unify(max_collect_indices); + geom_node->unify(max_indices); } PandaNode::Children children = node->get_children(); int num_children = children.get_num_children(); 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(). //////////////////////////////////////////////////////////////////// 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()); if (node->is_geom_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; PandaNode::Children children = node->get_children(); int num_children = children.get_num_children(); 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(); int num_stashed = stashed.get_num_stashed(); for (i = 0; i < num_stashed; ++i) { - r_premunge(stashed.get_stashed(i), gsg, next_state); + r_premunge(stashed.get_stashed(i), next_state); } } diff --git a/panda/src/pgraph/sceneGraphReducer.h b/panda/src/pgraph/sceneGraphReducer.h index c776f4da8d..f2a5736017 100644 --- a/panda/src/pgraph/sceneGraphReducer.h +++ b/panda/src/pgraph/sceneGraphReducer.h @@ -29,6 +29,7 @@ #include "pStatTimer.h" #include "typedObject.h" #include "pointerTo.h" +#include "graphicsStateGuardianBase.h" class PandaNode; @@ -45,7 +46,7 @@ class PandaNode; //////////////////////////////////////////////////////////////////// class EXPCL_PANDA SceneGraphReducer { PUBLISHED: - INLINE SceneGraphReducer(); + INLINE SceneGraphReducer(GraphicsStateGuardianBase *gsg = NULL); INLINE ~SceneGraphReducer(); enum AttribTypes { @@ -121,6 +122,10 @@ PUBLISHED: 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 float get_combine_radius() const; @@ -132,10 +137,9 @@ PUBLISHED: INLINE int collect_vertex_data(PandaNode *root, int collect_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: void r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs, @@ -165,12 +169,12 @@ protected: int r_collect_vertex_data(PandaNode *node, int collect_bits, GeomTransformer &transformer); 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: + PT(GraphicsStateGuardianBase) _gsg; float _combine_radius; GeomTransformer _transformer;