Browse Source

step one of eliminated NodeAttributes for scene graph performance

David Rose 24 năm trước cách đây
mục cha
commit
b13172afd6
100 tập tin đã thay đổi với 1897 bổ sung1227 xóa
  1. 2 3
      panda/src/chan/auto_bind.cxx
  2. 3 3
      panda/src/collide/collisionTraverser.cxx
  3. 2 3
      panda/src/collide/collisionTraverser.h
  4. 4 18
      panda/src/cull/cullState.I
  5. 3 4
      panda/src/cull/cullState.h
  6. 6 6
      panda/src/cull/cullTraverser.I
  7. 13 17
      panda/src/cull/cullTraverser.cxx
  8. 7 9
      panda/src/cull/cullTraverser.h
  9. 2 2
      panda/src/cull/geomBinBackToFront.I
  10. 7 8
      panda/src/cull/geomBinBackToFront.cxx
  11. 2 2
      panda/src/cull/geomBinFixed.I
  12. 3 5
      panda/src/cull/geomBinFixed.cxx
  13. 1 1
      panda/src/cull/geomBinGroup.cxx
  14. 3 5
      panda/src/cull/geomBinNormal.cxx
  15. 11 0
      panda/src/cull/geomBinTransition.cxx
  16. 1 0
      panda/src/cull/geomBinTransition.h
  17. 1 1
      panda/src/cull/geomBinUnsorted.cxx
  18. 9 8
      panda/src/device/mouse.h
  19. 1 1
      panda/src/display/graphicsStateGuardian.I
  20. 240 36
      panda/src/display/graphicsStateGuardian.cxx
  21. 16 18
      panda/src/display/graphicsStateGuardian.h
  22. 246 283
      panda/src/dxgsg/dxGraphicsStateGuardian.cxx
  23. 26 31
      panda/src/dxgsg/dxGraphicsStateGuardian.h
  24. 13 15
      panda/src/effects/lensFlareNode.cxx
  25. 3 4
      panda/src/effects/lensFlareNode.h
  26. 1 1
      panda/src/egg2sg/deferredArcTraverser.cxx
  27. 1 2
      panda/src/egg2sg/deferredArcTraverser.h
  28. 1 1
      panda/src/egg2sg/eggLoader.cxx
  29. 246 256
      panda/src/framework/framework.cxx
  30. 199 236
      panda/src/glgsg/glGraphicsStateGuardian.cxx
  31. 28 31
      panda/src/glgsg/glGraphicsStateGuardian.h
  32. 12 0
      panda/src/graph/allTransitionsWrapper.I
  33. 2 0
      panda/src/graph/allTransitionsWrapper.h
  34. 9 9
      panda/src/graph/dftraverser.T
  35. 4 5
      panda/src/graph/dftraverser.h
  36. 2 6
      panda/src/graph/multiTransition.T
  37. 2 2
      panda/src/graph/multiTransition.h
  38. 1 1
      panda/src/graph/node.cxx
  39. 2 2
      panda/src/graph/node.h
  40. 3 3
      panda/src/graph/nodeRelation.cxx
  41. 2 2
      panda/src/graph/nodeRelation.h
  42. 27 2
      panda/src/graph/nodeTransition.cxx
  43. 8 2
      panda/src/graph/nodeTransition.h
  44. 10 0
      panda/src/graph/nodeTransitionWrapper.I
  45. 1 0
      panda/src/graph/nodeTransitionWrapper.h
  46. 51 0
      panda/src/graph/nodeTransitions.I
  47. 7 1
      panda/src/graph/nodeTransitions.h
  48. 5 5
      panda/src/graph/traverserVisitor.T
  49. 3 4
      panda/src/graph/traverserVisitor.h
  50. 56 9
      panda/src/gsgbase/graphicsStateGuardianBase.h
  51. 0 9
      panda/src/light/lightTransition.I
  52. 52 0
      panda/src/light/lightTransition.cxx
  53. 6 1
      panda/src/light/lightTransition.h
  54. 2 3
      panda/src/pgui/pgEntry.cxx
  55. 0 1
      panda/src/pgui/pgEntry.h
  56. 2 3
      panda/src/pgui/pgItem.cxx
  57. 0 2
      panda/src/pgui/pgItem.h
  58. 14 12
      panda/src/pgui/pgTop.cxx
  59. 4 4
      panda/src/pgui/pgTop.h
  60. 1 2
      panda/src/pgui/pgWaitBar.cxx
  61. 0 1
      panda/src/pgui/pgWaitBar.h
  62. 3 15
      panda/src/sgattrib/Sources.pp
  63. 26 1
      panda/src/sgattrib/alphaTransformTransition.cxx
  64. 3 0
      panda/src/sgattrib/alphaTransformTransition.h
  65. 16 16
      panda/src/sgattrib/attribTraverser.cxx
  66. 6 7
      panda/src/sgattrib/attribTraverser.h
  67. 14 6
      panda/src/sgattrib/billboardTransition.cxx
  68. 3 2
      panda/src/sgattrib/billboardTransition.h
  69. 26 2
      panda/src/sgattrib/clipPlaneTransition.cxx
  70. 3 0
      panda/src/sgattrib/clipPlaneTransition.h
  71. 24 0
      panda/src/sgattrib/colorBlendTransition.cxx
  72. 4 1
      panda/src/sgattrib/colorBlendTransition.h
  73. 53 12
      panda/src/sgattrib/colorMaskTransition.I
  74. 24 0
      panda/src/sgattrib/colorMaskTransition.cxx
  75. 9 1
      panda/src/sgattrib/colorMaskTransition.h
  76. 24 0
      panda/src/sgattrib/colorMatrixTransition.cxx
  77. 3 0
      panda/src/sgattrib/colorMatrixTransition.h
  78. 24 0
      panda/src/sgattrib/colorTransition.cxx
  79. 3 0
      panda/src/sgattrib/colorTransition.h
  80. 0 4
      panda/src/sgattrib/config_sgattrib.cxx
  81. 0 10
      panda/src/sgattrib/cullFaceTransition.I
  82. 24 0
      panda/src/sgattrib/cullFaceTransition.cxx
  83. 4 2
      panda/src/sgattrib/cullFaceTransition.h
  84. 11 0
      panda/src/sgattrib/decalTransition.cxx
  85. 1 0
      panda/src/sgattrib/decalTransition.h
  86. 0 10
      panda/src/sgattrib/depthTestTransition.I
  87. 24 0
      panda/src/sgattrib/depthTestTransition.cxx
  88. 4 2
      panda/src/sgattrib/depthTestTransition.h
  89. 24 0
      panda/src/sgattrib/depthWriteTransition.cxx
  90. 3 0
      panda/src/sgattrib/depthWriteTransition.h
  91. 30 29
      panda/src/sgattrib/drawBoundsTransition.cxx
  92. 6 5
      panda/src/sgattrib/drawBoundsTransition.h
  93. 24 0
      panda/src/sgattrib/fogTransition.cxx
  94. 3 0
      panda/src/sgattrib/fogTransition.h
  95. 24 0
      panda/src/sgattrib/linesmoothTransition.cxx
  96. 3 0
      panda/src/sgattrib/linesmoothTransition.h
  97. 24 0
      panda/src/sgattrib/materialTransition.cxx
  98. 3 0
      panda/src/sgattrib/materialTransition.h
  99. 24 0
      panda/src/sgattrib/pointShapeTransition.cxx
  100. 4 1
      panda/src/sgattrib/pointShapeTransition.h

+ 2 - 3
panda/src/chan/auto_bind.cxx

@@ -25,7 +25,6 @@
 #include <traverserVisitor.h>
 #include <dftraverser.h>
 #include <string_utils.h>
-#include <nullAttributeWrapper.h>
 #include <nullLevelState.h>
 #include <nullTransitionWrapper.h>
 #include "auto_bind.h"
