diff --git a/panda/src/framework/framework.cxx b/panda/src/framework/framework.cxx index 171cd67782..d5999de0f6 100644 --- a/panda/src/framework/framework.cxx +++ b/panda/src/framework/framework.cxx @@ -1118,6 +1118,10 @@ int framework_main(int argc, char *argv[]) { // And start looping any animations we successfully bound. anim_controls.loop_all(true); + + // Now prepare all the textures with the GSG. + NodePath render_path(render); + render_path.prepare_scene(main_win->get_gsg()); } // Set up keyboard events. diff --git a/panda/src/sgmanip/nodePath.cxx b/panda/src/sgmanip/nodePath.cxx index 1e9b34d3d7..c28302a0c2 100644 --- a/panda/src/sgmanip/nodePath.cxx +++ b/panda/src/sgmanip/nodePath.cxx @@ -19,10 +19,34 @@ #include #include #include +#include +#include +#include +#include +#include #include #include +// This class is used in prepare_scene() to traverse the scene graph +// and register textures with the gsg. +class ScenePrepareVisitor : public TraverserVisitor { +public: + bool forward_arc(NodeRelation *, NodeTransitionWrapper &trans, + NodeAttributeWrapper &, NodeAttributeWrapper &, + NullLevelState &) { + TextureTransition *tt; + if (get_transition_into(tt, trans)) { + if (tt->is_on()) { + tt->get_texture()->prepare(_gsg); + } + } + return true; + } + + GraphicsStateGuardianBase *_gsg; +}; + //////////////////////////////////////////////////////////////////// // Function: NodePath::extend_by // Access: Public @@ -2166,6 +2190,33 @@ get_hidden_ancestor() const { return next.get_hidden_ancestor(); } +//////////////////////////////////////////////////////////////////// +// Function: NodePath::prepare_scene +// Access: Public +// Description: Walks through the scene graph beginning at the bottom +// node, and does whatever initialization is required to +// render the scene properly with the indicated GSG. It +// is not strictly necessary to call this, since the GSG +// will initialize itself when the scene is rendered, +// but this may take some of the overhead away from that +// process. +//////////////////////////////////////////////////////////////////// +void NodePath:: +prepare_scene(GraphicsStateGuardianBase *gsg) { + nassertv(!is_empty()); + + // Use the ScenePrepareVisitor and fire off a traversal of the scene + // beginning at the bottom node. The ScenePrepareVisitor (defined + // above) will call prepare() on each texture it finds in the scene + // graph at this point at below. + ScenePrepareVisitor visitor; + visitor._gsg = gsg; + + NodeAttributeWrapper initial(TextureTransition::get_class_type()); + df_traverse(node(), visitor, initial, NullLevelState(), + RenderRelation::get_class_type()); +} + //////////////////////////////////////////////////////////////////// // Function: NodePath::show_bounds // Access: Public diff --git a/panda/src/sgmanip/nodePath.h b/panda/src/sgmanip/nodePath.h index 3e171d9811..25c04ece81 100644 --- a/panda/src/sgmanip/nodePath.h +++ b/panda/src/sgmanip/nodePath.h @@ -24,6 +24,7 @@ class Texture; class Fog; class Camera; class AllTransitionsWrapper; +class GraphicsStateGuardianBase; // // A NodePath is the fundamental unit of high-level interaction with @@ -419,6 +420,8 @@ PUBLISHED: bool is_hidden() const; NodePath get_hidden_ancestor() const; + void prepare_scene(GraphicsStateGuardianBase *gsg); + void show_bounds(); void hide_bounds(); PT(BoundingVolume) get_bounds() const; @@ -457,6 +460,8 @@ private: const FindApproxLevel &level, int max_matches, int num_levels_remaining) const; + void r_prepare_scene(Node *node); + void r_list_descendants(ostream &out, int indent_level) const; void r_list_transitions(ostream &out, int indent_level) const;