Browse Source

step one of eliminated NodeAttributes for scene graph performance

David Rose 24 years ago
parent
commit
b13172afd6
100 changed files with 1897 additions and 1227 deletions
  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 <traverserVisitor.h>
 #include <dftraverser.h>
 #include <dftraverser.h>
 #include <string_utils.h>
 #include <string_utils.h>
-#include <nullAttributeWrapper.h>
 #include <nullLevelState.h>
 #include <nullLevelState.h>
 #include <nullTransitionWrapper.h>
 #include <nullTransitionWrapper.h>
 #include "auto_bind.h"
 #include "auto_bind.h"
@@ -46,7 +45,7 @@ typedef pmap<string, PartNodes> Parts;
 class CollectNodes :
 class CollectNodes :
   public TraverserVisitor<NullTransitionWrapper, NullLevelState> {
   public TraverserVisitor<NullTransitionWrapper, NullLevelState> {
 public:
 public:
-  bool reached_node(Node *node, const NullAttributeWrapper &,
+  bool reached_node(Node *node, const NullTransitionWrapper &,
                     NullLevelState &) {
                     NullLevelState &) {
     if (node->is_of_type(AnimBundleNode::get_class_type())) {
     if (node->is_of_type(AnimBundleNode::get_class_type())) {
       AnimBundleNode *bn = DCAST(AnimBundleNode, node);
       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.
   // First, locate all the bundles in the subgraph.
   CollectNodes cn;
   CollectNodes cn;
-  df_traverse(root_node, cn, NullAttributeWrapper(), NullLevelState(),
+  df_traverse(root_node, cn, NullTransitionWrapper(), NullLevelState(),
               RenderRelation::get_class_type());
               RenderRelation::get_class_type());
 
 
   // Now, match up the bundles by name.
   // 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();
     (*hi).first->begin_group();
   }
   }
 
 
-  df_traverse(root.node(), *this, NullAttributeWrapper(),
+  df_traverse(root.node(), *this, NullTransitionWrapper(),
               level_state, _graph_type);
               level_state, _graph_type);
 
 
   for (hi = _handlers.begin(); hi != _handlers.end(); ++hi) {
   for (hi = _handlers.begin(); hi != _handlers.end(); ++hi) {
@@ -347,7 +347,7 @@ prepare_colliders(CollisionLevelState &level_state) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool CollisionTraverser::
 bool CollisionTraverser::
-reached_node(Node *node, NullAttributeWrapper &,
+reached_node(Node *node, NullTransitionWrapper &,
              CollisionLevelState &level_state) {
              CollisionLevelState &level_state) {
   if (node->is_of_type(CollisionNode::get_class_type())) {
   if (node->is_of_type(CollisionNode::get_class_type())) {
     level_state.reached_collision_node();
     level_state.reached_collision_node();
@@ -435,7 +435,7 @@ reached_node(Node *node, NullAttributeWrapper &,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool CollisionTraverser::
 bool CollisionTraverser::
 forward_arc(NodeRelation *arc, NullTransitionWrapper &,
 forward_arc(NodeRelation *arc, NullTransitionWrapper &,
-            NullAttributeWrapper &, NullAttributeWrapper &,
+            NullTransitionWrapper &, NullTransitionWrapper &,
             CollisionLevelState &level_state) {
             CollisionLevelState &level_state) {
   // Check the bounding volume on the arc against each of our
   // Check the bounding volume on the arc against each of our
   // colliders.
   // colliders.

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

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

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

@@ -25,7 +25,6 @@ INLINE CullState::
 CullState(const AllTransitionsWrapper &trans) :
 CullState(const AllTransitionsWrapper &trans) :
   _trans(trans)
   _trans(trans)
 {
 {
-  _attrib = (NodeAttributes *)NULL;
   _bin = (GeomBin *)NULL;
   _bin = (GeomBin *)NULL;
   _empty_frames_count = 0;
   _empty_frames_count = 0;
 }
 }
@@ -41,10 +40,6 @@ INLINE CullState::
   // If it is, something went screwy with the reference counts or with
   // If it is, something went screwy with the reference counts or with
   // the bin logic somewhere.
   // the bin logic somewhere.
   nassertv(_bin == (GeomBin *)NULL);
   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.
 //               CullState and stored within the CullState object.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void CullState::
 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
 //               object, based on the CullState's net transitions set
 //               and the initial state set by apply_to().
 //               and the initial state set by apply_to().
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE const NodeAttributes &CullState::
+INLINE const AllTransitionsWrapper &CullState::
 get_attributes() const {
 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 <geomNode.h>
 #include <allTransitionsWrapper.h>
 #include <allTransitionsWrapper.h>
-#include <allAttributesWrapper.h>
 #include <pointerTo.h>
 #include <pointerTo.h>
 #include <pointerToArray.h>
 #include <pointerToArray.h>
 #include <updateSeq.h>
 #include <updateSeq.h>
@@ -71,8 +70,8 @@ public:
   INLINE int count_current_nodes() const;
   INLINE int count_current_nodes() const;
   INLINE int get_empty_frames_count() 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 const AllTransitionsWrapper &get_transitions() const;
 
 
   INLINE bool has_bin() const;
   INLINE bool has_bin() const;
@@ -105,7 +104,7 @@ public:
 
 
 private:
 private:
   AllTransitionsWrapper _trans;
   AllTransitionsWrapper _trans;
-  NodeAttributes *_attrib;
+  AllTransitionsWrapper _attrib;
 
 
   typedef pmap<Node *, UpdateSeq> Verified;
   typedef pmap<Node *, UpdateSeq> Verified;
   Verified _verified;
   Verified _verified;

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

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

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

@@ -163,7 +163,7 @@ clear_state() {
   }
   }
   _default_bin->clear_current_states();
   _default_bin->clear_current_states();
 
 
-  _initial_state = AllAttributesWrapper();
+  _initial_state = AllTransitionsWrapper();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -224,8 +224,7 @@ write(ostream &out, int indent_level) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CullTraverser::
 void CullTraverser::
 traverse(Node *root,
 traverse(Node *root,
-         const AllAttributesWrapper &initial_state,
-         const AllTransitionsWrapper &net_trans) {
+         const AllTransitionsWrapper &initial_state) {
   // Statistics
   // Statistics
   PStatTimer timer(_cull_pcollector);
   PStatTimer timer(_cull_pcollector);
 
 
@@ -247,7 +246,7 @@ traverse(Node *root,
   _nested_count++;
   _nested_count++;
 
 
   if (is_initial) {
   if (is_initial) {
-    _initial_state.apply_from(initial_state, net_trans);
+    _initial_state = initial_state;
 
 
     States::iterator si;
     States::iterator si;
     for (si = _states.begin(); si != _states.end(); ++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,
   fc_traverse(_arc_chain, root, rel_from_camera, *this,
-              NullAttributeWrapper(), level_state, _gsg, _graph_type);
+              NullTransitionWrapper(), level_state, _gsg, _graph_type);
 
 
   if (is_initial) {
   if (is_initial) {
     draw();
     draw();
@@ -407,9 +406,8 @@ draw() {
       int draw_order = 0;
       int draw_order = 0;
 
 
       // Check the requested bin for the Geoms in this state.
       // 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();
         draw_order = bin_attrib->get_draw_order();
         bin_name = bin_attrib->get_bin();
         bin_name = bin_attrib->get_bin();
         requested_bin = get_bin(bin_name);
         requested_bin = get_bin(bin_name);
@@ -573,7 +571,7 @@ add_direct_node(Node *node, const AllTransitionsWrapper &trans,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool CullTraverser::
 bool CullTraverser::
 forward_arc(NodeRelation *arc, NullTransitionWrapper &,
 forward_arc(NodeRelation *arc, NullTransitionWrapper &,
-            NullAttributeWrapper &, NullAttributeWrapper &,
+            NullTransitionWrapper &, NullTransitionWrapper &,
             CullLevelState &level_state) {
             CullLevelState &level_state) {
   nassertr(level_state._lookup != (CullStateLookup *)NULL, false);
   nassertr(level_state._lookup != (CullStateLookup *)NULL, false);
 
 
@@ -689,18 +687,16 @@ forward_arc(NodeRelation *arc, NullTransitionWrapper &,
     if (_gsg != (GraphicsStateGuardian *)NULL) {
     if (_gsg != (GraphicsStateGuardian *)NULL) {
       AllTransitionsWrapper complete_trans;
       AllTransitionsWrapper complete_trans;
       level_state._lookup->compose_trans(trans, 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);
         mark_backward_arc(arc);
         return false;
         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 <renderTraverser.h>
 #include <traverserVisitor.h>
 #include <traverserVisitor.h>
 #include <nullTransitionWrapper.h>
 #include <nullTransitionWrapper.h>
-#include <nullAttributeWrapper.h>
 #include <pStatCollector.h>
 #include <pStatCollector.h>
 
 
 #include "plist.h"
 #include "plist.h"
@@ -67,15 +66,14 @@ PUBLISHED:
 public:
 public:
 
 
   virtual void traverse(Node *root,
   virtual void traverse(Node *root,
-                        const AllAttributesWrapper &initial_state,
-                        const AllTransitionsWrapper &net_trans);
+                        const AllTransitionsWrapper &initial_state);
 
 
   INLINE void draw_geom(GeomNode *geom_node,
   INLINE void draw_geom(GeomNode *geom_node,
-                        const AllAttributesWrapper &initial_state);
+                        const AllTransitionsWrapper &initial_state);
   INLINE void draw_geom(const ArcChain &arc_chain,
   INLINE void draw_geom(const ArcChain &arc_chain,
-                        const AllAttributesWrapper &initial_state);
+                        const AllTransitionsWrapper &initial_state);
   INLINE void draw_direct(const ArcChain &arc_chain,
   INLINE void draw_direct(const ArcChain &arc_chain,
-                          const AllAttributesWrapper &initial_state);
+                          const AllTransitionsWrapper &initial_state);
 
 
 private:
 private:
   void setup_initial_bins();
   void setup_initial_bins();
@@ -103,12 +101,12 @@ public:
   // behavior of the RenderTraverser as it traverses the graph.
   // behavior of the RenderTraverser as it traverses the graph.
   // Normally you would never call these directly.
   // Normally you would never call these directly.
   bool forward_arc(NodeRelation *arc, NullTransitionWrapper &trans,
   bool forward_arc(NodeRelation *arc, NullTransitionWrapper &trans,
-                   NullAttributeWrapper &pre, NullAttributeWrapper &post,
+                   NullTransitionWrapper &pre, NullTransitionWrapper &post,
                    CullLevelState &level_state);
                    CullLevelState &level_state);
 
 
   INLINE void
   INLINE void
   backward_arc(NodeRelation *arc, NullTransitionWrapper &trans,
   backward_arc(NodeRelation *arc, NullTransitionWrapper &trans,
-               NullAttributeWrapper &pre, NullAttributeWrapper &post,
+               NullTransitionWrapper &pre, NullTransitionWrapper &post,
                const CullLevelState &level_state);
                const CullLevelState &level_state);
 
 
 private:
 private:
@@ -117,7 +115,7 @@ private:
   void detach_toplevel_bin(GeomBin *bin);
   void detach_toplevel_bin(GeomBin *bin);
   void detach_sub_bin(GeomBin *bin);
   void detach_sub_bin(GeomBin *bin);
 
 
-  AllAttributesWrapper _initial_state;
+  AllTransitionsWrapper _initial_state;
 
 
   typedef pmap<string,  PT(GeomBin) > ToplevelBins;
   typedef pmap<string,  PT(GeomBin) > ToplevelBins;
   typedef pmultimap<int,  PT(GeomBin) > SubBins;
   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 {
 draw(CullTraverser *trav) const {
   nassertv(!_arc_chain.empty());
   nassertv(!_arc_chain.empty());
   if (_is_direct) {
   if (_is_direct) {
-    trav->draw_direct(_arc_chain, AllAttributesWrapper(_state->get_attributes()));
+    trav->draw_direct(_arc_chain, _state->get_attributes());
   } else {
   } 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 "geomBinBackToFront.h"
 #include "cullTraverser.h"
 #include "cullTraverser.h"
 
 
-#include <nodeAttributes.h>
+#include <nodeTransitions.h>
 #include <graphicsStateGuardian.h>
 #include <graphicsStateGuardian.h>
 #include <transformTransition.h>
 #include <transformTransition.h>
-#include <transformAttribute.h>
 #include <geometricBoundingVolume.h>
 #include <geometricBoundingVolume.h>
 #include <pStatTimer.h>
 #include <pStatTimer.h>
 
 
@@ -55,9 +54,8 @@ record_current_state(GraphicsStateGuardian *gsg, CullState *cs, int,
   PStatTimer timer(CullTraverser::_cull_bins_btf_pcollector);
   PStatTimer timer(CullTraverser::_cull_bins_btf_pcollector);
 
 
   // Get the transform matrix from the state.
   // 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;
   CullState::geom_const_iterator gi;
   for (gi = cs->geom_begin(); gi != cs->geom_end(); ++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);
       DCAST_INTO_V(gbv, &volume);
 
 
       LPoint3f center = gbv->get_approx_center();
       LPoint3f center = gbv->get_approx_center();
-      if (trans_attrib != (TransformAttribute *)NULL) {
+      if (trans_attrib != (TransformTransition *)NULL) {
         center = center * trans_attrib->get_matrix();
         center = center * trans_attrib->get_matrix();
       }
       }
 
 
       float distance = gsg->compute_distance_to(center);
       float distance = gsg->compute_distance_to(center);
+
       _node_entries.insert(NodeEntry(distance, cs, arc_chain, false));
       _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);
       DCAST_INTO_V(gbv, &volume);
 
 
       LPoint3f center = gbv->get_approx_center();
       LPoint3f center = gbv->get_approx_center();
-      if (trans_attrib != (TransformAttribute *)NULL) {
+      if (trans_attrib != (TransformTransition *)NULL) {
         center = center * trans_attrib->get_matrix();
         center = center * trans_attrib->get_matrix();
       }
       }
 
 
@@ -132,7 +131,7 @@ record_current_state(GraphicsStateGuardian *gsg, CullState *cs, int,
 
 
       if (num_points > 0) {
       if (num_points > 0) {
         avg /= (float)num_points;
         avg /= (float)num_points;
-        if (trans_attrib != (TransformAttribute *)NULL) {
+        if (trans_attrib != (TransformTransition *)NULL) {
           avg = avg * trans_attrib->get_matrix();
           avg = avg * trans_attrib->get_matrix();
         }
         }
         distance = gsg->compute_distance_to(avg);
         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 {
 draw(CullTraverser *trav) const {
   nassertv(!_arc_chain.empty());
   nassertv(!_arc_chain.empty());
   if (_is_direct) {
   if (_is_direct) {
-    trav->draw_direct(_arc_chain, AllAttributesWrapper(_state->get_attributes()));
+    trav->draw_direct(_arc_chain, _state->get_attributes());
   } else {
   } 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 "geomBinFixed.h"
 #include "cullTraverser.h"
 #include "cullTraverser.h"
 
 
-#include <nodeAttributes.h>
+#include <nodeTransitions.h>
 #include <graphicsStateGuardian.h>
 #include <graphicsStateGuardian.h>
 #include <transformTransition.h>
 #include <transformTransition.h>
-#include <transformAttribute.h>
 #include <geometricBoundingVolume.h>
 #include <geometricBoundingVolume.h>
 #include <pStatTimer.h>
 #include <pStatTimer.h>
 
 
@@ -57,9 +56,8 @@ record_current_state(GraphicsStateGuardian *, CullState *cs,
   PStatTimer timer(CullTraverser::_cull_bins_fixed_pcollector);
   PStatTimer timer(CullTraverser::_cull_bins_fixed_pcollector);
 
 
   // Get the transform matrix from the state.
   // 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;
   CullState::geom_const_iterator gi;
   for (gi = cs->geom_begin(); gi != cs->geom_end(); ++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
 //     Function: GeomBinUnsorted::record_current_state
 //       Access: Public, Virtual
 //       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
 //               that the given CullState (and all of its current
 //               GeomNodes) is visible this frame.
 //               GeomNodes) is visible this frame.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

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

@@ -21,10 +21,9 @@
 #include "geomBinUnsorted.h"
 #include "geomBinUnsorted.h"
 #include "geomBinBackToFront.h"
 #include "geomBinBackToFront.h"
 
 
-#include <nodeAttributes.h>
+#include <nodeTransitions.h>
 
 
 #include <transparencyTransition.h>
 #include <transparencyTransition.h>
-#include <transparencyAttribute.h>
 
 
 TypeHandle GeomBinNormal::_type_handle;
 TypeHandle GeomBinNormal::_type_handle;
 
 
@@ -56,9 +55,8 @@ int GeomBinNormal::
 choose_bin(CullState *cs) const {
 choose_bin(CullState *cs) const {
   bool is_transparent = false;
   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 =
     is_transparent =
       (trans_attrib->get_mode() != TransparencyProperty::M_none);
       (trans_attrib->get_mode() != TransparencyProperty::M_none);
   }
   }

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

@@ -45,6 +45,17 @@ make_attrib() const {
   return new GeomBinAttribute;
   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
 //     Function: GeomBinTransition::set_value_from
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

@@ -41,6 +41,7 @@ PUBLISHED:
 public:
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
 
 
 protected:
 protected:
   virtual void set_value_from(const OnOffTransition *other);
   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) {
     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();
       gsg->prepare_display_region();
 
 
       CullState::geom_iterator gi;
       CullState::geom_iterator gi;

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

@@ -21,15 +21,16 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 // Includes
 // 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
 // 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
 //               should be used with caution, as it could grow to be
 //               expensive.
 //               expensive.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE const NodeAttributes &GraphicsStateGuardian::
+INLINE const NodeTransitions &GraphicsStateGuardian::
 get_state() const {
 get_state() const {
   return _state;
   return _state;
 }
 }

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

@@ -145,7 +145,7 @@ reset() {
 //               that absent attributes should remain unchanged.
 //               that absent attributes should remain unchanged.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
 void GraphicsStateGuardian::
-set_state(const NodeAttributes &new_state, bool complete) {
+set_state(const NodeTransitions &new_state, bool complete) {
   PStatTimer timer(_set_state_pcollector);
   PStatTimer timer(_set_state_pcollector);
 
 
   if (gsg_cat.is_debug()) {
   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);
     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();
   new_i = new_state.begin();
   current_i = _state.begin();
   current_i = _state.begin();
 
 
   while (new_i != new_state.end() && current_i != _state.end()) {
   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
       // The user requested setting an attribute that we've never set
       // before.  Issue the command.
       // before.  Issue the command.
 
 
-      if ((*new_i).second != (NodeAttribute *)NULL) {
+      if (new_trans != (NodeTransition *)NULL) {
         if (gsg_cat.is_debug()) {
         if (gsg_cat.is_debug()) {
           gsg_cat.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.
         // And store the new value.
         current_i = _state.insert(current_i, *new_i);
         current_i = _state.insert(current_i, *new_i);
@@ -182,7 +187,7 @@ set_state(const NodeAttributes &new_state, bool complete) {
 
 
       ++new_i;
       ++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
       // Here's an attribute that we've set previously, but the user
       // didn't specify this time.
       // didn't specify this time.
 
 
@@ -192,15 +197,15 @@ set_state(const NodeAttributes &new_state, bool complete) {
 
 
         if (gsg_cat.is_debug()) {
         if (gsg_cat.is_debug()) {
           gsg_cat.debug()
           gsg_cat.debug()
-            << "Unissuing attrib " << *(*current_i).second
+            << "Unissuing attrib " << *current_trans
             << " (previously set, not now)\n";
             << " (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);
         initial->issue(this);
 
 
-        NodeAttributes::iterator erase_i = current_i;
+        NodeTransitions::iterator erase_i = current_i;
         ++current_i;
         ++current_i;
 
 
         _state.erase(erase_i);
         _state.erase(erase_i);
@@ -209,9 +214,9 @@ set_state(const NodeAttributes &new_state, bool complete) {
         ++current_i;
         ++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
         // Here's an attribute that we've set previously, which
         // appears in the new list, but is NULL indicating it should
         // appears in the new list, but is NULL indicating it should
         // be removed.
         // be removed.
@@ -221,16 +226,16 @@ set_state(const NodeAttributes &new_state, bool complete) {
 
 
           if (gsg_cat.is_debug()) {
           if (gsg_cat.is_debug()) {
             gsg_cat.debug()
             gsg_cat.debug()
-              << "Unissuing attrib " << *(*current_i).second
+              << "Unissuing attrib " << *current_trans
               << " (previously set, now NULL)\n";
               << " (previously set, now NULL)\n";
           }
           }
-          record_state_change((*current_i).first);
+          record_state_change(current_type);
 
 
           // Issue the initial attribute before clearing the state.
           // 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);
           initial->issue(this);
 
 
-          NodeAttributes::iterator erase_i = current_i;
+          NodeTransitions::iterator erase_i = current_i;
           ++current_i;
           ++current_i;
 
 
           _state.erase(erase_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
         // 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
         // asked us to set it again.  Issue the command only if the new
         // attribute is different from that which we'd set before.
         // 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()) {
           if (gsg_cat.is_debug()) {
             gsg_cat.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.
           // And store the new value.
-          (*current_i).second = (*new_i).second;
+          current_trans = new_trans;
 
 
         } else if (gsg_cat.is_debug()) {
         } else if (gsg_cat.is_debug()) {
           gsg_cat.debug()
           gsg_cat.debug()
-            << "Not reissuing unchanged attrib " << *(*new_i).second << "\n";
+            << "Not reissuing unchanged attrib " << *new_trans << "\n";
         }
         }
 
 
         ++current_i;
         ++current_i;
@@ -269,15 +276,17 @@ set_state(const NodeAttributes &new_state, bool complete) {
   while (new_i != new_state.end()) {
   while (new_i != new_state.end()) {
     // The user requested setting an attribute that we've never set
     // The user requested setting an attribute that we've never set
     // before.  Issue the command.
     // 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()) {
       if (gsg_cat.is_debug()) {
         gsg_cat.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.
       // And store the new value.
       _state.insert(_state.end(), *new_i);
       _state.insert(_state.end(), *new_i);
@@ -289,20 +298,22 @@ set_state(const NodeAttributes &new_state, bool complete) {
     while (current_i != _state.end()) {
     while (current_i != _state.end()) {
       // Here's an attribute that we've set previously, but the user
       // Here's an attribute that we've set previously, but the user
       // didn't specify this time.
       // didn't specify this time.
+      TypeHandle current_type = (*current_i).first;
+      PT(NodeTransition) &current_trans = (*current_i).second;
 
 
       if (gsg_cat.is_debug()) {
       if (gsg_cat.is_debug()) {
         gsg_cat.debug()
         gsg_cat.debug()
-          << "Unissuing attrib " << *(*current_i).second
+          << "Unissuing attrib " << *current_trans
           << " (previously set, end of list)\n";
           << " (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
       // If we're in the "complete state" model, that means this
       // attribute should now get the default initial value.
       // 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);
       initial->issue(this);
 
 
-      NodeAttributes::iterator erase_i = current_i;
+      NodeTransitions::iterator erase_i = current_i;
       ++current_i;
       ++current_i;
 
 
       _state.erase(erase_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
 //     Function: GraphicsStateGuardian::get_render_buffer
@@ -454,10 +658,10 @@ release_all_geoms() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
 void GraphicsStateGuardian::
 clear_attribute(TypeHandle type) {
 clear_attribute(TypeHandle type) {
-  NodeAttributes::iterator ai = _state.find(type);
+  NodeTransitions::iterator ai = _state.find(type);
   if (ai != _state.end()) {
   if (ai != _state.end()) {
     // The state is already set; get the initial value and reset it.
     // 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);
     initial->issue(this);
 
 
     // Now remove the state entry from the set.
     // Now remove the state entry from the set.
@@ -610,7 +814,7 @@ wants_colors() const {
 //               necessary to render the decals properly.
 //               necessary to render the decals properly.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
 void GraphicsStateGuardian::
-begin_decal(GeomNode *base_geom, AllAttributesWrapper &attrib) {
+begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib) {
   base_geom->draw(this);
   base_geom->draw(this);
 }
 }
 
 

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

@@ -19,23 +19,23 @@
 #ifndef GRAPHICSSTATEGUARDIAN_H
 #ifndef GRAPHICSSTATEGUARDIAN_H
 #define GRAPHICSSTATEGUARDIAN_H
 #define GRAPHICSSTATEGUARDIAN_H
 
 
-#include <pandabase.h>
+#include "pandabase.h"
 
 
 #include "savedFrameBuffer.h"
 #include "savedFrameBuffer.h"
 #include "frameBufferStack.h"
 #include "frameBufferStack.h"
 #include "displayRegionStack.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"
 #include "plist.h"
 
 
-class AllAttributesWrapper;
 class AllTransitionsWrapper;
 class AllTransitionsWrapper;
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -102,16 +102,13 @@ public:
 
 
   virtual void prepare_display_region()=0;
   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,
   virtual void render_subgraph(RenderTraverser *traverser,
                                Node *subgraph, ProjectionNode *projnode,
                                Node *subgraph, ProjectionNode *projnode,
-                               const AllAttributesWrapper &initial_state,
                                const AllTransitionsWrapper &net_trans)=0;
                                const AllTransitionsWrapper &net_trans)=0;
   virtual void render_subgraph(RenderTraverser *traverser,
   virtual void render_subgraph(RenderTraverser *traverser,
                                Node *subgraph,
                                Node *subgraph,
-                               const AllAttributesWrapper &initial_state,
                                const AllTransitionsWrapper &net_trans)=0;
                                const AllTransitionsWrapper &net_trans)=0;
 
 
   INLINE void enable_normals(bool val) { _normals_enabled = val; }
   INLINE void enable_normals(bool val) { _normals_enabled = val; }
@@ -124,13 +121,14 @@ public:
   virtual bool wants_texcoords(void) const;
   virtual bool wants_texcoords(void) const;
   virtual bool wants_colors(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 end_decal(GeomNode *base_geom);
 
 
   virtual void reset();
   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);
   RenderBuffer get_render_buffer(int buffer_type);
 
 
@@ -191,7 +189,7 @@ protected:
 
 
 protected:
 protected:
   int _buffer_mask;
   int _buffer_mask;
-  NodeAttributes _state;
+  NodeTransitions _state;
   Colorf _color_clear_value;
   Colorf _color_clear_value;
   float _depth_clear_value;
   float _depth_clear_value;
   bool _stencil_clear_value;
   bool _stencil_clear_value;

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

@@ -36,43 +36,24 @@
 #include <pointLight.h>
 #include <pointLight.h>
 #include <spotlight.h>
 #include <spotlight.h>
 #include <projectionNode.h>
 #include <projectionNode.h>
-#include <transformAttribute.h>
 #include <transformTransition.h>
 #include <transformTransition.h>
-#include <colorAttribute.h>
 #include <colorTransition.h>
 #include <colorTransition.h>
-#include <lightAttribute.h>
 #include <lightTransition.h>
 #include <lightTransition.h>
-#include <textureAttribute.h>
 #include <textureTransition.h>
 #include <textureTransition.h>
-#include <renderModeAttribute.h>
 #include <renderModeTransition.h>
 #include <renderModeTransition.h>
-#include <materialAttribute.h>
 #include <materialTransition.h>
 #include <materialTransition.h>
-#include <colorBlendAttribute.h>
 #include <colorBlendTransition.h>
 #include <colorBlendTransition.h>
-#include <colorMaskAttribute.h>
 #include <colorMaskTransition.h>
 #include <colorMaskTransition.h>
-#include <texMatrixAttribute.h>
 #include <texMatrixTransition.h>
 #include <texMatrixTransition.h>
-#include <texGenAttribute.h>
 #include <texGenTransition.h>
 #include <texGenTransition.h>
-#include <textureApplyAttribute.h>
 #include <textureApplyTransition.h>
 #include <textureApplyTransition.h>
-#include <clipPlaneAttribute.h>
 #include <clipPlaneTransition.h>
 #include <clipPlaneTransition.h>
-#include <transparencyAttribute.h>
 #include <transparencyTransition.h>
 #include <transparencyTransition.h>
-#include <fogAttribute.h>
 #include <fogTransition.h>
 #include <fogTransition.h>
-#include <linesmoothAttribute.h>
 #include <linesmoothTransition.h>
 #include <linesmoothTransition.h>
-#include <depthTestAttribute.h>
 #include <depthTestTransition.h>
 #include <depthTestTransition.h>
-#include <depthWriteAttribute.h>
 #include <depthWriteTransition.h>
 #include <depthWriteTransition.h>
-#include <cullFaceAttribute.h>
 #include <cullFaceTransition.h>
 #include <cullFaceTransition.h>
-#include <stencilAttribute.h>
 #include <stencilTransition.h>
 #include <stencilTransition.h>
 #include <throw_event.h>
 #include <throw_event.h>
 #ifdef DO_PSTATS
 #ifdef DO_PSTATS
@@ -489,11 +470,11 @@ init_dx(  LPDIRECTDRAW7     context,
 
 
     // Make sure the GL state matches all of our initial attribute
     // Make sure the GL state matches all of our initial attribute
     // states.
     // 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);
     dta->issue(this);
     dwa->issue(this);
     dwa->issue(this);
@@ -727,7 +708,7 @@ void DXGraphicsStateGuardian::set_clipper(RECT cliprect) {
 //               pre- and post-processing like swapping buffers.
 //               pre- and post-processing like swapping buffers.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-render_frame(const AllAttributesWrapper &initial_state) {
+render_frame() {
   if (!_dx_ready) 
   if (!_dx_ready) 
     return;
     return;
 
 
@@ -743,8 +724,8 @@ render_frame(const AllAttributesWrapper &initial_state) {
   // texture state has changed, we have to be sure to clear the
   // texture state has changed, we have to be sure to clear the
   // current texture state now.  A bit unfortunate, but probably not
   // current texture state now.  A bit unfortunate, but probably not
   // measurably expensive.
   // measurably expensive.
-  NodeAttributes state;
-  state.set_attribute(TextureTransition::get_class_type(), new TextureAttribute);
+  NodeTransitions state;
+  state.set_transition(new TextureTransition);
   set_state(state, false);
   set_state(state, false);
 #endif
 #endif
 
 
@@ -799,7 +780,7 @@ render_frame(const AllAttributesWrapper &initial_state) {
                                 cam->is_active() && cam->get_scene() != (Node *)NULL) {
                                 cam->is_active() && cam->get_scene() != (Node *)NULL) {
                                 DisplayRegionStack old_dr = push_display_region(dr);
                                 DisplayRegionStack old_dr = push_display_region(dr);
                                 prepare_display_region();
                                 prepare_display_region();
-                                render_scene(cam->get_scene(), cam, initial_state);
+                                render_scene(cam->get_scene(), cam);
                                 pop_display_region(old_dr);
                                 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()
         // Also force the lighting state to unlit, so that issue_light()
         // will be guaranteed to be called next frame even if we have the
         // will be guaranteed to be called next frame even if we have the
         // same set of light pointers we had this frame.
         // 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);
         set_state(state, false);
 
 
         // All this work to undo the lighting state each frame doesn't seem
         // 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.
 //               may be modified during rendering.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-render_scene(Node *root, ProjectionNode *projnode,
-             const AllAttributesWrapper &initial_state) {
+render_scene(Node *root, ProjectionNode *projnode) {
 #ifdef GSG_VERBOSE
 #ifdef GSG_VERBOSE
     _pass_number = 0;
     _pass_number = 0;
     dxgsg_cat.debug()
     dxgsg_cat.debug()
@@ -1046,7 +1026,7 @@ render_scene(Node *root, ProjectionNode *projnode,
 #endif
 #endif
     _current_root_node = root;
     _current_root_node = root;
 
 
-    render_subgraph(_render_traverser, root, projnode, initial_state,
+    render_subgraph(_render_traverser, root, projnode,
                     AllTransitionsWrapper());
                     AllTransitionsWrapper());
 
 
 #ifdef GSG_VERBOSE
 #ifdef GSG_VERBOSE
@@ -1067,7 +1047,6 @@ render_scene(Node *root, ProjectionNode *projnode,
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
 render_subgraph(RenderTraverser *traverser,
 render_subgraph(RenderTraverser *traverser,
                 Node *subgraph, ProjectionNode *projnode,
                 Node *subgraph, ProjectionNode *projnode,
-                const AllAttributesWrapper &initial_state,
                 const AllTransitionsWrapper &net_trans) {
                 const AllTransitionsWrapper &net_trans) {
     ProjectionNode *old_projection_node = _current_projection_node;
     ProjectionNode *old_projection_node = _current_projection_node;
     _current_projection_node = projnode;
     _current_projection_node = projnode;
@@ -1124,7 +1103,7 @@ render_subgraph(RenderTraverser *traverser,
     AllTransitionsWrapper sub_trans = net_trans;
     AllTransitionsWrapper sub_trans = net_trans;
     sub_trans.set_transition(new TransformTransition(modelview_mat));
     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_node = old_projection_node;
     _current_projection_mat = old_projection_mat;
     _current_projection_mat = old_projection_mat;
@@ -1149,7 +1128,6 @@ render_subgraph(RenderTraverser *traverser,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
 render_subgraph(RenderTraverser *traverser, Node *subgraph,
 render_subgraph(RenderTraverser *traverser, Node *subgraph,
-                const AllAttributesWrapper &initial_state,
                 const AllTransitionsWrapper &net_trans) {
                 const AllTransitionsWrapper &net_trans) {
 #ifdef GSG_VERBOSE
 #ifdef GSG_VERBOSE
     dxgsg_cat.debug()
     dxgsg_cat.debug()
@@ -1158,7 +1136,7 @@ render_subgraph(RenderTraverser *traverser, Node *subgraph,
 #endif
 #endif
 
 
     nassertv(traverser != (RenderTraverser *)NULL);
     nassertv(traverser != (RenderTraverser *)NULL);
-    traverser->traverse(subgraph, initial_state, net_trans);
+    traverser->traverse(subgraph, net_trans);
 
 
 #ifdef GSG_VERBOSE
 #ifdef GSG_VERBOSE
     dxgsg_cat.debug()
     dxgsg_cat.debug()
@@ -1310,8 +1288,8 @@ wants_colors() const {
     // If we have scene graph color enabled, return false to indicate we
     // If we have scene graph color enabled, return false to indicate we
     // shouldn't bother issuing geometry color commands.
     // 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.
         // No scene graph color at all.
         return true;
         return true;
     }
     }
@@ -1810,8 +1788,8 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) {
     // save the modelview matrix
     // save the modelview matrix
     LMatrix4f modelview_mat;
     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();
         modelview_mat = LMatrix4f::ident_mat();
     else
     else
         modelview_mat = ctatt->get_matrix();
         modelview_mat = ctatt->get_matrix();
@@ -1835,16 +1813,14 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) {
     float scaled_width, scaled_height;
     float scaled_width, scaled_height;
 
 
     // set up the texture-rendering state
     // 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
     // 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);
     set_state(state, false);
 
 
@@ -1853,8 +1829,8 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) {
 
 
     if (!geom->get_alpha_disable()) {
     if (!geom->get_alpha_disable()) {
         // figure out if alpha's enabled (if not, no reason to sort)
         // 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;
             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);
         bool bDoGlobalSceneGraphColor=FALSE,bDoColor=(ColorBinding != G_OFF);
 
 
         // We should issue geometry colors only if the scene graph color is 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())
             if (!catt->is_real())
                 bDoColor=FALSE;  // this turns off any Geom colors
                 bDoColor=FALSE;  // this turns off any Geom colors
             else {
             else {
@@ -2705,11 +2681,11 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) {
             }
             }
         }
         }
 
 
-        ColorAttribute *catt=NULL;
+        ColorTransition *catt=NULL;
         bool bDoGlobalSceneGraphColor=FALSE,bDoColor=(ColorBinding != G_OFF);
         bool bDoGlobalSceneGraphColor=FALSE,bDoColor=(ColorBinding != G_OFF);
 
 
         // We should issue geometry colors only if the scene graph color is 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())
             if (!catt->is_real())
                 bDoColor=FALSE;  // this turns off any Geom colors
                 bDoColor=FALSE;  // this turns off any Geom colors
             else {
             else {
@@ -3507,35 +3483,24 @@ draw_texture(TextureContext *tc, const DisplayRegion *dr) {
     DisplayRegionStack old_dr = push_display_region(dr);
     DisplayRegionStack old_dr = push_display_region(dr);
     prepare_display_region();
     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);
     set_state(state, false);
 
 
     // We set up an orthographic projection that defines our entire
     // We set up an orthographic projection that defines our entire
@@ -3693,7 +3658,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
-                  const NodeAttributes& na) {
+                  const NodeTransitions& na) {
 
 
     dxgsg_cat.fatal() << "DXGSG draw_pixel_buffer unimplemented!!!";
     dxgsg_cat.fatal() << "DXGSG draw_pixel_buffer unimplemented!!!";
     return;
     return;
@@ -3705,31 +3670,23 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
     DisplayRegionStack old_dr = push_display_region(dr);
     DisplayRegionStack old_dr = push_display_region(dr);
     prepare_display_region();
     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()) {
     switch (pb->get_format()) {
         case PixelBuffer::F_depth_component:
         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;
             break;
 
 
@@ -3742,14 +3699,12 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
         case PixelBuffer::F_rgba8:
         case PixelBuffer::F_rgba8:
         case PixelBuffer::F_rgba12:
         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;
             break;
         default:
         default:
@@ -3822,7 +3777,7 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
-                  const RenderBuffer &rb, const NodeAttributes& na) {
+                  const RenderBuffer &rb, const NodeTransitions& na) {
     set_read_buffer(rb);
     set_read_buffer(rb);
     draw_pixel_buffer(pb, dr, na);
     draw_pixel_buffer(pb, dr, na);
 }
 }
@@ -4161,7 +4116,7 @@ void DXGraphicsStateGuardian::apply_light( AmbientLight* light ) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_transform(const TransformAttribute *attrib) {
+issue_transform(const TransformTransition *attrib) {
 #ifndef NDEBUG
 #ifndef NDEBUG
     if (dx_show_transforms) {
     if (dx_show_transforms) {
 
 
@@ -4205,7 +4160,7 @@ issue_transform(const TransformAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_tex_matrix(const TexMatrixAttribute *attrib) {
+issue_tex_matrix(const TexMatrixTransition *attrib) {
     dxgsg_cat.fatal() << "DXGSG issue_tex_matrix unimplemented!!!";
     dxgsg_cat.fatal() << "DXGSG issue_tex_matrix unimplemented!!!";
     return;
     return;
 
 
@@ -4228,7 +4183,7 @@ issue_tex_matrix(const TexMatrixAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_color(const ColorAttribute *attrib) {
+issue_color(const ColorTransition *attrib) {
     
     
     bool bAttribOn=attrib->is_on();
     bool bAttribOn=attrib->is_on();
     bool bIsReal = (bAttribOn ? attrib->is_real() : false);
     bool bIsReal = (bAttribOn ? attrib->is_real() : false);
@@ -4254,11 +4209,11 @@ issue_color(const ColorAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_color_transform(const ColorMatrixAttribute *attrib) {
+issue_color_transform(const ColorMatrixTransition *attrib) {
     _current_color_mat = attrib->get_matrix();
     _current_color_mat = attrib->get_matrix();
 
 
     // couldnt we compare a single ptr instead of doing full comparison?
     // 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
     // so we dont have to do this comparison
     if (_current_color_mat == LMatrix4f::ident_mat()) { 
     if (_current_color_mat == LMatrix4f::ident_mat()) { 
         _color_transform_enabled = false;
         _color_transform_enabled = false;
@@ -4279,7 +4234,7 @@ issue_color_transform(const ColorMatrixAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_alpha_transform(const AlphaTransformAttribute *attrib) {
+issue_alpha_transform(const AlphaTransformTransition *attrib) {
     _current_alpha_offset = attrib->get_offset();
     _current_alpha_offset = attrib->get_offset();
     _current_alpha_scale = attrib->get_scale();
     _current_alpha_scale = attrib->get_scale();
 
 
@@ -4302,7 +4257,7 @@ issue_alpha_transform(const AlphaTransformAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_texture(const TextureAttribute *attrib) {
+issue_texture(const TextureTransition *attrib) {
     if (attrib->is_on()) {
     if (attrib->is_on()) {
         enable_texturing(true);
         enable_texturing(true);
         Texture *tex = attrib->get_texture();
         Texture *tex = attrib->get_texture();
@@ -4319,7 +4274,7 @@ issue_texture(const TextureAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_tex_gen(const TexGenAttribute *attrib) {
+issue_tex_gen(const TexGenTransition *attrib) {
     dxgsg_cat.fatal() << "DXGSG issue_tex_gen unimplemented!!!";
     dxgsg_cat.fatal() << "DXGSG issue_tex_gen unimplemented!!!";
     return;
     return;
 #ifdef WBD_GL_MODE
 #ifdef WBD_GL_MODE
@@ -4374,7 +4329,7 @@ issue_tex_gen(const TexGenAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_material(const MaterialAttribute *attrib) {
+issue_material(const MaterialTransition *attrib) {
     if (attrib->is_on()) {
     if (attrib->is_on()) {
         const Material *material = attrib->get_material();
         const Material *material = attrib->get_material();
         nassertv(material != (const Material *)NULL);
         nassertv(material != (const Material *)NULL);
@@ -4388,7 +4343,7 @@ issue_material(const MaterialAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_fog(const FogAttribute *attrib) {
+issue_fog(const FogTransition *attrib) {
 
 
     if (attrib->is_on()) {
     if (attrib->is_on()) {
         enable_fog(true);
         enable_fog(true);
@@ -4406,7 +4361,7 @@ issue_fog(const FogAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_render_mode(const RenderModeAttribute *attrib) {
+issue_render_mode(const RenderModeTransition *attrib) {
 
 
     RenderModeProperty::Mode mode = attrib->get_mode();
     RenderModeProperty::Mode mode = attrib->get_mode();
 
 
@@ -4431,93 +4386,98 @@ issue_render_mode(const RenderModeAttribute *attrib) {
 //       Access: Public, Virtual
 //       Access: Public, Virtual
 //  Description:
 //  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:                                                  //
 //  Description:                                                  //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_color_blend(const ColorBlendAttribute *attrib) {
+issue_color_blend(const ColorBlendTransition *attrib) {
     
     
     ColorBlendProperty::Mode mode = attrib->get_mode();
     ColorBlendProperty::Mode mode = attrib->get_mode();
 
 
@@ -4686,10 +4646,10 @@ enable_texturing(bool val) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian::issue_texture_apply
 //     Function: DXGraphicsStateGuardian::issue_texture_apply
 //       Access: Public, Virtual
 //       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::
 void DXGraphicsStateGuardian::
-issue_texture_apply(const TextureApplyAttribute *attrib) {
+issue_texture_apply(const TextureApplyTransition *attrib) {
 
 
     _CurTexBlendMode = attrib->get_mode();
     _CurTexBlendMode = attrib->get_mode();
 
 
@@ -4706,7 +4666,7 @@ issue_texture_apply(const TextureApplyAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 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)!!!";
     dxgsg_cat.fatal() << "DXGSG issue_color_mask unimplemented (not implementable on DX7)!!!";
     return;
     return;
 }
 }
@@ -4717,7 +4677,7 @@ issue_color_mask(const ColorMaskAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_depth_test(const DepthTestAttribute *attrib) {
+issue_depth_test(const DepthTestTransition *attrib) {
     
     
 
 
     DepthTestProperty::Mode mode = attrib->get_mode();
     DepthTestProperty::Mode mode = attrib->get_mode();
@@ -4738,7 +4698,7 @@ issue_depth_test(const DepthTestAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_depth_write(const DepthWriteAttribute *attrib) {
+issue_depth_write(const DepthWriteTransition *attrib) {
     _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, attrib->is_on());
     _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, attrib->is_on());
 }
 }
 
 
@@ -4748,7 +4708,7 @@ issue_depth_write(const DepthWriteAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_stencil(const StencilAttribute *attrib) {
+issue_stencil(const StencilTransition *attrib) {
 
 
   StencilProperty::Mode mode = attrib->get_mode();
   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
 //       Access: Public, Virtual
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_cull_face(const CullFaceAttribute *attrib) {
+issue_cull_face(const CullFaceTransition *attrib) {
     
     
 #ifndef NDEBUG
 #ifndef NDEBUG
     if(dx_force_backface_culling!=0) {
     if(dx_force_backface_culling!=0) {
@@ -4817,82 +4777,85 @@ issue_cull_face(const CullFaceAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 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:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_transparency(const TransparencyAttribute *attrib ) {
+issue_transparency(const TransparencyTransition *attrib ) {
 
 
     TransparencyProperty::Mode mode = attrib->get_mode();
     TransparencyProperty::Mode mode = attrib->get_mode();
 
 
@@ -4959,7 +4922,7 @@ issue_transparency(const TransparencyAttribute *attrib ) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-issue_linesmooth(const LinesmoothAttribute *attrib) {
+issue_linesmooth(const LinesmoothTransition *attrib) {
     enable_line_smooth(attrib->is_on());
     enable_line_smooth(attrib->is_on());
 }
 }
 
 
@@ -4993,13 +4956,13 @@ wants_texcoords() const {
 //               rendered up until the next call of end_decal() should
 //               rendered up until the next call of end_decal() should
 //               be rendered as decals of the base_geom.
 //               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
 //               base geometry node.  It may or may not be modified by
 //               the GSG to reflect whatever rendering state is
 //               the GSG to reflect whatever rendering state is
 //               necessary to render the decals properly.
 //               necessary to render the decals properly.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian::
 void DXGraphicsStateGuardian::
-begin_decal(GeomNode *base_geom, AllAttributesWrapper &attrib) {
+begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib) {
     nassertv(base_geom != (GeomNode *)NULL);
     nassertv(base_geom != (GeomNode *)NULL);
 
 
     _decal_level++;
     _decal_level++;

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

@@ -33,9 +33,7 @@
 #include <stencilProperty.h>
 #include <stencilProperty.h>
 #include <fog.h>
 #include <fog.h>
 
 
-#include <colorMatrixAttribute.h>
 #include <colorMatrixTransition.h>
 #include <colorMatrixTransition.h>
-#include <alphaTransformAttribute.h>
 #include <alphaTransformTransition.h>
 #include <alphaTransformTransition.h>
 #include <pointerToArray.h>
 #include <pointerToArray.h>
 #include <planeNode.h>
 #include <planeNode.h>
@@ -98,16 +96,13 @@ public:
 
 
   virtual void prepare_display_region();
   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,
   virtual void render_subgraph(RenderTraverser *traverser,
                    Node *subgraph, ProjectionNode *projnode,
                    Node *subgraph, ProjectionNode *projnode,
-                   const AllAttributesWrapper &initial_state,
                    const AllTransitionsWrapper &net_trans);
                    const AllTransitionsWrapper &net_trans);
   virtual void render_subgraph(RenderTraverser *traverser,
   virtual void render_subgraph(RenderTraverser *traverser,
                    Node *subgraph,
                    Node *subgraph,
-                   const AllAttributesWrapper &initial_state,
                    const AllTransitionsWrapper &net_trans);
                    const AllTransitionsWrapper &net_trans);
 
 
   virtual void draw_point(GeomPoint *geom, GeomContext *gc);
   virtual void draw_point(GeomPoint *geom, GeomContext *gc);
@@ -145,10 +140,10 @@ public:
   virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
   virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb);
                                  const RenderBuffer &rb);
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
   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,
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb,
                                  const RenderBuffer &rb,
-                 const NodeAttributes& na=NodeAttributes());
+                 const NodeTransitions& na=NodeTransitions());
 
 
   virtual void apply_material(const Material *material);
   virtual void apply_material(const Material *material);
   virtual void apply_fog(Fog *fog);
   virtual void apply_fog(Fog *fog);
@@ -158,33 +153,33 @@ public:
   virtual void apply_light(Spotlight* light);
   virtual void apply_light(Spotlight* light);
   virtual void apply_light(AmbientLight* 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_normals(void) const;
   virtual bool wants_texcoords(void) const;
   virtual bool wants_texcoords(void) const;
   virtual bool wants_colors(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 end_decal(GeomNode *base_geom);
 
 
   INLINE float compute_distance_to(const LPoint3f &point) const;
   INLINE float compute_distance_to(const LPoint3f &point) const;

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

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

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

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

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

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

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

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

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

@@ -1973,6 +1973,6 @@ void EggLoader::
 apply_deferred_arcs(Node *root) {
 apply_deferred_arcs(Node *root) {
   DeferredArcTraverser trav(_deferred_arcs);
   DeferredArcTraverser trav(_deferred_arcs);
 
 
-  df_traverse(root, trav, NullAttributeWrapper(), DeferredArcProperty(),
+  df_traverse(root, trav, NullTransitionWrapper(), DeferredArcProperty(),
               RenderRelation::get_class_type());
               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
 // We need to include bitMask.h first to avoid a VC++ compiler bug
 // related to 2 parameter templates
 // related to 2 parameter templates
-#include <bitMask.h>
+#include "bitMask.h"
 
 
 #include "framework.h"
 #include "framework.h"
 #include "config_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
 // Since framework.cxx includes pystub.h, no program that links with
 // framework needs to do so.  No Python code should attempt to link
 // framework needs to do so.  No Python code should attempt to link
 // with libframework.so.
 // 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 "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
 #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
 #endif
 
 
 Configure(framework);
 Configure(framework);
@@ -118,7 +117,9 @@ AppTraverser *app_traverser;
 PT_NamedNode data_root;
 PT_NamedNode data_root;
 PT_NamedNode root;
 PT_NamedNode root;
 PT(GeomNode) geomnode;
 PT(GeomNode) geomnode;
+PT_NamedNode render_top;
 PT_NamedNode render;
 PT_NamedNode render;
+NodeRelation *render_arc;
 PT_NamedNode cameras;
 PT_NamedNode cameras;
 PT(MouseAndKeyboard) mak;
 PT(MouseAndKeyboard) mak;
 PT(MouseWatcher) mouse_watcher;
 PT(MouseWatcher) mouse_watcher;
@@ -128,7 +129,6 @@ PT(DriveInterface) drive_interface;
 static Node *current_trackball = NULL;
 static Node *current_trackball = NULL;
 static Node *alt_trackball = NULL;
 static Node *alt_trackball = NULL;
 
 
-NodeAttributes initial_state;
 Texture* ttex;
 Texture* ttex;
 PT(GraphicsPipe) main_pipe;
 PT(GraphicsPipe) main_pipe;
 PT(GraphicsPipe) rib_pipe;
 PT(GraphicsPipe) rib_pipe;
@@ -217,7 +217,7 @@ class NormalAddTraverser :
   public TraverserVisitor<NullTransitionWrapper, NullLevelState> {
   public TraverserVisitor<NullTransitionWrapper, NullLevelState> {
 public:
 public:
   NormalAddTraverser(GraphicsStateGuardian *gsg) : _gsg(gsg) {}
   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
   // No need to declare a forward_arc() function that simply returns
   // true; this is the default behavior.
   // true; this is the default behavior.
@@ -227,7 +227,7 @@ public:
 };
 };
 
 
 bool NormalAddTraverser::
 bool NormalAddTraverser::
-reached_node(Node *node, NullAttributeWrapper &, NullLevelState &) {
+reached_node(Node *node, NullTransitionWrapper &, NullLevelState &) {
   if (node->is_of_type(GeomNode::get_class_type())) {
   if (node->is_of_type(GeomNode::get_class_type())) {
     GeomNorms *gn = new GeomNorms;
     GeomNorms *gn = new GeomNorms;
     GeomNode *geom = DCAST(GeomNode, node);
     GeomNode *geom = DCAST(GeomNode, node);
@@ -286,13 +286,13 @@ class NormalDelTraverser :
   public TraverserVisitor<NullTransitionWrapper, NullLevelState> {
   public TraverserVisitor<NullTransitionWrapper, NullLevelState> {
 public:
 public:
   NormalDelTraverser(GraphicsStateGuardian *gsg) : _gsg(gsg) {}
   NormalDelTraverser(GraphicsStateGuardian *gsg) : _gsg(gsg) {}
-  bool reached_node(Node*, NullAttributeWrapper&, NullLevelState&);
+  bool reached_node(Node*, NullTransitionWrapper&, NullLevelState&);
 public:
 public:
   GraphicsStateGuardian *_gsg;
   GraphicsStateGuardian *_gsg;
 };
 };
 
 
 bool NormalDelTraverser::
 bool NormalDelTraverser::
-reached_node(Node *node, NullAttributeWrapper &, NullLevelState &) {
+reached_node(Node *node, NullTransitionWrapper &, NullLevelState &) {
   if (node->is_of_type(GeomNode::get_class_type())) {
   if (node->is_of_type(GeomNode::get_class_type())) {
     GeomNode *geom = DCAST(GeomNode, node);
     GeomNode *geom = DCAST(GeomNode, node);
     int i, j;
     int i, j;
@@ -313,11 +313,11 @@ reached_node(Node *node, NullAttributeWrapper &, NullLevelState &) {
 }
 }
 
 
 void render_frame(GraphicsPipe *pipe) {
 void render_frame(GraphicsPipe *pipe) {
-  app_traverser->traverse(render);
+  app_traverser->traverse(render_top);
   int num_windows = pipe->get_num_windows();
   int num_windows = pipe->get_num_windows();
   for (int w = 0; w < num_windows; w++) {
   for (int w = 0; w < num_windows; w++) {
     GraphicsWindow *win = pipe->get_window(w);
     GraphicsWindow *win = pipe->get_window(w);
-    win->get_gsg()->render_frame(initial_state);
+    win->get_gsg()->render_frame();
   }
   }
   ClockObject::get_global_clock()->tick();
   ClockObject::get_global_clock()->tick();
   throw_event("NewFrame");
   throw_event("NewFrame");
@@ -343,17 +343,17 @@ void display_func( void ) {
 void set_lighting(bool enabled) {
 void set_lighting(bool enabled) {
   if (enabled) {
   if (enabled) {
     // Enable the lights on the initial state.
     // Enable the lights on the initial state.
-    LightAttribute *la = new LightAttribute;
+    PT(LightTransition) la = new LightTransition;
     la->set_on(light.p());
     la->set_on(light.p());
 
 
     if (have_dlight) {
     if (have_dlight) {
       la->set_on(dlight.p());
       la->set_on(dlight.p());
     }
     }
-    initial_state.set_attribute(LightTransition::get_class_type(), la);
+    render_arc->set_transition(la);
 
 
   } else {
   } else {
     // Remove the lights from the initial state.
     // 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
       // Perform the collision traversal, if we have a collision
       // traverser standing by.
       // traverser standing by.
       if (col_trans != (CollisionTraverser *)NULL) {
       if (col_trans != (CollisionTraverser *)NULL) {
-        col_trans->traverse(render);
+        col_trans->traverse(render_top);
       }
       }
 
 
       // Throw any events generated recently.
       // Throw any events generated recently.
@@ -620,12 +620,12 @@ void event_t(CPT_Event) {
   textures_enabled = !textures_enabled;
   textures_enabled = !textures_enabled;
   if (textures_enabled) {
   if (textures_enabled) {
     // Remove the override from the initial state.
     // Remove the override from the initial state.
-    initial_state.clear_attribute(TextureTransition::get_class_type());
+    render_arc->clear_transition(TextureTransition::get_class_type());
   } else {
   } else {
     // Set an override on the initial state to disable texturing.
     // Set an override on the initial state to disable texturing.
-    TextureAttribute *ta = new TextureAttribute;
+    TextureTransition *ta = new TextureTransition;
     ta->set_priority(100);
     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;
   wireframe_mode = !wireframe_mode;
   if (!wireframe_mode) {
   if (!wireframe_mode) {
     // Set the normal, filled mode on the render arc.
     // 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 {
   } else {
     // Set the initial state up for wireframe mode.
     // 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;
   backface_mode = !backface_mode;
   if (backface_mode) {
   if (backface_mode) {
     material->set_twoside(true);
     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 {
   } else {
     material->set_twoside(false);
     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;
   normals_on = !normals_on;
   if (normals_on) {
   if (normals_on) {
     NormalAddTraverser trav(main_win->get_gsg());
     NormalAddTraverser trav(main_win->get_gsg());
-    df_traverse(render, trav, NullAttributeWrapper(), NullLevelState(),
+    df_traverse(render, trav, NullTransitionWrapper(), NullLevelState(),
                 RenderRelation::get_class_type());
                 RenderRelation::get_class_type());
   } else {
   } else {
     NormalDelTraverser trav(main_win->get_gsg());
     NormalDelTraverser trav(main_win->get_gsg());
-    df_traverse(render, trav, NullAttributeWrapper(), NullLevelState(),
+    df_traverse(render, trav, NullTransitionWrapper(), NullLevelState(),
                 RenderRelation::get_class_type());
                 RenderRelation::get_class_type());
   }
   }
 }
 }
@@ -911,12 +905,11 @@ void event_g(CPT_Event) {
 
 
   fog_mode = !fog_mode;
   fog_mode = !fog_mode;
   if (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 {
   } 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++) {
   for(int i = 0; i < size; i++) {
   double time_delta = (now-InfoArr[i].starttime);
   double time_delta = (now-InfoArr[i].starttime);
   #define DO_FP_MODULUS(VAL,MAXVAL)  \
   #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
   // 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;
   int gridrepeats=1;
   GriddedMotionType gridmotiontype = None;
   GriddedMotionType gridmotiontype = None;
 
 
-  bool bRotateGriddedObjs = false;
-  bool bMoveGriddedObjs = false;
+  //  bool bRotateGriddedObjs = false;
+  //  bool bMoveGriddedObjs = false;
 
 
   for (int a = 1; a < argc; a++) {
   for (int a = 1; a < argc; a++) {
     if ((argv[a] != (char*)0L) && ((argv[a])[0] != '-') &&
     if ((argv[a] != (char*)0L) && ((argv[a])[0] != '-') &&
@@ -1187,32 +1180,32 @@ int framework_main(int argc, char *argv[]) {
     extra_overrides_func(override, conf);
     extra_overrides_func(override, conf);
 
 
   // Create the render node
   // Create the render node
+  render_top = new NamedNode("render_top");
   render = new NamedNode("render");
   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();
   main_win = chanConfig.get_win();
   assert(main_win != (GraphicsWindow*)0L);
   assert(main_win != (GraphicsWindow*)0L);
   cameras = chanConfig.get_group_node(0);
   cameras = chanConfig.get_group_node(0);
   cameras->set_name("cameras");
   cameras->set_name("cameras");
   for(int group_node_index=1;group_node_index<chanConfig.get_num_groups();
   for(int group_node_index=1;group_node_index<chanConfig.get_num_groups();
       group_node_index++) {
       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);
   RenderRelation* arc1 = new RenderRelation(render, cameras);
 
 
   // is ok if this doesn't work or returns NULL
   // is ok if this doesn't work or returns NULL
   if (rib_pipe != (GraphicsPipe*)0L) { 
   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();
     rib_win = chanConfig.get_win();
     NamedNode *rib_cameras = chanConfig.get_group_node(0);
     NamedNode *rib_cameras = chanConfig.get_group_node(0);
     rib_cameras->set_name("rib_cameras");
     rib_cameras->set_name("rib_cameras");
     for(int rib_group_node_index=1;
     for(int rib_group_node_index=1;
         rib_group_node_index<chanConfig.get_num_groups();
         rib_group_node_index<chanConfig.get_num_groups();
         rib_group_node_index++) {
         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);
     new RenderRelation(render, rib_cameras);
   }
   }
@@ -1238,16 +1231,14 @@ int framework_main(int argc, char *argv[]) {
 #endif
 #endif
 
 
   // Turn on culling.
   // 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 = new Material;
   material->set_ambient( Colorf( 1, 1, 1, 1 ) );
   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
   // Set up a default fog
   fog = new Fog;
   fog = new Fog;
@@ -1363,164 +1354,163 @@ int framework_main(int argc, char *argv[]) {
       filename.resolve_filename(local_path);
       filename.resolve_filename(local_path);
 
 
       PT_Node node = loader.load_sync(filename);
       PT_Node node = loader.load_sync(filename);
-
+      
       if (node == (Node *)NULL) {
       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,
                                 // cant directly instance characters due to LOD problems,
                                 // must copy using copy_subgraph for now
                                 // 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
     // If we happened to load up both a character file and its
     // matching animation file, attempt to bind them together now.
     // matching animation file, attempt to bind them together now.

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

@@ -42,52 +42,29 @@
 #include <spotlight.h>
 #include <spotlight.h>
 #include <GL/glu.h>
 #include <GL/glu.h>
 #include <projectionNode.h>
 #include <projectionNode.h>
-#include <transformAttribute.h>
 #include <transformTransition.h>
 #include <transformTransition.h>
-#include <colorMatrixAttribute.h>
 #include <colorMatrixTransition.h>
 #include <colorMatrixTransition.h>
-#include <alphaTransformAttribute.h>
 #include <alphaTransformTransition.h>
 #include <alphaTransformTransition.h>
-#include <colorAttribute.h>
 #include <colorTransition.h>
 #include <colorTransition.h>
-#include <lightAttribute.h>
 #include <lightTransition.h>
 #include <lightTransition.h>
-#include <textureAttribute.h>
 #include <textureTransition.h>
 #include <textureTransition.h>
-#include <renderModeAttribute.h>
 #include <renderModeTransition.h>
 #include <renderModeTransition.h>
-#include <materialAttribute.h>
 #include <materialTransition.h>
 #include <materialTransition.h>
-#include <colorBlendAttribute.h>
 #include <colorBlendTransition.h>
 #include <colorBlendTransition.h>
-#include <colorMaskAttribute.h>
 #include <colorMaskTransition.h>
 #include <colorMaskTransition.h>
-#include <texMatrixAttribute.h>
 #include <texMatrixTransition.h>
 #include <texMatrixTransition.h>
-#include <texGenAttribute.h>
 #include <texGenTransition.h>
 #include <texGenTransition.h>
-#include <textureApplyAttribute.h>
 #include <textureApplyTransition.h>
 #include <textureApplyTransition.h>
-#include <clipPlaneAttribute.h>
 #include <clipPlaneTransition.h>
 #include <clipPlaneTransition.h>
-#include <transparencyAttribute.h>
 #include <transparencyTransition.h>
 #include <transparencyTransition.h>
-#include <fogAttribute.h>
 #include <fogTransition.h>
 #include <fogTransition.h>
-#include <linesmoothAttribute.h>
 #include <linesmoothTransition.h>
 #include <linesmoothTransition.h>
-#include <depthTestAttribute.h>
 #include <depthTestTransition.h>
 #include <depthTestTransition.h>
-#include <depthWriteAttribute.h>
 #include <depthWriteTransition.h>
 #include <depthWriteTransition.h>
-#include <cullFaceAttribute.h>
 #include <cullFaceTransition.h>
 #include <cullFaceTransition.h>
-#include <stencilAttribute.h>
 #include <stencilTransition.h>
 #include <stencilTransition.h>
-#include <pointShapeAttribute.h>
 #include <pointShapeTransition.h>
 #include <pointShapeTransition.h>
 #include <polygonOffsetTransition.h>
 #include <polygonOffsetTransition.h>
-#include <polygonOffsetAttribute.h>
 #include <clockObject.h>
 #include <clockObject.h>
 #include <pStatTimer.h>
 #include <pStatTimer.h>
 #include <string_utils.h>
 #include <string_utils.h>
@@ -317,11 +294,11 @@ reset() {
 
 
   // Make sure the GL state matches all of our initial attribute
   // Make sure the GL state matches all of our initial attribute
   // states.
   // 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);
   dta->issue(this);
   dwa->issue(this);
   dwa->issue(this);
@@ -354,15 +331,14 @@ clear(const RenderBuffer &buffer) {
   nassertv(buffer._gsg == this);
   nassertv(buffer._gsg == this);
   int buffer_type = buffer._buffer_type;
   int buffer_type = buffer._buffer_type;
   GLbitfield mask = 0;
   GLbitfield mask = 0;
-  NodeAttributes state;
+  NodeTransitions state;
 
 
   if (buffer_type & RenderBuffer::T_color) {
   if (buffer_type & RenderBuffer::T_color) {
     call_glClearColor(_color_clear_value[0],
     call_glClearColor(_color_clear_value[0],
                       _color_clear_value[1],
                       _color_clear_value[1],
                       _color_clear_value[2],
                       _color_clear_value[2],
                       _color_clear_value[3]);
                       _color_clear_value[3]);
-    state.set_attribute(ColorMaskTransition::get_class_type(),
-                        new ColorMaskAttribute);
+    state.set_transition(new ColorMaskTransition);
     mask |= GL_COLOR_BUFFER_BIT;
     mask |= GL_COLOR_BUFFER_BIT;
 
 
     set_draw_buffer(buffer);
     set_draw_buffer(buffer);
@@ -375,8 +351,7 @@ clear(const RenderBuffer &buffer) {
     // In order to clear the depth buffer, the depth mask must enable
     // In order to clear the depth buffer, the depth mask must enable
     // writing to the depth buffer.
     // writing to the depth buffer.
     if (!_depth_mask) {
     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.
 //               pre- and post-processing like swapping buffers.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-render_frame(const AllAttributesWrapper &initial_state) {
+render_frame() {
 #ifdef GSG_VERBOSE
 #ifdef GSG_VERBOSE
   glgsg_cat.debug()
   glgsg_cat.debug()
     << "begin frame " << ClockObject::get_global_clock()->get_frame_count()
     << "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) {
                   cam->is_active() && cam->get_scene() != (Node *)NULL) {
                 DisplayRegionStack old_dr = push_display_region(dr);
                 DisplayRegionStack old_dr = push_display_region(dr);
                 prepare_display_region();
                 prepare_display_region();
-                render_scene(cam->get_scene(), cam, initial_state);
+                render_scene(cam->get_scene(), cam);
                 pop_display_region(old_dr);
                 pop_display_region(old_dr);
               }
               }
             }
             }
@@ -580,8 +555,7 @@ render_frame(const AllAttributesWrapper &initial_state) {
 //               may be modified during rendering.
 //               may be modified during rendering.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-render_scene(Node *root, ProjectionNode *projnode,
-             const AllAttributesWrapper &initial_state) {
+render_scene(Node *root, ProjectionNode *projnode) {
 #ifdef GSG_VERBOSE
 #ifdef GSG_VERBOSE
   _pass_number = 0;
   _pass_number = 0;
   glgsg_cat.debug()
   glgsg_cat.debug()
@@ -590,7 +564,7 @@ render_scene(Node *root, ProjectionNode *projnode,
 #endif
 #endif
   _current_root_node = root;
   _current_root_node = root;
 
 
-  render_subgraph(_render_traverser, root, projnode, initial_state,
+  render_subgraph(_render_traverser, root, projnode,
                   AllTransitionsWrapper());
                   AllTransitionsWrapper());
 
 
 #ifdef GSG_VERBOSE
 #ifdef GSG_VERBOSE
@@ -611,7 +585,6 @@ render_scene(Node *root, ProjectionNode *projnode,
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
 render_subgraph(RenderTraverser *traverser,
 render_subgraph(RenderTraverser *traverser,
                 Node *subgraph, ProjectionNode *projnode,
                 Node *subgraph, ProjectionNode *projnode,
-                const AllAttributesWrapper &initial_state,
                 const AllTransitionsWrapper &net_trans) {
                 const AllTransitionsWrapper &net_trans) {
   // Calling activate() frequently seems to be intolerably expensive
   // Calling activate() frequently seems to be intolerably expensive
   // on some platforms.  We'll limit ourselves for now to calling it
   // 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;
   AllTransitionsWrapper sub_trans = net_trans;
   sub_trans.set_transition(new TransformTransition(modelview_mat));
   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_node = old_projection_node;
   _current_projection_mat = old_projection_mat;
   _current_projection_mat = old_projection_mat;
@@ -688,7 +661,6 @@ render_subgraph(RenderTraverser *traverser,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
 render_subgraph(RenderTraverser *traverser, Node *subgraph,
 render_subgraph(RenderTraverser *traverser, Node *subgraph,
-                const AllAttributesWrapper &initial_state,
                 const AllTransitionsWrapper &net_trans) {
                 const AllTransitionsWrapper &net_trans) {
 #ifdef GSG_VERBOSE
 #ifdef GSG_VERBOSE
   glgsg_cat.debug()
   glgsg_cat.debug()
@@ -698,7 +670,7 @@ render_subgraph(RenderTraverser *traverser, Node *subgraph,
   //  activate();
   //  activate();
 
 
   nassertv(traverser != (RenderTraverser *)NULL);
   nassertv(traverser != (RenderTraverser *)NULL);
-  traverser->traverse(subgraph, initial_state, net_trans);
+  traverser->traverse(subgraph, net_trans);
 
 
 #ifdef GSG_VERBOSE
 #ifdef GSG_VERBOSE
   glgsg_cat.debug()
   glgsg_cat.debug()
@@ -972,8 +944,8 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
   // save the modelview matrix
   // save the modelview matrix
   LMatrix4f modelview_mat;
   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();
     modelview_mat = LMatrix4f::ident_mat();
   else
   else
     modelview_mat = ctatt->get_matrix();
     modelview_mat = ctatt->get_matrix();
@@ -1029,15 +1001,15 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
   float scaled_width, scaled_height;
   float scaled_width, scaled_height;
 
 
   // set up the texture-rendering state
   // set up the texture-rendering state
-  NodeAttributes state;
+  NodeTransitions state;
 
 
-  TextureAttribute *ta = new TextureAttribute;
+  TextureTransition *ta = new TextureTransition;
   ta->set_on(tex);
   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);
   taa->set_mode(TextureApplyProperty::M_modulate);
-  state.set_attribute(TextureApplyTransition::get_class_type(), taa);
+  state.set_transition(taa);
 
 
   set_state(state, false);
   set_state(state, false);
 
 
@@ -1046,8 +1018,8 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
 
 
   if (geom->get_alpha_disable() == false) {
   if (geom->get_alpha_disable() == false) {
     // figure out if alpha's enabled (if not, no reason to sort)
     // 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;
       alpha = true;
   }
   }
 
 
@@ -2031,35 +2003,29 @@ draw_texture(TextureContext *tc, const DisplayRegion *dr) {
   DisplayRegionStack old_dr = push_display_region(dr);
   DisplayRegionStack old_dr = push_display_region(dr);
   prepare_display_region();
   prepare_display_region();
 
 
-  NodeAttributes state;
-  CullFaceAttribute *cfa = new CullFaceAttribute;
+  NodeTransitions state;
+  CullFaceTransition *cfa = new CullFaceTransition;
   cfa->set_mode(CullFaceProperty::M_cull_none);
   cfa->set_mode(CullFaceProperty::M_cull_none);
-  DepthTestAttribute *dta = new DepthTestAttribute;
+  DepthTestTransition *dta = new DepthTestTransition;
   dta->set_mode(DepthTestProperty::M_none);
   dta->set_mode(DepthTestProperty::M_none);
-  DepthWriteAttribute *dwa = new DepthWriteAttribute;
+  DepthWriteTransition *dwa = new DepthWriteTransition;
   dwa->set_off();
   dwa->set_off();
-  TextureAttribute *ta = new TextureAttribute;
+  TextureTransition *ta = new TextureTransition;
   ta->set_on(tex);
   ta->set_on(tex);
-  TextureApplyAttribute *taa = new TextureApplyAttribute;
+  TextureApplyTransition *taa = new TextureApplyTransition;
   taa->set_mode(TextureApplyProperty::M_decal);
   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);
   set_state(state, false);
 
 
   // We set up an orthographic projection that defines our entire
   // We set up an orthographic projection that defines our entire
@@ -2248,7 +2214,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
-                  const NodeAttributes& na) {
+                  const NodeTransitions& na) {
   nassertv(pb != NULL && dr != NULL);
   nassertv(pb != NULL && dr != NULL);
   nassertv(!pb->_image.empty());
   nassertv(!pb->_image.empty());
   //  activate();
   //  activate();
@@ -2256,30 +2222,22 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
   DisplayRegionStack old_dr = push_display_region(dr);
   DisplayRegionStack old_dr = push_display_region(dr);
   prepare_display_region();
   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()) {
   switch (pb->get_format()) {
   case PixelBuffer::F_depth_component:
   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;
     break;
 
 
@@ -2294,14 +2252,12 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
   case PixelBuffer::F_rgba8:
   case PixelBuffer::F_rgba8:
   case PixelBuffer::F_rgba12:
   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;
     break;
   default:
   default:
@@ -2373,7 +2329,7 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
 draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
-                  const RenderBuffer &rb, const NodeAttributes& na) {
+                  const RenderBuffer &rb, const NodeTransitions& na) {
   //  activate();
   //  activate();
   set_draw_buffer(rb);
   set_draw_buffer(rb);
   draw_pixel_buffer(pb, dr, na);
   draw_pixel_buffer(pb, dr, na);
@@ -2639,7 +2595,7 @@ void GLGraphicsStateGuardian::apply_light( AmbientLight* )
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_transform(const TransformAttribute *attrib) {
+issue_transform(const TransformTransition *attrib) {
   //  activate();
   //  activate();
 #ifdef GSG_VERBOSE
 #ifdef GSG_VERBOSE
   glgsg_cat.debug()
   glgsg_cat.debug()
@@ -2686,7 +2642,7 @@ issue_transform(const TransformAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_color_transform(const ColorMatrixAttribute *attrib) {
+issue_color_transform(const ColorMatrixTransition *attrib) {
   _current_color_mat = attrib->get_matrix();
   _current_color_mat = attrib->get_matrix();
 
 
   if (_current_color_mat == LMatrix4f::ident_mat()) {
   if (_current_color_mat == LMatrix4f::ident_mat()) {
@@ -2704,7 +2660,7 @@ issue_color_transform(const ColorMatrixAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_alpha_transform(const AlphaTransformAttribute *attrib) {
+issue_alpha_transform(const AlphaTransformTransition *attrib) {
   _current_alpha_offset= attrib->get_offset();
   _current_alpha_offset= attrib->get_offset();
   _current_alpha_scale = attrib->get_scale();
   _current_alpha_scale = attrib->get_scale();
 
 
@@ -2723,7 +2679,7 @@ issue_alpha_transform(const AlphaTransformAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_tex_matrix(const TexMatrixAttribute *attrib) {
+issue_tex_matrix(const TexMatrixTransition *attrib) {
   //  activate();
   //  activate();
 #ifdef GSG_VERBOSE
 #ifdef GSG_VERBOSE
   glgsg_cat.debug()
   glgsg_cat.debug()
@@ -2740,7 +2696,7 @@ issue_tex_matrix(const TexMatrixAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_color(const ColorAttribute *attrib) {
+issue_color(const ColorTransition *attrib) {
   if (attrib->is_on()) {
   if (attrib->is_on()) {
     if (attrib->is_real()) {
     if (attrib->is_real()) {
       // The color attribute is "on" and "real": it specifies a scene
       // The color attribute is "on" and "real": it specifies a scene
@@ -2773,7 +2729,7 @@ issue_color(const ColorAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_texture(const TextureAttribute *attrib) {
+issue_texture(const TextureTransition *attrib) {
   //  activate();
   //  activate();
 
 
   if (attrib->is_on()) {
   if (attrib->is_on()) {
@@ -2793,7 +2749,7 @@ issue_texture(const TextureAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_tex_gen(const TexGenAttribute *attrib) {
+issue_tex_gen(const TexGenTransition *attrib) {
   //  activate();
   //  activate();
   TexGenProperty::Mode mode = attrib->get_mode();
   TexGenProperty::Mode mode = attrib->get_mode();
 
 
@@ -2846,7 +2802,7 @@ issue_tex_gen(const TexGenAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_material(const MaterialAttribute *attrib) {
+issue_material(const MaterialTransition *attrib) {
   //  activate();
   //  activate();
   if (attrib->is_on()) {
   if (attrib->is_on()) {
     const Material *material = attrib->get_material();
     const Material *material = attrib->get_material();
@@ -2862,7 +2818,7 @@ issue_material(const MaterialAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_fog(const FogAttribute *attrib) {
+issue_fog(const FogTransition *attrib) {
   //  activate();
   //  activate();
 
 
   if (attrib->is_on()) {
   if (attrib->is_on()) {
@@ -2882,7 +2838,7 @@ issue_fog(const FogAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_render_mode(const RenderModeAttribute *attrib) {
+issue_render_mode(const RenderModeTransition *attrib) {
   //  activate();
   //  activate();
 
 
   RenderModeProperty::Mode mode = attrib->get_mode();
   RenderModeProperty::Mode mode = attrib->get_mode();
@@ -2910,9 +2866,9 @@ issue_render_mode(const RenderModeAttribute *attrib) {
 //       Access: Public, Virtual
 //       Access: Public, Virtual
 //  Description:
 //  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();
   //  activate();
 
 
   // Initialize the current ambient light total and newly enabled
   // Initialize the current ambient light total and newly enabled
@@ -2924,64 +2880,68 @@ void GLGraphicsStateGuardian::issue_light(const LightAttribute *attrib )
   }
   }
 
 
   int num_enabled = 0;
   int num_enabled = 0;
-  LightAttribute::const_iterator li;
+  LightTransition::const_iterator li;
   for (li = attrib->begin(); li != attrib->end(); ++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);
     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++) {
         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;
             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:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_color_blend(const ColorBlendAttribute *attrib) {
+issue_color_blend(const ColorBlendTransition *attrib) {
   //  activate();
   //  activate();
   ColorBlendProperty::Mode mode = attrib->get_mode();
   ColorBlendProperty::Mode mode = attrib->get_mode();
 
 
@@ -3045,7 +3005,7 @@ issue_color_blend(const ColorBlendAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_texture_apply(const TextureApplyAttribute *attrib) {
+issue_texture_apply(const TextureApplyTransition *attrib) {
   //  activate();
   //  activate();
   GLint glmode = get_texture_apply_mode_type(attrib->get_mode());
   GLint glmode = get_texture_apply_mode_type(attrib->get_mode());
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);
@@ -3058,7 +3018,7 @@ issue_texture_apply(const TextureApplyAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_color_mask(const ColorMaskAttribute *attrib) {
+issue_color_mask(const ColorMaskTransition *attrib) {
   //  activate();
   //  activate();
   glColorMask(attrib->is_write_r(),
   glColorMask(attrib->is_write_r(),
               attrib->is_write_g(),
               attrib->is_write_g(),
@@ -3073,7 +3033,7 @@ issue_color_mask(const ColorMaskAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_depth_test(const DepthTestAttribute *attrib) {
+issue_depth_test(const DepthTestTransition *attrib) {
   //  activate();
   //  activate();
 
 
   DepthTestProperty::Mode mode = attrib->get_mode();
   DepthTestProperty::Mode mode = attrib->get_mode();
@@ -3092,7 +3052,7 @@ issue_depth_test(const DepthTestAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_depth_write(const DepthWriteAttribute *attrib) {
+issue_depth_write(const DepthWriteTransition *attrib) {
   //  activate();
   //  activate();
 
 
   call_glDepthMask(attrib->is_on());
   call_glDepthMask(attrib->is_on());
@@ -3105,7 +3065,7 @@ issue_depth_write(const DepthWriteAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_stencil(const StencilAttribute *attrib) {
+issue_stencil(const StencilTransition *attrib) {
   //  activate();
   //  activate();
 
 
   StencilProperty::Mode mode = attrib->get_mode();
   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
 //       Access: Public, Virtual
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_cull_face(const CullFaceAttribute *attrib) {
+issue_cull_face(const CullFaceTransition *attrib) {
   //  activate();
   //  activate();
-
   CullFaceProperty::Mode mode = attrib->get_mode();
   CullFaceProperty::Mode mode = attrib->get_mode();
 
 
   switch (mode) {
   switch (mode) {
@@ -3161,8 +3120,9 @@ issue_cull_face(const CullFaceAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_clip_plane(const ClipPlaneAttribute *attrib)
+issue_clip_plane(const ClipPlaneTransition *attrib)
 {
 {
+  nassertv(attrib->get_default_dir() != TD_on);
   //  activate();
   //  activate();
 
 
   // Initialize the currently enabled clip plane list
   // Initialize the currently enabled clip plane list
@@ -3171,68 +3131,71 @@ issue_clip_plane(const ClipPlaneAttribute *attrib)
     _cur_clip_plane_enabled[i] = false;
     _cur_clip_plane_enabled[i] = false;
 
 
   int num_enabled = 0;
   int num_enabled = 0;
-  ClipPlaneAttribute::const_iterator pi;
+  ClipPlaneTransition::const_iterator pi;
   for (pi = attrib->begin(); pi != attrib->end(); ++pi) {
   for (pi = attrib->begin(); pi != attrib->end(); ++pi) {
     PlaneNode *plane_node;
     PlaneNode *plane_node;
-    DCAST_INTO_V(plane_node, (*pi));
+    DCAST_INTO_V(plane_node, (*pi).first);
     nassertv(plane_node != (PlaneNode *)NULL);
     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++) {
       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;
           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:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_transparency(const TransparencyAttribute *attrib )
+issue_transparency(const TransparencyTransition *attrib )
 {
 {
   //  activate();
   //  activate();
 
 
@@ -3311,7 +3274,7 @@ issue_transparency(const TransparencyAttribute *attrib )
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_linesmooth(const LinesmoothAttribute *attrib) {
+issue_linesmooth(const LinesmoothTransition *attrib) {
   //  activate();
   //  activate();
   enable_line_smooth(attrib->is_on());
   enable_line_smooth(attrib->is_on());
   report_errors();
   report_errors();
@@ -3323,7 +3286,7 @@ issue_linesmooth(const LinesmoothAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_point_shape(const PointShapeAttribute *attrib) {
+issue_point_shape(const PointShapeTransition *attrib) {
   //  activate();
   //  activate();
 
 
   if (attrib->get_mode() == PointShapeProperty::M_square)
   if (attrib->get_mode() == PointShapeProperty::M_square)
@@ -3339,7 +3302,7 @@ issue_point_shape(const PointShapeAttribute *attrib) {
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_polygon_offset(const PolygonOffsetAttribute *attrib) {
+issue_polygon_offset(const PolygonOffsetTransition *attrib) {
   //  activate();
   //  activate();
   //GL really wants to do a enable/disable of PolygonOffset, but it
   //GL really wants to do a enable/disable of PolygonOffset, but it
   //seems more intuitive to have a PolygonOffset "on" all the time,
   //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
 //               rendered up until the next call of end_decal() should
 //               be rendered as decals of the base_geom.
 //               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
 //               base geometry node.  It may or may not be modified by
 //               the GSG to reflect whatever rendering state is
 //               the GSG to reflect whatever rendering state is
 //               necessary to render the decals properly.
 //               necessary to render the decals properly.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-begin_decal(GeomNode *base_geom, AllAttributesWrapper &attrib) {
+begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib) {
   nassertv(base_geom != (GeomNode *)NULL);
   nassertv(base_geom != (GeomNode *)NULL);
   _decal_level++;
   _decal_level++;
 
 
@@ -3432,9 +3395,9 @@ begin_decal(GeomNode *base_geom, AllAttributesWrapper &attrib) {
     } else {
     } else {
       // Turn off writing the depth buffer to render the base geometry.
       // Turn off writing the depth buffer to render the base geometry.
       call_glDepthMask(false);
       call_glDepthMask(false);
-      DepthWriteAttribute *dwa = new DepthWriteAttribute;
+      DepthWriteTransition *dwa = new DepthWriteTransition;
       dwa->set_off();
       dwa->set_off();
-      attrib.set_attribute(DepthWriteTransition::get_class_type(), dwa);
+      attrib.set_transition(dwa);
 
 
       // Now render the base geometry.
       // Now render the base geometry.
       base_geom->draw(this);
       base_geom->draw(this);
@@ -3512,8 +3475,8 @@ end_decal(GeomNode *base_geom) {
 
 
       // Finally, restore the depth write and color mask states to the
       // Finally, restore the depth write and color mask states to the
       // way they're supposed to be.
       // 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())) {
                              DepthWriteTransition::get_class_type())) {
         issue_depth_write(depth_write);
         issue_depth_write(depth_write);
       }
       }
@@ -3524,8 +3487,8 @@ end_decal(GeomNode *base_geom) {
           call_glBlendFunc(old_blend_source_func, old_blend_dest_func);
           call_glBlendFunc(old_blend_source_func, old_blend_dest_func);
         }
         }
       } else {
       } 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);
           issue_color_mask(color_mask);
         } else {
         } else {
           glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
           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 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,
   virtual void render_subgraph(RenderTraverser *traverser,
                                Node *subgraph, ProjectionNode *projnode,
                                Node *subgraph, ProjectionNode *projnode,
-                               const AllAttributesWrapper &initial_state,
                                const AllTransitionsWrapper &net_trans);
                                const AllTransitionsWrapper &net_trans);
   virtual void render_subgraph(RenderTraverser *traverser,
   virtual void render_subgraph(RenderTraverser *traverser,
                                Node *subgraph,
                                Node *subgraph,
-                               const AllAttributesWrapper &initial_state,
                                const AllTransitionsWrapper &net_trans);
                                const AllTransitionsWrapper &net_trans);
 
 
   virtual void draw_point(GeomPoint *geom, GeomContext *gc);
   virtual void draw_point(GeomPoint *geom, GeomContext *gc);
@@ -121,10 +118,10 @@ public:
   virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
   virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb);
                                  const RenderBuffer &rb);
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
   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,
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb,
                                  const RenderBuffer &rb,
-                                 const NodeAttributes& na=NodeAttributes());
+                                 const NodeTransitions& na=NodeTransitions());
 
 
   virtual void apply_material(const Material *material);
   virtual void apply_material(const Material *material);
   virtual void apply_fog(Fog *fog);
   virtual void apply_fog(Fog *fog);
@@ -134,35 +131,35 @@ public:
   virtual void apply_light(Spotlight* light);
   virtual void apply_light(Spotlight* light);
   virtual void apply_light(AmbientLight* 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_normals(void) const;
   virtual bool wants_texcoords(void) const;
   virtual bool wants_texcoords(void) const;
   virtual bool wants_colors(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 end_decal(GeomNode *base_geom);
 
 
   virtual float compute_distance_to(const LPoint3f &point) const;
   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();
   _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
 //     Function: AllTransitionsWrapper::invert_in_place
 //       Access: Public
 //       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 store_to(NodeRelation *arc) const;
 
 
   INLINE_GRAPH void compose_in_place(const AllTransitionsWrapper &other);
   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_in_place();
   INLINE_GRAPH void invert_compose_in_place(const AllTransitionsWrapper &other);
   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>
 template<class Visitor, class LevelState>
 INLINE_GRAPH DFTraverser<Visitor, LevelState>::
 INLINE_GRAPH DFTraverser<Visitor, LevelState>::
 DFTraverser(Visitor &visitor,
 DFTraverser(Visitor &visitor,
-            const AttributeWrapper &initial_render_state,
+            const TransitionWrapper &initial_render_state,
             TypeHandle graph_type) :
             TypeHandle graph_type) :
   _visitor(visitor),
   _visitor(visitor),
   _initial_render_state(initial_render_state),
   _initial_render_state(initial_render_state),
@@ -63,7 +63,7 @@ start(Node *root, const LevelState &initial_level_state) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class Visitor, class LevelState>
 template<class Visitor, class LevelState>
 void DFTraverser<Visitor, 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);
   nassertv(arc->get_child() != (Node *)NULL);
 
 
   // Give the visitor a chance to veto this arc.
   // 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);
     TransitionWrapper::init_from(_initial_render_state);
   trans.extract_from(arc);
   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)) {
   if (_visitor.forward_arc(arc, trans, state, post_state, level_state)) {
     traverse(arc->get_child(), post_state, level_state);
     traverse(arc->get_child(), post_state, level_state);
     _visitor.backward_arc(arc, trans, state, 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>
 template<class Visitor, class LevelState>
 void DFTraverser<Visitor, 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
   // Tell the visitor we reached the node, and give it a chance to
   // veto our further progress.
   // veto our further progress.
   if (_visitor.reached_node(node, state, level_state)) {
   if (_visitor.reached_node(node, state, level_state)) {
@@ -106,10 +106,10 @@ traverse(Node *node, AttributeWrapper &state, LevelState &level_state) {
 }
 }
 
 
 // Convenience functions.
 // Convenience functions.
-template<class Visitor, class AttributeWrapper, class LevelState>
+template<class Visitor, class TransitionWrapper, class LevelState>
 INLINE void
 INLINE void
 df_traverse(NodeRelation *arc, Visitor &visitor,
 df_traverse(NodeRelation *arc, Visitor &visitor,
-            const AttributeWrapper &initial_render_state,
+            const TransitionWrapper &initial_render_state,
             const LevelState &initial_level_state,
             const LevelState &initial_level_state,
             TypeHandle graph_type) {
             TypeHandle graph_type) {
   DFTraverser<Visitor, LevelState>
   DFTraverser<Visitor, LevelState>
@@ -117,10 +117,10 @@ df_traverse(NodeRelation *arc, Visitor &visitor,
   dft.start(arc, initial_level_state);
   dft.start(arc, initial_level_state);
 }
 }
 
 
-template<class Visitor, class AttributeWrapper, class LevelState>
+template<class Visitor, class TransitionWrapper, class LevelState>
 INLINE void
 INLINE void
 df_traverse(Node *root, Visitor &visitor,
 df_traverse(Node *root, Visitor &visitor,
-            const AttributeWrapper &initial_render_state,
+            const TransitionWrapper &initial_render_state,
             const LevelState &initial_level_state,
             const LevelState &initial_level_state,
             TypeHandle graph_type) {
             TypeHandle graph_type) {
   DFTraverser<Visitor, LevelState>
   DFTraverser<Visitor, LevelState>

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

@@ -39,10 +39,9 @@ template<class Visitor, class LevelState>
 class DFTraverser {
 class DFTraverser {
 public:
 public:
   typedef TYPENAME Visitor::TransitionWrapper TransitionWrapper;
   typedef TYPENAME Visitor::TransitionWrapper TransitionWrapper;
-  typedef TYPENAME Visitor::AttributeWrapper AttributeWrapper;
 
 
   INLINE_GRAPH DFTraverser(Visitor &visitor,
   INLINE_GRAPH DFTraverser(Visitor &visitor,
-                           const AttributeWrapper &initial_render_state,
+                           const TransitionWrapper &initial_render_state,
                            TypeHandle graph_type);
                            TypeHandle graph_type);
 
 
   INLINE_GRAPH void start(NodeRelation *arc, const LevelState &initial_level_state);
   INLINE_GRAPH void start(NodeRelation *arc, const LevelState &initial_level_state);
@@ -50,14 +49,14 @@ public:
 
 
 protected:
 protected:
   void traverse(NodeRelation *arc,
   void traverse(NodeRelation *arc,
-                AttributeWrapper render_state,
+                TransitionWrapper render_state,
                 LevelState level_state);
                 LevelState level_state);
   void traverse(Node *node,
   void traverse(Node *node,
-                AttributeWrapper &render_state,
+                TransitionWrapper &render_state,
                 LevelState &level_state);
                 LevelState &level_state);
 
 
   Visitor &_visitor;
   Visitor &_visitor;
-  AttributeWrapper _initial_render_state;
+  TransitionWrapper _initial_render_state;
   TypeHandle _graph_type;
   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
 //     Function: MultiTransition::output_property
 //       Access: Public, Virtual
 //       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>
 template<class Property, class NameClass>
 void MultiTransition<Property, NameClass>::
 void MultiTransition<Property, NameClass>::
@@ -526,9 +524,7 @@ output_property(ostream &, const Property &) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: MultiTransition::write_property
 //     Function: MultiTransition::write_property
 //       Access: Public, Virtual
 //       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>
 template<class Property, class NameClass>
 void MultiTransition<Property, NameClass>::
 void MultiTransition<Property, NameClass>::

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

@@ -100,9 +100,9 @@ public:
 protected:
 protected:
   virtual int internal_compare_to(const NodeTransition *other) const;
   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,
   virtual void write_property(ostream &out, const Property &prop,
-                              int indent_level) const=0;
+                              int indent_level) const;
 
 
 public:
 public:
   // These functions and typedefs allow one to peruse all of the
   // 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:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool Node::
 bool Node::
-sub_render(const AllAttributesWrapper &, AllTransitionsWrapper &,
+sub_render(const AllTransitionsWrapper &, AllTransitionsWrapper &, 
            RenderTraverser *) {
            RenderTraverser *) {
   return true;
   return true;
 }
 }

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

@@ -90,8 +90,8 @@ public:
 
 
   // This function is similar to another function in NodeTransition.
   // This function is similar to another function in NodeTransition.
   // It may or may not intercept the render traversal.
   // 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);
                           RenderTraverser *trav);
   virtual bool has_sub_render() const;
   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.
 //               false if any returned false.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool NodeRelation::
 bool NodeRelation::
-sub_render_trans(const AllAttributesWrapper &attrib,
-                 AllTransitionsWrapper &trans,
+sub_render_trans(const AllTransitionsWrapper &input_trans,
+                 AllTransitionsWrapper &modify_trans,
                  RenderTraverser *trav) {
                  RenderTraverser *trav) {
   bool all_true = true;
   bool all_true = true;
   NodeTransitions::const_iterator ti;
   NodeTransitions::const_iterator ti;
   for (ti = _transitions.begin(); ti != _transitions.end(); ++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;
       all_true = false;
     }
     }
   }
   }

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

@@ -125,8 +125,8 @@ PUBLISHED:
   INLINE_GRAPH void clear_wrt_cache();
   INLINE_GRAPH void clear_wrt_cache();
 
 
 public:
 public:
-  bool sub_render_trans(const AllAttributesWrapper &attrib,
-                        AllTransitionsWrapper &trans,
+  bool sub_render_trans(const AllTransitionsWrapper &input_trans,
+                        AllTransitionsWrapper &modify_trans,
                         RenderTraverser *trav);
                         RenderTraverser *trav);
   bool has_sub_render_trans() const;
   bool has_sub_render_trans() const;
   int get_num_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 "nodeTransition.h"
 #include "nodeTransitions.h"
 #include "nodeTransitions.h"
 #include "nodeRelation.h"
 #include "nodeRelation.h"
+#include "config_graph.h"
 
 
-#include <indent.h>
+#include "indent.h"
 
 
 TypeHandle NodeTransition::_type_handle;
 TypeHandle NodeTransition::_type_handle;
 
 
@@ -38,6 +39,18 @@ get_handle() const {
   return get_type();
   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
 //     Function: NodeTransition::sub_render
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -48,7 +61,7 @@ get_handle() const {
 //               process.
 //               process.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool NodeTransition::
 bool NodeTransition::
-sub_render(NodeRelation *, const AllAttributesWrapper &,
+sub_render(NodeRelation *, const AllTransitionsWrapper &, 
            AllTransitionsWrapper &, RenderTraverser *) {
            AllTransitionsWrapper &, RenderTraverser *) {
   return true;
   return true;
 }
 }
@@ -85,6 +98,18 @@ write(ostream &out, int indent_level) const {
   indent(out, indent_level) << *this << "\n";
   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
 //     Function: NodeTransition::internal_generate_hash
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

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

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

@@ -65,6 +65,7 @@ public:
   INLINE_GRAPH TypeHandle get_handle() const;
   INLINE_GRAPH TypeHandle get_handle() const;
   INLINE_GRAPH bool has_trans() const;
   INLINE_GRAPH bool has_trans() const;
   INLINE_GRAPH NodeTransition *get_trans() const;
   INLINE_GRAPH NodeTransition *get_trans() const;
+  INLINE_GRAPH void set_trans(NodeTransition *trans);
 
 
   INLINE_GRAPH bool is_identity() const;
   INLINE_GRAPH bool is_identity() const;
   INLINE_GRAPH int compare_to(const NodeTransitionWrapper &other) 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();
   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
 //     Function: NodeTransitions::begin
 //       Access: Public
 //       Access: Public
@@ -63,6 +83,37 @@ end() const {
   return _transitions.end();
   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) {
 INLINE_GRAPH ostream &operator << (ostream &out, const NodeTransitions &nts) {
   nts.output(out);
   nts.output(out);
   return 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
   // STL-like definitions to allow read-only traversal of the
   // individual transitions.  Beware!  These are not safe to use
   // individual transitions.  Beware!  These are not safe to use
   // outside of PANDA.DLL.
   // outside of PANDA.DLL.
-  typedef Transitions::const_iterator iterator;
+  typedef Transitions::iterator iterator;
   typedef Transitions::const_iterator const_iterator;
   typedef Transitions::const_iterator const_iterator;
+  typedef Transitions::key_type key_type;
   typedef Transitions::value_type value_type;
   typedef Transitions::value_type value_type;
   typedef Transitions::size_type size_type;
   typedef Transitions::size_type size_type;
 
 
   INLINE_GRAPH size_type size() const;
   INLINE_GRAPH size_type size() const;
+  INLINE_GRAPH iterator begin();
+  INLINE_GRAPH iterator end();
   INLINE_GRAPH const_iterator begin() const;
   INLINE_GRAPH const_iterator begin() const;
   INLINE_GRAPH const_iterator end() 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:
 public:
   void output(ostream &out) const;
   void output(ostream &out) const;

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

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

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

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

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

@@ -19,11 +19,10 @@
 #ifndef GRAPHICSSTATEGUARDIANBASE_H
 #ifndef GRAPHICSSTATEGUARDIANBASE_H
 #define 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.
 // A handful of forward references.
 
 
@@ -52,6 +51,30 @@ class PixelBuffer;
 class Material;
 class Material;
 class Fog;
 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 TransformAttribute;
 class ColorMatrixAttribute;
 class ColorMatrixAttribute;
 class AlphaTransformAttribute;
 class AlphaTransformAttribute;
@@ -93,7 +116,7 @@ class ProjectionNode;
 //               class, which is itself a base class for the various
 //               class, which is itself a base class for the various
 //               GSG's for different platforms.  This class contains
 //               GSG's for different platforms.  This class contains
 //               all the function prototypes to support the
 //               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
 //               lives in a separate class in its own package so we
 //               can avoid circular build dependency problems.
 //               can avoid circular build dependency problems.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -109,9 +132,9 @@ public:
 
 
   // Defined here are some internal interface functions for the
   // Defined here are some internal interface functions for the
   // GraphicsStateGuardian.  These are here to support
   // 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
   // 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
   // inconvenient to declare each of those types to be friends of this
   // class.
   // class.
 
 
@@ -152,10 +175,10 @@ public:
   virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
   virtual void copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb)=0;
                                  const RenderBuffer &rb)=0;
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
   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,
   virtual void draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
                                  const RenderBuffer &rb,
                                  const RenderBuffer &rb,
-                                 const NodeAttributes& na=NodeAttributes())=0;
+                                 const NodeTransitions& na=NodeTransitions())=0;
 
 
   virtual void apply_material(const Material *material)=0;
   virtual void apply_material(const Material *material)=0;
   virtual void apply_fog(Fog *fog)=0;
   virtual void apply_fog(Fog *fog)=0;
@@ -165,6 +188,30 @@ public:
   virtual void apply_light(Spotlight *light)=0;
   virtual void apply_light(Spotlight *light)=0;
   virtual void apply_light(AmbientLight *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_transform(const TransformAttribute *) { }
   virtual void issue_color_transform(const ColorMatrixAttribute *) { }
   virtual void issue_color_transform(const ColorMatrixAttribute *) { }
   virtual void issue_alpha_transform(const AlphaTransformAttribute *) { }
   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
 //     Function: LightTransition::all_off
 //       Access: Public
 //       Access: Public

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

@@ -23,6 +23,34 @@
 
 
 TypeHandle LightTransition::_type_handle;
 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
 //     Function: LightTransition::make_copy
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -55,6 +83,30 @@ make_identity() const {
   return new LightTransition;
   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
 //     Function: LightTransition::output_value
 //       Access: Protected, Virtual
 //       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> {
 class EXPCL_PANDA LightTransition : public MultiTransition<PT_Light, LightNameClass> {
 PUBLISHED:
 PUBLISHED:
-  INLINE LightTransition();
+  LightTransition();
+  LightTransition(const LightTransition &copy);
+  ~LightTransition();
   INLINE static LightTransition all_off();
   INLINE static LightTransition all_off();
 
 
 public:
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
   virtual NodeAttribute *make_attrib() const;
   virtual NodeTransition *make_identity() const;
   virtual NodeTransition *make_identity() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 
 protected:
 protected:
   virtual void output_property(ostream &out, const PT_Light &prop) const;
   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::
 void PGEntry::
 draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
 draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-          const AllAttributesWrapper &attrib,
           const AllTransitionsWrapper &trans) {
           const AllTransitionsWrapper &trans) {
-  PGItem::draw_item(top, gsg, attrib, trans);
+  PGItem::draw_item(top, gsg, trans);
   update_text();
   update_text();
   update_cursor();
   update_cursor();
 
 
@@ -144,7 +143,7 @@ draw_item(PGTop *top, GraphicsStateGuardian *gsg,
   // of the text.
   // of the text.
   DirectRenderTraverser drt(gsg, RenderRelation::get_class_type());
   DirectRenderTraverser drt(gsg, RenderRelation::get_class_type());
   drt.set_view_frustum_cull(false);
   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 Node *make_copy() const;
 
 
   virtual void draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
   virtual void draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-                         const AllAttributesWrapper &attrib,
                          const AllTransitionsWrapper &trans);
                          const AllTransitionsWrapper &trans);
 
 
   virtual void press(const MouseWatcherParameter &param);
   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::
 void PGItem::
 draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
 draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-          const AllAttributesWrapper &attrib,
           const AllTransitionsWrapper &trans) {
           const AllTransitionsWrapper &trans) {
   if (has_state_def(get_state())) {
   if (has_state_def(get_state())) {
     // This item has a current state definition that we should use
     // This item has a current state definition that we should use
@@ -212,11 +211,11 @@ draw_item(PGTop *top, GraphicsStateGuardian *gsg,
       // of the subgraph.
       // of the subgraph.
       DirectRenderTraverser drt(gsg, RenderRelation::get_class_type());
       DirectRenderTraverser drt(gsg, RenderRelation::get_class_type());
       drt.set_view_frustum_cull(false);
       drt.set_view_frustum_cull(false);
-      drt.traverse(def, attrib, trans);
+      drt.traverse(def, trans);
 
 
     } else {
     } else {
       QuickRenderTraverser qrt(gsg, RenderRelation::get_class_type());
       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 PGTop;
 class GraphicsStateGuardian;
 class GraphicsStateGuardian;
-class AllAttributesWrapper;
 class AllTransitionsWrapper;
 class AllTransitionsWrapper;
 class MouseWatcherParameter;
 class MouseWatcherParameter;
 class ArcChain;
 class ArcChain;
@@ -72,7 +71,6 @@ public:
   INLINE PGMouseWatcherRegion *get_region() const;
   INLINE PGMouseWatcherRegion *get_region() const;
 
 
   virtual void draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
   virtual void draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-                         const AllAttributesWrapper &attrib,
                          const AllTransitionsWrapper &trans);
                          const AllTransitionsWrapper &trans);
 
 
   virtual void enter(const MouseWatcherParameter &param);
   virtual void enter(const MouseWatcherParameter &param);

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

@@ -26,7 +26,7 @@
 #include "renderRelation.h"
 #include "renderRelation.h"
 #include "geomNode.h"
 #include "geomNode.h"
 #include "allTransitionsWrapper.h"
 #include "allTransitionsWrapper.h"
-#include "allAttributesWrapper.h"
+#include "allTransitionsWrapper.h"
 #include "wrt.h"
 #include "wrt.h"
 #include "switchNode.h"
 #include "switchNode.h"
 #include "transformTransition.h"
 #include "transformTransition.h"
@@ -87,9 +87,9 @@ make_copy() const {
 //               in the scene graph order.
 //               in the scene graph order.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool PGTop::
 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();
   _gsg = trav->get_gsg();
   const ArcChain &chain = trav->get_arc_chain();
   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.
     // And draw the item, however it wishes to be drawn.
     
     
     // Get the net transitions to the PGItem.
     // Get the net transitions to the PGItem.
-    AllTransitionsWrapper complete_trans;
+    AllTransitionsWrapper wrt_trans;
     wrt(pgi, chain.begin(), chain.end(), this,
     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())) {
   } else if (node->is_of_type(GeomNode::get_class_type())) {
     _gsg->_geom_nodes_pcollector.add_level(1);
     _gsg->_geom_nodes_pcollector.add_level(1);
     GeomNode *geom = DCAST(GeomNode, node);
     GeomNode *geom = DCAST(GeomNode, node);
 
 
     // Get the complete state of the GeomNode.
     // 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;
     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.
     // Finally, draw the Geom.
     _gsg->prepare_display_region();
     _gsg->prepare_display_region();

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

@@ -26,7 +26,7 @@
 #include "namedNode.h"
 #include "namedNode.h"
 #include "mouseWatcher.h"
 #include "mouseWatcher.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
-#include "allAttributesWrapper.h"
+#include "allTransitionsWrapper.h"
 
 
 class GraphicsStateGuardian;
 class GraphicsStateGuardian;
 class RenderTraverser;
 class RenderTraverser;
@@ -58,8 +58,8 @@ public:
 
 
   virtual Node *make_copy() const;
   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);
                           RenderTraverser *trav);
   virtual bool has_sub_render() const;
   virtual bool has_sub_render() const;
 
 
@@ -79,7 +79,7 @@ private:
   PGMouseWatcherGroup *_watcher_group;
   PGMouseWatcherGroup *_watcher_group;
   GraphicsStateGuardian *_gsg;
   GraphicsStateGuardian *_gsg;
   RenderTraverser *_trav;
   RenderTraverser *_trav;
-  AllAttributesWrapper _attrib;
+  AllTransitionsWrapper _trans;
   int _sort_index;
   int _sort_index;
   
   
 public:
 public:

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

@@ -96,10 +96,9 @@ make_copy() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void PGWaitBar::
 void PGWaitBar::
 draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
 draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-          const AllAttributesWrapper &attrib,
           const AllTransitionsWrapper &trans) {
           const AllTransitionsWrapper &trans) {
   update();
   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 Node *make_copy() const;
 
 
   virtual void draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
   virtual void draw_item(PGTop *top, GraphicsStateGuardian *gsg, 
-                         const AllAttributesWrapper &attrib,
                          const AllTransitionsWrapper &trans);
                          const AllTransitionsWrapper &trans);
 
 
 PUBLISHED:
 PUBLISHED:

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

@@ -50,8 +50,7 @@
      renderModeAttribute.h renderModeProperty.I \
      renderModeAttribute.h renderModeProperty.I \
      renderModeProperty.h renderModeTransition.I \
      renderModeProperty.h renderModeTransition.I \
      renderModeTransition.h renderRelation.I renderRelation.N \
      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 \
      stencilAttribute.h stencilProperty.I stencilProperty.h \
      stencilTransition.I stencilTransition.h texGenAttribute.I \
      stencilTransition.I stencilTransition.h texGenAttribute.I \
      texGenAttribute.h texGenProperty.I texGenProperty.h \
      texGenAttribute.h texGenProperty.I texGenProperty.h \
@@ -85,7 +84,7 @@
         pointShapeTransition.cxx polygonOffsetAttribute.cxx \
         pointShapeTransition.cxx polygonOffsetAttribute.cxx \
         polygonOffsetProperty.cxx polygonOffsetTransition.cxx pruneTransition.cxx \
         polygonOffsetProperty.cxx polygonOffsetTransition.cxx pruneTransition.cxx \
         renderModeAttribute.cxx renderModeProperty.cxx renderModeTransition.cxx \
         renderModeAttribute.cxx renderModeProperty.cxx renderModeTransition.cxx \
-        renderRelation.cxx showHideAttribute.cxx showHideTransition.cxx \
+        renderRelation.cxx \
         stencilAttribute.cxx stencilProperty.cxx stencilTransition.cxx \
         stencilAttribute.cxx stencilProperty.cxx stencilTransition.cxx \
         texGenAttribute.cxx texGenProperty.cxx texGenTransition.cxx \
         texGenAttribute.cxx texGenProperty.cxx texGenTransition.cxx \
         texMatrixAttribute.cxx texMatrixTransition.cxx textureApplyAttribute.cxx \
         texMatrixAttribute.cxx texMatrixTransition.cxx textureApplyAttribute.cxx \
@@ -128,8 +127,7 @@
     pruneTransition.I pruneTransition.h renderModeAttribute.I \
     pruneTransition.I pruneTransition.h renderModeAttribute.I \
     renderModeAttribute.h renderModeProperty.I renderModeProperty.h \
     renderModeAttribute.h renderModeProperty.I renderModeProperty.h \
     renderModeTransition.I renderModeTransition.h renderRelation.I \
     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 \
     stencilAttribute.I stencilAttribute.h stencilProperty.I \
     stencilProperty.h stencilTransition.I stencilTransition.h \
     stencilProperty.h stencilTransition.I stencilTransition.h \
     texGenAttribute.I texGenAttribute.h texGenProperty.I \
     texGenAttribute.I texGenAttribute.h texGenProperty.I \
@@ -146,16 +144,6 @@
     transparencyTransition.I transparencyTransition.h
     transparencyTransition.I transparencyTransition.h
 
 
   #define IGATESCAN all
   #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
 #end lib_target
 
 

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

@@ -19,7 +19,8 @@
 #include "alphaTransformTransition.h"
 #include "alphaTransformTransition.h"
 #include "alphaTransformAttribute.h"
 #include "alphaTransformAttribute.h"
 
 
-#include <indent.h>
+#include "graphicsStateGuardianBase.h"
+#include "indent.h"
 
 
 TypeHandle AlphaTransformTransition::_type_handle;
 TypeHandle AlphaTransformTransition::_type_handle;
 
 
@@ -44,6 +45,30 @@ make_attrib() const {
   return new AlphaTransformAttribute;
   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
 //     Function: AlphaTransformTransition::set_value_from
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

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

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

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

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

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

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

@@ -47,14 +47,25 @@ make_copy() const {
   return new BillboardTransition(*this);
   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
 //     Function: BillboardTransition::sub_render
 //       Access: Public, Virtual
 //       Access: Public, Virtual
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool BillboardTransition::
 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();
   Node *node = arc->get_child();
   GraphicsStateGuardian *gsg = trav->get_gsg();
   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
   // And finally, apply the rotation transform to the set of
   // transitions we've accumulated for this node.
   // 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
   // Continue the render pass
   return true;
   return true;

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

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

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

@@ -44,17 +44,41 @@ make_attrib() const {
   return new ClipPlaneAttribute;
   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
 //     Function: ClipPlaneTransition::make_identity
 //       Access: Public, Virtual
 //       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::
 NodeTransition *ClipPlaneTransition::
 make_identity() const {
 make_identity() const {
   return new ClipPlaneTransition;
   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
 //     Function: ClipPlaneTransition::output_value
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

@@ -46,8 +46,11 @@ public:
 
 
   virtual NodeTransition *make_copy() const;
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
   virtual NodeTransition *make_identity() const;
   virtual NodeTransition *make_identity() const;
 
 
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
+
 protected:
 protected:
   virtual void output_property(ostream &out, const PT_Node &prop) const;
   virtual void output_property(ostream &out, const PT_Node &prop) const;
   virtual void write_property(ostream &out, const PT_Node &prop,
   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;
   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
 //     Function: ColorBlendTransition::set_value_from
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

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

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

@@ -22,23 +22,20 @@
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE ColorMaskTransition::
 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 {
 get_mask() const {
   return _value.get_mask();
   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;
   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
 //     Function: ColorMaskTransition::set_value_from
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

@@ -37,14 +37,22 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA ColorMaskTransition : public OnTransition {
 class EXPCL_PANDA ColorMaskTransition : public OnTransition {
 public:
 public:
+  INLINE ColorMaskTransition();
   INLINE ColorMaskTransition(int mask);
   INLINE ColorMaskTransition(int mask);
-  INLINE static ColorMaskTransition all_on();
 
 
   INLINE void set_mask(int mask);
   INLINE void set_mask(int mask);
   INLINE int get_mask() const;
   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 NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 
 protected:
 protected:
   virtual void set_value_from(const OnTransition *other);
   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;
   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
 //     Function: ColorMatrixTransition::make_with_matrix
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

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

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

@@ -48,6 +48,30 @@ make_attrib() const {
   return new ColorAttribute;
   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
 //     Function: ColorTransition::set_value_from
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

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

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

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

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

@@ -47,13 +47,3 @@ INLINE CullFaceProperty::Mode CullFaceTransition::
 get_mode() const {
 get_mode() const {
   return _value.get_mode();
   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;
   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
 //     Function: CullFaceTransition::set_value_from
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

@@ -34,16 +34,18 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA CullFaceTransition : public OnTransition {
 class EXPCL_PANDA CullFaceTransition : public OnTransition {
 public:
 public:
-  INLINE CullFaceTransition(CullFaceProperty::Mode mode);
+  INLINE CullFaceTransition(CullFaceProperty::Mode mode = CullFaceProperty::M_cull_none);
 
 
   INLINE void set_mode(CullFaceProperty::Mode mode);
   INLINE void set_mode(CullFaceProperty::Mode mode);
   INLINE CullFaceProperty::Mode get_mode() const;
   INLINE CullFaceProperty::Mode get_mode() const;
 
 
   virtual NodeTransition *make_copy() const;
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 
 protected:
 protected:
-  INLINE CullFaceTransition(void);
   virtual void set_value_from(const OnTransition *other);
   virtual void set_value_from(const OnTransition *other);
   virtual int compare_values(const OnTransition *other) const;
   virtual int compare_values(const OnTransition *other) const;
   virtual void output_value(ostream &out) 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;
   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
 //     Function: DecalTransition::has_sub_render
 //       Access: Public, Virtual
 //       Access: Public, Virtual

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

@@ -48,6 +48,7 @@ PUBLISHED:
 public:
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
 
 
   virtual bool has_sub_render() 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 {
 get_mode() const {
   return _value.get_mode();
   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;
   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
 //     Function: DepthTestTransition::set_value_from
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

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

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

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

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

@@ -18,20 +18,15 @@
 
 
 #include "config_sgattrib.h"
 #include "config_sgattrib.h"
 #include "drawBoundsTransition.h"
 #include "drawBoundsTransition.h"
-#include "renderModeAttribute.h"
 #include "renderModeTransition.h"
 #include "renderModeTransition.h"
-#include "cullFaceAttribute.h"
 #include "cullFaceTransition.h"
 #include "cullFaceTransition.h"
-#include "colorAttribute.h"
 #include "colorTransition.h"
 #include "colorTransition.h"
 #include "transformTransition.h"
 #include "transformTransition.h"
-#include "transformAttribute.h"
 
 
 #include <boundingSphere.h>
 #include <boundingSphere.h>
-#include <nodeAttributes.h>
+#include <nodeTransitions.h>
 #include <nodeTransitionWrapper.h>
 #include <nodeTransitionWrapper.h>
 #include <allTransitionsWrapper.h>
 #include <allTransitionsWrapper.h>
-#include <allAttributesWrapper.h>
 #include <graphicsStateGuardian.h>
 #include <graphicsStateGuardian.h>
 #include <renderTraverser.h>
 #include <renderTraverser.h>
 #include <geomSphere.h>
 #include <geomSphere.h>
@@ -45,24 +40,19 @@ TypeHandle DrawBoundsTransition::_type_handle;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 DrawBoundsTransition::
 DrawBoundsTransition::
 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);
   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
 //     Function: DrawBoundsTransition::sub_render
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -83,7 +84,7 @@ make_copy() const {
 //               drawBounds to do its thing.
 //               drawBounds to do its thing.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DrawBoundsTransition::
 bool DrawBoundsTransition::
-sub_render(NodeRelation *arc, const AllAttributesWrapper &attrib,
+sub_render(NodeRelation *arc, const AllTransitionsWrapper &input_trans, 
            AllTransitionsWrapper &, RenderTraverser *trav) {
            AllTransitionsWrapper &, RenderTraverser *trav) {
   GraphicsStateGuardian *gsg = trav->get_gsg();
   GraphicsStateGuardian *gsg = trav->get_gsg();
 
 
@@ -93,8 +94,8 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &attrib,
     // been transformed by this arc's transform.
     // been transformed by this arc's transform.
 
 
     LMatrix4f mat;
     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();
       mat = ta->get_matrix();
     } else {
     } else {
       mat = LMatrix4f::ident_mat();
       mat = LMatrix4f::ident_mat();
@@ -106,9 +107,9 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &attrib,
       mat = ::invert(tt->get_matrix()) * mat;
       mat = ::invert(tt->get_matrix()) * mat;
     }
     }
 
 
-    TransformAttribute *new_ta = new TransformAttribute;
+    TransformTransition *new_ta = new TransformTransition;
     new_ta->set_matrix(mat);
     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);
     gsg->set_state(_outside_attrib, true);
 
 

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

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

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

@@ -44,6 +44,30 @@ make_attrib() const {
   return new FogAttribute;
   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
 //     Function: FogTransition::set_value_from
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

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

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

@@ -41,3 +41,27 @@ NodeAttribute *LinesmoothTransition::
 make_attrib() const {
 make_attrib() const {
   return new LinesmoothAttribute;
   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 NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 
 public:
 public:
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {

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

@@ -49,6 +49,30 @@ make_attrib() const {
   return new MaterialAttribute;
   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
 //     Function: MaterialTransition::set_value_from
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

@@ -42,6 +42,9 @@ public:
 public:
 public:
   virtual NodeTransition *make_copy() const;
   virtual NodeTransition *make_copy() const;
   virtual NodeAttribute *make_attrib() const;
   virtual NodeAttribute *make_attrib() const;
+  virtual NodeTransition *make_initial() const;
+
+  virtual void issue(GraphicsStateGuardianBase *gsgbase);
 
 
 protected:
 protected:
   virtual void set_value_from(const OnOffTransition *other);
   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;
   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
 //     Function: PointShapeTransition
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

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

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

Some files were not shown because too many files changed in this diff