@@ -46,7 +45,7 @@ typedef pmap<string, PartNodes> Parts;
 class CollectNodes :
   public TraverserVisitor<NullTransitionWrapper, NullLevelState> {
 public:
-  bool reached_node(Node *node, const NullAttributeWrapper &,
+  bool reached_node(Node *node, const NullTransitionWrapper &,
                     NullLevelState &) {
     if (node->is_of_type(AnimBundleNode::get_class_type())) {
       AnimBundleNode *bn = DCAST(AnimBundleNode, node);
@@ -139,7 +138,7 @@ void auto_bind(Node *root_node, AnimControlCollection &controls,
 
   // First, locate all the bundles in the subgraph.
   CollectNodes cn;
-  df_traverse(root_node, cn, NullAttributeWrapper(), NullLevelState(),
+  df_traverse(root_node, cn, NullTransitionWrapper(), NullLevelState(),
               RenderRelation::get_class_type());
 
   // Now, match up the bundles by name.

+ 3 - 3
panda/src/collide/collisionTraverser.cxx

@@ -254,7 +254,7 @@ traverse(const NodePath &root) {
     (*hi).first->begin_group();
   }
 
-  df_traverse(root.node(), *this, NullAttributeWrapper(),
+  df_traverse(root.node(), *this, NullTransitionWrapper(),
               level_state, _graph_type);
 
   for (hi = _handlers.begin(); hi != _handlers.end(); ++hi) {
@@ -347,7 +347,7 @@ prepare_colliders(CollisionLevelState &level_state) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 bool CollisionTraverser::
-reached_node(Node *node, NullAttributeWrapper &,
+reached_node(Node *node, NullTransitionWrapper &,
              CollisionLevelState &level_state) {
   if (node->is_of_type(CollisionNode::get_class_type())) {
     level_state.reached_collision_node();
@@ -435,7 +435,7 @@ reached_node(Node *node, NullAttributeWrapper &,
 ////////////////////////////////////////////////////////////////////
 bool CollisionTraverser::
 forward_arc(NodeRelation *arc, NullTransitionWrapper &,
-            NullAttributeWrapper &, NullAttributeWrapper &,
+            NullTransitionWrapper &, NullTransitionWrapper &,
             CollisionLevelState &level_state) {
   // Check the bounding volume on the arc against each of our
   // colliders.

+ 2 - 3
panda/src/collide/collisionTraverser.h

@@ -26,7 +26,6 @@
 
 #include <traverserVisitor.h>
 #include <nullTransitionWrapper.h>
-#include <nullAttributeWrapper.h>
 #include <pointerTo.h>
 #include <renderRelation.h>
 #include <pointerTo.h>
@@ -69,11 +68,11 @@ public:
   // These methods, from parent class TraverserVisitor, define the
   // behavior of the CollisionTraverser as it traverses the graph.
   // Normally you would never call these directly.
-  bool reached_node(Node *node, NullAttributeWrapper &render_state,
+  bool reached_node(Node *node, NullTransitionWrapper &render_state,
                     CollisionLevelState &level_state);
 
   bool forward_arc(NodeRelation *arc, NullTransitionWrapper &trans,
-                   NullAttributeWrapper &pre, NullAttributeWrapper &post,
+                   NullTransitionWrapper &pre, NullTransitionWrapper &post,
                    CollisionLevelState &level_state);
 
 private:

+ 4 - 18
panda/src/cull/cullState.I

@@ -25,7 +25,6 @@ INLINE CullState::
 CullState(const AllTransitionsWrapper &trans) :
   _trans(trans)
 {
-  _attrib = (NodeAttributes *)NULL;
   _bin = (GeomBin *)NULL;
   _empty_frames_count = 0;
 }
@@ -41,10 +40,6 @@ INLINE CullState::
   // If it is, something went screwy with the reference counts or with
   // the bin logic somewhere.
   nassertv(_bin == (GeomBin *)NULL);
-
-  if (_attrib != (NodeAttributes *)NULL) {
-    delete _attrib;
-  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -157,12 +152,8 @@ get_empty_frames_count() const {
 //               CullState and stored within the CullState object.
 ////////////////////////////////////////////////////////////////////
 INLINE void CullState::
-apply_to(const AllAttributesWrapper &initial_state) {
-  if (_attrib != (NodeAttributes *)NULL) {
-    delete _attrib;
-  }
-  _attrib = initial_state.apply(_trans);
-  nassertv(_attrib != NULL);
+apply_to(const AllTransitionsWrapper &initial_state) {
+  _attrib.compose_from(initial_state, _trans);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -172,14 +163,9 @@ apply_to(const AllAttributesWrapper &initial_state) {
 //               object, based on the CullState's net transitions set
 //               and the initial state set by apply_to().
 ////////////////////////////////////////////////////////////////////
-INLINE const NodeAttributes &CullState::
+INLINE const AllTransitionsWrapper &CullState::
 get_attributes() const {
-#ifndef NDEBUG
-  static NodeAttributes empty_attributes;
-#endif
-
-  nassertr(_attrib != NULL, empty_attributes);
-  return *_attrib;
+  return _attrib;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 3 - 4
panda/src/cull/cullState.h

@@ -25,7 +25,6 @@
 
 #include <geomNode.h>
 #include <allTransitionsWrapper.h>
-#include <allAttributesWrapper.h>
 #include <pointerTo.h>
 #include <pointerToArray.h>
 #include <updateSeq.h>
@@ -71,8 +70,8 @@ public:
   INLINE int count_current_nodes() const;
   INLINE int get_empty_frames_count() const;
 
-  INLINE void apply_to(const AllAttributesWrapper &initial_state);
-  INLINE const NodeAttributes &get_attributes() const;
+  INLINE void apply_to(const AllTransitionsWrapper &initial_state);
+  INLINE const AllTransitionsWrapper &get_attributes() const;
   INLINE const AllTransitionsWrapper &get_transitions() const;
 
   INLINE bool has_bin() const;
@@ -105,7 +104,7 @@ public:
 
 private:
   AllTransitionsWrapper _trans;
-  NodeAttributes *_attrib;
+  AllTransitionsWrapper _attrib;
 
   typedef pmap<Node *, UpdateSeq> Verified;
   Verified _verified;

+ 6 - 6
panda/src/cull/cullTraverser.I

@@ -31,13 +31,13 @@
 //               hierarchy below it immediately.
 ////////////////////////////////////////////////////////////////////
 INLINE void CullTraverser::
-draw_geom(GeomNode *geom_node, const AllAttributesWrapper &initial_state) {
+draw_geom(GeomNode *geom_node, const AllTransitionsWrapper &initial_state) {
   if (cull_cat.is_spam()) {
     cull_cat.spam()
       << "Drawing " << *geom_node << " with state: " << initial_state << "\n";
   }
   nassertv(geom_node != (GeomNode *)NULL);
-  _gsg->set_state(initial_state.get_attributes(), true);
+  _gsg->set_state(initial_state.get_transitions(), true);
   _gsg->prepare_display_region();
   geom_node->draw(_gsg);
 }
@@ -51,7 +51,7 @@ draw_geom(GeomNode *geom_node, const AllAttributesWrapper &initial_state) {
 //               hierarchy below it immediately.
 ////////////////////////////////////////////////////////////////////
 INLINE void CullTraverser::
-draw_geom(const ArcChain &arc_chain, const AllAttributesWrapper &initial_state) {
+draw_geom(const ArcChain &arc_chain, const AllTransitionsWrapper &initial_state) {
   nassertv(!arc_chain.empty());
   GeomNode *geom_node;
   DCAST_INTO_V(geom_node, arc_chain.back()->get_child());
@@ -66,7 +66,7 @@ draw_geom(const ArcChain &arc_chain, const AllAttributesWrapper &initial_state)
 ////////////////////////////////////////////////////////////////////
 INLINE void CullTraverser::
 draw_direct(const ArcChain &arc_chain,
-            const AllAttributesWrapper &initial_state) {
+            const AllTransitionsWrapper &initial_state) {
   nassertv(!arc_chain.empty());
   Node *node = arc_chain.back()->get_child();
   if (cull_cat.is_spam()) {
@@ -75,7 +75,7 @@ draw_direct(const ArcChain &arc_chain,
   }
   nassertv(node != (Node *)NULL);
   DirectRenderTraverser drt(_gsg, _graph_type, arc_chain);
-  drt.traverse(node, initial_state, AllTransitionsWrapper());
+  drt.traverse(node, initial_state);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -145,7 +145,7 @@ find_bin_state(const AllTransitionsWrapper &trans) {
 ////////////////////////////////////////////////////////////////////
 INLINE void CullTraverser::
 backward_arc(NodeRelation *arc, NullTransitionWrapper &,
-             NullAttributeWrapper &, NullAttributeWrapper &,
+             NullTransitionWrapper &, NullTransitionWrapper &,
              const CullLevelState &) {
   mark_backward_arc(arc);
 }

+ 13 - 17
panda/src/cull/cullTraverser.cxx

@@ -163,7 +163,7 @@ clear_state() {
   }
   _default_bin->clear_current_states();
 
-  _initial_state = AllAttributesWrapper();
+  _initial_state = AllTransitionsWrapper();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -224,8 +224,7 @@ write(ostream &out, int indent_level) const {
 ////////////////////////////////////////////////////////////////////
 void CullTraverser::
 traverse(Node *root,
-         const AllAttributesWrapper &initial_state,
-         const AllTransitionsWrapper &net_trans) {
+         const AllTransitionsWrapper &initial_state) {
   // Statistics
   PStatTimer timer(_cull_pcollector);
 
@@ -247,7 +246,7 @@ traverse(Node *root,
   _nested_count++;
 
   if (is_initial) {
-    _initial_state.apply_from(initial_state, net_trans);
+    _initial_state = initial_state;
 
     States::iterator si;
     for (si = _states.begin(); si != _states.end(); ++si) {
@@ -276,7 +275,7 @@ traverse(Node *root,
   }
 
   fc_traverse(_arc_chain, root, rel_from_camera, *this,
-              NullAttributeWrapper(), level_state, _gsg, _graph_type);
+              NullTransitionWrapper(), level_state, _gsg, _graph_type);
 
   if (is_initial) {
     draw();
@@ -407,9 +406,8 @@ draw() {
       int draw_order = 0;
 
       // Check the requested bin for the Geoms in this state.
-      const GeomBinAttribute *bin_attrib;
-      if (get_attribute_into(bin_attrib, cs->get_attributes(),
-                             GeomBinTransition::get_class_type())) {
+      const GeomBinTransition *bin_attrib;
+      if (get_transition_into(bin_attrib, cs->get_attributes())) {
         draw_order = bin_attrib->get_draw_order();
         bin_name = bin_attrib->get_bin();
         requested_bin = get_bin(bin_name);
@@ -573,7 +571,7 @@ add_direct_node(Node *node, const AllTransitionsWrapper &trans,
 ////////////////////////////////////////////////////////////////////
 bool CullTraverser::
 forward_arc(NodeRelation *arc, NullTransitionWrapper &,
-            NullAttributeWrapper &, NullAttributeWrapper &,
+            NullTransitionWrapper &, NullTransitionWrapper &,
             CullLevelState &level_state) {
   nassertr(level_state._lookup != (CullStateLookup *)NULL, false);
 
@@ -689,18 +687,16 @@ forward_arc(NodeRelation *arc, NullTransitionWrapper &,
     if (_gsg != (GraphicsStateGuardian *)NULL) {
       AllTransitionsWrapper complete_trans;
       level_state._lookup->compose_trans(trans, complete_trans);
-      AllAttributesWrapper attrib;
-      attrib.apply_from(_initial_state, complete_trans);
+      AllTransitionsWrapper attrib;
+      attrib.compose_from(_initial_state, complete_trans);
 
-      AllTransitionsWrapper new_trans;
-
-      if (!arc->sub_render_trans(attrib, new_trans, this) ||
-          !node->sub_render(attrib, new_trans, this)) {
+      AllTransitionsWrapper modify_trans;
+      if (!arc->sub_render_trans(attrib, modify_trans, this) ||
+          !node->sub_render(attrib, modify_trans, this)) {
         mark_backward_arc(arc);
         return false;
       }
-
-      trans.compose_in_place(new_trans);
+      trans.compose_in_place(modify_trans);
     }
   }
 

+ 7 - 9
panda/src/cull/cullTraverser.h

@@ -28,7 +28,6 @@
 #include <renderTraverser.h>
 #include <traverserVisitor.h>
 #include <nullTransitionWrapper.h>
-#include <nullAttributeWrapper.h>
 #include <pStatCollector.h>
 
 #include "plist.h"
@@ -67,15 +66,14 @@ PUBLISHED:
 public:
 
   virtual void traverse(Node *root,
-                        const AllAttributesWrapper &initial_state,
-                        const AllTransitionsWrapper &net_trans);
+                        const AllTransitionsWrapper &initial_state);
 
   INLINE void draw_geom(GeomNode *geom_node,
-                        const AllAttributesWrapper &initial_state);
+                        const AllTransitionsWrapper &initial_state);
   INLINE void draw_geom(const ArcChain &arc_chain,
-                        const AllAttributesWrapper &initial_state);
+                        const AllTransitionsWrapper &initial_state);
   INLINE void draw_direct(const ArcChain &arc_chain,
-                          const AllAttributesWrapper &initial_state);
+                          const AllTransitionsWrapper &initial_state);
 
 private:
   void setup_initial_bins();
@@ -103,12 +101,12 @@ public:
   // behavior of the RenderTraverser as it traverses the graph.
   // Normally you would never call these directly.
   bool forward_arc(NodeRelation *arc, NullTransitionWrapper &trans,
-                   NullAttributeWrapper &pre, NullAttributeWrapper &post,
+                   NullTransitionWrapper &pre, NullTransitionWrapper &post,
                    CullLevelState &level_state);
 
   INLINE void
   backward_arc(NodeRelation *arc, NullTransitionWrapper &trans,
-               NullAttributeWrapper &pre, NullAttributeWrapper &post,
+               NullTransitionWrapper &pre, NullTransitionWrapper &post,
                const CullLevelState &level_state);
 
 private:
@@ -117,7 +115,7 @@ private:
   void detach_toplevel_bin(GeomBin *bin);
   void detach_sub_bin(GeomBin *bin);
 
-  AllAttributesWrapper _initial_state;
+  AllTransitionsWrapper _initial_state;
 
   typedef pmap<string,  PT(GeomBin) > ToplevelBins;
   typedef pmultimap<int,  PT(GeomBin) > SubBins;

+ 2 - 2
panda/src/cull/geomBinBackToFront.I

@@ -78,9 +78,9 @@ INLINE void GeomBinBackToFront::NodeEntry::
 draw(CullTraverser *trav) const {
   nassertv(!_arc_chain.empty());
   if (_is_direct) {
-    trav->draw_direct(_arc_chain, AllAttributesWrapper(_state->get_attributes()));
+    trav->draw_direct(_arc_chain, _state->get_attributes());
   } else {
-    trav->draw_geom(_arc_chain, AllAttributesWrapper(_state->get_attributes()));
+    trav->draw_geom(_arc_chain, _state->get_attributes());
   }
 }
 

+ 7 - 8
panda/src/cull/geomBinBackToFront.cxx

@@ -20,10 +20,9 @@
 #include "geomBinBackToFront.h"
 #include "cullTraverser.h"
 
-#include <nodeAttributes.h>
+#include <nodeTransitions.h>
 #include <graphicsStateGuardian.h>
 #include <transformTransition.h>
-#include <transformAttribute.h>
 #include <geometricBoundingVolume.h>
 #include <pStatTimer.h>
 
@@ -55,9 +54,8 @@ record_current_state(GraphicsStateGuardian *gsg, CullState *cs, int,
   PStatTimer timer(CullTraverser::_cull_bins_btf_pcollector);
 
   // Get the transform matrix from the state.
-  TransformAttribute *trans_attrib = NULL;
-  get_attribute_into(trans_attrib, cs->get_attributes(),
-                     TransformTransition::get_class_type());
+  TransformTransition *trans_attrib = NULL;
+  get_transition_into(trans_attrib, cs->get_attributes());
 
   CullState::geom_const_iterator gi;
   for (gi = cs->geom_begin(); gi != cs->geom_end(); ++gi) {
@@ -74,11 +72,12 @@ record_current_state(GraphicsStateGuardian *gsg, CullState *cs, int,
       DCAST_INTO_V(gbv, &volume);
 
       LPoint3f center = gbv->get_approx_center();
-      if (trans_attrib != (TransformAttribute *)NULL) {
+      if (trans_attrib != (TransformTransition *)NULL) {
         center = center * trans_attrib->get_matrix();
       }
 
       float distance = gsg->compute_distance_to(center);
+
       _node_entries.insert(NodeEntry(distance, cs, arc_chain, false));
     }
   }
@@ -100,7 +99,7 @@ record_current_state(GraphicsStateGuardian *gsg, CullState *cs, int,
       DCAST_INTO_V(gbv, &volume);
 
       LPoint3f center = gbv->get_approx_center();
-      if (trans_attrib != (TransformAttribute *)NULL) {
+      if (trans_attrib != (TransformTransition *)NULL) {
         center = center * trans_attrib->get_matrix();
       }
 
@@ -132,7 +131,7 @@ record_current_state(GraphicsStateGuardian *gsg, CullState *cs, int,
 
       if (num_points > 0) {
         avg /= (float)num_points;
-        if (trans_attrib != (TransformAttribute *)NULL) {
+        if (trans_attrib != (TransformTransition *)NULL) {
           avg = avg * trans_attrib->get_matrix();
         }
         distance = gsg->compute_distance_to(avg);

+ 2 - 2
panda/src/cull/geomBinFixed.I

@@ -79,9 +79,9 @@ INLINE void GeomBinFixed::NodeEntry::
 draw(CullTraverser *trav) const {
   nassertv(!_arc_chain.empty());
   if (_is_direct) {
-    trav->draw_direct(_arc_chain, AllAttributesWrapper(_state->get_attributes()));
+    trav->draw_direct(_arc_chain, _state->get_attributes());
   } else {
-    trav->draw_geom(_arc_chain, AllAttributesWrapper(_state->get_attributes()));
+    trav->draw_geom(_arc_chain, _state->get_attributes());
   }
 }
 

+ 3 - 5
panda/src/cull/geomBinFixed.cxx

@@ -20,10 +20,9 @@
 #include "geomBinFixed.h"
 #include "cullTraverser.h"
 
-#include <nodeAttributes.h>
+#include <nodeTransitions.h>
 #include <graphicsStateGuardian.h>
 #include <transformTransition.h>
-#include <transformAttribute.h>
 #include <geometricBoundingVolume.h>
 #include <pStatTimer.h>
 
@@ -57,9 +56,8 @@ record_current_state(GraphicsStateGuardian *, CullState *cs,
   PStatTimer timer(CullTraverser::_cull_bins_fixed_pcollector);
 
   // Get the transform matrix from the state.
-  TransformAttribute *trans_attrib = NULL;
-  get_attribute_into(trans_attrib, cs->get_attributes(),
-                     TransformTransition::get_class_type());
+  TransformTransition *trans_attrib = NULL;
+  get_transition_into(trans_attrib, cs->get_attributes());
 
   CullState::geom_const_iterator gi;
   for (gi = cs->geom_begin(); gi != cs->geom_end(); ++gi) {

+ 1 - 1
panda/src/cull/geomBinGroup.cxx

@@ -137,7 +137,7 @@ clear_current_states() {
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomBinUnsorted::record_current_state
 //       Access: Public, Virtual
-//  Description: Called each frame by the CullTraverser to indicated
+//  Description: Called each frame by the CullTraverser to indicate
 //               that the given CullState (and all of its current
 //               GeomNodes) is visible this frame.
 ////////////////////////////////////////////////////////////////////

+ 3 - 5
panda/src/cull/geomBinNormal.cxx

@@ -21,10 +21,9 @@
 #include "geomBinUnsorted.h"
 #include "geomBinBackToFront.h"
 
-#include <nodeAttributes.h>
+#include <nodeTransitions.h>
 
 #include <transparencyTransition.h>
-#include <transparencyAttribute.h>
 
 TypeHandle GeomBinNormal::_type_handle;
 
@@ -56,9 +55,8 @@ int GeomBinNormal::
 choose_bin(CullState *cs) const {
   bool is_transparent = false;
 
-  TransparencyAttribute *trans_attrib;
-  if (get_attribute_into(trans_attrib, cs->get_attributes(),
-                         TransparencyTransition::get_class_type())) {
+  TransparencyTransition *trans_attrib;
+  if (get_transition_into(trans_attrib, cs->get_attributes())) {
     is_transparent =
       (trans_attrib->get_mode() != TransparencyProperty::M_none);
   }

+ 11 - 0
panda/src/cull/geomBinTransition.cxx

@@ -45,6 +45,17 @@ make_attrib() const {
   return new GeomBinAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomBinTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated GeomBinTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *GeomBinTransition::
+make_initial() const {
+  return new GeomBinTransition;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomBinTransition::set_value_from
 //       Access: Protected, Virtual

+ 1 - 0
panda/src/cull/geomBinTransition.h

@@ -41,6 +41,7 @@ PUBLISHED:
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
 
 protected:
   virtual void set_value_from(const OnOffTransition *other);

+ 1 - 1
panda/src/cull/geomBinUnsorted.cxx

@@ -100,7 +100,7 @@ draw(CullTraverser *trav) {
     }
 
     if (cs->geom_size() != 0) {
-      gsg->set_state(cs->get_attributes(), true);
+      gsg->set_state(cs->get_attributes().get_transitions(), true);
       gsg->prepare_display_region();
 
       CullState::geom_iterator gi;

+ 9 - 8
panda/src/device/mouse.h

@@ -21,15 +21,16 @@
 ////////////////////////////////////////////////////////////////////
 // Includes
 ////////////////////////////////////////////////////////////////////
-#include <pandabase.h>
+#include "pandabase.h"
 
-#include <dataNode.h>
-#include <vec3DataTransition.h>
-#include <vec3DataAttribute.h>
-#include <buttonEventDataTransition.h>
-#include <buttonEventDataAttribute.h>
-#include <graphicsWindow.h>
-#include <pointerTo.h>
+#include "dataNode.h"
+#include "vec3DataTransition.h"
+#include "vec3DataAttribute.h"
+#include "buttonEventDataTransition.h"
+#include "buttonEventDataAttribute.h"
+#include "graphicsWindow.h"
+#include "pointerTo.h"
+#include "nodeAttributes.h"
 
 ////////////////////////////////////////////////////////////////////
 // Defines

+ 1 - 1
panda/src/display/graphicsStateGuardian.I

@@ -62,7 +62,7 @@ is_closed() const {
 //               should be used with caution, as it could grow to be
 //               expensive.
 ////////////////////////////////////////////////////////////////////
-INLINE const NodeAttributes &GraphicsStateGuardian::
+INLINE const NodeTransitions &GraphicsStateGuardian::
 get_state() const {
   return _state;
 }

+ 240 - 36
panda/src/display/graphicsStateGuardian.cxx

@@ -145,7 +145,7 @@ reset() {
 //               that absent attributes should remain unchanged.
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
-set_state(const NodeAttributes &new_state, bool complete) {
+set_state(const NodeTransitions &new_state, bool complete) {
   PStatTimer timer(_set_state_pcollector);
 
   if (gsg_cat.is_debug()) {
@@ -156,24 +156,29 @@ set_state(const NodeAttributes &new_state, bool complete) {
     new_state.write(gsg_cat.debug(false), 10);
   }
 
-  NodeAttributes::const_iterator new_i;
-  NodeAttributes::iterator current_i;
+  NodeTransitions::const_iterator new_i;
+  NodeTransitions::iterator current_i;
 
   new_i = new_state.begin();
   current_i = _state.begin();
 
   while (new_i != new_state.end() && current_i != _state.end()) {
-    if ((*new_i).first < (*current_i).first) {
+    TypeHandle new_type = (*new_i).first;
+    NodeTransition *new_trans = (*new_i).second;
+    TypeHandle current_type = (*current_i).first;
+    PT(NodeTransition) &current_trans = (*current_i).second;
+
+    if (new_type < current_type) {
       // The user requested setting an attribute that we've never set
       // before.  Issue the command.
 
-      if ((*new_i).second != (NodeAttribute *)NULL) {
+      if (new_trans != (NodeTransition *)NULL) {
         if (gsg_cat.is_debug()) {
           gsg_cat.debug()
-            << "Issuing new attrib " << *(*new_i).second << "\n";
+            << "Issuing new attrib " << *new_trans << "\n";
         }
-        record_state_change((*new_i).first);
-        (*new_i).second->issue(this);
+        record_state_change(new_type);
+        new_trans->issue(this);
 
         // And store the new value.
         current_i = _state.insert(current_i, *new_i);
@@ -182,7 +187,7 @@ set_state(const NodeAttributes &new_state, bool complete) {
 
       ++new_i;
 
-    } else if ((*current_i).first < (*new_i).first) {
+    } else if (current_type < new_type) {
       // Here's an attribute that we've set previously, but the user
       // didn't specify this time.
 
@@ -192,15 +197,15 @@ set_state(const NodeAttributes &new_state, bool complete) {
 
         if (gsg_cat.is_debug()) {
           gsg_cat.debug()
-            << "Unissuing attrib " << *(*current_i).second
+            << "Unissuing attrib " << *current_trans
             << " (previously set, not now)\n";
         }
-        record_state_change((*current_i).first);
+        record_state_change(current_type);
 
-        PT(NodeAttribute) initial = (*current_i).second->make_initial();
+        PT(NodeTransition) initial = current_trans->make_initial();
         initial->issue(this);
 
-        NodeAttributes::iterator erase_i = current_i;
+        NodeTransitions::iterator erase_i = current_i;
         ++current_i;
 
         _state.erase(erase_i);
@@ -209,9 +214,9 @@ set_state(const NodeAttributes &new_state, bool complete) {
         ++current_i;
       }
 
-    } else {  // (*current_i).first == (*new_i).first)
+    } else {  // current_type == new_type)
 
-      if ((*new_i).second == (NodeAttribute *)NULL) {
+      if (new_trans == (NodeTransition *)NULL) {
         // Here's an attribute that we've set previously, which
         // appears in the new list, but is NULL indicating it should
         // be removed.
@@ -221,16 +226,16 @@ set_state(const NodeAttributes &new_state, bool complete) {
 
           if (gsg_cat.is_debug()) {
             gsg_cat.debug()
-              << "Unissuing attrib " << *(*current_i).second
+              << "Unissuing attrib " << *current_trans
               << " (previously set, now NULL)\n";
           }
-          record_state_change((*current_i).first);
+          record_state_change(current_type);
 
           // Issue the initial attribute before clearing the state.
-          PT(NodeAttribute) initial = (*current_i).second->make_initial();
+          PT(NodeTransition) initial = current_trans->make_initial();
           initial->issue(this);
 
-          NodeAttributes::iterator erase_i = current_i;
+          NodeTransitions::iterator erase_i = current_i;
           ++current_i;
 
           _state.erase(erase_i);
@@ -244,20 +249,22 @@ set_state(const NodeAttributes &new_state, bool complete) {
         // Here's an attribute that we've set previously, and the user
         // asked us to set it again.  Issue the command only if the new
         // attribute is different from that which we'd set before.
-        if ((*new_i).second->compare_to(*(*current_i).second) != 0) {
+        if (new_trans->compare_to(*current_trans) != 0) {
           if (gsg_cat.is_debug()) {
             gsg_cat.debug()
-              << "Reissuing attrib " << *(*new_i).second << "\n";
+              << "Reissuing attrib " << *new_trans << "\n";
+            gsg_cat.debug()
+              << "Previous was " << *current_trans << "\n";
           }
-          record_state_change((*new_i).first);
-          (*new_i).second->issue(this);
+          record_state_change(new_type);
+          new_trans->issue(this);
 
           // And store the new value.
-          (*current_i).second = (*new_i).second;
+          current_trans = new_trans;
 
         } else if (gsg_cat.is_debug()) {
           gsg_cat.debug()
-            << "Not reissuing unchanged attrib " << *(*new_i).second << "\n";
+            << "Not reissuing unchanged attrib " << *new_trans << "\n";
         }
 
         ++current_i;
@@ -269,15 +276,17 @@ set_state(const NodeAttributes &new_state, bool complete) {
   while (new_i != new_state.end()) {
     // The user requested setting an attribute that we've never set
     // before.  Issue the command.
+    TypeHandle new_type = (*new_i).first;
+    NodeTransition *new_trans = (*new_i).second;
 
-    if ((*new_i).second != (NodeAttribute *)NULL) {
+    if (new_trans != (NodeTransition *)NULL) {
       if (gsg_cat.is_debug()) {
         gsg_cat.debug()
-          << "Issuing new attrib " << *(*new_i).second << "\n";
+          << "Issuing new attrib " << *new_trans << "\n";
       }
-      record_state_change((*new_i).first);
+      record_state_change(new_type);
 
-      (*new_i).second->issue(this);
+      new_trans->issue(this);
 
       // And store the new value.
       _state.insert(_state.end(), *new_i);
@@ -289,20 +298,22 @@ set_state(const NodeAttributes &new_state, bool complete) {
     while (current_i != _state.end()) {
       // Here's an attribute that we've set previously, but the user
       // didn't specify this time.
+      TypeHandle current_type = (*current_i).first;
+      PT(NodeTransition) &current_trans = (*current_i).second;
 
       if (gsg_cat.is_debug()) {
         gsg_cat.debug()
-          << "Unissuing attrib " << *(*current_i).second
+          << "Unissuing attrib " << *current_trans
           << " (previously set, end of list)\n";
       }
-      record_state_change((*current_i).first);
+      record_state_change(current_type);
 
       // If we're in the "complete state" model, that means this
       // attribute should now get the default initial value.
-      PT(NodeAttribute) initial = (*current_i).second->make_initial();
+      PT(NodeTransition) initial = current_trans->make_initial();
       initial->issue(this);
 
-      NodeAttributes::iterator erase_i = current_i;
+      NodeTransitions::iterator erase_i = current_i;
       ++current_i;
 
       _state.erase(erase_i);
@@ -310,6 +321,199 @@ set_state(const NodeAttributes &new_state, bool complete) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::set_state
+//       Access: Public
+//  Description: Sets the graphics backend to the state represented by
+//               the indicated set of attributes.  Only the minimal
+//               number of graphics commands are issued--attributes
+//               which have not changed since the last call to
+//               set_state are detected and not issued again.
+//
+//               If complete is true, it means that the supplied state
+//               is a complete description of the desired state--if an
+//               attribute is absent, it should be taken to be the
+//               same as the initial value for that attribute.  If
+//               complete is false, it means that the supplied state
+//               specifies only a subset of the desired state, and
+//               that absent attributes should remain unchanged.
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardian::
+set_state(const NodeTransitionCache &new_state, bool complete) {
+  PStatTimer timer(_set_state_pcollector);
+
+  if (gsg_cat.is_debug()) {
+    gsg_cat.debug() << "\n";
+    gsg_cat.debug()
+      << "Frame " << ClockObject::get_global_clock()->get_frame_count()
+      << ", setting to (complete = " << complete << ")\n";
+    new_state.write(gsg_cat.debug(false), 10);
+  }
+
+  NodeTransitionCache::const_iterator new_i;
+  NodeTransitions::iterator current_i;
+
+  new_i = new_state.begin();
+  current_i = _state.begin();
+
+  while (new_i != new_state.end() && current_i != _state.end()) {
+    TypeHandle new_type = (*new_i).first;
+    NodeTransition *new_trans = (*new_i).second.get_trans();
+    TypeHandle current_type = (*current_i).first;
+    PT(NodeTransition) &current_trans = (*current_i).second;
+
+    if (new_type < current_type) {
+      // The user requested setting an attribute that we've never set
+      // before.  Issue the command.
+
+      if (new_trans != (NodeTransition *)NULL) {
+        if (gsg_cat.is_debug()) {
+          gsg_cat.debug()
+            << "Issuing new attrib " << *new_trans << "\n";
+        }
+        record_state_change(new_type);
+        new_trans->issue(this);
+
+        // And store the new value.
+        current_i = _state.insert(current_i, *new_i);
+        ++current_i;
+      }
+
+      ++new_i;
+
+    } else if (current_type < new_type) {
+      // Here's an attribute that we've set previously, but the user
+      // didn't specify this time.
+
+      if (complete) {
+        // If we're in the "complete state" model, that means this
+        // attribute should now get the default initial value.
+
+        if (gsg_cat.is_debug()) {
+          gsg_cat.debug()
+            << "Unissuing attrib " << *current_trans
+            << " (previously set, not now)\n";
+        }
+        record_state_change(current_type);
+
+        PT(NodeTransition) initial = current_trans->make_initial();
+        initial->issue(this);
+
+        NodeTransitions::iterator erase_i = current_i;
+        ++current_i;
+
+        _state.erase(erase_i);
+
+      } else {
+        ++current_i;
+      }
+
+    } else {  // current_type == new_type)
+
+      if (new_trans == (NodeTransition *)NULL) {
+        // Here's an attribute that we've set previously, which
+        // appears in the new list, but is NULL indicating it should
+        // be removed.
+
+        if (complete) {
+          // Only remove it if we're in the "complete state" model.
+
+          if (gsg_cat.is_debug()) {
+            gsg_cat.debug()
+              << "Unissuing attrib " << *current_trans
+              << " (previously set, now NULL)\n";
+          }
+          record_state_change(current_type);
+
+          // Issue the initial attribute before clearing the state.
+          PT(NodeTransition) initial = current_trans->make_initial();
+          initial->issue(this);
+
+          NodeTransitions::iterator erase_i = current_i;
+          ++current_i;
+
+          _state.erase(erase_i);
+
+        } else {
+          ++current_i;
+        }
+        ++new_i;
+
+      } else {
+        // Here's an attribute that we've set previously, and the user
+        // asked us to set it again.  Issue the command only if the new
+        // attribute is different from that which we'd set before.
+        if (new_trans->compare_to(*current_trans) != 0) {
+          if (gsg_cat.is_debug()) {
+            gsg_cat.debug()
+              << "Reissuing attrib " << *new_trans << "\n";
+            gsg_cat.debug()
+              << "Previous was " << *current_trans << "\n";
+          }
+          record_state_change(new_type);
+          new_trans->issue(this);
+
+          // And store the new value.
+          current_trans = new_trans;
+
+        } else if (gsg_cat.is_debug()) {
+          gsg_cat.debug()
+            << "Not reissuing unchanged attrib " << *new_trans << "\n";
+        }
+
+        ++current_i;
+        ++new_i;
+      }
+    }
+  }
+
+  while (new_i != new_state.end()) {
+    // The user requested setting an attribute that we've never set
+    // before.  Issue the command.
+    TypeHandle new_type = (*new_i).first;
+    NodeTransition *new_trans = (*new_i).second.get_trans();
+
+    if (new_trans != (NodeTransition *)NULL) {
+      if (gsg_cat.is_debug()) {
+        gsg_cat.debug()
+          << "Issuing new attrib " << *new_trans << "\n";
+      }
+      record_state_change(new_type);
+
+      new_trans->issue(this);
+
+      // And store the new value.
+      _state.insert(_state.end(), *new_i);
+    }
+    ++new_i;
+  }
+
+  if (complete) {
+    while (current_i != _state.end()) {
+      // Here's an attribute that we've set previously, but the user
+      // didn't specify this time.
+      TypeHandle current_type = (*current_i).first;
+      PT(NodeTransition) &current_trans = (*current_i).second;
+
+      if (gsg_cat.is_debug()) {
+        gsg_cat.debug()
+          << "Unissuing attrib " << *current_trans
+          << " (previously set, end of list)\n";
+      }
+      record_state_change(current_type);
+
+      // If we're in the "complete state" model, that means this
+      // attribute should now get the default initial value.
+      PT(NodeTransition) initial = current_trans->make_initial();
+      initial->issue(this);
+
+      NodeTransitions::iterator erase_i = current_i;
+      ++current_i;
+
+      _state.erase(erase_i);
+    }
+  }
+}
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_render_buffer
@@ -454,10 +658,10 @@ release_all_geoms() {
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
 clear_attribute(TypeHandle type) {
-  NodeAttributes::iterator ai = _state.find(type);
+  NodeTransitions::iterator ai = _state.find(type);
   if (ai != _state.end()) {
     // The state is already set; get the initial value and reset it.
-    PT(NodeAttribute) initial = (*ai).second->make_initial();
+    PT(NodeTransition) initial = (*ai).second->make_initial();
     initial->issue(this);
 
     // Now remove the state entry from the set.
@@ -610,7 +814,7 @@ wants_colors() const {
 //               necessary to render the decals properly.
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
-begin_decal(GeomNode *base_geom, AllAttributesWrapper &attrib) {
+begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib) {
   base_geom->draw(this);
 }
 

+ 16 - 18
panda/src/display/graphicsStateGuardian.h

@@ -19,23 +19,23 @@
 #ifndef GRAPHICSSTATEGUARDIAN_H
 #define GRAPHICSSTATEGUARDIAN_H
 
-#include <pandabase.h>
+#include "pandabase.h"
 
 #include "savedFrameBuffer.h"
 #include "frameBufferStack.h"
 #include "displayRegionStack.h"
 
-#include <graphicsStateGuardianBase.h>
-#include <nodeTransition.h>
-#include <luse.h>
-#include <coordinateSystem.h>
-#include <factory.h>
-#include <renderTraverser.h>
-#include <pStatCollector.h>
+#include "graphicsStateGuardianBase.h"
+#include "nodeTransition.h"
+#include "nodeTransitionCache.h"
+#include "luse.h"
+#include "coordinateSystem.h"
+#include "factory.h"
+#include "renderTraverser.h"
+#include "pStatCollector.h"
 
 #include "plist.h"
 
-class AllAttributesWrapper;
 class AllTransitionsWrapper;
 
 ////////////////////////////////////////////////////////////////////
@@ -102,16 +102,13 @@ public:
 
   virtual void prepare_display_region()=0;
 
-  virtual void render_frame(const AllAttributesWrapper &initial_state)=0;
-  virtual void render_scene(Node *root, ProjectionNode *projnode,
-                            const AllAttributesWrapper &initial_state)=0;
+  virtual void render_frame()=0;
+  virtual void render_scene(Node *root, ProjectionNode *projnode)=0;
   virtual void render_subgraph(RenderTraverser *traverser,
                                Node *subgraph, ProjectionNode *projnode,
-                               const AllAttributesWrapper &initial_state,
                                const AllTransitionsWrapper &net_trans)=0;
   virtual void render_subgraph(RenderTraverser *traverser,
                                Node *subgraph,
-                               const AllAttributesWrapper &initial_state,
                                const AllTransitionsWrapper &net_trans)=0;
 
   INLINE void enable_normals(bool val) { _normals_enabled = val; }
@@ -124,13 +121,14 @@ public:
   virtual bool wants_texcoords(void) const;
   virtual bool wants_colors(void) const;
 
-  virtual void begin_decal(GeomNode *base_geom, AllAttributesWrapper &attrib);
+  virtual void begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib);
   virtual void end_decal(GeomNode *base_geom);
 
   virtual void reset();
 
-  void set_state(const NodeAttributes &new_state, bool complete);
-  INLINE const NodeAttributes &get_state() const;
+  void set_state(const NodeTransitions &new_state, bool complete);
+  void set_state(const NodeTransitionCache &new_state, bool complete);
+  INLINE const NodeTransitions &get_state() const;
 
   RenderBuffer get_render_buffer(int buffer_type);
 
@@ -191,7 +189,7 @@ protected:
 
 protected:
   int _buffer_mask;
-  NodeAttributes _state;
+  NodeTransitions _state;
   Colorf _color_clear_value;
   float _depth_clear_value;
   bool _stencil_clear_value;

+ 246 - 283
panda/src/dxgsg/dxGraphicsStateGuardian.cxx

@@ -36,43 +36,24 @@
 #include <pointLight.h>
 #include <spotlight.h>
 #include <projectionNode.h>
-#include <transformAttribute.h>
 #include <transformTransition.h>
-#include <colorAttribute.h>
 #include <colorTransition.h>
-#include <lightAttribute.h>
 #include <lightTransition.h>
-#include <textureAttribute.h>
 #include <textureTransition.h>
-#include <renderModeAttribute.h>
 #include <renderModeTransition.h>
-#include <materialAttribute.h>
 #include <materialTransition.h>
-#include <colorBlendAttribute.h>
 #include <colorBlendTransition.h>
-#include <colorMaskAttribute.h>
 #include <colorMaskTransition.h>
-#include <texMatrixAttribute.h>
 #include <texMatrixTransition.h>
-#include <texGenAttribute.h>
 #include <texGenTransition.h>
-#include <textureApplyAttribute.h>
 #include <textureApplyTransition.h>
-#include <clipPlaneAttribute.h>
 #include <clipPlaneTransition.h>
-#include <transparencyAttribute.h>
 #include <transparencyTransition.h>
-#include <fogAttribute.h>
 #include <fogTransition.h>
-#include <linesmoothAttribute.h>
 #include <linesmoothTransition.h>
-#include <depthTestAttribute.h>
 #include <depthTestTransition.h>
-#include <depthWriteAttribute.h>
 #include <depthWriteTransition.h>
-#include <cullFaceAttribute.h>
 #include <cullFaceTransition.h>
-#include <stencilAttribute.h>
 #include <stencilTransition.h>
 #include <throw_event.h>
 #ifdef DO_PSTATS
@@ -489,11 +470,11 @@ init_dx(  LPDIRECTDRAW7     context,
 
     // Make sure the GL state matches all of our initial attribute
     // states.
-    PT(DepthTestAttribute) dta = new DepthTestAttribute;
-    PT(DepthWriteAttribute) dwa = new DepthWriteAttribute;
-    PT(CullFaceAttribute) cfa = new CullFaceAttribute;
-    PT(LightAttribute) la = new LightAttribute;
-    PT(TextureAttribute) ta = new TextureAttribute;
+    PT(DepthTestTransition) dta = new DepthTestTransition;
+    PT(DepthWriteTransition) dwa = new DepthWriteTransition;
+    PT(CullFaceTransition) cfa = new CullFaceTransition;
+    PT(LightTransition) la = new LightTransition;
+    PT(TextureTransition) ta = new TextureTransition;
 
     dta->issue(this);
     dwa->issue(this);
@@ -727,7 +708,7 @@ void DXGraphicsStateGuardian::set_clipper(RECT cliprect) {
 //               pre- and post-processing like swapping buffers.
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-render_frame(const AllAttributesWrapper &initial_state) {
+render_frame() {
   if (!_dx_ready) 
     return;
 
@@ -743,8 +724,8 @@ render_frame(const AllAttributesWrapper &initial_state) {
   // texture state has changed, we have to be sure to clear the
   // current texture state now.  A bit unfortunate, but probably not
   // measurably expensive.
-  NodeAttributes state;
-  state.set_attribute(TextureTransition::get_class_type(), new TextureAttribute);
+  NodeTransitions state;
+  state.set_transition(new TextureTransition);
   set_state(state, false);
 #endif
 
@@ -799,7 +780,7 @@ render_frame(const AllAttributesWrapper &initial_state) {
                                 cam->is_active() && cam->get_scene() != (Node *)NULL) {
                                 DisplayRegionStack old_dr = push_display_region(dr);
                                 prepare_display_region();
-                                render_scene(cam->get_scene(), cam, initial_state);
+                                render_scene(cam->get_scene(), cam);
                                 pop_display_region(old_dr);
                             }
                         }
@@ -826,8 +807,8 @@ render_frame(const AllAttributesWrapper &initial_state) {
         // Also force the lighting state to unlit, so that issue_light()
         // will be guaranteed to be called next frame even if we have the
         // same set of light pointers we had this frame.
-        NodeAttributes state;
-        state.set_attribute(LightTransition::get_class_type(), new LightAttribute);
+        NodeTransitions state;
+        state.set_transition(new LightTransition);
         set_state(state, false);
 
         // All this work to undo the lighting state each frame doesn't seem
@@ -1036,8 +1017,7 @@ report_texmgr_stats() {
 //               may be modified during rendering.
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-render_scene(Node *root, ProjectionNode *projnode,
-             const AllAttributesWrapper &initial_state) {
+render_scene(Node *root, ProjectionNode *projnode) {
 #ifdef GSG_VERBOSE
     _pass_number = 0;
     dxgsg_cat.debug()
@@ -1046,7 +1026,7 @@ render_scene(Node *root, ProjectionNode *projnode,
 #endif
     _current_root_node = root;
 
-    render_subgraph(_render_traverser, root, projnode, initial_state,
+    render_subgraph(_render_traverser, root, projnode,
                     AllTransitionsWrapper());
 
 #ifdef GSG_VERBOSE
@@ -1067,7 +1047,6 @@ render_scene(Node *root, ProjectionNode *projnode,
 void DXGraphicsStateGuardian::
 render_subgraph(RenderTraverser *traverser,
                 Node *subgraph, ProjectionNode *projnode,
-                const AllAttributesWrapper &initial_state,
                 const AllTransitionsWrapper &net_trans) {
     ProjectionNode *old_projection_node = _current_projection_node;
     _current_projection_node = projnode;
@@ -1124,7 +1103,7 @@ render_subgraph(RenderTraverser *traverser,
     AllTransitionsWrapper sub_trans = net_trans;
     sub_trans.set_transition(new TransformTransition(modelview_mat));
 
-    render_subgraph(traverser, subgraph, initial_state, sub_trans);
+    render_subgraph(traverser, subgraph, sub_trans);
 
     _current_projection_node = old_projection_node;
     _current_projection_mat = old_projection_mat;
@@ -1149,7 +1128,6 @@ render_subgraph(RenderTraverser *traverser,
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 render_subgraph(RenderTraverser *traverser, Node *subgraph,
-                const AllAttributesWrapper &initial_state,
                 const AllTransitionsWrapper &net_trans) {
 #ifdef GSG_VERBOSE
     dxgsg_cat.debug()
@@ -1158,7 +1136,7 @@ render_subgraph(RenderTraverser *traverser, Node *subgraph,
 #endif
 
     nassertv(traverser != (RenderTraverser *)NULL);
-    traverser->traverse(subgraph, initial_state, net_trans);
+    traverser->traverse(subgraph, net_trans);
 
 #ifdef GSG_VERBOSE
     dxgsg_cat.debug()
@@ -1310,8 +1288,8 @@ wants_colors() const {
     // If we have scene graph color enabled, return false to indicate we
     // shouldn't bother issuing geometry color commands.
 
-    const ColorAttribute *catt;
-    if (!get_attribute_into(catt, _state, ColorTransition::get_class_type())) {
+    const ColorTransition *catt;
+    if (!get_transition_into(catt, _state, ColorTransition::get_class_type())) {
         // No scene graph color at all.
         return true;
     }
@@ -1810,8 +1788,8 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) {
     // save the modelview matrix
     LMatrix4f modelview_mat;
 
-    const TransformAttribute *ctatt;
-    if (!get_attribute_into(ctatt, _state, TransformTransition::get_class_type()))
+    const TransformTransition *ctatt;
+    if (!get_transition_into(ctatt, _state, TransformTransition::get_class_type()))
         modelview_mat = LMatrix4f::ident_mat();
     else
         modelview_mat = ctatt->get_matrix();
@@ -1835,16 +1813,14 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) {
     float scaled_width, scaled_height;
 
     // set up the texture-rendering state
-    NodeAttributes state;
+    NodeTransitions state;
 
     // this sets up texturing.  Could just set the renderstates directly, but this is a little cleaner
-    TextureAttribute *ta = new TextureAttribute;
-    ta->set_on(tex);
-    state.set_attribute(TextureTransition::get_class_type(), ta);
+    TextureTransition *ta = new TextureTransition(tex);
+    state.set_transition(ta);
 
-    TextureApplyAttribute *taa = new TextureApplyAttribute;
-    taa->set_mode(TextureApplyProperty::M_modulate);
-    state.set_attribute(TextureApplyTransition::get_class_type(), taa);
+    TextureApplyTransition *taa = new TextureApplyTransition(TextureApplyProperty::M_modulate);
+    state.set_transition(taa);
 
     set_state(state, false);
 
@@ -1853,8 +1829,8 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) {
 
     if (!geom->get_alpha_disable()) {
         // figure out if alpha's enabled (if not, no reason to sort)
-        const TransparencyAttribute *ctratt;
-        if (get_attribute_into(ctratt, _state, TransparencyTransition::get_class_type()))
+        const TransparencyTransition *ctratt;
+        if (get_transition_into(ctratt, _state, TransparencyTransition::get_class_type()))
             alpha = true;
     }
 
@@ -2304,11 +2280,11 @@ draw_tri(GeomTri *geom, GeomContext *gc) {
             }
         }
 
-        ColorAttribute *catt=NULL;
+        ColorTransition *catt=NULL;
         bool bDoGlobalSceneGraphColor=FALSE,bDoColor=(ColorBinding != G_OFF);
 
         // We should issue geometry colors only if the scene graph color is off.
-        if (get_attribute_into(catt, _state, ColorTransition::get_class_type()) && !catt->is_off()) {
+        if (get_transition_into(catt, _state, ColorTransition::get_class_type()) && !catt->is_off()) {
             if (!catt->is_real())
                 bDoColor=FALSE;  // this turns off any Geom colors
             else {
@@ -2705,11 +2681,11 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) {
             }
         }
 
-        ColorAttribute *catt=NULL;
+        ColorTransition *catt=NULL;
         bool bDoGlobalSceneGraphColor=FALSE,bDoColor=(ColorBinding != G_OFF);
 
         // We should issue geometry colors only if the scene graph color is off.
-        if (get_attribute_into(catt, _state, ColorTransition::get_class_type()) && !catt->is_off()) {
+        if (get_transition_into(catt, _state, ColorTransition::get_class_type()) && !catt->is_off()) {
             if (!catt->is_real())
                 bDoColor=FALSE;  // this turns off any Geom colors
             else {
@@ -3507,35 +3483,24 @@ draw_texture(TextureContext *tc, const DisplayRegion *dr) {
     DisplayRegionStack old_dr = push_display_region(dr);
     prepare_display_region();
 
-    NodeAttributes state;
-    CullFaceAttribute *cfa = new CullFaceAttribute;
-    cfa->set_mode(CullFaceProperty::M_cull_none);
-    DepthTestAttribute *dta = new DepthTestAttribute;
-    dta->set_mode(DepthTestProperty::M_none);
-    DepthWriteAttribute *dwa = new DepthWriteAttribute;
-    dwa->set_off();
-    TextureAttribute *ta = new TextureAttribute;
-    ta->set_on(tex);
-    TextureApplyAttribute *taa = new TextureApplyAttribute;
-    taa->set_mode(TextureApplyProperty::M_decal);
-
-    state.set_attribute(LightTransition::get_class_type(),
-                        new LightAttribute);
-    state.set_attribute(ColorMaskTransition::get_class_type(),
-                        new ColorMaskAttribute);
-    state.set_attribute(RenderModeTransition::get_class_type(),
-                        new RenderModeAttribute);
-    state.set_attribute(TexMatrixTransition::get_class_type(),
-                        new TexMatrixAttribute);
-    state.set_attribute(TransformTransition::get_class_type(),
-                        new TransformAttribute);
-    state.set_attribute(ColorBlendTransition::get_class_type(),
-                        new ColorBlendAttribute);
-    state.set_attribute(CullFaceTransition::get_class_type(), cfa);
-    state.set_attribute(DepthTestTransition::get_class_type(), dta);
-    state.set_attribute(DepthWriteTransition::get_class_type(), dwa);
-    state.set_attribute(TextureTransition::get_class_type(), ta);
-    state.set_attribute(TextureApplyTransition::get_class_type(), taa);
+    NodeTransitions state;
+    CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_none);
+    DepthTestTransition *dta = new DepthTestTransition(DepthTestProperty::M_none);
+    DepthWriteTransition *dwa = new DepthWriteTransition(DepthWriteTransition::off());
+    TextureTransition *ta = new TextureTransition(tex);
+    TextureApplyTransition *taa = new TextureApplyTransition(TextureApplyProperty::M_decal);
+
+    state.set_transition(new LightTransition);
+    state.set_transition(new ColorMaskTransition);
+    state.set_transition(new RenderModeTransition);
+    state.set_transition(new TexMatrixTransition);
+    state.set_transition(new TransformTransition);
+    state.set_transition(new ColorBlendTransition);
+    state.set_transition(cfa);
+    state.set_transition(dta);
+    state.set_transition(dwa);
+    state.set_transition(ta);
+    state.set_transition(taa);
     set_state(state, false);
 
     // We set up an orthographic projection that defines our entire
@@ -3693,7 +3658,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
-                  const NodeAttributes& na) {
+                  const NodeTransitions& na) {
 
     dxgsg_cat.fatal() << "DXGSG draw_pixel_buffer unimplemented!!!";
     return;
@@ -3705,31 +3670,23 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
     DisplayRegionStack old_dr = push_display_region(dr);
     prepare_display_region();
 
-    NodeAttributes state(na);
-    state.set_attribute(LightTransition::get_class_type(),
-                        new LightAttribute);
-    state.set_attribute(TextureTransition::get_class_type(),
-                        new TextureAttribute);
-    state.set_attribute(TransformTransition::get_class_type(),
-                        new TransformAttribute);
-    state.set_attribute(ColorBlendTransition::get_class_type(),
-                        new ColorBlendAttribute);
-    state.set_attribute(StencilTransition::get_class_type(),
-                        new StencilAttribute);
+    NodeTransitions state(na);
+    state.set_transition(new LightTransition);
+    state.set_transition(new TextureTransition);
+    state.set_transition(new TransformTransition);
+    state.set_transition(new ColorBlendTransition);
+    state.set_transition(new StencilTransition);
 
 
     switch (pb->get_format()) {
         case PixelBuffer::F_depth_component:
             {
-                ColorMaskAttribute *cma = new ColorMaskAttribute;
-                cma->set_mask(0);
-                DepthTestAttribute *dta = new DepthTestAttribute;
-                dta->set_mode(DepthTestProperty::M_always);
-                DepthWriteAttribute *dwa = new DepthWriteAttribute;
-                dwa->set_off();
-                state.set_attribute(ColorMaskTransition::get_class_type(), cma);
-                state.set_attribute(DepthTestTransition::get_class_type(), dta);
-                state.set_attribute(DepthWriteTransition::get_class_type(), dwa);
+                ColorMaskTransition *cma = new ColorMaskTransition(0);
+                DepthTestTransition *dta = new DepthTestTransition(DepthTestProperty::M_always);
+                DepthWriteTransition *dwa = new DepthWriteTransition(DepthWriteTransition::off());
+                state.set_transition(cma);
+                state.set_transition(dta);
+                state.set_transition(dwa);
             }
             break;
 
@@ -3742,14 +3699,12 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
         case PixelBuffer::F_rgba8:
         case PixelBuffer::F_rgba12:
             {
-                ColorMaskAttribute *cma = new ColorMaskAttribute;
-                DepthTestAttribute *dta = new DepthTestAttribute;
-                dta->set_mode(DepthTestProperty::M_none);
-                DepthWriteAttribute *dwa = new DepthWriteAttribute;
-                dwa->set_off();
-                state.set_attribute(ColorMaskTransition::get_class_type(), cma);
-                state.set_attribute(DepthTestTransition::get_class_type(), dta);
-                state.set_attribute(DepthWriteTransition::get_class_type(), dwa);
+                ColorMaskTransition *cma = new ColorMaskTransition;
+                DepthTestTransition *dta = new DepthTestTransition(DepthTestProperty::M_none);
+                DepthWriteTransition *dwa = new DepthWriteTransition(DepthWriteTransition::off());
+                state.set_transition(cma);
+                state.set_transition(dta);
+                state.set_transition(dwa);
             }
             break;
         default:
@@ -3822,7 +3777,7 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
-                  const RenderBuffer &rb, const NodeAttributes& na) {
+                  const RenderBuffer &rb, const NodeTransitions& na) {
     set_read_buffer(rb);
     draw_pixel_buffer(pb, dr, na);
 }
@@ -4161,7 +4116,7 @@ void DXGraphicsStateGuardian::apply_light( AmbientLight* light ) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_transform(const TransformAttribute *attrib) {
+issue_transform(const TransformTransition *attrib) {
 #ifndef NDEBUG
     if (dx_show_transforms) {
 
@@ -4205,7 +4160,7 @@ issue_transform(const TransformAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_tex_matrix(const TexMatrixAttribute *attrib) {
+issue_tex_matrix(const TexMatrixTransition *attrib) {
     dxgsg_cat.fatal() << "DXGSG issue_tex_matrix unimplemented!!!";
     return;
 
@@ -4228,7 +4183,7 @@ issue_tex_matrix(const TexMatrixAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_color(const ColorAttribute *attrib) {
+issue_color(const ColorTransition *attrib) {
     
     bool bAttribOn=attrib->is_on();
     bool bIsReal = (bAttribOn ? attrib->is_real() : false);
@@ -4254,11 +4209,11 @@ issue_color(const ColorAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_color_transform(const ColorMatrixAttribute *attrib) {
+issue_color_transform(const ColorMatrixTransition *attrib) {
     _current_color_mat = attrib->get_matrix();
 
     // couldnt we compare a single ptr instead of doing full comparison?
-    // bugbug: the ColorMatrixAttribute needs to be an On/Off attribute 
+    // bugbug: the ColorMatrixTransition needs to be an On/Off transition 
     // so we dont have to do this comparison
     if (_current_color_mat == LMatrix4f::ident_mat()) { 
         _color_transform_enabled = false;
@@ -4279,7 +4234,7 @@ issue_color_transform(const ColorMatrixAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_alpha_transform(const AlphaTransformAttribute *attrib) {
+issue_alpha_transform(const AlphaTransformTransition *attrib) {
     _current_alpha_offset = attrib->get_offset();
     _current_alpha_scale = attrib->get_scale();
 
@@ -4302,7 +4257,7 @@ issue_alpha_transform(const AlphaTransformAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_texture(const TextureAttribute *attrib) {
+issue_texture(const TextureTransition *attrib) {
     if (attrib->is_on()) {
         enable_texturing(true);
         Texture *tex = attrib->get_texture();
@@ -4319,7 +4274,7 @@ issue_texture(const TextureAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_tex_gen(const TexGenAttribute *attrib) {
+issue_tex_gen(const TexGenTransition *attrib) {
     dxgsg_cat.fatal() << "DXGSG issue_tex_gen unimplemented!!!";
     return;
 #ifdef WBD_GL_MODE
@@ -4374,7 +4329,7 @@ issue_tex_gen(const TexGenAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_material(const MaterialAttribute *attrib) {
+issue_material(const MaterialTransition *attrib) {
     if (attrib->is_on()) {
         const Material *material = attrib->get_material();
         nassertv(material != (const Material *)NULL);
@@ -4388,7 +4343,7 @@ issue_material(const MaterialAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_fog(const FogAttribute *attrib) {
+issue_fog(const FogTransition *attrib) {
 
     if (attrib->is_on()) {
         enable_fog(true);
@@ -4406,7 +4361,7 @@ issue_fog(const FogAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_render_mode(const RenderModeAttribute *attrib) {
+issue_render_mode(const RenderModeTransition *attrib) {
 
     RenderModeProperty::Mode mode = attrib->get_mode();
 
@@ -4431,93 +4386,98 @@ issue_render_mode(const RenderModeAttribute *attrib) {
 //       Access: Public, Virtual
 //  Description:
 ////////////////////////////////////////////////////////////////////
-void DXGraphicsStateGuardian::issue_light(const LightAttribute *attrib ) {
-    nassertv(attrib->get_properties_is_on());
+void DXGraphicsStateGuardian::issue_light(const LightTransition *attrib ) {
+  nassertv(attrib->get_default_dir() != TD_on);
 
-    // Initialize the current ambient light total and currently enabled
-    // light list
-    _cur_ambient_light.set(0, 0, 0, 1);
-    int i;
-    for (i = 0; i < _max_lights; i++)
-        _cur_light_enabled[i] = false;
-
-    int num_enabled = 0;
-    LightAttribute::const_iterator li;
-    for (li = attrib->begin(); li != attrib->end(); ++li) {
-        _cur_light_id = -1;
-        num_enabled++;
-        enable_lighting(true);
-        Light *light = (*li);
-        nassertv(light != (Light *)NULL);
-
-        // Ambient lights don't require specific light ids
-        // Simply add in the ambient contribution to the current total
-        if (light->get_light_type() == AmbientLight::get_class_type()) {
-            light->apply(this);
-            // We need to indicate that no light id is necessary because
-            // it's an ambient light
-            _cur_light_id = -2;
-        }
+  // Initialize the current ambient light total and currently enabled
+  // light list
+  _cur_ambient_light.set(0, 0, 0, 1);
+  int i;
+  for (i = 0; i < _max_lights; i++)
+    _cur_light_enabled[i] = false;
+
+  int num_enabled = 0;
+  LightTransition::const_iterator li;
+  for (li = attrib->begin(); li != attrib->end(); ++li) {
+    Light *light = (*li).first;
+    nassertv(light != (Light *)NULL);
+    TransitionDirection dir = (*li).second;
+ 
+    if (dir == TD_on) {
+      num_enabled++;
+      enable_lighting(true);
+
+      _cur_light_id = -1;
+            
+      // Ambient lights don't require specific light ids
+      // Simply add in the ambient contribution to the current total
+      if (light->get_light_type() == AmbientLight::get_class_type()) {
+        light->apply(this);
+        // We need to indicate that no light id is necessary because
+        // it's an ambient light
+        _cur_light_id = -2;
+      }
 
-        // Check to see if this light has already been bound to an id
-        for (i = 0; i < _max_lights; i++) {
-            if (_available_light_ids[i] == light) {
-                // Light has already been bound to an id, we only need
-                // to enable the light, not apply it
-                _cur_light_id = -2;
-                if (enable_light(i, true))  _cur_light_enabled[i] = true;
-                break;
-            }
+      // Check to see if this light has already been bound to an id
+      for (i = 0; i < _max_lights; i++) {
+        if (_available_light_ids[i] == light) {
+          // Light has already been bound to an id, we only need
+          // to enable the light, not apply it
+          _cur_light_id = -2;
+          if (enable_light(i, true))  _cur_light_enabled[i] = true;
+          break;
         }
+      }
 
-        // See if there are any unbound light ids
-        if (_cur_light_id == -1) {
-            for (i = 0; i < _max_lights; i++) {
-                if (_available_light_ids[i] == NULL) {
-                    _available_light_ids[i] = light;
-                    _cur_light_id = i;
-                    break;
-                }
-            }
+      // See if there are any unbound light ids
+      if (_cur_light_id == -1) {
+        for (i = 0; i < _max_lights; i++) {
+          if (_available_light_ids[i] == NULL) {
+            _available_light_ids[i] = light;
+            _cur_light_id = i;
+            break;
+          }
         }
+      }
 
-        // If there were no unbound light ids, see if we can replace
-        // a currently unused but previously bound id
-        if (_cur_light_id == -1) {
-            for (i = 0; i < _max_lights; i++) {
-                if (attrib->is_off(_available_light_ids[i])) {
-                    _available_light_ids[i] = light;
-                    _cur_light_id = i;
-                    break;
-                }
-            }
+      // If there were no unbound light ids, see if we can replace
+      // a currently unused but previously bound id
+      if (_cur_light_id == -1) {
+        for (i = 0; i < _max_lights; i++) {
+          if (attrib->is_off(_available_light_ids[i])) {
+            _available_light_ids[i] = light;
+            _cur_light_id = i;
+            break;
+          }
         }
+      }
 
-        if (_cur_light_id >= 0) {
-            if (enable_light(_cur_light_id, true))  _cur_light_enabled[_cur_light_id] = true;
-
-            // We need to do something different for each type of light
-            light->apply(this);
-        } else if (_cur_light_id == -1) {
-            dxgsg_cat.error()
-            << "issue_light() - failed to bind light to id" << endl;
-        }
-    }
+      if (_cur_light_id >= 0) {
+        if (enable_light(_cur_light_id, true))  _cur_light_enabled[_cur_light_id] = true;
 
-    // Disable all unused lights
-    for (i = 0; i < _max_lights; i++) {
-        if (!_cur_light_enabled[i])
-            enable_light(i, false);
+        // We need to do something different for each type of light
+        light->apply(this);
+      } else if (_cur_light_id == -1) {
+        dxgsg_cat.error()
+          << "issue_light() - failed to bind light to id" << endl;
+      }
     }
+  }
 
-    // If no lights were enabled, disable lighting
-    if (num_enabled == 0) {
-        enable_lighting(false);
-        enable_color_material(false);
-    } else {
-        call_dxLightModelAmbient(_cur_ambient_light);
-        enable_color_material(true);
-    }
+  // Disable all unused lights
+  for (i = 0; i < _max_lights; i++) {
+    if (!_cur_light_enabled[i])
+      enable_light(i, false);
+  }
+  
+  // If no lights were enabled, disable lighting
+  if (num_enabled == 0) {
+    enable_lighting(false);
+    enable_color_material(false);
+  } else {
+    call_dxLightModelAmbient(_cur_ambient_light);
+    enable_color_material(true);
+  }
 }
 
 
@@ -4539,7 +4499,7 @@ reset_ambient() {
 //  Description:                                                  //
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_color_blend(const ColorBlendAttribute *attrib) {
+issue_color_blend(const ColorBlendTransition *attrib) {
     
     ColorBlendProperty::Mode mode = attrib->get_mode();
 
@@ -4686,10 +4646,10 @@ enable_texturing(bool val) {
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian::issue_texture_apply
 //       Access: Public, Virtual
-//  Description: handles texture attribute (i.e. filter modes, etc) changes
+//  Description: handles texture transition (i.e. filter modes, etc) changes
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_texture_apply(const TextureApplyAttribute *attrib) {
+issue_texture_apply(const TextureApplyTransition *attrib) {
 
     _CurTexBlendMode = attrib->get_mode();
 
@@ -4706,7 +4666,7 @@ issue_texture_apply(const TextureApplyAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_color_mask(const ColorMaskAttribute *attrib) {
+issue_color_mask(const ColorMaskTransition *attrib) {
     dxgsg_cat.fatal() << "DXGSG issue_color_mask unimplemented (not implementable on DX7)!!!";
     return;
 }
@@ -4717,7 +4677,7 @@ issue_color_mask(const ColorMaskAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_depth_test(const DepthTestAttribute *attrib) {
+issue_depth_test(const DepthTestTransition *attrib) {
     
 
     DepthTestProperty::Mode mode = attrib->get_mode();
@@ -4738,7 +4698,7 @@ issue_depth_test(const DepthTestAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_depth_write(const DepthWriteAttribute *attrib) {
+issue_depth_write(const DepthWriteTransition *attrib) {
     _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, attrib->is_on());
 }
 
@@ -4748,7 +4708,7 @@ issue_depth_write(const DepthWriteAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_stencil(const StencilAttribute *attrib) {
+issue_stencil(const StencilTransition *attrib) {
 
   StencilProperty::Mode mode = attrib->get_mode();
 
@@ -4775,12 +4735,12 @@ issue_stencil(const StencilAttribute *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian::issue_cull_attribute
+//     Function: DXGraphicsStateGuardian::issue_cull_transition
 //       Access: Public, Virtual
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_cull_face(const CullFaceAttribute *attrib) {
+issue_cull_face(const CullFaceTransition *attrib) {
     
 #ifndef NDEBUG
     if(dx_force_backface_culling!=0) {
@@ -4817,82 +4777,85 @@ issue_cull_face(const CullFaceAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_clip_plane(const ClipPlaneAttribute *attrib) {
+issue_clip_plane(const ClipPlaneTransition *attrib) {
+  nassertv(attrib->get_default_dir() != TD_on);
     
-
-    // Initialize the currently enabled clip plane list
-    int i;
-    for (i = 0; i < _max_clip_planes; i++)
-        _cur_clip_plane_enabled[i] = false;
-
-    int num_enabled = 0;
-    ClipPlaneAttribute::const_iterator pi;
-    for (pi = attrib->begin(); pi != attrib->end(); ++pi) {
-        PlaneNode *plane_node;
-        DCAST_INTO_V(plane_node, (*pi));
-        nassertv(plane_node != (PlaneNode *)NULL);
-
-        _cur_clip_plane_id = -1;
-        num_enabled++;
-
-        // Check to see if this clip plane has already been bound to an id
-        for (i = 0; i < _max_clip_planes; i++) {
-            if (_available_clip_plane_ids[i] == plane_node) {
-                // Clip plane has already been bound to an id, we only need
-                // to enable the clip plane, not apply it
-                _cur_clip_plane_id = -2;
-                enable_clip_plane(i, true);
-                _cur_clip_plane_enabled[i] = true;
-                break;
-            }
-        }
-
-        // See if there are any unbound clip plane ids
-        if (_cur_clip_plane_id == -1) {
-            for (i = 0; i < _max_clip_planes; i++) {
-                if (_available_clip_plane_ids[i] == NULL) {
-                    _available_clip_plane_ids[i] = plane_node;
-                    _cur_clip_plane_id = i;
-                    break;
-                }
-            }
+  // Initialize the currently enabled clip plane list
+  int i;
+  for (i = 0; i < _max_clip_planes; i++)
+    _cur_clip_plane_enabled[i] = false;
+  
+  int num_enabled = 0;
+  ClipPlaneTransition::const_iterator pi;
+  for (pi = attrib->begin(); pi != attrib->end(); ++pi) {
+    PlaneNode *plane_node;
+    DCAST_INTO_V(plane_node, (*pi).first);
+    nassertv(plane_node != (PlaneNode *)NULL);
+    TransitionDirection dir = (*pi).second;
+
+    if (dir == TD_on) {
+      _cur_clip_plane_id = -1;
+      num_enabled++;
+      
+      // Check to see if this clip plane has already been bound to an id
+      for (i = 0; i < _max_clip_planes; i++) {
+        if (_available_clip_plane_ids[i] == plane_node) {
+          // Clip plane has already been bound to an id, we only need
+          // to enable the clip plane, not apply it
+          _cur_clip_plane_id = -2;
+          enable_clip_plane(i, true);
+          _cur_clip_plane_enabled[i] = true;
+          break;
         }
-
-        // If there were no unbound clip plane ids, see if we can replace
-        // a currently unused but previously bound id
-        if (_cur_clip_plane_id == -1) {
-            for (i = 0; i < _max_clip_planes; i++) {
-                if (attrib->is_off(_available_clip_plane_ids[i])) {
-                    _available_clip_plane_ids[i] = plane_node;
-                    _cur_clip_plane_id = i;
-                    break;
-                }
-            }
+      }
+      
+      // See if there are any unbound clip plane ids
+      if (_cur_clip_plane_id == -1) {
+        for (i = 0; i < _max_clip_planes; i++) {
+          if (_available_clip_plane_ids[i] == NULL) {
+            _available_clip_plane_ids[i] = plane_node;
+            _cur_clip_plane_id = i;
+            break;
+          }
         }
-
-        if (_cur_clip_plane_id >= 0) {
-            enable_clip_plane(_cur_clip_plane_id, true);
-            _cur_clip_plane_enabled[_cur_clip_plane_id] = true;
-            const Planef clip_plane = plane_node->get_plane();
-
-            D3DVALUE equation[4];
-            equation[0] = clip_plane._a;
-            equation[1] = clip_plane._b;
-            equation[2] = clip_plane._c;
-            equation[3] = clip_plane._d;
-            _d3dDevice->SetClipPlane(_cur_clip_plane_id, equation);
-
-        } else if (_cur_clip_plane_id == -1) {
-            dxgsg_cat.error()
-            << "issue_clip_plane() - failed to bind clip plane to id" << endl;
+      }
+      
+      // If there were no unbound clip plane ids, see if we can replace
+      // a currently unused but previously bound id
+      if (_cur_clip_plane_id == -1) {
+        for (i = 0; i < _max_clip_planes; i++) {
+          if (attrib->is_off(_available_clip_plane_ids[i])) {
+            _available_clip_plane_ids[i] = plane_node;
+            _cur_clip_plane_id = i;
+            break;
+          }
         }
+      }
+      
+      if (_cur_clip_plane_id >= 0) {
+        enable_clip_plane(_cur_clip_plane_id, true);
+        _cur_clip_plane_enabled[_cur_clip_plane_id] = true;
+        const Planef clip_plane = plane_node->get_plane();
+        
+        D3DVALUE equation[4];
+        equation[0] = clip_plane._a;
+        equation[1] = clip_plane._b;
+        equation[2] = clip_plane._c;
+        equation[3] = clip_plane._d;
+        _d3dDevice->SetClipPlane(_cur_clip_plane_id, equation);
+        
+      } else if (_cur_clip_plane_id == -1) {
+        dxgsg_cat.error()
+          << "issue_clip_plane() - failed to bind clip plane to id" << endl;
+      }
     }
+  }
 
-    // Disable all unused clip planes
-    for (i = 0; i < _max_clip_planes; i++) {
-        if (!_cur_clip_plane_enabled[i])
-            enable_clip_plane(i, false);
-    }
+  // Disable all unused clip planes
+  for (i = 0; i < _max_clip_planes; i++) {
+    if (!_cur_clip_plane_enabled[i])
+      enable_clip_plane(i, false);
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -4901,7 +4864,7 @@ issue_clip_plane(const ClipPlaneAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_transparency(const TransparencyAttribute *attrib ) {
+issue_transparency(const TransparencyTransition *attrib ) {
 
     TransparencyProperty::Mode mode = attrib->get_mode();
 
@@ -4959,7 +4922,7 @@ issue_transparency(const TransparencyAttribute *attrib ) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-issue_linesmooth(const LinesmoothAttribute *attrib) {
+issue_linesmooth(const LinesmoothTransition *attrib) {
     enable_line_smooth(attrib->is_on());
 }
 
@@ -4993,13 +4956,13 @@ wants_texcoords() const {
 //               rendered up until the next call of end_decal() should
 //               be rendered as decals of the base_geom.
 //
-//               The attributes wrapper is the current state as of the
+//               The transitions wrapper is the current state as of the
 //               base geometry node.  It may or may not be modified by
 //               the GSG to reflect whatever rendering state is
 //               necessary to render the decals properly.
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
-begin_decal(GeomNode *base_geom, AllAttributesWrapper &attrib) {
+begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib) {
     nassertv(base_geom != (GeomNode *)NULL);
 
     _decal_level++;

+ 26 - 31
panda/src/dxgsg/dxGraphicsStateGuardian.h

@@ -33,9 +33,7 @@
 #include <stencilProperty.h>
 #include <fog.h>
 
-#include <colorMatrixAttribute.h>
 #include <colorMatrixTransition.h>
-#include <alphaTransformAttribute.h>
 #include <alphaTransformTransition.h>
 #include <pointerToArray.h>
 #include <planeNode.h>
@@ -98,16 +96,13 @@ public:
 
   virtual void prepare_display_region();
 
-  virtual void render_frame(const AllAttributesWrapper &initial_state);
-  virtual void render_scene(Node *root, ProjectionNode *projnode,
-                const AllAttributesWrapper &initial_state);
+  virtual void render_frame();
+  virtual void render_scene(Node *root, ProjectionNode *projnode);
   virtual void render_subgraph(RenderTraverser *traverser,
                    Node *subgraph, ProjectionNode *projnode,
-                   const AllAttributesWrapper &initial_state,
                    const AllTransitionsWrapper &net_trans);
   virtual void render_subgraph(RenderTraverser *traverser,
                    Node *subgraph,
-                   const AllAttributesWrapper &initial_state,
                    const AllTransitionsWrapper &net_trans);
 
   virtual void draw_point(GeomPoint *geom, GeomContext *gc);
@@ -145,10 +140,10 @@ public:
   virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb);
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
-                 const NodeAttributes& na=NodeAttributes());
+                 const NodeTransitions& na=NodeTransitions());
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb,
-                 const NodeAttributes& na=NodeAttributes());
+                 const NodeTransitions& na=NodeTransitions());
 
   virtual void apply_material(const Material *material);
   virtual void apply_fog(Fog *fog);
@@ -158,33 +153,33 @@ public:
   virtual void apply_light(Spotlight* light);
   virtual void apply_light(AmbientLight* light);
 
-  virtual void issue_transform(const TransformAttribute *attrib);
-  virtual void issue_tex_matrix(const TexMatrixAttribute *attrib);
-  virtual void issue_color(const ColorAttribute *attrib);
-  virtual void issue_color_transform(const ColorMatrixAttribute *);
-  virtual void issue_alpha_transform(const AlphaTransformAttribute *);
-  virtual void issue_texture(const TextureAttribute *attrib);
-  virtual void issue_light(const LightAttribute *attrib);
-  virtual void issue_material(const MaterialAttribute *attrib);
-  virtual void issue_render_mode(const RenderModeAttribute *attrib);
-  virtual void issue_color_blend(const ColorBlendAttribute *attrib);
-  virtual void issue_texture_apply(const TextureApplyAttribute *attrib);
-  virtual void issue_color_mask(const ColorMaskAttribute *attrib);
-  virtual void issue_depth_test(const DepthTestAttribute *attrib);
-  virtual void issue_depth_write(const DepthWriteAttribute *attrib);
-  virtual void issue_tex_gen(const TexGenAttribute *attrib);
-  virtual void issue_cull_face(const CullFaceAttribute *attrib);
-  virtual void issue_stencil(const StencilAttribute *attrib);
-  virtual void issue_clip_plane(const ClipPlaneAttribute *attrib);
-  virtual void issue_transparency(const TransparencyAttribute *attrib);
-  virtual void issue_fog(const FogAttribute *attrib);
-  virtual void issue_linesmooth(const LinesmoothAttribute *attrib);
+  virtual void issue_transform(const TransformTransition *attrib);
+  virtual void issue_tex_matrix(const TexMatrixTransition *attrib);
+  virtual void issue_color(const ColorTransition *attrib);
+  virtual void issue_color_transform(const ColorMatrixTransition *);
+  virtual void issue_alpha_transform(const AlphaTransformTransition *);
+  virtual void issue_texture(const TextureTransition *attrib);
+  virtual void issue_light(const LightTransition *attrib);
+  virtual void issue_material(const MaterialTransition *attrib);
+  virtual void issue_render_mode(const RenderModeTransition *attrib);
+  virtual void issue_color_blend(const ColorBlendTransition *attrib);
+  virtual void issue_texture_apply(const TextureApplyTransition *attrib);
+  virtual void issue_color_mask(const ColorMaskTransition *attrib);
+  virtual void issue_depth_test(const DepthTestTransition *attrib);
+  virtual void issue_depth_write(const DepthWriteTransition *attrib);
+  virtual void issue_tex_gen(const TexGenTransition *attrib);
+  virtual void issue_cull_face(const CullFaceTransition *attrib);
+  virtual void issue_stencil(const StencilTransition *attrib);
+  virtual void issue_clip_plane(const ClipPlaneTransition *attrib);
+  virtual void issue_transparency(const TransparencyTransition *attrib);
+  virtual void issue_fog(const FogTransition *attrib);
+  virtual void issue_linesmooth(const LinesmoothTransition *attrib);
 
   virtual bool wants_normals(void) const;
   virtual bool wants_texcoords(void) const;
   virtual bool wants_colors(void) const;
 
-  virtual void begin_decal(GeomNode *base_geom, AllAttributesWrapper &attrib);
+  virtual void begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib);
   virtual void end_decal(GeomNode *base_geom);
 
   INLINE float compute_distance_to(const LPoint3f &point) const;

+ 13 - 15
panda/src/effects/lensFlareNode.cxx

@@ -25,14 +25,14 @@
 #include "textureTransition.h"
 #include "transformTransition.h"
 #include "billboardTransition.h"
-#include "transformAttribute.h"
+#include "transformTransition.h"
 #include "transparencyTransition.h"
 #include "renderTraverser.h"
 #include "orthoProjection.h"
 #include "perspectiveProjection.h"
 #include "get_rel_pos.h"
 #include "clockObject.h"
-#include "allAttributesWrapper.h"
+#include "allTransitionsWrapper.h"
 #include "allTransitionsWrapper.h"
 #include "graphicsStateGuardian.h"
 #include "datagram.h"
@@ -266,22 +266,21 @@ prepare_blind(const float &angle, const float &tnear)
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void LensFlareNode::
-render_child(RenderRelation *arc, const AllAttributesWrapper &attrib,
+render_child(RenderRelation *arc,
              AllTransitionsWrapper &trans, GraphicsStateGuardian *gsg)
 {
 
-  AllAttributesWrapper new_attrib(attrib);
-  new_attrib.clear_attribute(TransformTransition::get_class_type());
+  AllTransitionsWrapper new_trans(trans);
+  new_trans.clear_transition(TransformTransition::get_class_type());
 
   AllTransitionsWrapper arc_trans;
   arc_trans.extract_from(arc);
 
-  AllTransitionsWrapper new_trans(trans);
   new_trans.compose_in_place(arc_trans);
 
   // Now render everything from this node and below.
   gsg->render_subgraph(gsg->get_render_traverser(),
-                       arc->get_child(), new_attrib, new_trans);
+                       arc->get_child(), new_trans);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -290,12 +289,12 @@ render_child(RenderRelation *arc, const AllAttributesWrapper &attrib,
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void LensFlareNode::
-render_children(const vector_relation &arcs, const AllAttributesWrapper &attrib,
+render_children(const vector_relation &arcs, 
                 AllTransitionsWrapper &trans, GraphicsStateGuardian *gsg)
 {
   for(int i = 0; i < (int)arcs.size(); i++)
   {
-    render_child(arcs[i], attrib, trans, gsg);
+    render_child(arcs[i], trans, gsg);
   }
 }
 
@@ -305,8 +304,7 @@ render_children(const vector_relation &arcs, const AllAttributesWrapper &attrib,
 //  Description:
 ////////////////////////////////////////////////////////////////////
 bool LensFlareNode::
-sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &trans,
-           RenderTraverser *trav) {
+sub_render(AllTransitionsWrapper &trans, RenderTraverser *trav) {
   GraphicsStateGuardian *gsg = trav->get_gsg();
 
   nassertr(_light_node != (Node*) NULL, false);
@@ -322,8 +320,8 @@ sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &trans,
 
   LMatrix4f modelview_mat;
 
-  const TransformAttribute *ta;
-  if (!get_attribute_into(ta, attrib.get_attributes(), TransformTransition::get_class_type()))
+  const TransformTransition *ta;
+  if (!get_transition_into(ta, trans))
     modelview_mat = LMatrix4f::ident_mat();
   else
     modelview_mat = ta->get_matrix();
@@ -355,8 +353,8 @@ sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &trans,
   prepare_flares(delta, light_pos, dot);
   prepare_blind(dot, pp->get_frustum()._fnear);
 
-  render_children(_flare_arcs, attrib, trans, gsg);
-  render_child(_blind_arc, attrib, trans, gsg);
+  render_children(_flare_arcs, trans, gsg);
+  render_child(_blind_arc, trans, gsg);
 
   //Short circuit the rendering
   return false;

+ 3 - 4
panda/src/effects/lensFlareNode.h

@@ -51,8 +51,7 @@ PUBLISHED:
   INLINE void set_light_source(PT_Node source);
 
 public:
-  virtual bool sub_render(const AllAttributesWrapper &attrib,
-                          AllTransitionsWrapper &trans,
+  virtual bool sub_render(AllTransitionsWrapper &trans,
                           RenderTraverser *trav);
   virtual bool has_sub_render() const;
 
@@ -97,9 +96,9 @@ private:
                     const LPoint3f &light, const float &angle);
 
 
-  void render_child(RenderRelation *arc, const AllAttributesWrapper &attrib,
+  void render_child(RenderRelation *arc,
                     AllTransitionsWrapper &trans, GraphicsStateGuardian *gsg);
-  void render_children(const vector_relation &arcs, const AllAttributesWrapper &attrib,
+  void render_children(const vector_relation &arcs,
                        AllTransitionsWrapper &trans, GraphicsStateGuardian *gsg);
 
 public:

+ 1 - 1
panda/src/egg2sg/deferredArcTraverser.cxx

@@ -36,7 +36,7 @@ DeferredArcTraverser(const DeferredArcs &deferred_arcs) :
 ////////////////////////////////////////////////////////////////////
 bool DeferredArcTraverser::
 forward_arc(NodeRelation *arc, NullTransitionWrapper &,
-            NullAttributeWrapper &, NullAttributeWrapper &,
+            NullTransitionWrapper &, NullTransitionWrapper &,
             DeferredArcProperty &level_state) {
 
   // Do we have a DeferredArcProperty associated with this arc?

+ 1 - 2
panda/src/egg2sg/deferredArcTraverser.h

@@ -25,7 +25,6 @@
 
 #include <traverserVisitor.h>
 #include <nullTransitionWrapper.h>
-#include <nullAttributeWrapper.h>
 
 #include "pmap.h"
 
@@ -47,7 +46,7 @@ public:
   DeferredArcTraverser(const DeferredArcs &deferred_arcs);
 
   bool forward_arc(NodeRelation *arc, NullTransitionWrapper &,
-                   NullAttributeWrapper &, NullAttributeWrapper &,
+                   NullTransitionWrapper &, NullTransitionWrapper &,
                    DeferredArcProperty &level_state);
 
   const DeferredArcs &_deferred_arcs;

+ 1 - 1
panda/src/egg2sg/eggLoader.cxx

@@ -1973,6 +1973,6 @@ void EggLoader::
 apply_deferred_arcs(Node *root) {
   DeferredArcTraverser trav(_deferred_arcs);
 
-  df_traverse(root, trav, NullAttributeWrapper(), DeferredArcProperty(),
+  df_traverse(root, trav, NullTransitionWrapper(), DeferredArcProperty(),
               RenderRelation::get_class_type());
 }

+ 246 - 256
panda/src/framework/framework.cxx

@@ -18,95 +18,94 @@
 
 // We need to include bitMask.h first to avoid a VC++ compiler bug
 // related to 2 parameter templates
-#include <bitMask.h>
+#include "bitMask.h"
 
 #include "framework.h"
 #include "config_framework.h"
 
-#include <pystub.h>
-#include <time.h>
+#include "pystub.h"
+#include "time.h"
 // Since framework.cxx includes pystub.h, no program that links with
 // framework needs to do so.  No Python code should attempt to link
 // with libframework.so.
 
-#include <cullTraverser.h>
-#include <appTraverser.h>
-#include <directRenderTraverser.h>
-#include <mouse.h>
-#include <mouseWatcher.h>
-#include <buttonThrower.h>
-#include <keyboardButton.h>
-#include <eventHandler.h>
-#include <throw_event.h>
-#include <camera.h>
-#include <geom.h>
-#include <geomprimitives.h>
-#include <renderRelation.h>
-#include <dataRelation.h>
-#include <geomNode.h>
-#include <namedNode.h>
-#include <pt_NamedNode.h>
-#include <colorTransition.h>
-#include <renderModeTransition.h>
-#include <renderModeAttribute.h>
-#include <materialTransition.h>
-#include <dataGraphTraversal.h>
-#include <trackball.h>
-#include <driveInterface.h>
-#include <transform2sg.h>
-#include <texture.h>
-#include <texturePool.h>
-#include <textureTransition.h>
-#include <textureAttribute.h>
-#include <interactiveGraphicsPipe.h>
-#include <noninteractiveGraphicsPipe.h>
-#include <graphicsWindow.h>
+#include "cullTraverser.h"
+#include "appTraverser.h"
+#include "directRenderTraverser.h"
+#include "mouse.h"
+#include "mouseWatcher.h"
+#include "buttonThrower.h"
+#include "keyboardButton.h"
+#include "eventHandler.h"
+#include "throw_event.h"
+#include "camera.h"
+#include "geom.h"
+#include "geomprimitives.h"
+#include "renderRelation.h"
+#include "dataRelation.h"
+#include "geomNode.h"
+#include "namedNode.h"
+#include "pt_NamedNode.h"
+#include "colorTransition.h"
+#include "renderModeTransition.h"
+#include "renderModeAttribute.h"
+#include "materialTransition.h"
+#include "dataGraphTraversal.h"
+#include "trackball.h"
+#include "driveInterface.h"
+#include "transform2sg.h"
+#include "texture.h"
+#include "texturePool.h"
+#include "textureTransition.h"
+#include "textureAttribute.h"
+#include "interactiveGraphicsPipe.h"
+#include "noninteractiveGraphicsPipe.h"
+#include "graphicsWindow.h"
 #include "plist.h"
-#include <lightTransition.h>
-#include <lightAttribute.h>
-#include <materialTransition.h>
-#include <materialAttribute.h>
-#include <animControl.h>
-#include <animControlCollection.h>
-#include <auto_bind.h>
-#include <ambientLight.h>
-#include <directionalLight.h>
-#include <pointLight.h>
-#include <spotlight.h>
-#include <dconfig.h>
-#include <cullFaceTransition.h>
-#include <cullFaceAttribute.h>
-#include <pruneTransition.h>
-#include <dftraverser.h>
-#include <renderBuffer.h>
-#include <loader.h>
-#include <fogTransition.h>
-#include <fogAttribute.h>
-#include <clockObject.h>
-#include <compose_matrix.h>
-#include <notify.h>
-#include <nullTransitionWrapper.h>
-#include <nullAttributeWrapper.h>
-#include <nullLevelState.h>
-#include <sceneGraphReducer.h>
-#include <textNode.h>
-#include <depthTestTransition.h>
-#include <depthWriteTransition.h>
-#include <orthoProjection.h>
-#include <transparencyTransition.h>
-#include <bamReader.h>
-#include <collisionRay.h>
-#include <collisionNode.h>
-#include <collisionTraverser.h>
-#include <collisionHandlerFloor.h>
-#include <nodePath.h>
-#include <multiplexStream.h>
-#include <dSearchPath.h>
+#include "lightTransition.h"
+#include "lightAttribute.h"
+#include "materialTransition.h"
+#include "materialAttribute.h"
+#include "animControl.h"
+#include "animControlCollection.h"
+#include "auto_bind.h"
+#include "ambientLight.h"
+#include "directionalLight.h"
+#include "pointLight.h"
+#include "spotlight.h"
+#include "dconfig.h"
+#include "cullFaceTransition.h"
+#include "cullFaceAttribute.h"
+#include "pruneTransition.h"
+#include "dftraverser.h"
+#include "renderBuffer.h"
+#include "loader.h"
+#include "fogTransition.h"
+#include "fogAttribute.h"
+#include "clockObject.h"
+#include "compose_matrix.h"
+#include "notify.h"
+#include "nullTransitionWrapper.h"
+#include "nullLevelState.h"
+#include "sceneGraphReducer.h"
+#include "textNode.h"
+#include "depthTestTransition.h"
+#include "depthWriteTransition.h"
+#include "orthoProjection.h"
+#include "transparencyTransition.h"
+#include "bamReader.h"
+#include "collisionRay.h"
+#include "collisionNode.h"
+#include "collisionTraverser.h"
+#include "collisionHandlerFloor.h"
+#include "nodePath.h"
+#include "multiplexStream.h"
+#include "dSearchPath.h"
 
 #ifdef USE_IPC
-#include <ipc_file.h>
-#include <ipc_mutex.h>
-#include <ipc_thread.h>
+#include "ipc_file.h"
+#include "ipc_mutex.h"
+#include "ipc_thread.h"
 #endif
 
 Configure(framework);
@@ -118,7 +117,9 @@ AppTraverser *app_traverser;
 PT_NamedNode data_root;
 PT_NamedNode root;
 PT(GeomNode) geomnode;
+PT_NamedNode render_top;
 PT_NamedNode render;
+NodeRelation *render_arc;
 PT_NamedNode cameras;
 PT(MouseAndKeyboard) mak;
 PT(MouseWatcher) mouse_watcher;
@@ -128,7 +129,6 @@ PT(DriveInterface) drive_interface;
 static Node *current_trackball = NULL;
 static Node *alt_trackball = NULL;
 
-NodeAttributes initial_state;
 Texture* ttex;
 PT(GraphicsPipe) main_pipe;
 PT(GraphicsPipe) rib_pipe;
@@ -217,7 +217,7 @@ class NormalAddTraverser :
   public TraverserVisitor<NullTransitionWrapper, NullLevelState> {
 public:
   NormalAddTraverser(GraphicsStateGuardian *gsg) : _gsg(gsg) {}
-  bool reached_node(Node*, NullAttributeWrapper&, NullLevelState&);
+  bool reached_node(Node*, NullTransitionWrapper&, NullLevelState&);
 
   // No need to declare a forward_arc() function that simply returns
   // true; this is the default behavior.
@@ -227,7 +227,7 @@ public:
 };
 
 bool NormalAddTraverser::
-reached_node(Node *node, NullAttributeWrapper &, NullLevelState &) {
+reached_node(Node *node, NullTransitionWrapper &, NullLevelState &) {
   if (node->is_of_type(GeomNode::get_class_type())) {
     GeomNorms *gn = new GeomNorms;
     GeomNode *geom = DCAST(GeomNode, node);
@@ -286,13 +286,13 @@ class NormalDelTraverser :
   public TraverserVisitor<NullTransitionWrapper, NullLevelState> {
 public:
   NormalDelTraverser(GraphicsStateGuardian *gsg) : _gsg(gsg) {}
-  bool reached_node(Node*, NullAttributeWrapper&, NullLevelState&);
+  bool reached_node(Node*, NullTransitionWrapper&, NullLevelState&);
 public:
   GraphicsStateGuardian *_gsg;
 };
 
 bool NormalDelTraverser::
-reached_node(Node *node, NullAttributeWrapper &, NullLevelState &) {
+reached_node(Node *node, NullTransitionWrapper &, NullLevelState &) {
   if (node->is_of_type(GeomNode::get_class_type())) {
     GeomNode *geom = DCAST(GeomNode, node);
     int i, j;
@@ -313,11 +313,11 @@ reached_node(Node *node, NullAttributeWrapper &, NullLevelState &) {
 }
 
 void render_frame(GraphicsPipe *pipe) {
-  app_traverser->traverse(render);
+  app_traverser->traverse(render_top);
   int num_windows = pipe->get_num_windows();
   for (int w = 0; w < num_windows; w++) {
     GraphicsWindow *win = pipe->get_window(w);
-    win->get_gsg()->render_frame(initial_state);
+    win->get_gsg()->render_frame();
   }
   ClockObject::get_global_clock()->tick();
   throw_event("NewFrame");
@@ -343,17 +343,17 @@ void display_func( void ) {
 void set_lighting(bool enabled) {
   if (enabled) {
     // Enable the lights on the initial state.
-    LightAttribute *la = new LightAttribute;
+    PT(LightTransition) la = new LightTransition;
     la->set_on(light.p());
 
     if (have_dlight) {
       la->set_on(dlight.p());
     }
-    initial_state.set_attribute(LightTransition::get_class_type(), la);
+    render_arc->set_transition(la);
 
   } else {
     // Remove the lights from the initial state.
-    initial_state.clear_attribute(LightTransition::get_class_type());
+    render_arc->clear_transition(LightTransition::get_class_type());
   }
 }
 
@@ -368,7 +368,7 @@ class IdleCallback : public GraphicsWindow::Callback {
       // Perform the collision traversal, if we have a collision
       // traverser standing by.
       if (col_trans != (CollisionTraverser *)NULL) {
-        col_trans->traverse(render);
+        col_trans->traverse(render_top);
       }
 
       // Throw any events generated recently.
@@ -620,12 +620,12 @@ void event_t(CPT_Event) {
   textures_enabled = !textures_enabled;
   if (textures_enabled) {
     // Remove the override from the initial state.
-    initial_state.clear_attribute(TextureTransition::get_class_type());
+    render_arc->clear_transition(TextureTransition::get_class_type());
   } else {
     // Set an override on the initial state to disable texturing.
-    TextureAttribute *ta = new TextureAttribute;
+    TextureTransition *ta = new TextureTransition;
     ta->set_priority(100);
-    initial_state.set_attribute(TextureTransition::get_class_type(), ta);
+    render_arc->set_transition(ta);
   }
 }
 
@@ -644,21 +644,17 @@ void event_w(CPT_Event) {
   wireframe_mode = !wireframe_mode;
   if (!wireframe_mode) {
     // Set the normal, filled mode on the render arc.
-    RenderModeAttribute *rma = new RenderModeAttribute;
-    rma->set_mode(RenderModeProperty::M_filled);
-    CullFaceAttribute *cfa = new CullFaceAttribute;
-    cfa->set_mode(CullFaceProperty::M_cull_clockwise);
-    initial_state.set_attribute(RenderModeTransition::get_class_type(), rma);
-    initial_state.set_attribute(CullFaceTransition::get_class_type(), cfa);
+    RenderModeTransition *rma = new RenderModeTransition(RenderModeProperty::M_filled);
+    CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_clockwise);
+    render_arc->set_transition(rma);
+    render_arc->set_transition(cfa);
 
   } else {
     // Set the initial state up for wireframe mode.
-    RenderModeAttribute *rma = new RenderModeAttribute;
-    rma->set_mode(RenderModeProperty::M_wireframe);
-    CullFaceAttribute *cfa = new CullFaceAttribute;
-    cfa->set_mode(CullFaceProperty::M_cull_none);
-    initial_state.set_attribute(RenderModeTransition::get_class_type(), rma);
-    initial_state.set_attribute(CullFaceTransition::get_class_type(), cfa);
+    RenderModeTransition *rma = new RenderModeTransition(RenderModeProperty::M_wireframe);
+    CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_none);
+    render_arc->set_transition(rma);
+    render_arc->set_transition(cfa);
   }
 }
 
@@ -669,14 +665,12 @@ void event_b(CPT_Event) {
   backface_mode = !backface_mode;
   if (backface_mode) {
     material->set_twoside(true);
-    CullFaceAttribute *cfa = new CullFaceAttribute;
-    cfa->set_mode(CullFaceProperty::M_cull_none);
-    initial_state.set_attribute(CullFaceTransition::get_class_type(), cfa);
+    CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_none);
+    render_arc->set_transition(cfa);
   } else {
     material->set_twoside(false);
-    CullFaceAttribute *cfa = new CullFaceAttribute;
-    cfa->set_mode(CullFaceProperty::M_cull_clockwise);
-    initial_state.set_attribute(CullFaceTransition::get_class_type(), cfa);
+    CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_clockwise);
+    render_arc->set_transition(cfa);
   }
 }
 
@@ -734,11 +728,11 @@ void event_n(CPT_Event) {
   normals_on = !normals_on;
   if (normals_on) {
     NormalAddTraverser trav(main_win->get_gsg());
-    df_traverse(render, trav, NullAttributeWrapper(), NullLevelState(),
+    df_traverse(render, trav, NullTransitionWrapper(), NullLevelState(),
                 RenderRelation::get_class_type());
   } else {
     NormalDelTraverser trav(main_win->get_gsg());
-    df_traverse(render, trav, NullAttributeWrapper(), NullLevelState(),
+    df_traverse(render, trav, NullTransitionWrapper(), NullLevelState(),
                 RenderRelation::get_class_type());
   }
 }
@@ -911,12 +905,11 @@ void event_g(CPT_Event) {
 
   fog_mode = !fog_mode;
   if (fog_mode) {
-    FogAttribute *fa = new FogAttribute;
-    fa->set_on(fog);
-    initial_state.set_attribute(FogTransition::get_class_type(), fa);
+    FogTransition *fa = new FogTransition(fog);
+    render_arc->set_transition(fa);
   } else {
-    FogAttribute *fa = new FogAttribute;
-    initial_state.set_attribute(FogTransition::get_class_type(), fa);
+    FogTransition *fa = new FogTransition;
+    render_arc->set_transition(fa);
   }
 }
 
@@ -997,8 +990,8 @@ static void move_gridded_stuff(GriddedMotionType gridmotiontype,gridded_file_inf
   for(int i = 0; i < size; i++) {
   double time_delta = (now-InfoArr[i].starttime);
   #define DO_FP_MODULUS(VAL,MAXVAL)  \
-    {if(VAL > MAXVAL) {int idivresult = VAL / (float)MAXVAL;  VAL=VAL-idivresult*MAXVAL;} else  \
-    if(VAL < -MAXVAL) {int idivresult = VAL / (float)MAXVAL;  VAL=VAL+idivresult*MAXVAL;}}
+    {if(VAL > MAXVAL) {int idivresult = (int)(VAL / (float)MAXVAL);  VAL=VAL-idivresult*MAXVAL;} else  \
+    if(VAL < -MAXVAL) {int idivresult = (int)(VAL / (float)MAXVAL);  VAL=VAL+idivresult*MAXVAL;}}
   
   // probably should use panda lerps for this stuff, but I dont understand how
 
@@ -1112,8 +1105,8 @@ int framework_main(int argc, char *argv[]) {
   int gridrepeats=1;
   GriddedMotionType gridmotiontype = None;
 
-  bool bRotateGriddedObjs = false;
-  bool bMoveGriddedObjs = false;
+  //  bool bRotateGriddedObjs = false;
+  //  bool bMoveGriddedObjs = false;
 
   for (int a = 1; a < argc; a++) {
     if ((argv[a] != (char*)0L) && ((argv[a])[0] != '-') &&
@@ -1187,32 +1180,32 @@ int framework_main(int argc, char *argv[]) {
     extra_overrides_func(override, conf);
 
   // Create the render node
+  render_top = new NamedNode("render_top");
   render = new NamedNode("render");
+  render_arc = new RenderRelation(render_top, render);
 
-  ChanConfig chanConfig = ChanConfig(main_pipe, conf, render, override);
+  ChanConfig chanConfig = ChanConfig(main_pipe, conf, render_top, override);
   main_win = chanConfig.get_win();
   assert(main_win != (GraphicsWindow*)0L);
   cameras = chanConfig.get_group_node(0);
   cameras->set_name("cameras");
   for(int group_node_index=1;group_node_index<chanConfig.get_num_groups();
       group_node_index++) {
-    RenderRelation *arc2 = 
-      new RenderRelation(render, chanConfig.get_group_node(group_node_index));
+    new RenderRelation(render, chanConfig.get_group_node(group_node_index));
   }
   RenderRelation* arc1 = new RenderRelation(render, cameras);
 
   // is ok if this doesn't work or returns NULL
   if (rib_pipe != (GraphicsPipe*)0L) { 
-    ChanConfig chanConfig = ChanConfig(rib_pipe, "single", render, override);
+    ChanConfig chanConfig = ChanConfig(rib_pipe, "single", render_top, override);
     rib_win = chanConfig.get_win();
     NamedNode *rib_cameras = chanConfig.get_group_node(0);
     rib_cameras->set_name("rib_cameras");
     for(int rib_group_node_index=1;
         rib_group_node_index<chanConfig.get_num_groups();
         rib_group_node_index++) {
-      RenderRelation *ribarc = 
-        new RenderRelation(render, 
-                           chanConfig.get_group_node(rib_group_node_index));
+      new RenderRelation(render, 
+                         chanConfig.get_group_node(rib_group_node_index));
     }
     new RenderRelation(render, rib_cameras);
   }
@@ -1238,16 +1231,14 @@ int framework_main(int argc, char *argv[]) {
 #endif
 
   // Turn on culling.
-  CullFaceAttribute *cfa = new CullFaceAttribute;
-  cfa->set_mode(CullFaceProperty::M_cull_clockwise);
-  initial_state.set_attribute(CullFaceTransition::get_class_type(), cfa);
+  CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_clockwise);
+  render_arc->set_transition(cfa);
 
-  // Set up a default material
+  // Set up a default material.
   material = new Material;
   material->set_ambient( Colorf( 1, 1, 1, 1 ) );
-  MaterialAttribute *ma = new MaterialAttribute;
-  ma->set_on(material);
-  initial_state.set_attribute(MaterialTransition::get_class_type(), ma);
+  MaterialTransition *ma = new MaterialTransition(material);
+  render_arc->set_transition(ma);
 
   // Set up a default fog
   fog = new Fog;
@@ -1363,164 +1354,163 @@ int framework_main(int argc, char *argv[]) {
       filename.resolve_filename(local_path);
 
       PT_Node node = loader.load_sync(filename);
-
+      
       if (node == (Node *)NULL) {
-                  framework_cat.error() << "Unable to load file " << filename << "\n";
-                  continue;
-          }
+        framework_cat.error() << "Unable to load file " << filename << "\n";
+        continue;
+      }
+      
+      new RenderRelation(root, node);
+    }
 
-          RenderRelation *pArc = new RenderRelation(root, node);
+    if(!gridded_files.empty()) {
+      
+      typedef RenderRelation *RenderRelationPtr;
+      
+      gridded_files_size= gridded_files.size();
+      pNodeArr = new PT_Node[gridded_files.size()*gridrepeats];
+      pRRptrArr = new RenderRelationPtr[gridded_files.size()*gridrepeats];
+      InfoArr = new gridded_file_info[gridded_files.size()*gridrepeats];
+      
+      int j=0;
+      
+      for (fi = gridded_files.begin(); fi != gridded_files.end(); (++fi),j++) {
+        Filename filename = (*fi);
+        
+        filename.resolve_filename(local_path);
+        
+        pNodeArr[j] = loader.load_sync(filename);
+        
+        if (pNodeArr[j] == (Node *)NULL) {
+          framework_cat.error() << "Unable to load file " << filename << "\n";
+          j--;
+          gridded_files_size--;
+          continue;
         }
-
-        if(!gridded_files.empty()) {
-
-                typedef RenderRelation *RenderRelationPtr;
-
-                gridded_files_size= gridded_files.size();
-                pNodeArr = new PT_Node[gridded_files.size()*gridrepeats];
-                pRRptrArr = new RenderRelationPtr[gridded_files.size()*gridrepeats];
-                InfoArr = new gridded_file_info[gridded_files.size()*gridrepeats];
-
-
-                int j=0;
-
-                for (fi = gridded_files.begin(); fi != gridded_files.end(); (++fi),j++) {
-                          Filename filename = (*fi);
-
-                          filename.resolve_filename(local_path);
-
-                          pNodeArr[j] = loader.load_sync(filename);
-
-                          if (pNodeArr[j] == (Node *)NULL) {
-                                  framework_cat.error() << "Unable to load file " << filename << "\n";
-                                  j--;
-                                  gridded_files_size--;
-                                  continue;
-                          }
-                }
-
-                gridwidth=1;
-                while(gridwidth*gridwidth < gridded_files_size*gridrepeats) {
-                        gridwidth++;
-                }
-
-                grid_pos_offset = -gridwidth*GRIDCELLSIZE/2.0;
-                wander_area_pos_offset = -max(fabs(grid_pos_offset),MIN_WANDERAREA_DIMENSION/2.0);
-
-                float xpos = grid_pos_offset;
-                float ypos = grid_pos_offset;
-                int filenum=0;
-
-                srand( (unsigned)time( NULL ) );
-
-                double now = ClockObject::get_global_clock()->get_frame_time();
-
-                for(int passnum=0;passnum<gridrepeats;passnum++) {
-                  for (j = 0; j < gridded_files_size; j++,filenum++) {
-
-                          if(passnum>0) {
+      }
+      
+      gridwidth=1;
+      while(gridwidth*gridwidth < gridded_files_size*gridrepeats) {
+        gridwidth++;
+      }
+      
+      grid_pos_offset = -gridwidth*GRIDCELLSIZE/2.0;
+      wander_area_pos_offset = -max(fabs(grid_pos_offset),MIN_WANDERAREA_DIMENSION/2.0);
+      
+      float xpos = grid_pos_offset;
+      float ypos = grid_pos_offset;
+      int filenum=0;
+      
+      srand( (unsigned)time( NULL ) );
+      
+      double now = ClockObject::get_global_clock()->get_frame_time();
+
+      for(int passnum=0;passnum<gridrepeats;passnum++) {
+        for (j = 0; j < gridded_files_size; j++,filenum++) {
+
+          if(passnum>0) {
                                 // cant directly instance characters due to LOD problems,
                                 // must copy using copy_subgraph for now
 
-                                  pNodeArr[filenum] = pNodeArr[j]->copy_subgraph(RenderRelation::get_class_type());
-                          }
-
-                          pRRptrArr[filenum] = new RenderRelation(root, pNodeArr[filenum]);
+            pNodeArr[filenum] = pNodeArr[j]->copy_subgraph(RenderRelation::get_class_type());
+          }
 
-                          LMatrix4f xfm_mat,tmat1,tmat2;
+          pRRptrArr[filenum] = new RenderRelation(root, pNodeArr[filenum]);
 
-                          if(gridmotiontype==Rotation) {
+          LMatrix4f xfm_mat,tmat1,tmat2;
 
-                                  #define MIN_REVOLUTION_ANGVEL 30
-                                  #define MAX_REVOLUTION_ANGVEL 60
+          if(gridmotiontype==Rotation) {
 
-                                  #define MIN_ROTATION_ANGVEL 30
-                                  #define MAX_ROTATION_ANGVEL 600
+#define MIN_REVOLUTION_ANGVEL 30
+#define MAX_REVOLUTION_ANGVEL 60
 
-                                  #define MAX_RADIUS 4.0*GRIDCELLSIZE
-                                  #define MIN_RADIUS 0.1*GRIDCELLSIZE
+#define MIN_ROTATION_ANGVEL 30
+#define MAX_ROTATION_ANGVEL 600
 
-                                  InfoArr[filenum].starttime = now;
+#define MAX_RADIUS 4.0*GRIDCELLSIZE
+#define MIN_RADIUS 0.1*GRIDCELLSIZE
 
-                                  InfoArr[filenum].xcenter=xpos;
-                                  InfoArr[filenum].ycenter=ypos;
-                                  InfoArr[filenum].ang1=RANDFRAC * 360.0;
-                                  InfoArr[filenum].ang1_vel=((MAX_REVOLUTION_ANGVEL-MIN_REVOLUTION_ANGVEL) * RANDFRAC) + MIN_REVOLUTION_ANGVEL;
+            InfoArr[filenum].starttime = now;
 
-                                  InfoArr[filenum].ang2=RANDFRAC * 360.0;
-                                  InfoArr[filenum].ang2_vel=((MAX_ROTATION_ANGVEL-MIN_ROTATION_ANGVEL) * RANDFRAC) + MIN_ROTATION_ANGVEL;
+            InfoArr[filenum].xcenter=xpos;
+            InfoArr[filenum].ycenter=ypos;
+            InfoArr[filenum].ang1=RANDFRAC * 360.0;
+            InfoArr[filenum].ang1_vel=((MAX_REVOLUTION_ANGVEL-MIN_REVOLUTION_ANGVEL) * RANDFRAC) + MIN_REVOLUTION_ANGVEL;
 
-                                  InfoArr[filenum].radius = (RANDFRAC * (MAX_RADIUS-MIN_RADIUS)) + MIN_RADIUS;
+            InfoArr[filenum].ang2=RANDFRAC * 360.0;
+            InfoArr[filenum].ang2_vel=((MAX_ROTATION_ANGVEL-MIN_ROTATION_ANGVEL) * RANDFRAC) + MIN_ROTATION_ANGVEL;
 
-                                  if(RANDFRAC>0.5) {
-                                          InfoArr[filenum].ang1_vel=-InfoArr[filenum].ang1_vel;
-                                  }
+            InfoArr[filenum].radius = (RANDFRAC * (MAX_RADIUS-MIN_RADIUS)) + MIN_RADIUS;
 
-                                  if(RANDFRAC>0.5) {
-                                          InfoArr[filenum].ang2_vel=-InfoArr[filenum].ang2_vel;
-                                  }
+            if(RANDFRAC>0.5) {
+              InfoArr[filenum].ang1_vel=-InfoArr[filenum].ang1_vel;
+            }
 
-                                  // xforms happen left to right
-                                  LVector2f new_center = LVector2f(InfoArr[filenum].radius,0.0) *
-                                                   LMatrix3f::rotate_mat(InfoArr[filenum].ang1);
+            if(RANDFRAC>0.5) {
+              InfoArr[filenum].ang2_vel=-InfoArr[filenum].ang2_vel;
+            }
 
-                                  const LVector3f rotate_axis(0.0, 0.0, 1.0);
+            // xforms happen left to right
+            LVector2f new_center = LVector2f(InfoArr[filenum].radius,0.0) *
+              LMatrix3f::rotate_mat(InfoArr[filenum].ang1);
 
-                                  LVector3f translate_vec(xpos+new_center._v.v._0,
-                                                                                  ypos+new_center._v.v._1,
-                                                                                  0.0);
+            const LVector3f rotate_axis(0.0, 0.0, 1.0);
 
-                                  LMatrix4f::rotate_mat_normaxis(InfoArr[filenum].ang2,rotate_axis,tmat1);
-                                  tmat2 = LMatrix4f::translate_mat(translate_vec);
-                                  xfm_mat = tmat1 * tmat2;
-                          } else if(gridmotiontype==LinearMotion) {
+            LVector3f translate_vec(xpos+new_center._v.v._0,
+                                    ypos+new_center._v.v._1,
+                                    0.0);
 
-                                      #define MIN_VEL 2.0
-                                      #define MAX_VEL (fabs(wander_area_pos_offset))
+            LMatrix4f::rotate_mat_normaxis(InfoArr[filenum].ang2,rotate_axis,tmat1);
+            tmat2 = LMatrix4f::translate_mat(translate_vec);
+            xfm_mat = tmat1 * tmat2;
+          } else if(gridmotiontype==LinearMotion) {
 
-                                          InfoArr[filenum].vel=((MAX_VEL-MIN_VEL) * RANDFRAC) + MIN_VEL;
+#define MIN_VEL 2.0
+#define MAX_VEL (fabs(wander_area_pos_offset))
 
-                                          InfoArr[filenum].xstart=xpos;
-                                          InfoArr[filenum].ystart=ypos;
+            InfoArr[filenum].vel=((MAX_VEL-MIN_VEL) * RANDFRAC) + MIN_VEL;
 
-                                          InfoArr[filenum].xend = RANDFRAC*fabs(2.0*wander_area_pos_offset) + wander_area_pos_offset;
-                                          InfoArr[filenum].yend = RANDFRAC*fabs(2.0*wander_area_pos_offset) + wander_area_pos_offset;
+            InfoArr[filenum].xstart=xpos;
+            InfoArr[filenum].ystart=ypos;
 
-                                          InfoArr[filenum].starttime = now;
+            InfoArr[filenum].xend = RANDFRAC*fabs(2.0*wander_area_pos_offset) + wander_area_pos_offset;
+            InfoArr[filenum].yend = RANDFRAC*fabs(2.0*wander_area_pos_offset) + wander_area_pos_offset;
 
-                                          float xdel = InfoArr[filenum].xdel = InfoArr[filenum].xend-InfoArr[filenum].xstart;
-                                          float ydel = InfoArr[filenum].ydel = InfoArr[filenum].yend-InfoArr[filenum].ystart;
+            InfoArr[filenum].starttime = now;
 
-                                          InfoArr[filenum].endtime = csqrt(xdel*xdel+ydel*ydel)/InfoArr[filenum].vel;
+            float xdel = InfoArr[filenum].xdel = InfoArr[filenum].xend-InfoArr[filenum].xstart;
+            float ydel = InfoArr[filenum].ydel = InfoArr[filenum].yend-InfoArr[filenum].ystart;
 
-                                          InfoArr[filenum].timedel = InfoArr[filenum].endtime - InfoArr[filenum].starttime;
+            InfoArr[filenum].endtime = csqrt(xdel*xdel+ydel*ydel)/InfoArr[filenum].vel;
 
-                                          const LVector3f rotate_axis(0.0, 0.0, 1.0);
-                                          float ang = rad_2_deg(atan2(-xdel,ydel));
+            InfoArr[filenum].timedel = InfoArr[filenum].endtime - InfoArr[filenum].starttime;
 
-                                          LMatrix4f::rotate_mat_normaxis(ang,rotate_axis,InfoArr[filenum].rotmat);
+            const LVector3f rotate_axis(0.0, 0.0, 1.0);
+            float ang = rad_2_deg(atan2(-xdel,ydel));
 
-                                          LVector3f translate_vec(xpos, ypos, 0.0);
-                                          LMatrix4f tmat2 = LMatrix4f::translate_mat(translate_vec);
+            LMatrix4f::rotate_mat_normaxis(ang,rotate_axis,InfoArr[filenum].rotmat);
 
-                                          xfm_mat = InfoArr[filenum].rotmat * tmat2;
-                          } else {
-                                  LVector3f translate_vec(xpos, ypos, 0.0);
-                                  xfm_mat = LMatrix4f::translate_mat(translate_vec);
-                          }
+            LVector3f translate_vec(xpos, ypos, 0.0);
+            LMatrix4f tmat2 = LMatrix4f::translate_mat(translate_vec);
 
-                          pRRptrArr[filenum]->set_transition(new TransformTransition(xfm_mat));
+            xfm_mat = InfoArr[filenum].rotmat * tmat2;
+          } else {
+            LVector3f translate_vec(xpos, ypos, 0.0);
+            xfm_mat = LMatrix4f::translate_mat(translate_vec);
+          }
 
-                          if(((filenum+1) % gridwidth) == 0) {
-                                  xpos= -gridwidth*GRIDCELLSIZE/2.0;
-                                  ypos+=GRIDCELLSIZE;
-                          } else {
-                                  xpos+=GRIDCELLSIZE;
-                          }
-                        }
-                }
+          pRRptrArr[filenum]->set_transition(new TransformTransition(xfm_mat));
 
+          if(((filenum+1) % gridwidth) == 0) {
+            xpos= -gridwidth*GRIDCELLSIZE/2.0;
+            ypos+=GRIDCELLSIZE;
+          } else {
+            xpos+=GRIDCELLSIZE;
+          }
         }
+      }
+
+    }
 
     // If we happened to load up both a character file and its
     // matching animation file, attempt to bind them together now.

+ 199 - 236
panda/src/glgsg/glGraphicsStateGuardian.cxx

@@ -42,52 +42,29 @@
 #include <spotlight.h>
 #include <GL/glu.h>
 #include <projectionNode.h>
-#include <transformAttribute.h>
 #include <transformTransition.h>
-#include <colorMatrixAttribute.h>
 #include <colorMatrixTransition.h>
-#include <alphaTransformAttribute.h>
 #include <alphaTransformTransition.h>
-#include <colorAttribute.h>
 #include <colorTransition.h>
-#include <lightAttribute.h>
 #include <lightTransition.h>
-#include <textureAttribute.h>
 #include <textureTransition.h>
-#include <renderModeAttribute.h>
 #include <renderModeTransition.h>
-#include <materialAttribute.h>
 #include <materialTransition.h>
-#include <colorBlendAttribute.h>
 #include <colorBlendTransition.h>
-#include <colorMaskAttribute.h>
 #include <colorMaskTransition.h>
-#include <texMatrixAttribute.h>
 #include <texMatrixTransition.h>
-#include <texGenAttribute.h>
 #include <texGenTransition.h>
-#include <textureApplyAttribute.h>
 #include <textureApplyTransition.h>
-#include <clipPlaneAttribute.h>
 #include <clipPlaneTransition.h>
-#include <transparencyAttribute.h>
 #include <transparencyTransition.h>
-#include <fogAttribute.h>
 #include <fogTransition.h>
-#include <linesmoothAttribute.h>
 #include <linesmoothTransition.h>
-#include <depthTestAttribute.h>
 #include <depthTestTransition.h>
-#include <depthWriteAttribute.h>
 #include <depthWriteTransition.h>
-#include <cullFaceAttribute.h>
 #include <cullFaceTransition.h>
-#include <stencilAttribute.h>
 #include <stencilTransition.h>
-#include <pointShapeAttribute.h>
 #include <pointShapeTransition.h>
 #include <polygonOffsetTransition.h>
-#include <polygonOffsetAttribute.h>
 #include <clockObject.h>
 #include <pStatTimer.h>
 #include <string_utils.h>
@@ -317,11 +294,11 @@ reset() {
 
   // Make sure the GL state matches all of our initial attribute
   // states.
-  PT(DepthTestAttribute) dta = new DepthTestAttribute;
-  PT(DepthWriteAttribute) dwa = new DepthWriteAttribute;
-  PT(CullFaceAttribute) cfa = new CullFaceAttribute;
-  PT(LightAttribute) la = new LightAttribute;
-  PT(TextureAttribute) ta = new TextureAttribute;
+  PT(DepthTestTransition) dta = new DepthTestTransition;
+  PT(DepthWriteTransition) dwa = new DepthWriteTransition;
+  PT(CullFaceTransition) cfa = new CullFaceTransition;
+  PT(LightTransition) la = new LightTransition;
+  PT(TextureTransition) ta = new TextureTransition;
 
   dta->issue(this);
   dwa->issue(this);
@@ -354,15 +331,14 @@ clear(const RenderBuffer &buffer) {
   nassertv(buffer._gsg == this);
   int buffer_type = buffer._buffer_type;
   GLbitfield mask = 0;
-  NodeAttributes state;
+  NodeTransitions state;
 
   if (buffer_type & RenderBuffer::T_color) {
     call_glClearColor(_color_clear_value[0],
                       _color_clear_value[1],
                       _color_clear_value[2],
                       _color_clear_value[3]);
-    state.set_attribute(ColorMaskTransition::get_class_type(),
-                        new ColorMaskAttribute);
+    state.set_transition(new ColorMaskTransition);
     mask |= GL_COLOR_BUFFER_BIT;
 
     set_draw_buffer(buffer);
@@ -375,8 +351,7 @@ clear(const RenderBuffer &buffer) {
     // In order to clear the depth buffer, the depth mask must enable
     // writing to the depth buffer.
     if (!_depth_mask) {
-      state.set_attribute(DepthWriteTransition::get_class_type(),
-                          new DepthWriteAttribute);
+      state.set_transition(new DepthWriteTransition);
     }
   }
 
@@ -467,7 +442,7 @@ prepare_display_region() {
 //               pre- and post-processing like swapping buffers.
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-render_frame(const AllAttributesWrapper &initial_state) {
+render_frame() {
 #ifdef GSG_VERBOSE
   glgsg_cat.debug()
     << "begin frame " << ClockObject::get_global_clock()->get_frame_count()
@@ -524,7 +499,7 @@ render_frame(const AllAttributesWrapper &initial_state) {
                   cam->is_active() && cam->get_scene() != (Node *)NULL) {
                 DisplayRegionStack old_dr = push_display_region(dr);
                 prepare_display_region();
-                render_scene(cam->get_scene(), cam, initial_state);
+                render_scene(cam->get_scene(), cam);
                 pop_display_region(old_dr);
               }
             }
@@ -580,8 +555,7 @@ render_frame(const AllAttributesWrapper &initial_state) {
 //               may be modified during rendering.
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-render_scene(Node *root, ProjectionNode *projnode,
-             const AllAttributesWrapper &initial_state) {
+render_scene(Node *root, ProjectionNode *projnode) {
 #ifdef GSG_VERBOSE
   _pass_number = 0;
   glgsg_cat.debug()
@@ -590,7 +564,7 @@ render_scene(Node *root, ProjectionNode *projnode,
 #endif
   _current_root_node = root;
 
-  render_subgraph(_render_traverser, root, projnode, initial_state,
+  render_subgraph(_render_traverser, root, projnode,
                   AllTransitionsWrapper());
 
 #ifdef GSG_VERBOSE
@@ -611,7 +585,6 @@ render_scene(Node *root, ProjectionNode *projnode,
 void GLGraphicsStateGuardian::
 render_subgraph(RenderTraverser *traverser,
                 Node *subgraph, ProjectionNode *projnode,
-                const AllAttributesWrapper &initial_state,
                 const AllTransitionsWrapper &net_trans) {
   // Calling activate() frequently seems to be intolerably expensive
   // on some platforms.  We'll limit ourselves for now to calling it
@@ -661,7 +634,7 @@ render_subgraph(RenderTraverser *traverser,
   AllTransitionsWrapper sub_trans = net_trans;
   sub_trans.set_transition(new TransformTransition(modelview_mat));
 
-  render_subgraph(traverser, subgraph, initial_state, sub_trans);
+  render_subgraph(traverser, subgraph, sub_trans);
 
   _current_projection_node = old_projection_node;
   _current_projection_mat = old_projection_mat;
@@ -688,7 +661,6 @@ render_subgraph(RenderTraverser *traverser,
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 render_subgraph(RenderTraverser *traverser, Node *subgraph,
-                const AllAttributesWrapper &initial_state,
                 const AllTransitionsWrapper &net_trans) {
 #ifdef GSG_VERBOSE
   glgsg_cat.debug()
@@ -698,7 +670,7 @@ render_subgraph(RenderTraverser *traverser, Node *subgraph,
   //  activate();
 
   nassertv(traverser != (RenderTraverser *)NULL);
-  traverser->traverse(subgraph, initial_state, net_trans);
+  traverser->traverse(subgraph, net_trans);
 
 #ifdef GSG_VERBOSE
   glgsg_cat.debug()
@@ -972,8 +944,8 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
   // save the modelview matrix
   LMatrix4f modelview_mat;
 
-  const TransformAttribute *ctatt;
-  if (!get_attribute_into(ctatt, _state, TransformTransition::get_class_type()))
+  const TransformTransition *ctatt;
+  if (!get_transition_into(ctatt, _state, TransformTransition::get_class_type()))
     modelview_mat = LMatrix4f::ident_mat();
   else
     modelview_mat = ctatt->get_matrix();
@@ -1029,15 +1001,15 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
   float scaled_width, scaled_height;
 
   // set up the texture-rendering state
-  NodeAttributes state;
+  NodeTransitions state;
 
-  TextureAttribute *ta = new TextureAttribute;
+  TextureTransition *ta = new TextureTransition;
   ta->set_on(tex);
-  state.set_attribute(TextureTransition::get_class_type(), ta);
+  state.set_transition(ta);
 
-  TextureApplyAttribute *taa = new TextureApplyAttribute;
+  TextureApplyTransition *taa = new TextureApplyTransition;
   taa->set_mode(TextureApplyProperty::M_modulate);
-  state.set_attribute(TextureApplyTransition::get_class_type(), taa);
+  state.set_transition(taa);
 
   set_state(state, false);
 
@@ -1046,8 +1018,8 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
 
   if (geom->get_alpha_disable() == false) {
     // figure out if alpha's enabled (if not, no reason to sort)
-    const TransparencyAttribute *ctratt;
-    if (get_attribute_into(ctratt, _state, TransparencyTransition::get_class_type()))
+    const TransparencyTransition *ctratt;
+    if (get_transition_into(ctratt, _state))
       alpha = true;
   }
 
@@ -2031,35 +2003,29 @@ draw_texture(TextureContext *tc, const DisplayRegion *dr) {
   DisplayRegionStack old_dr = push_display_region(dr);
   prepare_display_region();
 
-  NodeAttributes state;
-  CullFaceAttribute *cfa = new CullFaceAttribute;
+  NodeTransitions state;
+  CullFaceTransition *cfa = new CullFaceTransition;
   cfa->set_mode(CullFaceProperty::M_cull_none);
-  DepthTestAttribute *dta = new DepthTestAttribute;
+  DepthTestTransition *dta = new DepthTestTransition;
   dta->set_mode(DepthTestProperty::M_none);
-  DepthWriteAttribute *dwa = new DepthWriteAttribute;
+  DepthWriteTransition *dwa = new DepthWriteTransition;
   dwa->set_off();
-  TextureAttribute *ta = new TextureAttribute;
+  TextureTransition *ta = new TextureTransition;
   ta->set_on(tex);
-  TextureApplyAttribute *taa = new TextureApplyAttribute;
+  TextureApplyTransition *taa = new TextureApplyTransition;
   taa->set_mode(TextureApplyProperty::M_decal);
 
-  state.set_attribute(LightTransition::get_class_type(),
-                      new LightAttribute);
-  state.set_attribute(ColorMaskTransition::get_class_type(),
-                      new ColorMaskAttribute);
-  state.set_attribute(RenderModeTransition::get_class_type(),
-                      new RenderModeAttribute);
-  state.set_attribute(TexMatrixTransition::get_class_type(),
-                      new TexMatrixAttribute);
-  state.set_attribute(TransformTransition::get_class_type(),
-                      new TransformAttribute);
-  state.set_attribute(ColorBlendTransition::get_class_type(),
-                      new ColorBlendAttribute);
-  state.set_attribute(CullFaceTransition::get_class_type(), cfa);
-  state.set_attribute(DepthTestTransition::get_class_type(), dta);
-  state.set_attribute(DepthWriteTransition::get_class_type(), dwa);
-  state.set_attribute(TextureTransition::get_class_type(), ta);
-  state.set_attribute(TextureApplyTransition::get_class_type(), taa);
+  state.set_transition(new LightTransition);
+  state.set_transition(new ColorMaskTransition);
+  state.set_transition(new RenderModeTransition);
+  state.set_transition(new TexMatrixTransition);
+  state.set_transition(new TransformTransition);
+  state.set_transition(new ColorBlendTransition);
+  state.set_transition(cfa);
+  state.set_transition(dta);
+  state.set_transition(dwa);
+  state.set_transition(ta);
+  state.set_transition(taa);
   set_state(state, false);
 
   // We set up an orthographic projection that defines our entire
@@ -2248,7 +2214,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
-                  const NodeAttributes& na) {
+                  const NodeTransitions& na) {
   nassertv(pb != NULL && dr != NULL);
   nassertv(!pb->_image.empty());
   //  activate();
@@ -2256,30 +2222,22 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
   DisplayRegionStack old_dr = push_display_region(dr);
   prepare_display_region();
 
-  NodeAttributes state(na);
-  state.set_attribute(LightTransition::get_class_type(),
-                      new LightAttribute);
-  state.set_attribute(TextureTransition::get_class_type(),
-                      new TextureAttribute);
-  state.set_attribute(TransformTransition::get_class_type(),
-                      new TransformAttribute);
-  //state.set_attribute(ColorBlendTransition::get_class_type(),
-  //              new ColorBlendAttribute);
-  state.set_attribute(StencilTransition::get_class_type(),
-                      new StencilAttribute);
+  NodeTransitions state(na);
+  state.set_transition(new LightTransition);
+  state.set_transition(new TextureTransition);
+  state.set_transition(new TransformTransition);
+  //state.set_transition(new ColorBlendTransition);
+  state.set_transition(new StencilTransition);
 
   switch (pb->get_format()) {
   case PixelBuffer::F_depth_component:
     {
-      ColorMaskAttribute *cma = new ColorMaskAttribute;
-      cma->set_mask(0);
-      DepthTestAttribute *dta = new DepthTestAttribute;
-      dta->set_mode(DepthTestProperty::M_always);
-      DepthWriteAttribute *dwa = new DepthWriteAttribute;
-      dwa->set_on();
-      state.set_attribute(ColorMaskTransition::get_class_type(), cma);
-      state.set_attribute(DepthTestTransition::get_class_type(), dta);
-      state.set_attribute(DepthWriteTransition::get_class_type(), dwa);
+      ColorMaskTransition *cma = new ColorMaskTransition(0);
+      DepthTestTransition *dta = new DepthTestTransition(DepthTestProperty::M_always);
+      DepthWriteTransition *dwa = new DepthWriteTransition;
+      state.set_transition(cma);
+      state.set_transition(dta);
+      state.set_transition(dwa);
     }
     break;
 
@@ -2294,14 +2252,12 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
   case PixelBuffer::F_rgba8:
   case PixelBuffer::F_rgba12:
     {
-      ColorMaskAttribute *cma = new ColorMaskAttribute;
-      DepthTestAttribute *dta = new DepthTestAttribute;
-      dta->set_mode(DepthTestProperty::M_none);
-      DepthWriteAttribute *dwa = new DepthWriteAttribute;
-      dwa->set_off();
-      state.set_attribute(ColorMaskTransition::get_class_type(), cma);
-      state.set_attribute(DepthTestTransition::get_class_type(), dta);
-      state.set_attribute(DepthWriteTransition::get_class_type(), dwa);
+      ColorMaskTransition *cma = new ColorMaskTransition;
+      DepthTestTransition *dta = new DepthTestTransition(DepthTestProperty::M_none);
+      DepthWriteTransition *dwa = new DepthWriteTransition(DepthWriteTransition::off());
+      state.set_transition(cma);
+      state.set_transition(dta);
+      state.set_transition(dwa);
     }
     break;
   default:
@@ -2373,7 +2329,7 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
-                  const RenderBuffer &rb, const NodeAttributes& na) {
+                  const RenderBuffer &rb, const NodeTransitions& na) {
   //  activate();
   set_draw_buffer(rb);
   draw_pixel_buffer(pb, dr, na);
@@ -2639,7 +2595,7 @@ void GLGraphicsStateGuardian::apply_light( AmbientLight* )
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_transform(const TransformAttribute *attrib) {
+issue_transform(const TransformTransition *attrib) {
   //  activate();
 #ifdef GSG_VERBOSE
   glgsg_cat.debug()
@@ -2686,7 +2642,7 @@ issue_transform(const TransformAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_color_transform(const ColorMatrixAttribute *attrib) {
+issue_color_transform(const ColorMatrixTransition *attrib) {
   _current_color_mat = attrib->get_matrix();
 
   if (_current_color_mat == LMatrix4f::ident_mat()) {
@@ -2704,7 +2660,7 @@ issue_color_transform(const ColorMatrixAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_alpha_transform(const AlphaTransformAttribute *attrib) {
+issue_alpha_transform(const AlphaTransformTransition *attrib) {
   _current_alpha_offset= attrib->get_offset();
   _current_alpha_scale = attrib->get_scale();
 
@@ -2723,7 +2679,7 @@ issue_alpha_transform(const AlphaTransformAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_tex_matrix(const TexMatrixAttribute *attrib) {
+issue_tex_matrix(const TexMatrixTransition *attrib) {
   //  activate();
 #ifdef GSG_VERBOSE
   glgsg_cat.debug()
@@ -2740,7 +2696,7 @@ issue_tex_matrix(const TexMatrixAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_color(const ColorAttribute *attrib) {
+issue_color(const ColorTransition *attrib) {
   if (attrib->is_on()) {
     if (attrib->is_real()) {
       // The color attribute is "on" and "real": it specifies a scene
@@ -2773,7 +2729,7 @@ issue_color(const ColorAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_texture(const TextureAttribute *attrib) {
+issue_texture(const TextureTransition *attrib) {
   //  activate();
 
   if (attrib->is_on()) {
@@ -2793,7 +2749,7 @@ issue_texture(const TextureAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_tex_gen(const TexGenAttribute *attrib) {
+issue_tex_gen(const TexGenTransition *attrib) {
   //  activate();
   TexGenProperty::Mode mode = attrib->get_mode();
 
@@ -2846,7 +2802,7 @@ issue_tex_gen(const TexGenAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_material(const MaterialAttribute *attrib) {
+issue_material(const MaterialTransition *attrib) {
   //  activate();
   if (attrib->is_on()) {
     const Material *material = attrib->get_material();
@@ -2862,7 +2818,7 @@ issue_material(const MaterialAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_fog(const FogAttribute *attrib) {
+issue_fog(const FogTransition *attrib) {
   //  activate();
 
   if (attrib->is_on()) {
@@ -2882,7 +2838,7 @@ issue_fog(const FogAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_render_mode(const RenderModeAttribute *attrib) {
+issue_render_mode(const RenderModeTransition *attrib) {
   //  activate();
 
   RenderModeProperty::Mode mode = attrib->get_mode();
@@ -2910,9 +2866,9 @@ issue_render_mode(const RenderModeAttribute *attrib) {
 //       Access: Public, Virtual
 //  Description:
 ////////////////////////////////////////////////////////////////////
-void GLGraphicsStateGuardian::issue_light(const LightAttribute *attrib )
+void GLGraphicsStateGuardian::issue_light(const LightTransition *attrib )
 {
-  nassertv(attrib->get_properties_is_on());
+  nassertv(attrib->get_default_dir() != TD_on);
   //  activate();
 
   // Initialize the current ambient light total and newly enabled
@@ -2924,64 +2880,68 @@ void GLGraphicsStateGuardian::issue_light(const LightAttribute *attrib )
   }
 
   int num_enabled = 0;
-  LightAttribute::const_iterator li;
+  LightTransition::const_iterator li;
   for (li = attrib->begin(); li != attrib->end(); ++li) {
-    num_enabled++;
-    enable_lighting(true);
-    Light *light = (*li);
+    Light *light = (*li).first;
     nassertv(light != (Light *)NULL);
+    TransitionDirection dir = (*li).second;
 
-    if (light->get_light_type() == AmbientLight::get_class_type()) {
-      // Ambient lights don't require specific light ids; simply add
-      // in the ambient contribution to the current total
-      cur_ambient_light += light->get_color();
+    if (dir == TD_on) {
+      num_enabled++;
+      enable_lighting(true);
 
-    } else {
-      // Check to see if this light has already been bound to an id
-      _cur_light_id = -1;
-      for (i = 0; i < _max_lights; i++) {
-        if (_light_info[i]._light == light) {
-          // Light has already been bound to an id, we only need
-          // to enable the light, not apply it
-          _cur_light_id = -2;
-          enable_light(i, true);
-          _light_info[i]._next_enabled = true;
-          break;
-        }
-      }
-
-      // See if there are any unbound light ids
-      if (_cur_light_id == -1) {
+      if (light->get_light_type() == AmbientLight::get_class_type()) {
+        // Ambient lights don't require specific light ids; simply add
+        // in the ambient contribution to the current total
+        cur_ambient_light += light->get_color();
+        
+      } else {
+        // Check to see if this light has already been bound to an id
+        _cur_light_id = -1;
         for (i = 0; i < _max_lights; i++) {
-          if (_light_info[i]._light == (Light *)NULL) {
-            _light_info[i]._light = light;
-            _cur_light_id = i;
+          if (_light_info[i]._light == light) {
+            // Light has already been bound to an id, we only need
+            // to enable the light, not apply it
+            _cur_light_id = -2;
+            enable_light(i, true);
+            _light_info[i]._next_enabled = true;
             break;
           }
         }
-      }
-
-      // If there were no unbound light ids, see if we can replace
-      // a currently unused but previously bound id
-      if (_cur_light_id == -1) {
-        for (i = 0; i < _max_lights; i++) {
-          if (attrib->is_off(_light_info[i]._light)) {
-            _light_info[i]._light = light;
-            _cur_light_id = i;
-            break;
+        
+        // See if there are any unbound light ids
+        if (_cur_light_id == -1) {
+          for (i = 0; i < _max_lights; i++) {
+            if (_light_info[i]._light == (Light *)NULL) {
+              _light_info[i]._light = light;
+              _cur_light_id = i;
+              break;
+            }
           }
         }
-      }
-
-      if (_cur_light_id >= 0) {
-        enable_light(_cur_light_id, true);
-        _light_info[i]._next_enabled = true;
-
-        // We need to do something different for each type of light
-        light->apply(this);
-      } else if (_cur_light_id == -1) {
-        glgsg_cat.error()
-          << "issue_light() - failed to bind light to id" << endl;
+        
+        // If there were no unbound light ids, see if we can replace
+        // a currently unused but previously bound id
+        if (_cur_light_id == -1) {
+          for (i = 0; i < _max_lights; i++) {
+            if (attrib->is_off(_light_info[i]._light)) {
+              _light_info[i]._light = light;
+              _cur_light_id = i;
+              break;
+            }
+          }
+        }
+        
+        if (_cur_light_id >= 0) {
+          enable_light(_cur_light_id, true);
+          _light_info[i]._next_enabled = true;
+          
+          // We need to do something different for each type of light
+          light->apply(this);
+        } else if (_cur_light_id == -1) {
+          glgsg_cat.error()
+            << "issue_light() - failed to bind light to id" << endl;
+        }
       }
     }
   }
@@ -3007,7 +2967,7 @@ void GLGraphicsStateGuardian::issue_light(const LightAttribute *attrib )
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_color_blend(const ColorBlendAttribute *attrib) {
+issue_color_blend(const ColorBlendTransition *attrib) {
   //  activate();
   ColorBlendProperty::Mode mode = attrib->get_mode();
 
@@ -3045,7 +3005,7 @@ issue_color_blend(const ColorBlendAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_texture_apply(const TextureApplyAttribute *attrib) {
+issue_texture_apply(const TextureApplyTransition *attrib) {
   //  activate();
   GLint glmode = get_texture_apply_mode_type(attrib->get_mode());
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);
@@ -3058,7 +3018,7 @@ issue_texture_apply(const TextureApplyAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_color_mask(const ColorMaskAttribute *attrib) {
+issue_color_mask(const ColorMaskTransition *attrib) {
   //  activate();
   glColorMask(attrib->is_write_r(),
               attrib->is_write_g(),
@@ -3073,7 +3033,7 @@ issue_color_mask(const ColorMaskAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_depth_test(const DepthTestAttribute *attrib) {
+issue_depth_test(const DepthTestTransition *attrib) {
   //  activate();
 
   DepthTestProperty::Mode mode = attrib->get_mode();
@@ -3092,7 +3052,7 @@ issue_depth_test(const DepthTestAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_depth_write(const DepthWriteAttribute *attrib) {
+issue_depth_write(const DepthWriteTransition *attrib) {
   //  activate();
 
   call_glDepthMask(attrib->is_on());
@@ -3105,7 +3065,7 @@ issue_depth_write(const DepthWriteAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_stencil(const StencilAttribute *attrib) {
+issue_stencil(const StencilTransition *attrib) {
   //  activate();
 
   StencilProperty::Mode mode = attrib->get_mode();
@@ -3121,14 +3081,13 @@ issue_stencil(const StencilAttribute *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_cull_attribute
+//     Function: GLGraphicsStateGuardian::issue_cull_transition
 //       Access: Public, Virtual
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_cull_face(const CullFaceAttribute *attrib) {
+issue_cull_face(const CullFaceTransition *attrib) {
   //  activate();
-
   CullFaceProperty::Mode mode = attrib->get_mode();
 
   switch (mode) {
@@ -3161,8 +3120,9 @@ issue_cull_face(const CullFaceAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_clip_plane(const ClipPlaneAttribute *attrib)
+issue_clip_plane(const ClipPlaneTransition *attrib)
 {
+  nassertv(attrib->get_default_dir() != TD_on);
   //  activate();
 
   // Initialize the currently enabled clip plane list
@@ -3171,68 +3131,71 @@ issue_clip_plane(const ClipPlaneAttribute *attrib)
     _cur_clip_plane_enabled[i] = false;
 
   int num_enabled = 0;
-  ClipPlaneAttribute::const_iterator pi;
+  ClipPlaneTransition::const_iterator pi;
   for (pi = attrib->begin(); pi != attrib->end(); ++pi) {
     PlaneNode *plane_node;
-    DCAST_INTO_V(plane_node, (*pi));
+    DCAST_INTO_V(plane_node, (*pi).first);
     nassertv(plane_node != (PlaneNode *)NULL);
+    TransitionDirection dir = (*pi).second;
 
-    _cur_clip_plane_id = -1;
-    num_enabled++;
-
-    // Check to see if this clip plane has already been bound to an id
-    for (i = 0; i < _max_clip_planes; i++) {
-      if (_available_clip_plane_ids[i] == plane_node) {
-        // Clip plane has already been bound to an id, we only need
-        // to enable the clip plane, not apply it
-        _cur_clip_plane_id = -2;
-        enable_clip_plane(i, true);
-        _cur_clip_plane_enabled[i] = true;
-        break;
-      }
-    }
+    if (dir == TD_on) {
+      _cur_clip_plane_id = -1;
+      num_enabled++;
 
-    // See if there are any unbound clip plane ids
-    if (_cur_clip_plane_id == -1) {
+      // Check to see if this clip plane has already been bound to an id
       for (i = 0; i < _max_clip_planes; i++) {
-        if (_available_clip_plane_ids[i] == NULL) {
-          _available_clip_plane_ids[i] = plane_node;
-          _cur_clip_plane_id = i;
+        if (_available_clip_plane_ids[i] == plane_node) {
+          // Clip plane has already been bound to an id, we only need
+          // to enable the clip plane, not apply it
+          _cur_clip_plane_id = -2;
+          enable_clip_plane(i, true);
+          _cur_clip_plane_enabled[i] = true;
           break;
         }
       }
-    }
 
-    // If there were no unbound clip plane ids, see if we can replace
-    // a currently unused but previously bound id
-    if (_cur_clip_plane_id == -1) {
-      for (i = 0; i < _max_clip_planes; i++) {
-        if (attrib->is_off(_available_clip_plane_ids[i])) {
-          _available_clip_plane_ids[i] = plane_node;
-          _cur_clip_plane_id = i;
-          break;
+      // See if there are any unbound clip plane ids
+      if (_cur_clip_plane_id == -1) {
+        for (i = 0; i < _max_clip_planes; i++) {
+          if (_available_clip_plane_ids[i] == NULL) {
+            _available_clip_plane_ids[i] = plane_node;
+            _cur_clip_plane_id = i;
+            break;
+          }
         }
       }
-    }
-
-    if (_cur_clip_plane_id >= 0) {
-      enable_clip_plane(_cur_clip_plane_id, true);
-      _cur_clip_plane_enabled[_cur_clip_plane_id] = true;
-      double equation[4];
-      const Planef clip_plane = plane_node->get_plane();
-      // Move us into the coordinate space of the plane
-      glMatrixMode(GL_MODELVIEW);
-      glPushMatrix();
-      glLoadMatrixf(clip_plane.get_reflection_mat().get_data());
-      equation[0] = clip_plane._a;
-      equation[1] = clip_plane._b;
-      equation[2] = clip_plane._c;
-      equation[3] = clip_plane._d;
-      glClipPlane(get_clip_plane_id(_cur_clip_plane_id), equation);
-      glPopMatrix();
-    } else if (_cur_clip_plane_id == -1) {
-      glgsg_cat.error()
-        << "issue_clip_plane() - failed to bind clip plane to id" << endl;
+      
+      // If there were no unbound clip plane ids, see if we can replace
+      // a currently unused but previously bound id
+      if (_cur_clip_plane_id == -1) {
+        for (i = 0; i < _max_clip_planes; i++) {
+          if (attrib->is_off(_available_clip_plane_ids[i])) {
+            _available_clip_plane_ids[i] = plane_node;
+            _cur_clip_plane_id = i;
+            break;
+          }
+        }
+      }
+      
+      if (_cur_clip_plane_id >= 0) {
+        enable_clip_plane(_cur_clip_plane_id, true);
+        _cur_clip_plane_enabled[_cur_clip_plane_id] = true;
+        double equation[4];
+        const Planef clip_plane = plane_node->get_plane();
+        // Move us into the coordinate space of the plane
+        glMatrixMode(GL_MODELVIEW);
+        glPushMatrix();
+        glLoadMatrixf(clip_plane.get_reflection_mat().get_data());
+        equation[0] = clip_plane._a;
+        equation[1] = clip_plane._b;
+        equation[2] = clip_plane._c;
+        equation[3] = clip_plane._d;
+        glClipPlane(get_clip_plane_id(_cur_clip_plane_id), equation);
+        glPopMatrix();
+      } else if (_cur_clip_plane_id == -1) {
+        glgsg_cat.error()
+          << "issue_clip_plane() - failed to bind clip plane to id" << endl;
+      }
     }
   }
 
@@ -3250,7 +3213,7 @@ issue_clip_plane(const ClipPlaneAttribute *attrib)
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_transparency(const TransparencyAttribute *attrib )
+issue_transparency(const TransparencyTransition *attrib )
 {
   //  activate();
 
@@ -3311,7 +3274,7 @@ issue_transparency(const TransparencyAttribute *attrib )
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_linesmooth(const LinesmoothAttribute *attrib) {
+issue_linesmooth(const LinesmoothTransition *attrib) {
   //  activate();
   enable_line_smooth(attrib->is_on());
   report_errors();
@@ -3323,7 +3286,7 @@ issue_linesmooth(const LinesmoothAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_point_shape(const PointShapeAttribute *attrib) {
+issue_point_shape(const PointShapeTransition *attrib) {
   //  activate();
 
   if (attrib->get_mode() == PointShapeProperty::M_square)
@@ -3339,7 +3302,7 @@ issue_point_shape(const PointShapeAttribute *attrib) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-issue_polygon_offset(const PolygonOffsetAttribute *attrib) {
+issue_polygon_offset(const PolygonOffsetTransition *attrib) {
   //  activate();
   //GL really wants to do a enable/disable of PolygonOffset, but it
   //seems more intuitive to have a PolygonOffset "on" all the time,
@@ -3402,13 +3365,13 @@ wants_colors() const {
 //               rendered up until the next call of end_decal() should
 //               be rendered as decals of the base_geom.
 //
-//               The attributes wrapper is the current state as of the
+//               The transitions wrapper is the current state as of the
 //               base geometry node.  It may or may not be modified by
 //               the GSG to reflect whatever rendering state is
 //               necessary to render the decals properly.
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
-begin_decal(GeomNode *base_geom, AllAttributesWrapper &attrib) {
+begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib) {
   nassertv(base_geom != (GeomNode *)NULL);
   _decal_level++;
 
@@ -3432,9 +3395,9 @@ begin_decal(GeomNode *base_geom, AllAttributesWrapper &attrib) {
     } else {
       // Turn off writing the depth buffer to render the base geometry.
       call_glDepthMask(false);
-      DepthWriteAttribute *dwa = new DepthWriteAttribute;
+      DepthWriteTransition *dwa = new DepthWriteTransition;
       dwa->set_off();
-      attrib.set_attribute(DepthWriteTransition::get_class_type(), dwa);
+      attrib.set_transition(dwa);
 
       // Now render the base geometry.
       base_geom->draw(this);
@@ -3512,8 +3475,8 @@ end_decal(GeomNode *base_geom) {
 
       // Finally, restore the depth write and color mask states to the
       // way they're supposed to be.
-      DepthWriteAttribute *depth_write;
-      if (get_attribute_into(depth_write, _state,
+      DepthWriteTransition *depth_write;
+      if (get_transition_into(depth_write, _state,
                              DepthWriteTransition::get_class_type())) {
         issue_depth_write(depth_write);
       }
@@ -3524,8 +3487,8 @@ end_decal(GeomNode *base_geom) {
           call_glBlendFunc(old_blend_source_func, old_blend_dest_func);
         }
       } else {
-        ColorMaskAttribute *color_mask;
-        if (get_attribute_into(color_mask, _state, ColorMaskTransition::get_class_type())) {
+        ColorMaskTransition *color_mask;
+        if (get_transition_into(color_mask, _state, ColorMaskTransition::get_class_type())) {
           issue_color_mask(color_mask);
         } else {
           glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

+ 28 - 31
panda/src/glgsg/glGraphicsStateGuardian.h

@@ -75,16 +75,13 @@ public:
 
   virtual void prepare_display_region();
 
-  virtual void render_frame(const AllAttributesWrapper &initial_state);
-  virtual void render_scene(Node *root, ProjectionNode *projnode,
-                            const AllAttributesWrapper &initial_state);
+  virtual void render_frame();
+  virtual void render_scene(Node *root, ProjectionNode *projnode);
   virtual void render_subgraph(RenderTraverser *traverser,
                                Node *subgraph, ProjectionNode *projnode,
-                               const AllAttributesWrapper &initial_state,
                                const AllTransitionsWrapper &net_trans);
   virtual void render_subgraph(RenderTraverser *traverser,
                                Node *subgraph,
-                               const AllAttributesWrapper &initial_state,
                                const AllTransitionsWrapper &net_trans);
 
   virtual void draw_point(GeomPoint *geom, GeomContext *gc);
@@ -121,10 +118,10 @@ public:
   virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb);
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
-                                 const NodeAttributes& na=NodeAttributes());
+                                 const NodeTransitions& na=NodeTransitions());
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb,
-                                 const NodeAttributes& na=NodeAttributes());
+                                 const NodeTransitions& na=NodeTransitions());
 
   virtual void apply_material(const Material *material);
   virtual void apply_fog(Fog *fog);
@@ -134,35 +131,35 @@ public:
   virtual void apply_light(Spotlight* light);
   virtual void apply_light(AmbientLight* light);
 
-  virtual void issue_transform(const TransformAttribute *attrib);
-  virtual void issue_color_transform(const ColorMatrixAttribute *attrib);
-  virtual void issue_alpha_transform(const AlphaTransformAttribute *attrib);
-  virtual void issue_tex_matrix(const TexMatrixAttribute *attrib);
-  virtual void issue_color(const ColorAttribute *attrib);
-  virtual void issue_texture(const TextureAttribute *attrib);
-  virtual void issue_light(const LightAttribute *attrib);
-  virtual void issue_material(const MaterialAttribute *attrib);
-  virtual void issue_render_mode(const RenderModeAttribute *attrib);
-  virtual void issue_color_blend(const ColorBlendAttribute *attrib);
-  virtual void issue_texture_apply(const TextureApplyAttribute *attrib);
-  virtual void issue_color_mask(const ColorMaskAttribute *attrib);
-  virtual void issue_depth_test(const DepthTestAttribute *attrib);
-  virtual void issue_depth_write(const DepthWriteAttribute *attrib);
-  virtual void issue_tex_gen(const TexGenAttribute *attrib);
-  virtual void issue_cull_face(const CullFaceAttribute *attrib);
-  virtual void issue_stencil(const StencilAttribute *attrib);
-  virtual void issue_clip_plane(const ClipPlaneAttribute *attrib);
-  virtual void issue_transparency(const TransparencyAttribute *attrib);
-  virtual void issue_fog(const FogAttribute *attrib);
-  virtual void issue_linesmooth(const LinesmoothAttribute *attrib);
-  virtual void issue_point_shape(const PointShapeAttribute *attrib);
-  virtual void issue_polygon_offset(const PolygonOffsetAttribute *attrib);
+  virtual void issue_transform(const TransformTransition *attrib);
+  virtual void issue_color_transform(const ColorMatrixTransition *attrib);
+  virtual void issue_alpha_transform(const AlphaTransformTransition *attrib);
+  virtual void issue_tex_matrix(const TexMatrixTransition *attrib);
+  virtual void issue_color(const ColorTransition *attrib);
+  virtual void issue_texture(const TextureTransition *attrib);
+  virtual void issue_light(const LightTransition *attrib);
+  virtual void issue_material(const MaterialTransition *attrib);
+  virtual void issue_render_mode(const RenderModeTransition *attrib);
+  virtual void issue_color_blend(const ColorBlendTransition *attrib);
+  virtual void issue_texture_apply(const TextureApplyTransition *attrib);
+  virtual void issue_color_mask(const ColorMaskTransition *attrib);
+  virtual void issue_depth_test(const DepthTestTransition *attrib);
+  virtual void issue_depth_write(const DepthWriteTransition *attrib);
+  virtual void issue_tex_gen(const TexGenTransition *attrib);
+  virtual void issue_cull_face(const CullFaceTransition *attrib);
+  virtual void issue_stencil(const StencilTransition *attrib);
+  virtual void issue_clip_plane(const ClipPlaneTransition *attrib);
+  virtual void issue_transparency(const TransparencyTransition *attrib);
+  virtual void issue_fog(const FogTransition *attrib);
+  virtual void issue_linesmooth(const LinesmoothTransition *attrib);
+  virtual void issue_point_shape(const PointShapeTransition *attrib);
+  virtual void issue_polygon_offset(const PolygonOffsetTransition *attrib);
 
   virtual bool wants_normals(void) const;
   virtual bool wants_texcoords(void) const;
   virtual bool wants_colors(void) const;
 
-  virtual void begin_decal(GeomNode *base_geom, AllAttributesWrapper &attrib);
+  virtual void begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib);
   virtual void end_decal(GeomNode *base_geom);
 
   virtual float compute_distance_to(const LPoint3f &point) const;

+ 12 - 0
panda/src/graph/allTransitionsWrapper.I

@@ -300,6 +300,18 @@ compose_in_place(const AllTransitionsWrapper &other) {
   _all_verified.clear();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: AllTransitionsWrapper::compose_from
+//       Access: Public
+//  Description: Sets this transition to the composition of the two
+//               transitions.
+////////////////////////////////////////////////////////////////////
+INLINE_GRAPH void AllTransitionsWrapper::
+compose_from(const AllTransitionsWrapper &a, const AllTransitionsWrapper &b) {
+  _cache = NodeTransitionCache::compose(a._cache, b._cache);
+  _all_verified.clear();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: AllTransitionsWrapper::invert_in_place
 //       Access: Public

+ 2 - 0
panda/src/graph/allTransitionsWrapper.h

@@ -88,6 +88,8 @@ public:
   INLINE_GRAPH void store_to(NodeRelation *arc) const;
 
   INLINE_GRAPH void compose_in_place(const AllTransitionsWrapper &other);
+  INLINE_GRAPH void compose_from(const AllTransitionsWrapper &a,
+                                 const AllTransitionsWrapper &b);
   INLINE_GRAPH void invert_in_place();
   INLINE_GRAPH void invert_compose_in_place(const AllTransitionsWrapper &other);
 

+ 9 - 9
panda/src/graph/dftraverser.T

@@ -25,7 +25,7 @@
 template<class Visitor, class LevelState>
 INLINE_GRAPH DFTraverser<Visitor, LevelState>::
 DFTraverser(Visitor &visitor,
-            const AttributeWrapper &initial_render_state,
+            const TransitionWrapper &initial_render_state,
             TypeHandle graph_type) :
   _visitor(visitor),
   _initial_render_state(initial_render_state),
@@ -63,7 +63,7 @@ start(Node *root, const LevelState &initial_level_state) {
 ////////////////////////////////////////////////////////////////////
 template<class Visitor, class LevelState>
 void DFTraverser<Visitor, LevelState>::
-traverse(NodeRelation *arc, AttributeWrapper state, LevelState level_state) {
+traverse(NodeRelation *arc, TransitionWrapper state, LevelState level_state) {
   nassertv(arc->get_child() != (Node *)NULL);
 
   // Give the visitor a chance to veto this arc.
@@ -71,8 +71,8 @@ traverse(NodeRelation *arc, AttributeWrapper state, LevelState level_state) {
     TransitionWrapper::init_from(_initial_render_state);
   trans.extract_from(arc);
 
-  AttributeWrapper post_state(state);
-  post_state.apply_in_place(trans);
+  TransitionWrapper post_state(state);
+  post_state.compose_in_place(trans);
   if (_visitor.forward_arc(arc, trans, state, post_state, level_state)) {
     traverse(arc->get_child(), post_state, level_state);
     _visitor.backward_arc(arc, trans, state, post_state, level_state);
@@ -88,7 +88,7 @@ traverse(NodeRelation *arc, AttributeWrapper state, LevelState level_state) {
 ////////////////////////////////////////////////////////////////////
 template<class Visitor, class LevelState>
 void DFTraverser<Visitor, LevelState>::
-traverse(Node *node, AttributeWrapper &state, LevelState &level_state) {
+traverse(Node *node, TransitionWrapper &state, LevelState &level_state) {
   // Tell the visitor we reached the node, and give it a chance to
   // veto our further progress.
   if (_visitor.reached_node(node, state, level_state)) {
@@ -106,10 +106,10 @@ traverse(Node *node, AttributeWrapper &state, LevelState &level_state) {
 }
 
 // Convenience functions.
-template<class Visitor, class AttributeWrapper, class LevelState>
+template<class Visitor, class TransitionWrapper, class LevelState>
 INLINE void
 df_traverse(NodeRelation *arc, Visitor &visitor,
-            const AttributeWrapper &initial_render_state,
+            const TransitionWrapper &initial_render_state,
             const LevelState &initial_level_state,
             TypeHandle graph_type) {
   DFTraverser<Visitor, LevelState>
@@ -117,10 +117,10 @@ df_traverse(NodeRelation *arc, Visitor &visitor,
   dft.start(arc, initial_level_state);
 }
 
-template<class Visitor, class AttributeWrapper, class LevelState>
+template<class Visitor, class TransitionWrapper, class LevelState>
 INLINE void
 df_traverse(Node *root, Visitor &visitor,
-            const AttributeWrapper &initial_render_state,
+            const TransitionWrapper &initial_render_state,
             const LevelState &initial_level_state,
             TypeHandle graph_type) {
   DFTraverser<Visitor, LevelState>

+ 4 - 5
panda/src/graph/dftraverser.h

@@ -39,10 +39,9 @@ template<class Visitor, class LevelState>
 class DFTraverser {
 public:
   typedef TYPENAME Visitor::TransitionWrapper TransitionWrapper;
-  typedef TYPENAME Visitor::AttributeWrapper AttributeWrapper;
 
   INLINE_GRAPH DFTraverser(Visitor &visitor,
-                           const AttributeWrapper &initial_render_state,
+                           const TransitionWrapper &initial_render_state,
                            TypeHandle graph_type);
 
   INLINE_GRAPH void start(NodeRelation *arc, const LevelState &initial_level_state);
@@ -50,14 +49,14 @@ public:
 
 protected:
   void traverse(NodeRelation *arc,
-                AttributeWrapper render_state,
+                TransitionWrapper render_state,
                 LevelState level_state);
   void traverse(Node *node,
-                AttributeWrapper &render_state,
+                TransitionWrapper &render_state,
                 LevelState &level_state);
 
   Visitor &_visitor;
-  AttributeWrapper _initial_render_state;
+  TransitionWrapper _initial_render_state;
   TypeHandle _graph_type;
 };
 

+ 2 - 6
panda/src/graph/multiTransition.T

@@ -514,9 +514,7 @@ internal_compare_to(const NodeTransition *other) const {
 ////////////////////////////////////////////////////////////////////
 //     Function: MultiTransition::output_property
 //       Access: Public, Virtual
-//  Description: This is a pure virtual function and normally would
-//               not need a body, except that VC++ doesn't seem happy
-//               about instantiating the template otherwise.
+//  Description: 
 ////////////////////////////////////////////////////////////////////
 template<class Property, class NameClass>
 void MultiTransition<Property, NameClass>::
@@ -526,9 +524,7 @@ output_property(ostream &, const Property &) const {
 ////////////////////////////////////////////////////////////////////
 //     Function: MultiTransition::write_property
 //       Access: Public, Virtual
-//  Description: This is a pure virtual function and normally would
-//               not need a body, except that VC++ doesn't seem happy
-//               about instantiating the template otherwise.
+//  Description: 
 ////////////////////////////////////////////////////////////////////
 template<class Property, class NameClass>
 void MultiTransition<Property, NameClass>::

+ 2 - 2
panda/src/graph/multiTransition.h

@@ -100,9 +100,9 @@ public:
 protected:
   virtual int internal_compare_to(const NodeTransition *other) const;
 
-  virtual void output_property(ostream &out, const Property &prop) const=0;
+  virtual void output_property(ostream &out, const Property &prop) const;
   virtual void write_property(ostream &out, const Property &prop,
-                              int indent_level) const=0;
+                              int indent_level) const;
 
 public:
   // These functions and typedefs allow one to peruse all of the

+ 1 - 1
panda/src/graph/node.cxx

@@ -329,7 +329,7 @@ dgraph_traverse(const ArcChain &) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 bool Node::
-sub_render(const AllAttributesWrapper &, AllTransitionsWrapper &,
+sub_render(const AllTransitionsWrapper &, AllTransitionsWrapper &, 
            RenderTraverser *) {
   return true;
 }

+ 2 - 2
panda/src/graph/node.h

@@ -90,8 +90,8 @@ public:
 
   // This function is similar to another function in NodeTransition.
   // It may or may not intercept the render traversal.
-  virtual bool sub_render(const AllAttributesWrapper &attrib,
-                          AllTransitionsWrapper &trans,
+  virtual bool sub_render(const AllTransitionsWrapper &input_trans,
+                          AllTransitionsWrapper &modify_trans,
                           RenderTraverser *trav);
   virtual bool has_sub_render() const;
 

+ 3 - 3
panda/src/graph/nodeRelation.cxx

@@ -542,13 +542,13 @@ adjust_all_priorities(int adjustment) {
 //               false if any returned false.
 ////////////////////////////////////////////////////////////////////
 bool NodeRelation::
-sub_render_trans(const AllAttributesWrapper &attrib,
-                 AllTransitionsWrapper &trans,
+sub_render_trans(const AllTransitionsWrapper &input_trans,
+                 AllTransitionsWrapper &modify_trans,
                  RenderTraverser *trav) {
   bool all_true = true;
   NodeTransitions::const_iterator ti;
   for (ti = _transitions.begin(); ti != _transitions.end(); ++ti) {
-    if (!(*ti).second->sub_render(this, attrib, trans, trav)) {
+    if (!(*ti).second->sub_render(this, input_trans, modify_trans, trav)) {
       all_true = false;
     }
   }

+ 2 - 2
panda/src/graph/nodeRelation.h

@@ -125,8 +125,8 @@ PUBLISHED:
   INLINE_GRAPH void clear_wrt_cache();
 
 public:
-  bool sub_render_trans(const AllAttributesWrapper &attrib,
-                        AllTransitionsWrapper &trans,
+  bool sub_render_trans(const AllTransitionsWrapper &input_trans,
+                        AllTransitionsWrapper &modify_trans,
                         RenderTraverser *trav);
   bool has_sub_render_trans() const;
   int get_num_sub_render_trans() const;

+ 27 - 2
panda/src/graph/nodeTransition.cxx

@@ -19,8 +19,9 @@
 #include "nodeTransition.h"
 #include "nodeTransitions.h"
 #include "nodeRelation.h"
+#include "config_graph.h"
 
-#include <indent.h>
+#include "indent.h"
 
 TypeHandle NodeTransition::_type_handle;
 
@@ -38,6 +39,18 @@ get_handle() const {
   return get_type();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodeTransition::make_initial
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+NodeTransition *NodeTransition::
+make_initial() const {
+  graph_cat.warning()
+    << "make_initial() not defined for " << get_type() << "\n";
+  return (NodeTransition *)this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: NodeTransition::sub_render
 //       Access: Public, Virtual
@@ -48,7 +61,7 @@ get_handle() const {
 //               process.
 ////////////////////////////////////////////////////////////////////
 bool NodeTransition::
-sub_render(NodeRelation *, const AllAttributesWrapper &,
+sub_render(NodeRelation *, const AllTransitionsWrapper &, 
            AllTransitionsWrapper &, RenderTraverser *) {
   return true;
 }
@@ -85,6 +98,18 @@ write(ostream &out, int indent_level) const {
   indent(out, indent_level) << *this << "\n";
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodeTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void NodeTransition::
+issue(GraphicsStateGuardianBase *) {
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: NodeTransition::internal_generate_hash
 //       Access: Protected, Virtual

+ 8 - 2
panda/src/graph/nodeTransition.h

@@ -37,6 +37,7 @@ class BamWriter;
 class BamReader;
 class Datagram;
 class DatagramIterator;
+class GraphicsStateGuardianBase;
 
 ////////////////////////////////////////////////////////////////////
 //       Class : NodeTransition
@@ -75,6 +76,7 @@ PUBLISHED:
 public:
   virtual NodeTransition *make_copy() const=0;
   virtual NodeAttribute *make_attrib() const=0;
+  virtual NodeTransition *make_initial() const;
 
   virtual TypeHandle get_handle() const;
 
@@ -83,14 +85,18 @@ public:
   virtual NodeAttribute *apply(const NodeAttribute *attrib) const=0;
 
   virtual bool sub_render(NodeRelation *arc,
-                          const AllAttributesWrapper &attrib,
-                          AllTransitionsWrapper &trans,
+                          const AllTransitionsWrapper &input_trans,
+                          AllTransitionsWrapper &modify_trans,
                           RenderTraverser *trav);
   virtual bool has_sub_render() const;
 
+PUBLISHED:
   virtual void output(ostream &out) const;
   virtual void write(ostream &out, int indent_level = 0) const;
 
+public:
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
+
 protected:
   virtual int internal_compare_to(const NodeTransition *other) const=0;
   virtual void internal_generate_hash(GraphHashGenerator &hash) const;

+ 10 - 0
panda/src/graph/nodeTransitionWrapper.I

@@ -94,6 +94,16 @@ get_trans() const {
   return _entry.get_trans();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodeTransitionWrapper::set_trans
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_GRAPH void NodeTransitionWrapper::
+set_trans(NodeTransition *trans) {
+  _entry.set_trans(trans);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: NodeTransitionWrapper::is_identity
 //       Access: Public

+ 1 - 0
panda/src/graph/nodeTransitionWrapper.h

@@ -65,6 +65,7 @@ public:
   INLINE_GRAPH TypeHandle get_handle() const;
   INLINE_GRAPH bool has_trans() const;
   INLINE_GRAPH NodeTransition *get_trans() const;
+  INLINE_GRAPH void set_trans(NodeTransition *trans);
 
   INLINE_GRAPH bool is_identity() const;
   INLINE_GRAPH int compare_to(const NodeTransitionWrapper &other) const;

+ 51 - 0
panda/src/graph/nodeTransitions.I

@@ -43,6 +43,26 @@ size() const {
   return _transitions.size();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodeTransitions::begin
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_GRAPH NodeTransitions::iterator NodeTransitions::
+begin() {
+  return _transitions.begin();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: NodeTransitions::end
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_GRAPH NodeTransitions::iterator NodeTransitions::
+end() {
+  return _transitions.end();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: NodeTransitions::begin
 //       Access: Public
@@ -63,6 +83,37 @@ end() const {
   return _transitions.end();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodeTransitions::insert
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_GRAPH NodeTransitions::iterator NodeTransitions::
+insert(NodeTransitions::iterator position,
+       const NodeTransitions::value_type &x) {
+  return _transitions.insert(position, x);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: NodeTransitions::find
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_GRAPH NodeTransitions::iterator NodeTransitions::
+find(const key_type &k) {
+  return _transitions.find(k);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: NodeTransitions::erase
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE_GRAPH void NodeTransitions::
+erase(NodeTransitions::iterator position) {
+  _transitions.erase(position);
+}
+
 INLINE_GRAPH ostream &operator << (ostream &out, const NodeTransitions &nts) {
   nts.output(out);
   return out;

+ 7 - 1
panda/src/graph/nodeTransitions.h

@@ -68,14 +68,20 @@ public:
   // STL-like definitions to allow read-only traversal of the
   // individual transitions.  Beware!  These are not safe to use
   // outside of PANDA.DLL.
-  typedef Transitions::const_iterator iterator;
+  typedef Transitions::iterator iterator;
   typedef Transitions::const_iterator const_iterator;
+  typedef Transitions::key_type key_type;
   typedef Transitions::value_type value_type;
   typedef Transitions::size_type size_type;
 
   INLINE_GRAPH size_type size() const;
+  INLINE_GRAPH iterator begin();
+  INLINE_GRAPH iterator end();
   INLINE_GRAPH const_iterator begin() const;
   INLINE_GRAPH const_iterator end() const;
+  INLINE_GRAPH iterator insert(iterator position, const value_type &x);
+  INLINE_GRAPH iterator find(const key_type &k);
+  INLINE_GRAPH void erase(iterator position);
 
 public:
   void output(ostream &out) const;

+ 5 - 5
panda/src/graph/traverserVisitor.T

@@ -27,7 +27,7 @@
 template<class TW, class LevelState>
 INLINE_GRAPH bool TraverserVisitor<TW, LevelState>::
 reached_node(Node *,
-             TraverserVisitor<TW, LevelState>::AttributeWrapper &,
+             TraverserVisitor<TW, LevelState>::TransitionWrapper &,
              LevelState &) {
   return true;
 }
@@ -44,8 +44,8 @@ template<class TW, class LevelState>
 INLINE_GRAPH bool TraverserVisitor<TW, LevelState>::
 forward_arc(NodeRelation *,
             TraverserVisitor<TW, LevelState>::TransitionWrapper &,
-            TraverserVisitor<TW, LevelState>::AttributeWrapper &,
-            TraverserVisitor<TW, LevelState>::AttributeWrapper &,
+            TraverserVisitor<TW, LevelState>::TransitionWrapper &,
+            TraverserVisitor<TW, LevelState>::TransitionWrapper &,
             LevelState &) {
   return true;
 }
@@ -64,7 +64,7 @@ template<class TW, class LevelState>
 INLINE_GRAPH void TraverserVisitor<TW, LevelState>::
 backward_arc(NodeRelation *,
              TraverserVisitor<TW, LevelState>::TransitionWrapper &,
-             TraverserVisitor<TW, LevelState>::AttributeWrapper &,
-             TraverserVisitor<TW, LevelState>::AttributeWrapper &,
+             TraverserVisitor<TW, LevelState>::TransitionWrapper &,
+             TraverserVisitor<TW, LevelState>::TransitionWrapper &,
              const LevelState &) {
 }

+ 3 - 4
panda/src/graph/traverserVisitor.h

@@ -28,10 +28,9 @@ template<class TW, class LevelState>
 class EXPCL_PANDA TraverserVisitor {
 public:
   typedef TW TransitionWrapper;
-  typedef TYPENAME TransitionWrapper::AttributeWrapper AttributeWrapper;
 
   INLINE_GRAPH bool reached_node(Node *node,
-                                 AttributeWrapper &render_state,
+                                 TransitionWrapper &render_state,
                                  LevelState &level_state);
 
   // Some traversers (notably DFTraverser) will also call the
@@ -39,10 +38,10 @@ public:
   // allow the Visitor to maintain its own internal state as needed.
 
   INLINE_GRAPH bool forward_arc(NodeRelation *arc, TransitionWrapper &trans,
-                                AttributeWrapper &pre, AttributeWrapper &post,
+                                TransitionWrapper &pre, TransitionWrapper &post,
                                 LevelState &level_state);
   INLINE_GRAPH void backward_arc(NodeRelation *arc, TransitionWrapper &trans,
-                                 AttributeWrapper &pre, AttributeWrapper &post,
+                                 TransitionWrapper &pre, TransitionWrapper &post,
                                  const LevelState &level_state);
 };
 

+ 56 - 9
panda/src/gsgbase/graphicsStateGuardianBase.h

@@ -19,11 +19,10 @@
 #ifndef GRAPHICSSTATEGUARDIANBASE_H
 #define GRAPHICSSTATEGUARDIANBASE_H
 
-#include <pandabase.h>
+#include "pandabase.h"
 
-#include <typedReferenceCount.h>
-#include <nodeTransition.h>
-#include <nodeAttributes.h>
+#include "typedReferenceCount.h"
+#include "nodeTransitions.h"
 
 // A handful of forward references.
 
@@ -52,6 +51,30 @@ class PixelBuffer;
 class Material;
 class Fog;
 
+class TransformTransition;
+class ColorMatrixTransition;
+class AlphaTransformTransition;
+class TexMatrixTransition;
+class ColorTransition;
+class TextureTransition;
+class LightTransition;
+class MaterialTransition;
+class RenderModeTransition;
+class ColorBlendTransition;
+class TextureApplyTransition;
+class ColorMaskTransition;
+class DepthTestTransition;
+class DepthWriteTransition;
+class TexGenTransition;
+class CullFaceTransition;
+class StencilTransition;
+class ClipPlaneTransition;
+class TransparencyTransition;
+class FogTransition;
+class LinesmoothTransition;
+class PointShapeTransition;
+class PolygonOffsetTransition;
+
 class TransformAttribute;
 class ColorMatrixAttribute;
 class AlphaTransformAttribute;
@@ -93,7 +116,7 @@ class ProjectionNode;
 //               class, which is itself a base class for the various
 //               GSG's for different platforms.  This class contains
 //               all the function prototypes to support the
-//               double-dispatch of GSG to geoms, attributes, etc.  It
+//               double-dispatch of GSG to geoms, transitions, etc.  It
 //               lives in a separate class in its own package so we
 //               can avoid circular build dependency problems.
 ////////////////////////////////////////////////////////////////////
@@ -109,9 +132,9 @@ public:
 
   // Defined here are some internal interface functions for the
   // GraphicsStateGuardian.  These are here to support
-  // double-dispatching from Geoms and NodeAttributes, and are
+  // double-dispatching from Geoms and NodeTransitions, and are
   // intended to be invoked only directly by the appropriate Geom and
-  // NodeAttribute types.  They're public only because it would be too
+  // NodeTransition types.  They're public only because it would be too
   // inconvenient to declare each of those types to be friends of this
   // class.
 
@@ -152,10 +175,10 @@ public:
   virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb)=0;
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
-                                 const NodeAttributes& na=NodeAttributes())=0;
+                                 const NodeTransitions& na=NodeTransitions())=0;
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb,
-                                 const NodeAttributes& na=NodeAttributes())=0;
+                                 const NodeTransitions& na=NodeTransitions())=0;
 
   virtual void apply_material(const Material *material)=0;
   virtual void apply_fog(Fog *fog)=0;
@@ -165,6 +188,30 @@ public:
   virtual void apply_light(Spotlight *light)=0;
   virtual void apply_light(AmbientLight *light)=0;
 
+  virtual void issue_transform(const TransformTransition *) { }
+  virtual void issue_color_transform(const ColorMatrixTransition *) { }
+  virtual void issue_alpha_transform(const AlphaTransformTransition *) { }
+  virtual void issue_tex_matrix(const TexMatrixTransition *) { }
+  virtual void issue_color(const ColorTransition *) { }
+  virtual void issue_texture(const TextureTransition *) { }
+  virtual void issue_light(const LightTransition *) { }
+  virtual void issue_material(const MaterialTransition *) { }
+  virtual void issue_render_mode(const RenderModeTransition *) { }
+  virtual void issue_color_blend(const ColorBlendTransition *) { }
+  virtual void issue_texture_apply(const TextureApplyTransition *) { }
+  virtual void issue_color_mask(const ColorMaskTransition *) { }
+  virtual void issue_depth_test(const DepthTestTransition *) { }
+  virtual void issue_depth_write(const DepthWriteTransition *) { }
+  virtual void issue_tex_gen(const TexGenTransition *) { }
+  virtual void issue_cull_face(const CullFaceTransition *) { }
+  virtual void issue_stencil(const StencilTransition *) { }
+  virtual void issue_clip_plane(const ClipPlaneTransition *) { }
+  virtual void issue_transparency(const TransparencyTransition *) { }
+  virtual void issue_fog(const FogTransition *) { }
+  virtual void issue_linesmooth(const LinesmoothTransition *) { }
+  virtual void issue_point_shape(const PointShapeTransition *) { }
+  virtual void issue_polygon_offset(const PolygonOffsetTransition *) { }
+
   virtual void issue_transform(const TransformAttribute *) { }
   virtual void issue_color_transform(const ColorMatrixAttribute *) { }
   virtual void issue_alpha_transform(const AlphaTransformAttribute *) { }

+ 0 - 9
panda/src/light/lightTransition.I

@@ -16,15 +16,6 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-////////////////////////////////////////////////////////////////////
-//     Function: LightTransition::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE LightTransition::
-LightTransition() {
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: LightTransition::all_off
 //       Access: Public

+ 52 - 0
panda/src/light/lightTransition.cxx

@@ -23,6 +23,34 @@
 
 TypeHandle LightTransition::_type_handle;
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: LightTransition::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+LightTransition::
+LightTransition() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LightTransition::Copy Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+LightTransition::
+LightTransition(const LightTransition &copy) : MultiTransition<PT_Light, LightNameClass>(copy) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LightTransition::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+LightTransition::
+~LightTransition() {
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LightTransition::make_copy
 //       Access: Public, Virtual
@@ -55,6 +83,30 @@ make_identity() const {
   return new LightTransition;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: LightTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated LightTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *LightTransition::
+make_initial() const {
+  return new LightTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LightTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void LightTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_light(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LightTransition::output_value
 //       Access: Protected, Virtual

+ 6 - 1
panda/src/light/lightTransition.h

@@ -44,13 +44,18 @@ EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, MULTITRANSITION_LIGHT);
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA LightTransition : public MultiTransition<PT_Light, LightNameClass> {
 PUBLISHED:
-  INLINE LightTransition();
+  LightTransition();
+  LightTransition(const LightTransition &copy);
+  ~LightTransition();
   INLINE static LightTransition all_off();
 
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
   virtual NodeTransition *make_identity() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 protected:
   virtual void output_property(ostream &out, const PT_Light &prop) const;

+ 2 - 3
panda/src/pgui/pgEntry.cxx

@@ -132,9 +132,8 @@ make_copy() const {
 ////////////////////////////////////////////////////////////////////
 void PGEntry::
 draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-          const AllAttributesWrapper &attrib,
           const AllTransitionsWrapper &trans) {
-  PGItem::draw_item(top, gsg, attrib, trans);
+  PGItem::draw_item(top, gsg, trans);
   update_text();
   update_cursor();
 
@@ -144,7 +143,7 @@ draw_item(PGTop *top, GraphicsStateGuardian *gsg,
   // of the text.
   DirectRenderTraverser drt(gsg, RenderRelation::get_class_type());
   drt.set_view_frustum_cull(false);
-  drt.traverse(_text_render_root, attrib, trans);
+  drt.traverse(_text_render_root, trans);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 0 - 1
panda/src/pgui/pgEntry.h

@@ -46,7 +46,6 @@ public:
   virtual Node *make_copy() const;
 
   virtual void draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-                         const AllAttributesWrapper &attrib,
                          const AllTransitionsWrapper &trans);
 
   virtual void press(const MouseWatcherParameter &param);

+ 2 - 3
panda/src/pgui/pgItem.cxx

@@ -200,7 +200,6 @@ activate_region(PGTop *, const LMatrix4f &transform, int sort) {
 ////////////////////////////////////////////////////////////////////
 void PGItem::
 draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-          const AllAttributesWrapper &attrib,
           const AllTransitionsWrapper &trans) {
   if (has_state_def(get_state())) {
     // This item has a current state definition that we should use
@@ -212,11 +211,11 @@ draw_item(PGTop *top, GraphicsStateGuardian *gsg,
       // of the subgraph.
       DirectRenderTraverser drt(gsg, RenderRelation::get_class_type());
       drt.set_view_frustum_cull(false);
-      drt.traverse(def, attrib, trans);
+      drt.traverse(def, trans);
 
     } else {
       QuickRenderTraverser qrt(gsg, RenderRelation::get_class_type());
-      qrt.traverse(def, attrib, trans);
+      qrt.traverse(def, trans);
     }
   }
 }

+ 0 - 2
panda/src/pgui/pgItem.h

@@ -36,7 +36,6 @@
 
 class PGTop;
 class GraphicsStateGuardian;
-class AllAttributesWrapper;
 class AllTransitionsWrapper;
 class MouseWatcherParameter;
 class ArcChain;
@@ -72,7 +71,6 @@ public:
   INLINE PGMouseWatcherRegion *get_region() const;
 
   virtual void draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-                         const AllAttributesWrapper &attrib,
                          const AllTransitionsWrapper &trans);
 
   virtual void enter(const MouseWatcherParameter &param);

+ 14 - 12
panda/src/pgui/pgTop.cxx

@@ -26,7 +26,7 @@
 #include "renderRelation.h"
 #include "geomNode.h"
 #include "allTransitionsWrapper.h"
-#include "allAttributesWrapper.h"
+#include "allTransitionsWrapper.h"
 #include "wrt.h"
 #include "switchNode.h"
 #include "transformTransition.h"
@@ -87,9 +87,9 @@ make_copy() const {
 //               in the scene graph order.
 ////////////////////////////////////////////////////////////////////
 bool PGTop::
-sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &,
-           RenderTraverser *trav) {
-  _attrib = attrib;
+sub_render(const AllTransitionsWrapper &input_trans,
+           AllTransitionsWrapper &, RenderTraverser *trav) {
+  _trans = input_trans;
   _gsg = trav->get_gsg();
   const ArcChain &chain = trav->get_arc_chain();
 
@@ -203,22 +203,24 @@ r_traverse(Node *node, const ArcChain &chain) {
     // And draw the item, however it wishes to be drawn.
     
     // Get the net transitions to the PGItem.
-    AllTransitionsWrapper complete_trans;
+    AllTransitionsWrapper wrt_trans;
     wrt(pgi, chain.begin(), chain.end(), this,
-        complete_trans, RenderRelation::get_class_type());
-    pgi->draw_item(this, _gsg, _attrib, complete_trans);
+        wrt_trans, RenderRelation::get_class_type());
+    AllTransitionsWrapper complete_trans;
+    complete_trans.compose_from(_trans, wrt_trans);
+    pgi->draw_item(this, _gsg, complete_trans);
 
   } else if (node->is_of_type(GeomNode::get_class_type())) {
     _gsg->_geom_nodes_pcollector.add_level(1);
     GeomNode *geom = DCAST(GeomNode, node);
 
     // Get the complete state of the GeomNode.
+    AllTransitionsWrapper wrt_trans;
+    wrt(node, chain.begin(), chain.end(), this,
+        wrt_trans, RenderRelation::get_class_type());
     AllTransitionsWrapper complete_trans;
-    wrt(geom, chain.begin(), chain.end(), this,
-        complete_trans, RenderRelation::get_class_type());
-    AllAttributesWrapper complete_state;
-    complete_state.apply_from(_attrib, complete_trans);
-    _gsg->set_state(complete_state.get_attributes(), true);
+    complete_trans.compose_from(_trans, wrt_trans);
+    _gsg->set_state(complete_trans.get_transitions(), true);
 
     // Finally, draw the Geom.
     _gsg->prepare_display_region();

+ 4 - 4
panda/src/pgui/pgTop.h

@@ -26,7 +26,7 @@
 #include "namedNode.h"
 #include "mouseWatcher.h"
 #include "pointerTo.h"
-#include "allAttributesWrapper.h"
+#include "allTransitionsWrapper.h"
 
 class GraphicsStateGuardian;
 class RenderTraverser;
@@ -58,8 +58,8 @@ public:
 
   virtual Node *make_copy() const;
 
-  virtual bool sub_render(const AllAttributesWrapper &attrib,
-                          AllTransitionsWrapper &trans,
+  virtual bool sub_render(const AllTransitionsWrapper &input_trans,
+                          AllTransitionsWrapper &modify_trans,
                           RenderTraverser *trav);
   virtual bool has_sub_render() const;
 
@@ -79,7 +79,7 @@ private:
   PGMouseWatcherGroup *_watcher_group;
   GraphicsStateGuardian *_gsg;
   RenderTraverser *_trav;
-  AllAttributesWrapper _attrib;
+  AllTransitionsWrapper _trans;
   int _sort_index;
   
 public:

+ 1 - 2
panda/src/pgui/pgWaitBar.cxx

@@ -96,10 +96,9 @@ make_copy() const {
 ////////////////////////////////////////////////////////////////////
 void PGWaitBar::
 draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-          const AllAttributesWrapper &attrib,
           const AllTransitionsWrapper &trans) {
   update();
-  PGItem::draw_item(top, gsg, attrib, trans);
+  PGItem::draw_item(top, gsg, trans);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 0 - 1
panda/src/pgui/pgWaitBar.h

@@ -42,7 +42,6 @@ public:
   virtual Node *make_copy() const;
 
   virtual void draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-                         const AllAttributesWrapper &attrib,
                          const AllTransitionsWrapper &trans);
 
 PUBLISHED:

+ 3 - 15
panda/src/sgattrib/Sources.pp

@@ -50,8 +50,7 @@
      renderModeAttribute.h renderModeProperty.I \
      renderModeProperty.h renderModeTransition.I \
      renderModeTransition.h renderRelation.I renderRelation.N \
-     renderRelation.h showHideAttribute.I showHideAttribute.h \
-     showHideTransition.I showHideTransition.h stencilAttribute.I \
+     renderRelation.h stencilAttribute.I \
      stencilAttribute.h stencilProperty.I stencilProperty.h \
      stencilTransition.I stencilTransition.h texGenAttribute.I \
      texGenAttribute.h texGenProperty.I texGenProperty.h \
@@ -85,7 +84,7 @@
         pointShapeTransition.cxx polygonOffsetAttribute.cxx \
         polygonOffsetProperty.cxx polygonOffsetTransition.cxx pruneTransition.cxx \
         renderModeAttribute.cxx renderModeProperty.cxx renderModeTransition.cxx \
-        renderRelation.cxx showHideAttribute.cxx showHideTransition.cxx \
+        renderRelation.cxx \
         stencilAttribute.cxx stencilProperty.cxx stencilTransition.cxx \
         texGenAttribute.cxx texGenProperty.cxx texGenTransition.cxx \
         texMatrixAttribute.cxx texMatrixTransition.cxx textureApplyAttribute.cxx \
@@ -128,8 +127,7 @@
     pruneTransition.I pruneTransition.h renderModeAttribute.I \
     renderModeAttribute.h renderModeProperty.I renderModeProperty.h \
     renderModeTransition.I renderModeTransition.h renderRelation.I \
-    renderRelation.h showHideAttribute.I showHideAttribute.h \
-    showHideNameClass.h showHideTransition.I showHideTransition.h \
+    renderRelation.h \
     stencilAttribute.I stencilAttribute.h stencilProperty.I \
     stencilProperty.h stencilTransition.I stencilTransition.h \
     texGenAttribute.I texGenAttribute.h texGenProperty.I \
@@ -146,16 +144,6 @@
     transparencyTransition.I transparencyTransition.h
 
   #define IGATESCAN all
-  
-
-//  #define IGATESCAN \
-//    renderRelation.cxx textureTransition.cxx materialTransition.cxx \
-//    clipPlaneTransition.cxx linesmoothTransition.cxx transformTransition.cxx \
-//    texMatrixTransition.cxx colorTransition.cxx billboardTransition.cxx \
-//    depthWriteTransition.cxx decalTransition.cxx \
-//    showHideTransition.cxx showHideAttribute.cxx pruneTransition.cxx \
-//    fogTransition.cxx transparencyTransition.cxx polygonOffsetTransition.cxx \
-//    colorMatrixTransition.cxx alphaTransformTransition.cxx 
 
 #end lib_target
 

+ 26 - 1
panda/src/sgattrib/alphaTransformTransition.cxx

@@ -19,7 +19,8 @@
 #include "alphaTransformTransition.h"
 #include "alphaTransformAttribute.h"
 
-#include <indent.h>
+#include "graphicsStateGuardianBase.h"
+#include "indent.h"
 
 TypeHandle AlphaTransformTransition::_type_handle;
 
@@ -44,6 +45,30 @@ make_attrib() const {
   return new AlphaTransformAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: AlphaTransformTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated AlphaTransformTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *AlphaTransformTransition::
+make_initial() const {
+  return new AlphaTransformTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AlphaTransformTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void AlphaTransformTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_alpha_transform(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: AlphaTransformTransition::set_value_from
 //       Access: Protected, Virtual

+ 3 - 0
panda/src/sgattrib/alphaTransformTransition.h

@@ -41,6 +41,9 @@ public:
 
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 protected:
   virtual void set_value_from(const OnTransition *other);

+ 16 - 16
panda/src/sgattrib/attribTraverser.cxx

@@ -18,16 +18,16 @@
 
 #include "attribTraverser.h"
 #include "renderRelation.h"
-#include <onOffAttribute.h>
+#include <onOffTransition.h>
 #include <onOffTransition.h>
 #include <immediateTransition.h>
 
 #include "textureTransition.h"
-#include "textureAttribute.h"
+#include "textureTransition.h"
 
 #include <geomNode.h>
 #include <dftraverser.h>
-#include <allAttributesWrapper.h>
+#include <allTransitionsWrapper.h>
 #include <typedObject.h>
 
 ////////////////////////////////////////////////////////////////////
@@ -49,7 +49,7 @@ AttribTraverser()
 //  Description: Called for each node of the scene graph
 ////////////////////////////////////////////////////////////////////
 bool AttribTraverser::
-reached_node(Node *node, NodeAttributeWrapper &state, NullLevelState &) {
+reached_node(Node *node, NodeTransitionWrapper &state, NullLevelState &) {
 
   //Short circuit if we aren't looking for an attribute
   if (_attrib_type == TypeHandle::none())
@@ -59,14 +59,14 @@ reached_node(Node *node, NodeAttributeWrapper &state, NullLevelState &) {
 
   if (node->is_of_type(GeomNode::get_class_type()))
   {
-    NodeAttribute *attrib = state.get_attrib();
-    if (attrib != (NodeAttribute *)NULL)
+    NodeTransition *attrib = state.get_trans();
+    if (attrib != (NodeTransition *)NULL)
     {
       nassertr(attrib->is_of_type(_attrib_type), false);
 
-      if (attrib->is_of_type(OnOffAttribute::get_class_type()))
+      if (attrib->is_of_type(OnOffTransition::get_class_type()))
       {
-        if(DCAST(OnOffAttribute, attrib)->is_on())
+        if(DCAST(OnOffTransition, attrib)->is_on())
         {
           _has_attrib = true;
         }
@@ -91,7 +91,7 @@ reached_node(Node *node, NodeAttributeWrapper &state, NullLevelState &) {
 ////////////////////////////////////////////////////////////////////
 bool AttribTraverser::
 forward_arc(NodeRelation *, TransitionWrapper &trans,
-            NodeAttributeWrapper &, NodeAttributeWrapper &,
+            NodeTransitionWrapper &, NodeTransitionWrapper &,
             NullLevelState &)
 {
   //Short circuit if we aren't looking for a transition
@@ -143,10 +143,10 @@ bool
 is_textured(Node* root) {
   AttribTraverser trav;
 
-  trav.set_attrib_type(TextureAttribute::get_class_type());
+  trav.set_attrib_type(TextureTransition::get_class_type());
 
   df_traverse(root, trav,
-              NodeAttributeWrapper(TextureTransition::get_class_type()),
+              NodeTransitionWrapper(TextureTransition::get_class_type()),
               NullLevelState(), RenderRelation::get_class_type());
 
   return trav._has_attrib;
@@ -158,14 +158,14 @@ is_textured(Node* root) {
 //               see if any geometry is textured
 ////////////////////////////////////////////////////////////////////
 bool
-is_textured(Node* root, const AllAttributesWrapper &init_state)
+is_textured(Node* root, const AllTransitionsWrapper &init_state)
 {
   AttribTraverser trav;
 
-  trav.set_attrib_type(TextureAttribute::get_class_type());
+  trav.set_attrib_type(TextureTransition::get_class_type());
 
-  NodeAttributeWrapper state(TextureTransition::get_class_type());
-  state.set_attrib(init_state.get_attribute(TextureTransition::get_class_type()));
+  NodeTransitionWrapper state(TextureTransition::get_class_type());
+  state.set_trans(init_state.get_transition(TextureTransition::get_class_type()));
 
   df_traverse(root, trav, state, NullLevelState(), RenderRelation::get_class_type());
 
@@ -189,7 +189,7 @@ is_shaded(Node* root) {
   trav.set_transition_type(TypeRegistry::ptr()->find_type("ShaderTransition"));
 
   df_traverse(root, trav,
-              NodeAttributeWrapper(TypeRegistry::ptr()->find_type("ShaderTransition")),
+              NodeTransitionWrapper(TypeRegistry::ptr()->find_type("ShaderTransition")),
               NullLevelState(), RenderRelation::get_class_type());
 
   return trav._has_attrib;

+ 6 - 7
panda/src/sgattrib/attribTraverser.h

@@ -23,10 +23,9 @@
 
 #include <traverserVisitor.h>
 #include <nodeTransitionWrapper.h>
-#include <nodeAttributeWrapper.h>
 #include <nullLevelState.h>
 
-class AllAttributesWrapper;
+class AllTransitionsWrapper;
 
 ////////////////////////////////////////////////////////////////////
 //       Class : AttribTraverser
@@ -36,9 +35,9 @@ class EXPCL_PANDA AttribTraverser :
   public TraverserVisitor<NodeTransitionWrapper, NullLevelState> {
 public:
   AttribTraverser();
-  bool reached_node(Node *node, NodeAttributeWrapper &state, NullLevelState &);
+  bool reached_node(Node *node, NodeTransitionWrapper &state, NullLevelState &);
   bool forward_arc(NodeRelation *arc, TransitionWrapper &trans,
-                   NodeAttributeWrapper &, NodeAttributeWrapper &,
+                   NodeTransitionWrapper &, NodeTransitionWrapper &,
                    NullLevelState &);
 
 
@@ -52,10 +51,10 @@ private:
   TypeHandle _transition_type;
 };
 
-bool EXPCL_PANDA is_textured(Node* root);
-bool EXPCL_PANDA is_textured(Node* root, const AllAttributesWrapper &init_state);
+EXPCL_PANDA bool is_textured(Node* root);
+EXPCL_PANDA bool is_textured(Node* root, const AllTransitionsWrapper &init_state);
 
-bool EXPCL_PANDA is_shaded(Node* root);
+EXPCL_PANDA bool is_shaded(Node* root);
 
 #endif
 

+ 14 - 6
panda/src/sgattrib/billboardTransition.cxx

@@ -47,14 +47,25 @@ make_copy() const {
   return new BillboardTransition(*this);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: BillboardTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated BillboardTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *BillboardTransition::
+make_initial() const {
+  return new BillboardTransition;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: BillboardTransition::sub_render
 //       Access: Public, Virtual
 //  Description:
 ////////////////////////////////////////////////////////////////////
 bool BillboardTransition::
-sub_render(NodeRelation *arc, const AllAttributesWrapper &,
-           AllTransitionsWrapper &trans, RenderTraverser *trav) {
+sub_render(NodeRelation *arc, const AllTransitionsWrapper &, 
+           AllTransitionsWrapper &modify_trans, RenderTraverser *trav) {
   Node *node = arc->get_child();
   GraphicsStateGuardian *gsg = trav->get_gsg();
 
@@ -122,10 +133,7 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &,
 
   // And finally, apply the rotation transform to the set of
   // transitions we've accumulated for this node.
-  AllTransitionsWrapper new_trans;
-  new_trans.set_transition(new TransformTransition(rotate));
-
-  trans.compose_in_place(new_trans);
+  modify_trans.set_transition(new TransformTransition(rotate));
 
   // Continue the render pass
   return true;

+ 3 - 2
panda/src/sgattrib/billboardTransition.h

@@ -57,10 +57,11 @@ public:
   INLINE float get_offset() const;
 
   virtual NodeTransition *make_copy() const;
+  virtual NodeTransition *make_initial() const;
 
   virtual bool sub_render(NodeRelation *arc,
-                          const AllAttributesWrapper &attrib,
-                          AllTransitionsWrapper &trans,
+                          const AllTransitionsWrapper &input_trans,
+                          AllTransitionsWrapper &modify_trans,
                           RenderTraverser *trav);
   virtual bool has_sub_render() const;
 

+ 26 - 2
panda/src/sgattrib/clipPlaneTransition.cxx

@@ -44,17 +44,41 @@ make_attrib() const {
   return new ClipPlaneAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ClipPlaneTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated ClipPlaneTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *ClipPlaneTransition::
+make_initial() const {
+  return new ClipPlaneTransition;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ClipPlaneTransition::make_identity
 //       Access: Public, Virtual
-//  Description: Returns a newly allocated ClipPlaneTransition in the
-//               initial state.
+//  Description: Returns a newly allocated ClipPlaneTransition
+//               corresponding to identity state.
 ////////////////////////////////////////////////////////////////////
 NodeTransition *ClipPlaneTransition::
 make_identity() const {
   return new ClipPlaneTransition;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ClipPlaneTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void ClipPlaneTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_clip_plane(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ClipPlaneTransition::output_value
 //       Access: Protected, Virtual

+ 3 - 0
panda/src/sgattrib/clipPlaneTransition.h

@@ -46,8 +46,11 @@ public:
 
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
   virtual NodeTransition *make_identity() const;
 
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
+
 protected:
   virtual void output_property(ostream &out, const PT_Node &prop) const;
   virtual void write_property(ostream &out, const PT_Node &prop,

+ 24 - 0
panda/src/sgattrib/colorBlendTransition.cxx

@@ -44,6 +44,30 @@ make_attrib() const {
   return new ColorBlendAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated ColorBlendTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *ColorBlendTransition::
+make_initial() const {
+  return new ColorBlendTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void ColorBlendTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_color_blend(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorBlendTransition::set_value_from
 //       Access: Protected, Virtual

+ 4 - 1
panda/src/sgattrib/colorBlendTransition.h

@@ -32,13 +32,16 @@
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA ColorBlendTransition : public OnTransition {
 public:
-  INLINE ColorBlendTransition(ColorBlendProperty::Mode mode);
+  INLINE ColorBlendTransition(ColorBlendProperty::Mode mode = ColorBlendProperty::M_none);
 
   INLINE void set_mode(ColorBlendProperty::Mode mode);
   INLINE ColorBlendProperty::Mode get_mode() const;
 
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 protected:
   virtual void set_value_from(const OnTransition *other);

+ 53 - 12
panda/src/sgattrib/colorMaskTransition.I

@@ -22,23 +22,20 @@
 //  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE ColorMaskTransition::
-ColorMaskTransition(int mask) :
-  _value(mask)
+ColorMaskTransition() :
+  _value(ColorMaskProperty::all_on())
 {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: ColorMaskTransition::all_on
-//       Access: Public, Static
-//  Description: This named constructor returns a ColorMaskTransition
-//               whose bits are all on: that transition that writes to
-//               all the color planes at once (the normal case).
+//     Function: ColorMaskTransition::Constructor
+//       Access: Public
+//  Description:
 ////////////////////////////////////////////////////////////////////
-INLINE ColorMaskTransition ColorMaskTransition::
-all_on() {
-  ColorMaskTransition t(0);
-  t._value = ColorMaskProperty::all_on();
-  return t;
+INLINE ColorMaskTransition::
+ColorMaskTransition(int mask) :
+  _value(mask)
+{
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -61,3 +58,47 @@ INLINE int ColorMaskTransition::
 get_mask() const {
   return _value.get_mask();
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorMaskTransition::is_write_r
+//       Access: Public
+//  Description: Returns true if the red component is enabled for
+//               writing.
+////////////////////////////////////////////////////////////////////
+INLINE bool ColorMaskTransition::
+is_write_r() const {
+  return (_value.get_mask() & ColorMaskProperty::M_r) != 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorMaskTransition::is_write_g
+//       Access: Public
+//  Description: Returns true if the green component is enabled for
+//               writing.
+////////////////////////////////////////////////////////////////////
+INLINE bool ColorMaskTransition::
+is_write_g() const {
+  return (_value.get_mask() & ColorMaskProperty::M_g) != 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorMaskTransition::is_write_b
+//       Access: Public
+//  Description: Returns true if the blue component is enabled for
+//               writing.
+////////////////////////////////////////////////////////////////////
+INLINE bool ColorMaskTransition::
+is_write_b() const {
+  return (_value.get_mask() & ColorMaskProperty::M_b) != 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorMaskTransition::is_write_a
+//       Access: Public
+//  Description: Returns true if the alpha component is enabled for
+//               writing.
+////////////////////////////////////////////////////////////////////
+INLINE bool ColorMaskTransition::
+is_write_a() const {
+  return (_value.get_mask() & ColorMaskProperty::M_a) != 0;
+}

+ 24 - 0
panda/src/sgattrib/colorMaskTransition.cxx

@@ -44,6 +44,30 @@ make_attrib() const {
   return new ColorMaskAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ColorMaskTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated ColorMaskTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *ColorMaskTransition::
+make_initial() const {
+  return new ColorMaskTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorMaskTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void ColorMaskTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_color_mask(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorMaskTransition::set_value_from
 //       Access: Protected, Virtual

+ 9 - 1
panda/src/sgattrib/colorMaskTransition.h

@@ -37,14 +37,22 @@
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA ColorMaskTransition : public OnTransition {
 public:
+  INLINE ColorMaskTransition();
   INLINE ColorMaskTransition(int mask);
-  INLINE static ColorMaskTransition all_on();
 
   INLINE void set_mask(int mask);
   INLINE int get_mask() const;
 
+  INLINE bool is_write_r() const;
+  INLINE bool is_write_g() const;
+  INLINE bool is_write_b() const;
+  INLINE bool is_write_a() const;
+
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 protected:
   virtual void set_value_from(const OnTransition *other);

+ 24 - 0
panda/src/sgattrib/colorMatrixTransition.cxx

@@ -48,6 +48,30 @@ make_attrib() const {
   return new ColorMatrixAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ColorMatrixTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated ColorMatrixTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *ColorMatrixTransition::
+make_initial() const {
+  return new ColorMatrixTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorMatrixTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void ColorMatrixTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_color_transform(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorMatrixTransition::make_with_matrix
 //       Access: Protected, Virtual

+ 3 - 0
panda/src/sgattrib/colorMatrixTransition.h

@@ -36,6 +36,9 @@ public:
 
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 protected:
   virtual MatrixTransition<LMatrix4f> *

+ 24 - 0
panda/src/sgattrib/colorTransition.cxx

@@ -48,6 +48,30 @@ make_attrib() const {
   return new ColorAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ColorTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated ColorTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *ColorTransition::
+make_initial() const {
+  return new ColorTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void ColorTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_color(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorTransition::set_value_from
 //       Access: Protected, Virtual

+ 3 - 0
panda/src/sgattrib/colorTransition.h

@@ -53,6 +53,9 @@ PUBLISHED:
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 protected:
   virtual void set_value_from(const OnOffTransition *other);

+ 0 - 4
panda/src/sgattrib/config_sgattrib.cxx

@@ -57,8 +57,6 @@
 #include "texMatrixTransition.h"
 #include "texMatrixAttribute.h"
 #include "billboardTransition.h"
-#include "showHideTransition.h"
-#include "showHideAttribute.h"
 #include "polygonOffsetTransition.h"
 #include "polygonOffsetAttribute.h"
 #include "pruneTransition.h"
@@ -177,8 +175,6 @@ ConfigureFn(config_sgattrib) {
   FogAttribute::init_type();
   LinesmoothTransition::init_type();
   LinesmoothAttribute::init_type();
-  ShowHideTransition::init_type();
-  ShowHideAttribute::init_type();
   PruneTransition::init_type();
   ColorTransition::init_type();
   ColorAttribute::init_type();

+ 0 - 10
panda/src/sgattrib/cullFaceTransition.I

@@ -47,13 +47,3 @@ INLINE CullFaceProperty::Mode CullFaceTransition::
 get_mode() const {
   return _value.get_mode();
 }
-
-////////////////////////////////////////////////////////////////////
-//     Function: CullFaceTransition::Default Constructor
-//       Access: Protected
-//  Description: This constructor is only for the benefit of the Bam
-//               reader.
-////////////////////////////////////////////////////////////////////
-INLINE CullFaceTransition::
-CullFaceTransition() {
-}

+ 24 - 0
panda/src/sgattrib/cullFaceTransition.cxx

@@ -48,6 +48,30 @@ make_attrib() const {
   return new CullFaceAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CullFaceTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated CullFaceTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *CullFaceTransition::
+make_initial() const {
+  return new CullFaceTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CullFaceTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void CullFaceTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_cull_face(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CullFaceTransition::set_value_from
 //       Access: Protected, Virtual

+ 4 - 2
panda/src/sgattrib/cullFaceTransition.h

@@ -34,16 +34,18 @@
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA CullFaceTransition : public OnTransition {
 public:
-  INLINE CullFaceTransition(CullFaceProperty::Mode mode);
+  INLINE CullFaceTransition(CullFaceProperty::Mode mode = CullFaceProperty::M_cull_none);
 
   INLINE void set_mode(CullFaceProperty::Mode mode);
   INLINE CullFaceProperty::Mode get_mode() const;
 
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 protected:
-  INLINE CullFaceTransition(void);
   virtual void set_value_from(const OnTransition *other);
   virtual int compare_values(const OnTransition *other) const;
   virtual void output_value(ostream &out) const;

+ 11 - 0
panda/src/sgattrib/decalTransition.cxx

@@ -46,6 +46,17 @@ make_attrib() const {
   return new DecalAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DecalTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated DecalTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *DecalTransition::
+make_initial() const {
+  return new DecalTransition;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DecalTransition::has_sub_render
 //       Access: Public, Virtual

+ 1 - 0
panda/src/sgattrib/decalTransition.h

@@ -48,6 +48,7 @@ PUBLISHED:
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
 
   virtual bool has_sub_render() const;
 

+ 0 - 10
panda/src/sgattrib/depthTestTransition.I

@@ -47,13 +47,3 @@ INLINE DepthTestProperty::Mode DepthTestTransition::
 get_mode() const {
   return _value.get_mode();
 }
-
-////////////////////////////////////////////////////////////////////
-//     Function: DepthTestTransition::Default Constructor
-//       Access: Protected
-//  Description: This constructor is only for the benefit of the Bam
-//               reader.
-////////////////////////////////////////////////////////////////////
-INLINE DepthTestTransition::
-DepthTestTransition() {
-}

+ 24 - 0
panda/src/sgattrib/depthTestTransition.cxx

@@ -48,6 +48,30 @@ make_attrib() const {
   return new DepthTestAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DepthTestTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated DepthTestTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *DepthTestTransition::
+make_initial() const {
+  return new DepthTestTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthTestTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void DepthTestTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_depth_test(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DepthTestTransition::set_value_from
 //       Access: Protected, Virtual

+ 4 - 2
panda/src/sgattrib/depthTestTransition.h

@@ -35,7 +35,7 @@
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA DepthTestTransition : public OnTransition {
 PUBLISHED:
-  INLINE DepthTestTransition(DepthTestProperty::Mode mode);
+  INLINE DepthTestTransition(DepthTestProperty::Mode mode = DepthTestProperty::M_less);
 
   INLINE void set_mode(DepthTestProperty::Mode mode);
   INLINE DepthTestProperty::Mode get_mode() const;
@@ -43,9 +43,11 @@ PUBLISHED:
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 protected:
-  INLINE DepthTestTransition();
   virtual void set_value_from(const OnTransition *other);
   virtual int compare_values(const OnTransition *other) const;
   virtual void output_value(ostream &out) const;

+ 24 - 0
panda/src/sgattrib/depthWriteTransition.cxx

@@ -47,6 +47,30 @@ make_attrib() const {
   return new DepthWriteAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DepthWriteTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated DepthWriteTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *DepthWriteTransition::
+make_initial() const {
+  return new DepthWriteTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthWriteTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void DepthWriteTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_depth_write(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DepthWriteTransition::register_with_factory
 //       Access: Public, Static

+ 3 - 0
panda/src/sgattrib/depthWriteTransition.h

@@ -36,6 +36,9 @@ PUBLISHED:
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 public:
   static void register_with_read_factory();

+ 30 - 29
panda/src/sgattrib/drawBoundsTransition.cxx

@@ -18,20 +18,15 @@
 
 #include "config_sgattrib.h"
 #include "drawBoundsTransition.h"
-#include "renderModeAttribute.h"
 #include "renderModeTransition.h"
-#include "cullFaceAttribute.h"
 #include "cullFaceTransition.h"
-#include "colorAttribute.h"
 #include "colorTransition.h"
 #include "transformTransition.h"
-#include "transformAttribute.h"
 
 #include <boundingSphere.h>
-#include <nodeAttributes.h>
+#include <nodeTransitions.h>
 #include <nodeTransitionWrapper.h>
 #include <allTransitionsWrapper.h>
-#include <allAttributesWrapper.h>
 #include <graphicsStateGuardian.h>
 #include <renderTraverser.h>
 #include <geomSphere.h>
@@ -45,24 +40,19 @@ TypeHandle DrawBoundsTransition::_type_handle;
 ////////////////////////////////////////////////////////////////////
 DrawBoundsTransition::
 DrawBoundsTransition() {
-  RenderModeAttribute *rma = new RenderModeAttribute;
-  rma->set_mode(RenderModeProperty::M_wireframe);
-  CullFaceAttribute *cfao = new CullFaceAttribute;
-  cfao->set_mode(CullFaceProperty::M_cull_clockwise);
-  ColorAttribute *cao = new ColorAttribute;
-  cao->set_on(0.3, 1.0, 0.5, 1.0);
-
-  CullFaceAttribute *cfai = new CullFaceAttribute;
-  cfai->set_mode(CullFaceProperty::M_cull_counter_clockwise);
-  ColorAttribute *cai = new ColorAttribute;
-  cai->set_on(0.15, 0.5, 0.25, 1.0);
-
-  _outside_attrib.set_attribute(RenderModeTransition::get_class_type(), rma);
-  _outside_attrib.set_attribute(CullFaceTransition::get_class_type(), cfao);
-  _outside_attrib.set_attribute(ColorTransition::get_class_type(), cao);
-
-  _inside_attrib.set_attribute(CullFaceTransition::get_class_type(), cfai);
-  _inside_attrib.set_attribute(ColorTransition::get_class_type(), cai);
+  RenderModeTransition *rma = new RenderModeTransition(RenderModeProperty::M_wireframe);
+  CullFaceTransition *cfao = new CullFaceTransition(CullFaceProperty::M_cull_clockwise);
+  ColorTransition *cao = new ColorTransition(0.3, 1.0, 0.5, 1.0);
+
+  CullFaceTransition *cfai = new CullFaceTransition(CullFaceProperty::M_cull_counter_clockwise);
+  ColorTransition *cai = new ColorTransition(0.15, 0.5, 0.25, 1.0);
+
+  _outside_attrib.set_transition(rma);
+  _outside_attrib.set_transition(cfao);
+  _outside_attrib.set_transition(cao);
+
+  _inside_attrib.set_transition(cfai);
+  _inside_attrib.set_transition(cai);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -76,6 +66,17 @@ make_copy() const {
   return new DrawBoundsTransition(*this);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DrawBoundsTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated DrawBoundsTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *DrawBoundsTransition::
+make_initial() const {
+  return new DrawBoundsTransition;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DrawBoundsTransition::sub_render
 //       Access: Public, Virtual
@@ -83,7 +84,7 @@ make_copy() const {
 //               drawBounds to do its thing.
 ////////////////////////////////////////////////////////////////////
 bool DrawBoundsTransition::
-sub_render(NodeRelation *arc, const AllAttributesWrapper &attrib,
+sub_render(NodeRelation *arc, const AllTransitionsWrapper &input_trans, 
            AllTransitionsWrapper &, RenderTraverser *trav) {
   GraphicsStateGuardian *gsg = trav->get_gsg();
 
@@ -93,8 +94,8 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &attrib,
     // been transformed by this arc's transform.
 
     LMatrix4f mat;
-    TransformAttribute *ta;
-    if (get_attribute_into(ta, attrib, TransformTransition::get_class_type())) {
+    TransformTransition *ta;
+    if (get_transition_into(ta, input_trans)) {
       mat = ta->get_matrix();
     } else {
       mat = LMatrix4f::ident_mat();
@@ -106,9 +107,9 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &attrib,
       mat = ::invert(tt->get_matrix()) * mat;
     }
 
-    TransformAttribute *new_ta = new TransformAttribute;
+    TransformTransition *new_ta = new TransformTransition;
     new_ta->set_matrix(mat);
-    _outside_attrib.set_attribute(TransformTransition::get_class_type(), new_ta);
+    _outside_attrib.set_transition(new_ta);
 
     gsg->set_state(_outside_attrib, true);
 

+ 6 - 5
panda/src/sgattrib/drawBoundsTransition.h

@@ -22,7 +22,7 @@
 #include <pandabase.h>
 
 #include <immediateTransition.h>
-#include <nodeAttributes.h>
+#include <nodeTransitions.h>
 
 ////////////////////////////////////////////////////////////////////
 //       Class : DrawBoundsTransition
@@ -38,15 +38,16 @@ public:
 
 public:
   virtual NodeTransition *make_copy() const;
+  virtual NodeTransition *make_initial() const;
 
   virtual bool sub_render(NodeRelation *arc,
-                          const AllAttributesWrapper &attrib,
-                          AllTransitionsWrapper &trans,
+                          const AllTransitionsWrapper &input_trans,
+                          AllTransitionsWrapper &modify_trans,
                           RenderTraverser *trav);
   virtual bool has_sub_render() const;
 
-  NodeAttributes _outside_attrib;
-  NodeAttributes _inside_attrib;
+  NodeTransitions _outside_attrib;
+  NodeTransitions _inside_attrib;
 
 public:
   virtual TypeHandle get_type() const {

+ 24 - 0
panda/src/sgattrib/fogTransition.cxx

@@ -44,6 +44,30 @@ make_attrib() const {
   return new FogAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: FogTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated FogTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *FogTransition::
+make_initial() const {
+  return new FogTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void FogTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_fog(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: FogTransition::set_value_from
 //       Access: Protected, Virtual

+ 3 - 0
panda/src/sgattrib/fogTransition.h

@@ -42,6 +42,9 @@ public:
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 protected:
   virtual void set_value_from(const OnOffTransition *other);

+ 24 - 0
panda/src/sgattrib/linesmoothTransition.cxx

@@ -41,3 +41,27 @@ NodeAttribute *LinesmoothTransition::
 make_attrib() const {
   return new LinesmoothAttribute;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: LinesmoothTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated LinesmoothTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *LinesmoothTransition::
+make_initial() const {
+  return new LinesmoothTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LinesmoothTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void LinesmoothTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_linesmooth(this);
+}

+ 3 - 0
panda/src/sgattrib/linesmoothTransition.h

@@ -36,6 +36,9 @@ public:
 
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 public:
   virtual TypeHandle get_type() const {

+ 24 - 0
panda/src/sgattrib/materialTransition.cxx

@@ -49,6 +49,30 @@ make_attrib() const {
   return new MaterialAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: MaterialTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated MaterialTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *MaterialTransition::
+make_initial() const {
+  return new MaterialTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MaterialTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void MaterialTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_material(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: MaterialTransition::set_value_from
 //       Access: Protected, Virtual

+ 3 - 0
panda/src/sgattrib/materialTransition.h

@@ -42,6 +42,9 @@ public:
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 protected:
   virtual void set_value_from(const OnOffTransition *other);

+ 24 - 0
panda/src/sgattrib/pointShapeTransition.cxx

@@ -44,6 +44,30 @@ make_attrib() const {
   return new PointShapeAttribute;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PointShapeTransition::make_initial
+//       Access: Public, Virtual
+//  Description: Returns a newly allocated PointShapeTransition
+//               corresponding to the default initial state.
+////////////////////////////////////////////////////////////////////
+NodeTransition *PointShapeTransition::
+make_initial() const {
+  return new PointShapeTransition;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PointShapeTransition::issue
+//       Access: Public, Virtual
+//  Description: This is called on scene graph rendering attributes
+//               when it is time to issue the particular attribute to
+//               the graphics engine.  It should call the appropriate
+//               method on GraphicsStateGuardianBase.
+////////////////////////////////////////////////////////////////////
+void PointShapeTransition::
+issue(GraphicsStateGuardianBase *gsgbase) {
+  gsgbase->issue_point_shape(this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PointShapeTransition
 //       Access: Protected, Virtual

+ 4 - 1
panda/src/sgattrib/pointShapeTransition.h

@@ -32,13 +32,16 @@
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA PointShapeTransition : public OnTransition {
 public:
-  INLINE PointShapeTransition(PointShapeProperty::Mode mode);
+  INLINE PointShapeTransition(PointShapeProperty::Mode mode = PointShapeProperty::M_square);
 
   INLINE void set_mode(PointShapeProperty::Mode mode);
   INLINE PointShapeProperty::Mode get_mode() const;
 
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 protected:
   virtual void set_value_from(const OnTransition *other);

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác