Browse Source

New state handling code

Josh Yelon 20 years ago
parent
commit
0bb2f00f88
67 changed files with 1477 additions and 1325 deletions
  1. 102 102
      doc/makepanda/makepanda.py
  2. 0 75
      panda/src/display/graphicsStateGuardian.I
  3. 66 251
      panda/src/display/graphicsStateGuardian.cxx
  4. 11 48
      panda/src/display/graphicsStateGuardian.h
  5. 0 20
      panda/src/dxgsg8/dxGraphicsStateGuardian8.I
  6. 225 87
      panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx
  7. 19 19
      panda/src/dxgsg8/dxGraphicsStateGuardian8.h
  8. 2 14
      panda/src/glstuff/glGraphicsStateGuardian_src.I
  9. 261 174
      panda/src/glstuff/glGraphicsStateGuardian_src.cxx
  10. 20 25
      panda/src/glstuff/glGraphicsStateGuardian_src.h
  11. 1 0
      panda/src/glstuff/glShaderContext_src.cxx
  12. 2 0
      panda/src/gobj/shader.h
  13. 0 24
      panda/src/gsgbase/graphicsStateGuardianBase.h
  14. 13 14
      panda/src/pgraph/alphaTestAttrib.cxx
  15. 1 1
      panda/src/pgraph/alphaTestAttrib.h
  16. 13 14
      panda/src/pgraph/antialiasAttrib.cxx
  17. 1 1
      panda/src/pgraph/antialiasAttrib.h
  18. 74 0
      panda/src/pgraph/attribSlots.I
  19. 231 0
      panda/src/pgraph/attribSlots.cxx
  20. 105 0
      panda/src/pgraph/attribSlots.h
  21. 13 14
      panda/src/pgraph/clipPlaneAttrib.cxx
  22. 1 1
      panda/src/pgraph/clipPlaneAttrib.h
  23. 13 14
      panda/src/pgraph/colorAttrib.cxx
  24. 1 1
      panda/src/pgraph/colorAttrib.h
  25. 13 14
      panda/src/pgraph/colorBlendAttrib.cxx
  26. 1 1
      panda/src/pgraph/colorBlendAttrib.h
  27. 13 14
      panda/src/pgraph/colorScaleAttrib.cxx
  28. 1 1
      panda/src/pgraph/colorScaleAttrib.h
  29. 13 14
      panda/src/pgraph/colorWriteAttrib.cxx
  30. 1 1
      panda/src/pgraph/colorWriteAttrib.h
  31. 13 0
      panda/src/pgraph/cullBinAttrib.cxx
  32. 1 0
      panda/src/pgraph/cullBinAttrib.h
  33. 13 14
      panda/src/pgraph/cullFaceAttrib.cxx
  34. 1 1
      panda/src/pgraph/cullFaceAttrib.h
  35. 13 14
      panda/src/pgraph/depthOffsetAttrib.cxx
  36. 1 1
      panda/src/pgraph/depthOffsetAttrib.h
  37. 13 14
      panda/src/pgraph/depthTestAttrib.cxx
  38. 1 1
      panda/src/pgraph/depthTestAttrib.h
  39. 13 14
      panda/src/pgraph/depthWriteAttrib.cxx
  40. 1 1
      panda/src/pgraph/depthWriteAttrib.h
  41. 13 14
      panda/src/pgraph/fogAttrib.cxx
  42. 1 1
      panda/src/pgraph/fogAttrib.h
  43. 13 14
      panda/src/pgraph/lightAttrib.cxx
  44. 1 1
      panda/src/pgraph/lightAttrib.h
  45. 13 14
      panda/src/pgraph/materialAttrib.cxx
  46. 1 1
      panda/src/pgraph/materialAttrib.h
  47. 1 0
      panda/src/pgraph/pgraph_composite1.cxx
  48. 1 13
      panda/src/pgraph/renderAttrib.cxx
  49. 2 1
      panda/src/pgraph/renderAttrib.h
  50. 13 14
      panda/src/pgraph/renderModeAttrib.cxx
  51. 1 1
      panda/src/pgraph/renderModeAttrib.h
  52. 25 134
      panda/src/pgraph/renderState.cxx
  53. 4 6
      panda/src/pgraph/renderState.h
  54. 13 14
      panda/src/pgraph/rescaleNormalAttrib.cxx
  55. 1 1
      panda/src/pgraph/rescaleNormalAttrib.h
  56. 13 14
      panda/src/pgraph/shadeModelAttrib.cxx
  57. 1 1
      panda/src/pgraph/shadeModelAttrib.h
  58. 13 14
      panda/src/pgraph/shaderAttrib.cxx
  59. 4 3
      panda/src/pgraph/shaderAttrib.h
  60. 13 14
      panda/src/pgraph/texGenAttrib.cxx
  61. 1 1
      panda/src/pgraph/texGenAttrib.h
  62. 13 14
      panda/src/pgraph/texMatrixAttrib.cxx
  63. 1 1
      panda/src/pgraph/texMatrixAttrib.h
  64. 13 14
      panda/src/pgraph/textureAttrib.cxx
  65. 1 1
      panda/src/pgraph/textureAttrib.h
  66. 13 14
      panda/src/pgraph/transparencyAttrib.cxx
  67. 1 1
      panda/src/pgraph/transparencyAttrib.h

+ 102 - 102
doc/makepanda/makepanda.py

@@ -3834,15 +3834,15 @@ for VER in ["5","6","65"]:
 #
 # DIRECTORY: pandatool/src/mayaegg/
 #
-
-for VER in ["5","6","65"]:
-  if (OMIT.count("MAYA"+VER)==0):
-    IPATH=['pandatool/src/mayaegg', 'pandatool/src/maya']
-    OPTS=['MAYA'+VER, 'NSPR']
-    CopyAllHeaders(IPATH[0])
-    CompileC(ipath=IPATH, opts=OPTS, src='mayaEggLoader.cxx', obj='mayaegg'+VER+'_loader.obj')
-    CompileC(ipath=IPATH, opts=OPTS, src='mayaegg_composite1.cxx',   obj='mayaegg'+VER+'_composite1.obj')
-    CompileLIB(lib='libmayaegg'+VER+'.lib', obj=[ 'mayaegg'+VER+'_composite1.obj' ])
+# 
+# for VER in ["5","6","65"]:
+#   if (OMIT.count("MAYA"+VER)==0):
+#     IPATH=['pandatool/src/mayaegg', 'pandatool/src/maya']
+#     OPTS=['MAYA'+VER, 'NSPR']
+#     CopyAllHeaders(IPATH[0])
+#     CompileC(ipath=IPATH, opts=OPTS, src='mayaEggLoader.cxx', obj='mayaegg'+VER+'_loader.obj')
+#     CompileC(ipath=IPATH, opts=OPTS, src='mayaegg_composite1.cxx',   obj='mayaegg'+VER+'_composite1.obj')
+#     CompileLIB(lib='libmayaegg'+VER+'.lib', obj=[ 'mayaegg'+VER+'_composite1.obj' ])
 
 #
 # DIRECTORY: pandatool/src/maxegg/
@@ -4002,99 +4002,99 @@ CompileLink(dll='libptloader.dll', opts=['ADVAPI', 'NSPR'], obj=[
 # DIRECTORY: pandatool/src/mayaprogs/
 #
 
-for VER in ["5","6","65"]:
-  if (OMIT.count('MAYA'+VER)==0):
-    IPATH=['pandatool/src/mayaprogs', 'pandatool/src/maya', 'pandatool/src/mayaegg',
-           'pandatool/src/cvscopy']
-    OPTS=['BUILDING_MISC', 'MAYA'+VER, 'NSPR']
-    CompileC(ipath=IPATH, opts=OPTS, src='mayaEggImport.cxx', obj='mayaeggimport'+VER+'_mayaeggimport.obj')
-    CompileLink(opts=OPTS, dll='mayaeggimport'+VER+'.mll', obj=[
-                'mayaegg'+VER+'_loader.obj',
-                'mayaeggimport'+VER+'_mayaeggimport.obj',
-                'libpandaegg.dll',
-                'libpanda.dll',
-                'libpandaexpress.dll',
-                'libdtoolconfig.dll',
-                'libdtool.dll',
-                'libpystub.dll'
-               ])
-    CompileC(ipath=IPATH, opts=OPTS, src='config_mayaloader.cxx', obj='mayaloader'+VER+'_config_mayaloader.obj')
-    CompileLink(dll='libmayaloader'+VER+'.dll',                 opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
-                 'mayaloader'+VER+'_config_mayaloader.obj',
-                 'libmayaegg'+VER+'.lib',
-                 'libptloader.lib',
-                 'libconverter.lib',
-                 'libpandatoolbase.lib',
-                 'libmaya'+VER+'.lib',
-                 'libfltegg.lib',
-                 'libflt.lib',
-                 'liblwoegg.lib',
-                 'liblwo.lib',
-                 'libdxfegg.lib',
-                 'libdxf.lib',
-                 'libvrmlegg.lib',
-                 'libpvrml.lib',
-                 'libxfileegg.lib',
-                 'libxfile.lib',
-                 'libeggbase.lib',
-                 'libprogbase.lib',
-                 'libpandaegg.dll',
-                 'libpanda.dll',
-                 'libpandaexpress.dll',
-                 'libdtoolconfig.dll',
-                 'libdtool.dll',
-    ])
-    CompileC(ipath=IPATH, opts=OPTS, src='mayaPview.cxx', obj='mayapview'+VER+'_mayaPview.obj')
-    CompileLink(dll='libmayapview'+VER+'.mll', opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
-                 'mayapview'+VER+'_mayaPview.obj',
-                 'libmayaegg'+VER+'.lib',
-                 'libmaya'+VER+'.lib',
-                 'libconverter.lib',
-                 'libpandatoolbase.lib',
-                 'libpandaegg.dll',
-                 'libframework.dll',
-                 'libpanda.dll',
-                 'libpandaexpress.dll',
-                 'libdtoolconfig.dll',
-                 'libdtool.dll',
-                 'libpystub.dll',
-    ])
-    OPTS=['MAYA'+VER, 'NSPR']
-    CompileC(ipath=IPATH, opts=OPTS, src='mayaToEgg.cxx', obj='maya2egg'+VER+'_mayaToEgg.obj')
-    CompileLink(dll='maya2egg'+VER+'.exe',                 opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
-                 'maya2egg'+VER+'_mayaToEgg.obj',
-                 'libmayaegg'+VER+'.lib',
-                 'libmaya'+VER+'.lib',
-                 'libeggbase.lib',
-                 'libprogbase.lib',
-                 'libconverter.lib',
-                 'libpandatoolbase.lib',
-                 'libpandaegg.dll',
-                 'libpanda.dll',
-                 'libpandaexpress.dll',
-                 'libdtoolconfig.dll',
-                 'libdtool.dll',
-                 'libpystub.dll',
-    ])
-    CompileC(ipath=IPATH, opts=OPTS, src='mayaCopy.cxx', obj='mayacopy'+VER+'_mayaCopy.obj')
-    CompileLink(dll='mayacopy'+VER+'.exe',  opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
-                 'mayacopy'+VER+'_mayaCopy.obj',
-                 'libcvscopy.lib',
-                 'libmaya'+VER+'.lib',
-                 'libprogbase.lib',
-                 'libpandatoolbase.lib',
-                 'libconverter.lib',
-                 'libpandaegg.dll',
-                 'libpanda.dll',
-                 'libpandaexpress.dll',
-                 'libdtoolconfig.dll',
-                 'libdtool.dll',
-                 'libpystub.dll',
-    ])
-#    CompileC(ipath=IPATH, opts=OPTS, src='mayaSavePview.cxx', obj='mayasavepview'+VER+'_mayaSavePview.obj')
-#    CompileLink(dll='libmayasavepview'+VER+'.mll', opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
-#                 'mayasavepview'+VER+'_mayaSavePview.obj',
-#    ])
+# for VER in ["5","6","65"]:
+#   if (OMIT.count('MAYA'+VER)==0):
+#     IPATH=['pandatool/src/mayaprogs', 'pandatool/src/maya', 'pandatool/src/mayaegg',
+#            'pandatool/src/cvscopy']
+#     OPTS=['BUILDING_MISC', 'MAYA'+VER, 'NSPR']
+#     CompileC(ipath=IPATH, opts=OPTS, src='mayaEggImport.cxx', obj='mayaeggimport'+VER+'_mayaeggimport.obj')
+#     CompileLink(opts=OPTS, dll='mayaeggimport'+VER+'.mll', obj=[
+#                 'mayaegg'+VER+'_loader.obj',
+#                 'mayaeggimport'+VER+'_mayaeggimport.obj',
+#                 'libpandaegg.dll',
+#                 'libpanda.dll',
+#                 'libpandaexpress.dll',
+#                 'libdtoolconfig.dll',
+#                 'libdtool.dll',
+#                 'libpystub.dll'
+#                ])
+#     CompileC(ipath=IPATH, opts=OPTS, src='config_mayaloader.cxx', obj='mayaloader'+VER+'_config_mayaloader.obj')
+#     CompileLink(dll='libmayaloader'+VER+'.dll',                 opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
+#                  'mayaloader'+VER+'_config_mayaloader.obj',
+#                  'libmayaegg'+VER+'.lib',
+#                  'libptloader.lib',
+#                  'libconverter.lib',
+#                  'libpandatoolbase.lib',
+#                  'libmaya'+VER+'.lib',
+#                  'libfltegg.lib',
+#                  'libflt.lib',
+#                  'liblwoegg.lib',
+#                  'liblwo.lib',
+#                  'libdxfegg.lib',
+#                  'libdxf.lib',
+#                  'libvrmlegg.lib',
+#                  'libpvrml.lib',
+#                  'libxfileegg.lib',
+#                  'libxfile.lib',
+#                  'libeggbase.lib',
+#                  'libprogbase.lib',
+#                  'libpandaegg.dll',
+#                  'libpanda.dll',
+#                  'libpandaexpress.dll',
+#                  'libdtoolconfig.dll',
+#                  'libdtool.dll',
+#     ])
+#     CompileC(ipath=IPATH, opts=OPTS, src='mayaPview.cxx', obj='mayapview'+VER+'_mayaPview.obj')
+#     CompileLink(dll='libmayapview'+VER+'.mll', opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
+#                  'mayapview'+VER+'_mayaPview.obj',
+#                  'libmayaegg'+VER+'.lib',
+#                  'libmaya'+VER+'.lib',
+#                  'libconverter.lib',
+#                  'libpandatoolbase.lib',
+#                  'libpandaegg.dll',
+#                  'libframework.dll',
+#                  'libpanda.dll',
+#                  'libpandaexpress.dll',
+#                  'libdtoolconfig.dll',
+#                  'libdtool.dll',
+#                  'libpystub.dll',
+#     ])
+#     OPTS=['MAYA'+VER, 'NSPR']
+#     CompileC(ipath=IPATH, opts=OPTS, src='mayaToEgg.cxx', obj='maya2egg'+VER+'_mayaToEgg.obj')
+#     CompileLink(dll='maya2egg'+VER+'.exe',                 opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
+#                  'maya2egg'+VER+'_mayaToEgg.obj',
+#                  'libmayaegg'+VER+'.lib',
+#                  'libmaya'+VER+'.lib',
+#                  'libeggbase.lib',
+#                  'libprogbase.lib',
+#                  'libconverter.lib',
+#                  'libpandatoolbase.lib',
+#                  'libpandaegg.dll',
+#                  'libpanda.dll',
+#                  'libpandaexpress.dll',
+#                  'libdtoolconfig.dll',
+#                  'libdtool.dll',
+#                  'libpystub.dll',
+#     ])
+#     CompileC(ipath=IPATH, opts=OPTS, src='mayaCopy.cxx', obj='mayacopy'+VER+'_mayaCopy.obj')
+#     CompileLink(dll='mayacopy'+VER+'.exe',  opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
+#                  'mayacopy'+VER+'_mayaCopy.obj',
+#                  'libcvscopy.lib',
+#                  'libmaya'+VER+'.lib',
+#                  'libprogbase.lib',
+#                  'libpandatoolbase.lib',
+#                  'libconverter.lib',
+#                  'libpandaegg.dll',
+#                  'libpanda.dll',
+#                  'libpandaexpress.dll',
+#                  'libdtoolconfig.dll',
+#                  'libdtool.dll',
+#                  'libpystub.dll',
+#     ])
+# #    CompileC(ipath=IPATH, opts=OPTS, src='mayaSavePview.cxx', obj='mayasavepview'+VER+'_mayaSavePview.obj')
+# #    CompileLink(dll='libmayasavepview'+VER+'.mll', opts=['ADVAPI', 'NSPR', 'MAYA'+VER], obj=[
+# #                 'mayasavepview'+VER+'_mayaSavePview.obj',
+# #    ])
 
 #
 # DIRECTORY: pandatool/src/miscprogs/

+ 0 - 75
panda/src/display/graphicsStateGuardian.I

@@ -632,81 +632,6 @@ is_valid() const {
   return _is_valid;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::modify_state
-//       Access: Public
-//  Description: Applies the attributes indicated in the state set to
-//               the current state, and issues the changes to the
-//               graphics hardware.
-//
-//               Any transitions not mentioned are left unchanged.
-////////////////////////////////////////////////////////////////////
-INLINE void GraphicsStateGuardian::
-modify_state(const RenderState *state) {
-  if (!state->is_empty()) {
-#ifndef NDEBUG
-    if (gsg_cat.is_spam()) {
-      gsg_cat.spam() << "Modifying GSG state with:\n";
-      state->write(gsg_cat.spam(false), 2);
-    }
-#endif
-    _state_pcollector.add_level(1);
-    _state = _state->issue_delta_modify(state, this);
-    finish_modify_state();
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::set_state
-//       Access: Public
-//  Description: Applies the attributes indicated in the state set to
-//               the current state, and issues the changes to the
-//               graphics hardware.
-//
-//               The state is taken to be a complete description of
-//               what the graphics state should be; any transitions
-//               not mentioned are implicitly reset to their initial
-//               values.
-////////////////////////////////////////////////////////////////////
-INLINE void GraphicsStateGuardian::
-set_state(const RenderState *state) {
-  if (state != _state) {
-#ifndef NDEBUG
-    if (gsg_cat.is_spam()) {
-      gsg_cat.spam() << "Setting GSG state to " << (void *)state << ":\n";
-      state->write(gsg_cat.spam(false), 2);
-    }
-#endif
-    _state_pcollector.add_level(1);
-    _state = _state->issue_delta_set(state, this);
-    finish_modify_state();
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::set_transform
-//       Access: Public
-//  Description: Sets the world transform that will be applied to
-//               subsequent geometry.  This is normally called only
-//               during the draw process, immediately before issuing
-//               geometry commands.
-//
-//               This transform specified is the "external" net
-//               transform, expressed in the external coordinate
-//               space; internally, it will be pretransformed by
-//               get_cs_transform() to express it in the GSG's
-//               internal coordinate space.
-////////////////////////////////////////////////////////////////////
-INLINE void GraphicsStateGuardian::
-set_transform(const TransformState *transform) {
-  if (transform != _external_transform) {
-    _state_pcollector.add_level(1);
-    _external_transform = transform;
-    _internal_transform = _cs_transform->compose(transform);
-    issue_transform(_internal_transform);
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_transform
 //       Access: Public

+ 66 - 251
panda/src/display/graphicsStateGuardian.cxx

@@ -279,10 +279,14 @@ reset() {
   _frame_buffer_stack_level = 0;
   _lens_stack_level = 0;
 
-  _state = RenderState::make_empty();
+  _last_state = NULL;
+  _state.clear_to_zero();
+  _target.clear_to_defaults();
   _external_transform = TransformState::make_identity();
   _internal_transform = _cs_transform;
-
+  _scene_null = new SceneSetup;
+  _scene_setup = _scene_null;
+  
   _buffer_mask = 0;
   _color_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f);
   _depth_clear_value = 1.0f;
@@ -291,7 +295,6 @@ reset() {
   _force_normals = 0;
 
   _has_scene_graph_color = false;
-  _scene_graph_color_stale = false;
   _transform_stale = true;
   _color_blend_involves_color_scale = false;
   _texture_involves_color_scale = false;
@@ -305,19 +308,6 @@ reset() {
   _color_scale_enabled = false;
   _current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
 
-  _color_write_mode = ColorWriteAttrib::M_on;
-  _color_blend_mode = ColorBlendAttrib::M_none;
-  _transparency_mode = TransparencyAttrib::M_none;
-
-  _color_blend = NULL;
-  _blend_mode_stale = false;
-  _pending_texture = NULL;
-  _texture_stale = false;
-  _pending_light = NULL;
-  _light_stale = false;
-  _pending_material = NULL;
-  _material_stale = false;
-
   _has_material_force_color = false;
   _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
   _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
@@ -333,6 +323,26 @@ reset() {
   _is_valid = true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::set_state_and_transform
+//       Access: Public
+//  Description: Simultaneously resets the render state and the
+//               transform state.
+//
+//               This transform specified is the "external" net
+//               transform, expressed in the external coordinate
+//               space; internally, it will be pretransformed by
+//               get_cs_transform() to express it in the GSG's
+//               internal coordinate space.
+//
+//               Special case: if (state==NULL), then the target
+//               state is already stored in _target.
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardian::
+set_state_and_transform(const RenderState *state,
+                        const TransformState *trans) {
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_render_buffer
 //       Access: Public
@@ -532,25 +542,6 @@ make_geom_munger(const RenderState *state) {
   return NULL;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::set_state_and_transform
-//       Access: Public, Virtual
-//  Description: Simultaneously resets the render state and the
-//               transform state.
-//
-//               This transform specified is the "external" net
-//               transform, expressed in the external coordinate
-//               space; internally, it will be pretransformed by
-//               get_cs_transform() to express it in the GSG's
-//               internal coordinate space.
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-set_state_and_transform(const RenderState *state,
-                        const TransformState *transform) {
-  set_transform(transform);
-  set_state(state);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::compute_distance_to
 //       Access: Public, Virtual
@@ -681,8 +672,9 @@ begin_frame() {
   // have changed properties since last time without changing
   // attribute pointers--like textures, lighting, or fog--will still
   // be accurately updated.
-  set_state(RenderState::make_empty());
-
+  _last_state = 0;
+  _state.clear_to_zero();
+  
   return true;
 }
 
@@ -718,8 +710,10 @@ begin_scene() {
 void GraphicsStateGuardian::
 end_scene() {
   // We should clear this pointer now, so that we don't keep unneeded
-  // reference counts dangling.
-  _scene_setup = NULL;
+  // reference counts dangling.  We keep around a "null" scene setup 
+  // object instead of using a null pointer to avoid special-case code
+  // in set_state_and_transform.
+  _scene_setup = _scene_null;
   
   // Undo any lighting we had enabled last scene, to force the lights
   // to be reissued, in case their parameters or positions have
@@ -756,8 +750,9 @@ end_scene() {
     _clip_planes_enabled_this_frame = false;
   }
 
-  // Actually, just clear all the state between scenes.
-  set_state(RenderState::make_empty());
+  // Put the state into the 'unknown' state, forcing a reload.
+  _last_state = 0;
+  _state.clear_to_zero();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -1023,47 +1018,36 @@ framebuffer_release_texture(GraphicsOutput *, Texture *) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_transform
-//       Access: Public, Virtual
-//  Description: Sends the indicated transform matrix to the graphics
-//               API to be applied to future vertices.
-//
-//               This transform is the internal_transform, already
-//               converted into the GSG's internal coordinate system.
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-issue_transform(const TransformState *) {
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_color_scale
+//     Function: GraphicsStateGuardian::do_issue_color_scale
 //       Access: Public, Virtual
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
-issue_color_scale(const ColorScaleAttrib *attrib) {
+do_issue_color_scale() {
+  const ColorScaleAttrib *attrib = _target._color_scale;
   _color_scale_enabled = attrib->has_scale();
   _current_color_scale = attrib->get_scale();
-
-  _scene_graph_color_stale = _has_scene_graph_color;
-
+  
   if (_color_blend_involves_color_scale) {
-    _blend_mode_stale = true;
+    _last_state = 0;
+    _state._transparency = 0;
   }
   if (_texture_involves_color_scale) {
-    _texture_stale = true;
+    _last_state = 0;
+    _state._texture = 0;
   }
   if (_color_scale_via_lighting) {
-    _light_stale = true;
-    _material_stale = true;
+    _last_state = 0;
+    _state._light = 0;
+    _state._material = 0;
 
     determine_light_color_scale();
   }
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_color
-//       Access: Public, Virtual
+//     Function: GraphicsStateGuardian::do_issue_color
+//       Access: Public
 //  Description: This method is defined in the base class because it
 //               is likely that this functionality will be used for
 //               all (or at least most) kinds of
@@ -1075,7 +1059,8 @@ issue_color_scale(const ColorScaleAttrib *attrib) {
 //               _vertex_colors_enabled, etc.
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
-issue_color(const ColorAttrib *attrib) {
+do_issue_color() {
+  const ColorAttrib *attrib = _target._color;
   switch (attrib->get_color_type()) {
   case ColorAttrib::T_flat:
     // Color attribute flat: it specifies a scene graph color that
@@ -1083,14 +1068,12 @@ issue_color(const ColorAttrib *attrib) {
     _scene_graph_color = attrib->get_color();
     _has_scene_graph_color = true;
     _vertex_colors_enabled = false;
-    _scene_graph_color_stale = true;
     break;
 
   case ColorAttrib::T_off:
     // Color attribute off: it specifies that no scene graph color is
     // in effect, and vertex color is not important either.
     _has_scene_graph_color = false;
-    _scene_graph_color_stale = false;
     _vertex_colors_enabled = false;
     break;
 
@@ -1098,140 +1081,35 @@ issue_color(const ColorAttrib *attrib) {
     // Color attribute vertex: it specifies that vertex color should
     // be revealed.
     _has_scene_graph_color = false;
-    _scene_graph_color_stale = false;
     _vertex_colors_enabled = true;
     break;
   }
 
   if (_color_scale_via_lighting) {
-    _light_stale = true;
-    _material_stale = true;
+    _last_state = 0;
+    _state._light = 0;
+    _state._material = 0;
 
     determine_light_color_scale();
   }
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_tex_matrix
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-issue_tex_matrix(const TexMatrixAttrib *attrib) {
-  // We don't apply the texture matrix right away, since we might yet
-  // get a TextureAttrib that changes the set of TextureStages we have
-  // active.  Instead, we simply set a flag that indicates we need to
-  // re-issue the texture matrix after all of the other attribs are
-  // done being issued.
-  _current_tex_mat = attrib;
-  _needs_tex_mat = true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_light
-//       Access: Public, Virtual
-//  Description: 
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-issue_light(const LightAttrib *attrib) {
-  // By default, we don't apply the light attrib right away, since
-  // it might have a dependency on the current ColorScaleAttrib.
-  _pending_light = attrib;
-  _light_stale = true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_material
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-issue_material(const MaterialAttrib *attrib) {
-  // By default, we don't apply the material attrib right away, since
-  // it might have a dependency on the current ColorScaleAttrib.
-  _pending_material = attrib;
-  _material_stale = true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_color_write
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-issue_color_write(const ColorWriteAttrib *attrib) {
-  _color_write_mode = attrib->get_mode();
-  _blend_mode_stale = true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_transparency
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-issue_transparency(const TransparencyAttrib *attrib) {
-  _transparency_mode = attrib->get_mode();
-  _blend_mode_stale = true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_color_blend
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-issue_color_blend(const ColorBlendAttrib *attrib) {
-  _color_blend = attrib;
-  _color_blend_mode = attrib->get_mode();
-  _color_blend_involves_color_scale = attrib->involves_color_scale();
-  _blend_mode_stale = true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_tex_gen
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-issue_tex_gen(const TexGenAttrib *attrib) {
-  // We don't apply the texture coordinate generation commands right
-  // away, since we might yet get a TextureAttrib that changes the set
-  // of TextureStages we have active.  Instead, we simply set a flag
-  // that indicates we need to re-issue the TexGenAttrib after all of
-  // the other attribs are done being issued.
-  _current_tex_gen = attrib;
-  _needs_tex_gen = true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_texture
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-issue_texture(const TextureAttrib *attrib) {
-  // By default, we don't apply the texture attrib right away, since
-  // it might have a dependency on the current ColorScaleAttrib.
-  _pending_texture = attrib;
-  _texture_stale = true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::issue_clip_plane
-//       Access: Public, Virtual
-//  Description: This is fundametically similar to issue_light(), with
+//     Function: GraphicsStateGuardian::do_issue_clip_plane
+//       Access: Public
+//  Description: This is fundametically similar to do_issue_light(), with
 //               calls to apply_clip_plane() and enable_clip_planes(),
 //               as appropriate.
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
-issue_clip_plane(const ClipPlaneAttrib *attrib) {
+do_issue_clip_plane() {
+  const ClipPlaneAttrib *attrib = _target._clip_plane;
   int i;
   int cur_max_planes = (int)_clip_plane_info.size();
   for (i = 0; i < cur_max_planes; i++) {
     _clip_plane_info[i]._next_enabled = false;
   }
-
+  
   CPT(ClipPlaneAttrib) new_attrib = attrib->filter_to_max(_max_clip_planes);
 
   bool any_bound = false;
@@ -1374,7 +1252,7 @@ bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::do_issue_light
 //       Access: Protected
-//  Description: This implementation of issue_light() assumes
+//  Description: This implementation of do_issue_light() assumes
 //               we have a limited number of hardware lights
 //               available.  This function assigns each light to a
 //               different hardware light id, trying to keep each
@@ -1405,8 +1283,8 @@ do_issue_light() {
   bool any_bound = false;
 
   int num_enabled = 0;
-  if (_pending_light != (LightAttrib *)NULL) {
-    CPT(LightAttrib) new_light = _pending_light->filter_to_max(_max_lights);
+  if (_target._light != (LightAttrib *)NULL) {
+    CPT(LightAttrib) new_light = _target._light->filter_to_max(_max_lights);
 
     int num_on_lights = new_light->get_num_on_lights();
     for (int li = 0; li < num_on_lights; li++) {
@@ -1533,32 +1411,12 @@ do_issue_light() {
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::do_issue_material
-//       Access: Protected, Virtual
-//  Description: Should be overridden by derived classes to actually
-//               apply the material saved in _pending_material.
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-do_issue_material() {
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::do_issue_texture
-//       Access: Protected, Virtual
-//  Description: Should be overridden by derived classes to actually
-//               apply the texture saved in _pending_texture.
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-do_issue_texture() {
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::enable_lighting
 //       Access: Protected, Virtual
 //  Description: Intended to be overridden by a derived class to
 //               enable or disable the use of lighting overall.  This
-//               is called by issue_light() according to whether any
+//               is called by do_issue_light() according to whether any
 //               lights are in use or not.
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
@@ -1570,7 +1428,7 @@ enable_lighting(bool enable) {
 //       Access: Protected, Virtual
 //  Description: Intended to be overridden by a derived class to
 //               indicate the color of the ambient light that should
-//               be in effect.  This is called by issue_light() after
+//               be in effect.  This is called by do_issue_light() after
 //               all other lights have been enabled or disabled.
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
@@ -1622,7 +1480,7 @@ end_bind_lights() {
 //       Access: Protected, Virtual
 //  Description: Intended to be overridden by a derived class to
 //               enable or disable the use of clipping planes overall.
-//               This is called by issue_clip_plane() according to
+//               This is called by do_issue_clip_plane() according to
 //               whether any planes are in use or not.
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
@@ -1682,49 +1540,6 @@ void GraphicsStateGuardian::
 end_bind_clip_planes() {
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::set_blend_mode
-//       Access: Protected, Virtual
-//  Description: Called after any of the things that might change
-//               blending state have changed, this function is
-//               responsible for setting the appropriate color
-//               blending mode based on the current properties.
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-set_blend_mode() {
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::finish_modify_state
-//       Access: Protected, Virtual
-//  Description: Called after the GSG state has been modified via
-//               modify_state() or set_state(), this hook is provided
-//               for the derived class to do any further state setup
-//               work.
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-finish_modify_state() {
-  if (_blend_mode_stale) {
-    _blend_mode_stale = false;
-    set_blend_mode();
-  }
-
-  if (_texture_stale) {
-    _texture_stale = false;
-    do_issue_texture();
-  }
-
-  if (_material_stale) {
-    _material_stale = false;
-    do_issue_material();
-  }
-
-  if (_light_stale) {
-    _light_stale = false;
-    do_issue_light();
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::free_pointers
 //       Access: Protected, Virtual

+ 11 - 48
panda/src/display/graphicsStateGuardian.h

@@ -38,19 +38,12 @@
 #include "renderState.h"
 #include "light.h"
 #include "planeNode.h"
-#include "colorWriteAttrib.h"
-#include "colorBlendAttrib.h"
-#include "textureAttrib.h"
-#include "texGenAttrib.h"
-#include "materialAttrib.h"
-#include "lightAttrib.h"
-#include "transparencyAttrib.h"
-#include "shaderAttrib.h"
 #include "config_display.h"
 #include "geomMunger.h"
 #include "geomVertexData.h"
 #include "notify.h"
 #include "pvector.h"
+#include "attribSlots.h"
 
 class DrawableRegion;
 class GraphicsEngine;
@@ -206,9 +199,6 @@ public:
   virtual void reset();
   INLINE bool is_valid() const;
 
-  INLINE void modify_state(const RenderState *state);
-  INLINE void set_state(const RenderState *state);
-  INLINE void set_transform(const TransformState *transform);
   INLINE CPT(TransformState) get_transform();
   
   RenderBuffer get_render_buffer(int buffer_type);
@@ -222,19 +212,11 @@ public:
   INLINE const TransformState *get_cs_transform() const;
   INLINE const TransformState *get_inv_cs_transform() const;
 
-  virtual void issue_transform(const TransformState *transform);
-  virtual void issue_color_scale(const ColorScaleAttrib *attrib);
-  virtual void issue_color(const ColorAttrib *attrib);
-  virtual void issue_tex_matrix(const TexMatrixAttrib *attrib);
-  virtual void issue_light(const LightAttrib *attrib);
-  virtual void issue_material(const MaterialAttrib *attrib);
-  virtual void issue_color_write(const ColorWriteAttrib *attrib);
-  virtual void issue_transparency(const TransparencyAttrib *attrib);
-  virtual void issue_color_blend(const ColorBlendAttrib *attrib);
-  virtual void issue_tex_gen(const TexGenAttrib *attrib);
-  virtual void issue_texture(const TextureAttrib *attrib);
-  virtual void issue_clip_plane(const ClipPlaneAttrib *attrib);
-
+  void do_issue_clip_plane();
+  void do_issue_color();
+  void do_issue_color_scale();
+  void do_issue_light();
+  
   virtual void bind_light(PointLight *light_obj, const NodePath &light, 
                           int light_id);
   virtual void bind_light(DirectionalLight *light_obj, const NodePath &light,
@@ -243,10 +225,6 @@ public:
                           int light_id);
 
 protected:
-  void do_issue_light();
-  virtual void do_issue_material();
-  virtual void do_issue_texture();
-
   INLINE NodePath get_light(int light_id) const;
   virtual void enable_lighting(bool enable);
   virtual void set_ambient_light(const Colorf &color);
@@ -261,10 +239,6 @@ protected:
   virtual void bind_clip_plane(const NodePath &plane, int plane_id);
   virtual void end_bind_clip_planes();
 
-  virtual void set_blend_mode();
-
-  virtual void finish_modify_state();
-
   virtual void free_pointers();
   virtual void close_gsg();
   void panic_deactivate();
@@ -304,9 +278,12 @@ protected:
   static CPT(RenderState) get_untextured_state();
 
 protected:
+  PT(SceneSetup) _scene_null;
   PT(SceneSetup) _scene_setup;
-
-  CPT(RenderState) _state;
+  
+  CPT(RenderState) _last_state;
+  AttribSlots _state;
+  AttribSlots _target;
   CPT(TransformState) _external_transform;
   CPT(TransformState) _internal_transform;
   CPT(GeomMunger) _munger;
@@ -337,7 +314,6 @@ protected:
 
   Colorf _scene_graph_color;
   bool _has_scene_graph_color;
-  bool _scene_graph_color_stale;
   bool _transform_stale;
   bool _color_blend_involves_color_scale;
   bool _texture_involves_color_scale;
@@ -347,19 +323,6 @@ protected:
   bool _color_scale_enabled;
   LVecBase4f _current_color_scale;
 
-  ColorWriteAttrib::Mode _color_write_mode;
-  ColorBlendAttrib::Mode _color_blend_mode;
-  TransparencyAttrib::Mode _transparency_mode;
-  CPT(ColorBlendAttrib) _color_blend;
-  bool _blend_mode_stale;
-
-  CPT(TextureAttrib) _pending_texture;
-  bool _texture_stale;
-  CPT(LightAttrib) _pending_light;
-  bool _light_stale;
-  CPT(MaterialAttrib) _pending_material;
-  bool _material_stale;
-
   bool _has_material_force_color;
   Colorf _material_force_color;
   LVecBase4f _light_color_scale;

+ 0 - 20
panda/src/dxgsg8/dxGraphicsStateGuardian8.I

@@ -114,26 +114,6 @@ enable_zwritemask(bool val) {
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::set_color_writemask
-//       Access: Protected
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian8::
-set_color_writemask(UINT color_writemask) {
-  if (_color_writemask != color_writemask) {
-    _color_writemask = color_writemask;
-    if(_screen->_can_direct_disable_color_writes) {
-      // only newer HW supports this rstate
-      _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, (DWORD)color_writemask);
-    } else {
-      // blending can only handle on/off
-      assert((color_writemask==0x0)||(color_writemask==0xFFFFFFFF));
-      set_blend_mode();
-    }
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian8::set_vertex_format
 //       Access: Protected

+ 225 - 87
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -1483,7 +1483,8 @@ reset() {
   HRESULT hr;
 
   // make sure gsg passes all current state down to us
-  set_state(RenderState::make_empty());
+  // set_state_and_transform(RenderState::make_empty(),
+  // TransformState::make_identity());
   // want gsg to pass all state settings down so any non-matching defaults we set here get overwritten
 
   assert(_screen->_d3d8 != NULL);
@@ -1579,10 +1580,6 @@ reset() {
   _projection_mat = LMatrix4f::ident_mat();
   _has_scene_graph_color = false;
 
-  // Apply a default material when materials are turned off.
-  _pending_material = NULL;
-  do_issue_material();
-
   _last_testcooplevel_result = D3D_OK;
 
   for(int i = 0; i < MAX_POSSIBLE_TEXFMTS; i++) {
@@ -1670,17 +1667,6 @@ reset() {
   _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
 
   PRINT_REFCNT(dxgsg8, _d3d_device);
-
-  // Make sure the DX state matches all of our initial attribute states.
-  CPT(RenderAttrib) dta = DepthTestAttrib::make(DepthTestAttrib::M_less);
-  CPT(RenderAttrib) dwa = DepthWriteAttrib::make(DepthWriteAttrib::M_on);
-  CPT(RenderAttrib) cfa = CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise);
-
-  dta->issue(this);
-  dwa->issue(this);
-  cfa->issue(this);
-
-  PRINT_REFCNT(dxgsg8, _d3d_device);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -1730,8 +1716,8 @@ apply_fog(Fog *fog) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_transform
-//       Access: Public, Virtual
+//     Function: DXGraphicsStateGuardian8::do_issue_transform
+//       Access: Protected
 //  Description: Sends the indicated transform matrix to the graphics
 //               API to be applied to future vertices.
 //
@@ -1739,7 +1725,8 @@ apply_fog(Fog *fog) {
 //               converted into the GSG's internal coordinate system.
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-issue_transform(const TransformState *transform) {
+do_issue_transform() {
+  const TransformState *transform = _internal_transform;
   DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
 
   const D3DMATRIX *d3d_mat = (const D3DMATRIX *)transform->get_mat().get_data();
@@ -1752,12 +1739,13 @@ issue_transform(const TransformState *transform) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_alpha_test
-//       Access: Public, Virtual
+//     Function: DXGraphicsStateGuardian8::do_issue_alpha_test
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-issue_alpha_test(const AlphaTestAttrib *attrib) {
+do_issue_alpha_test() {
+  const AlphaTestAttrib *attrib = _target._alpha_test;
   AlphaTestAttrib::PandaCompareFunc mode = attrib->get_mode();
   if (mode == AlphaTestAttrib::M_none) {
     enable_alpha_test(false);
@@ -1770,12 +1758,13 @@ issue_alpha_test(const AlphaTestAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_render_mode
-//       Access: Public, Virtual
+//     Function: DXGraphicsStateGuardian8::do_issue_render_mode
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-issue_render_mode(const RenderModeAttrib *attrib) {
+do_issue_render_mode() {
+  const RenderModeAttrib *attrib = _target._render_mode;
   RenderModeAttrib::Mode mode = attrib->get_mode();
 
   switch (mode) {
@@ -1822,12 +1811,13 @@ issue_render_mode(const RenderModeAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_rescale_normal
-//       Access: Public, Virtual
+//     Function: DXGraphicsStateGuardian8::do_issue_rescale_normal
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-issue_rescale_normal(const RescaleNormalAttrib *attrib) {
+do_issue_rescale_normal() {
+  const RescaleNormalAttrib *attrib = _target._rescale_normal;
   RescaleNormalAttrib::Mode mode = attrib->get_mode();
 
   _auto_rescale_normal = false;
@@ -1854,23 +1844,13 @@ issue_rescale_normal(const RescaleNormalAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_color_write
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void DXGraphicsStateGuardian8::
-issue_color_write(const ColorWriteAttrib *attrib) {
-  _color_write_mode = attrib->get_mode();
-  set_color_writemask((_color_write_mode == ColorWriteAttrib::M_on) ? 0xFFFFFFFF : 0x0);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_depth_test
-//       Access: Public, Virtual
+//     Function: DXGraphicsStateGuardian8::do_issue_depth_test
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-issue_depth_test(const DepthTestAttrib *attrib) {
+do_issue_depth_test() {
+  const DepthTestAttrib *attrib = _target._depth_test;
   DepthTestAttrib::PandaCompareFunc mode = attrib->get_mode();
   if (mode == DepthTestAttrib::M_none) {
     _depth_test_enabled = false;
@@ -1883,22 +1863,24 @@ issue_depth_test(const DepthTestAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_depth_write
-//       Access: Public, Virtual
+//     Function: DXGraphicsStateGuardian8::do_issue_depth_write
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-issue_depth_write(const DepthWriteAttrib *attrib) {
+do_issue_depth_write() {
+  const DepthWriteAttrib *attrib = _target._depth_write;
   enable_zwritemask(attrib->get_mode() == DepthWriteAttrib::M_on);
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_cull_face
-//       Access: Public, Virtual
+//     Function: DXGraphicsStateGuardian8::do_issue_cull_face
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-issue_cull_face(const CullFaceAttrib *attrib) {
+do_issue_cull_face() {
+  const CullFaceAttrib *attrib = _target._cull_face;
   _cull_face_mode = attrib->get_effective_mode();
 
   switch (_cull_face_mode) {
@@ -1919,12 +1901,13 @@ issue_cull_face(const CullFaceAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_fog
-//       Access: Public, Virtual
+//     Function: DXGraphicsStateGuardian8::do_issue_fog
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-issue_fog(const FogAttrib *attrib) {
+do_issue_fog() {
+  const FogAttrib *attrib = _target._fog;
   if (!attrib->is_off()) {
     enable_fog(true);
     Fog *fog = attrib->get_fog();
@@ -1936,34 +1919,25 @@ issue_fog(const FogAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_depth_offset
-//       Access: Public, Virtual
+//     Function: DXGraphicsStateGuardian8::do_issue_depth_offset
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-issue_depth_offset(const DepthOffsetAttrib *attrib) {
+do_issue_depth_offset() {
+  const DepthOffsetAttrib *attrib = _target._depth_offset;
   int offset = attrib->get_offset();
   _d3d_device->SetRenderState(D3DRS_ZBIAS, offset);
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_tex_gen
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void DXGraphicsStateGuardian8::
-issue_tex_gen(const TexGenAttrib *attrib) {
-  _current_tex_gen = attrib;
-  _texture_stale = true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian8::issue_shade_model
-//       Access: Public, Virtual
+//     Function: DXGraphicsStateGuardian8::do_issue_shade_model
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-issue_shade_model(const ShadeModelAttrib *attrib) {
+do_issue_shade_model() {
+  const ShadeModelAttrib *attrib = _target._shade_model;
   switch (attrib->get_mode()) {
   case ShadeModelAttrib::M_smooth:
     _d3d_device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
@@ -1975,6 +1949,156 @@ issue_shade_model(const ShadeModelAttrib *attrib) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian8::set_state_and_transform
+//       Access: Public, Virtual
+//  Description: Simultaneously resets the render state and the
+//               transform state.
+//
+//               This transform specified is the "external" net
+//               transform, expressed in the external coordinate
+//               space; internally, it will be pretransformed by
+//               get_cs_transform() to express it in the GSG's
+//               internal coordinate space.
+//
+//               Special case: if (state==NULL), then the target
+//               state is already stored in _target.
+////////////////////////////////////////////////////////////////////
+void DXGraphicsStateGuardian8::
+set_state_and_transform(const RenderState *state,
+                        const TransformState *transform) {
+#ifndef NDEBUG
+  if (gsg_cat.is_spam()) {
+    gsg_cat.spam() << "Setting GSG state to " << (void *)state << ":\n";
+    state->write(gsg_cat.spam(false), 2);
+  }
+#endif
+  _state_pcollector.add_level(1);
+
+  if (transform != _external_transform) {
+    _state_pcollector.add_level(1);
+    _external_transform = transform;
+    _internal_transform = _cs_transform->compose(transform);
+    do_issue_transform();
+  }
+  
+  if (state) {
+    if (state == _last_state) {
+      return;
+    }
+    _target.clear_to_defaults();
+    state->store_into_slots(&_target);
+  }
+  _last_state = state;
+  
+  
+  if (_target._alpha_test != _state._alpha_test) {
+    do_issue_alpha_test();
+    _state._alpha_test = _target._alpha_test;
+  }
+  
+  if (_target._antialias != _state._antialias) {
+    // Antialias not implemented under DX8
+    _state._antialias = _target._antialias;
+  }
+  
+  if (_target._clip_plane != _state._clip_plane) {
+    do_issue_clip_plane();
+    _state._clip_plane = _target._clip_plane;
+  }
+  
+  if (_target._color != _state._color) {
+    do_issue_color();
+    _state._color = _target._color;
+  }
+  
+  if (_target._color_scale != _state._color_scale) {
+    do_issue_color_scale();
+    _state._color_scale = _target._color_scale;
+  }
+  
+  if (_target._cull_face != _state._cull_face) {
+    do_issue_cull_face();
+    _state._cull_face = _target._cull_face;
+  }
+  
+  if (_target._depth_offset != _state._depth_offset) {
+    do_issue_depth_offset();
+    _state._depth_offset = _target._depth_offset;
+  }
+  
+  if (_target._depth_test != _state._depth_test) {
+    do_issue_depth_test();
+    _state._depth_test = _target._depth_test;
+  }
+  
+  if (_target._depth_write != _state._depth_write) {
+    do_issue_depth_write();
+    _state._depth_write = _target._depth_write;
+  }
+  
+  if (_target._fog != _state._fog) {
+    do_issue_fog();
+    _state._fog = _target._fog;
+  }
+  
+  if (_target._render_mode != _state._render_mode) {
+    do_issue_render_mode();
+    _state._render_mode = _target._render_mode;
+  }
+  
+  if (_target._rescale_normal != _state._rescale_normal) {
+    do_issue_rescale_normal();
+    _state._rescale_normal = _target._rescale_normal;
+  }
+  
+  if (_target._shade_model != _state._shade_model) {
+    do_issue_shade_model();
+    _state._shade_model = _target._shade_model;
+  }
+  
+  // Shaders not implemented under DX8
+  if (_target._shader != _state._shader) {
+    _state._shader = _target._shader;
+  }
+  
+  if (_target._tex_gen != _state._tex_gen) {
+    _current_tex_gen = _target._tex_gen;
+    _state._texture = 0;
+    _state._tex_gen = _target._tex_gen;
+  }
+  
+  if (_target._tex_matrix != _state._tex_matrix) {
+    _current_tex_mat = _target._tex_matrix;
+    _needs_tex_mat = true;
+    _state._tex_matrix = _target._tex_matrix;
+  }
+  
+  if ((_target._transparency != _state._transparency)||
+      (_target._color_write != _state._color_write)||
+      (_target._color_blend != _state._color_blend)) {
+    do_issue_blending();
+    _state._transparency = _target._transparency;
+    _state._color_write = _target._color_write;
+    _state._color_blend = _target._color_blend;
+  }
+  
+  if (_target._texture != _state._texture) {
+    do_issue_texture();
+    _state._texture = _target._texture;
+  }
+
+  if (_target._material != _state._material) {
+    do_issue_material();
+    _state._material = _target._material;
+  }
+  
+  if (_target._light != _state._light) {
+    do_issue_light();
+    _state._light = _target._light;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian8::bind_light
 //       Access: Public, Virtual
@@ -2152,11 +2276,11 @@ void DXGraphicsStateGuardian8::
 do_issue_material() {
   static Material empty;
   const Material *material;
-  if (_pending_material == (MaterialAttrib *)NULL ||
-      _pending_material->is_off()) {
+  if (_target._material == (MaterialAttrib *)NULL ||
+      _target._material->is_off()) {
     material = &empty;
   } else {
-    material = _pending_material->get_material();
+    material = _target._material->get_material();
   }
 
   D3DMATERIAL8 cur_material;
@@ -2215,7 +2339,7 @@ void DXGraphicsStateGuardian8::
 do_issue_texture() {
   DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
 
-  CPT(TextureAttrib) new_texture = _pending_texture->filter_to_max(_max_texture_stages);
+  CPT(TextureAttrib) new_texture = _target._texture->filter_to_max(_max_texture_stages);
 
   int num_stages = new_texture->get_num_on_stages();
   int num_old_stages = _current_texture->get_num_on_stages();
@@ -2500,23 +2624,36 @@ bind_clip_plane(const NodePath &plane, int plane_id) {
 //               blending mode based on the current properties.
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-set_blend_mode() {
+do_issue_blending() {
 
-  if ((_color_write_mode == ColorWriteAttrib::M_off) && !_screen->_can_direct_disable_color_writes) {
-    // need !_screen->_can_direct_disable_color_writes guard because other
-    // issue_colorblend, issue_transp will come this way, and they
-    // should ignore the colorwriteattrib value since it's been
-    // handled separately in set_color_writemask
-    enable_blend(true);
-    call_dxBlendFunc(D3DBLEND_ZERO, D3DBLEND_ONE);
+  if (_target._color_write->get_mode() == ColorWriteAttrib::M_off) {
+    if (_target._color_write != _state._color_write) {
+      if (_screen->_can_direct_disable_color_writes) {
+        enable_blend(false);
+        _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, (DWORD)0x0);
+      } else {
+        enable_blend(true);
+        call_dxBlendFunc(D3DBLEND_ZERO, D3DBLEND_ONE);
+      }
+    }
     return;
+  } else {
+    if (_target._color_write != _state._color_write) {
+      if (_screen->_can_direct_disable_color_writes) {
+        _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, (DWORD)0xFFFFFFFF);
+      }
+    }
   }
 
+  CPT(ColorBlendAttrib) color_blend = _target._color_blend;
+  ColorBlendAttrib::Mode color_blend_mode = _target._color_blend->get_mode();
+  TransparencyAttrib::Mode transparency_mode = _target._transparency->get_mode();
+
   // Is there a color blend set?
-  if (_color_blend_mode != ColorBlendAttrib::M_none) {
+  if (color_blend_mode != ColorBlendAttrib::M_none) {
     enable_blend(true);
 
-    switch (_color_blend_mode) {
+    switch (color_blend_mode) {
     case ColorBlendAttrib::M_add:
       _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
       break;
@@ -2538,13 +2675,13 @@ set_blend_mode() {
       break;
     }
 
-    call_dxBlendFunc(get_blend_func(_color_blend->get_operand_a()),
-                     get_blend_func(_color_blend->get_operand_b()));
+    call_dxBlendFunc(get_blend_func(color_blend->get_operand_a()),
+                     get_blend_func(color_blend->get_operand_b()));
     return;
   }
 
   // No color blend; is there a transparency set?
-  switch (_transparency_mode) {
+  switch (transparency_mode) {
   case TransparencyAttrib::M_none:
   case TransparencyAttrib::M_binary:
     break;
@@ -2560,7 +2697,7 @@ set_blend_mode() {
 
   default:
     dxgsg8_cat.error()
-      << "invalid transparency mode " << (int)_transparency_mode << endl;
+      << "invalid transparency mode " << (int)transparency_mode << endl;
     break;
   }
 
@@ -2587,7 +2724,8 @@ free_nondx_resources() {
 void DXGraphicsStateGuardian8::
 free_d3d_device() {
   // dont want a full reset of gsg, just a state clear
-  set_state(RenderState::make_empty());
+  _last_state = 0;
+  _state.clear_to_zero();
   // want gsg to pass all state settings through
 
   _dx_is_ready = false;

+ 19 - 19
panda/src/dxgsg8/dxGraphicsStateGuardian8.h

@@ -94,19 +94,6 @@ public:
 
   virtual void apply_fog(Fog *fog);
 
-  virtual void issue_transform(const TransformState *transform);
-  virtual void issue_alpha_test(const AlphaTestAttrib *attrib);
-  virtual void issue_render_mode(const RenderModeAttrib *attrib);
-  virtual void issue_rescale_normal(const RescaleNormalAttrib *attrib);
-  virtual void issue_color_write(const ColorWriteAttrib *attrib);
-  virtual void issue_depth_test(const DepthTestAttrib *attrib);
-  virtual void issue_depth_write(const DepthWriteAttrib *attrib);
-  virtual void issue_cull_face(const CullFaceAttrib *attrib);
-  virtual void issue_fog(const FogAttrib *attrib);
-  virtual void issue_depth_offset(const DepthOffsetAttrib *attrib);
-  virtual void issue_tex_gen(const TexGenAttrib *attrib);
-  virtual void issue_shade_model(const ShadeModelAttrib *attrib);
-
   virtual void bind_light(PointLight *light_obj, const NodePath &light, 
                           int light_id);
   virtual void bind_light(DirectionalLight *light_obj, const NodePath &light, 
@@ -117,10 +104,26 @@ public:
   static D3DFORMAT get_index_type(Geom::NumericType numeric_type);
   INLINE static DWORD Colorf_to_D3DCOLOR(const Colorf &cColorf);
 
-protected:
-  virtual void do_issue_material();
-  virtual void do_issue_texture();
+  virtual void set_state_and_transform(const RenderState *state,
+                                       const TransformState *transform);
 
+protected:
+  void do_issue_transform();
+  void do_issue_alpha_test();
+  void do_issue_render_mode();
+  void do_issue_rescale_normal();
+  void do_issue_color_write();
+  void do_issue_depth_test();
+  void do_issue_depth_write();
+  void do_issue_cull_face();
+  void do_issue_fog();
+  void do_issue_depth_offset();
+  void do_issue_tex_gen();
+  void do_issue_shade_model();
+  void do_issue_material();
+  void do_issue_texture();
+  void do_issue_blending();
+  
   virtual void enable_lighting(bool enable);
   virtual void set_ambient_light(const Colorf &color);
   virtual void enable_light(int light_id, bool enable);
@@ -128,8 +131,6 @@ protected:
   virtual void enable_clip_plane(int plane_id, bool enable);
   virtual void bind_clip_plane(const NodePath &plane, int plane_id);
 
-  virtual void set_blend_mode();
-
   void free_nondx_resources();
   void free_d3d_device();
 
@@ -142,7 +143,6 @@ protected:
   INLINE void enable_color_material(bool val);
   INLINE void enable_fog(bool val);
   INLINE void enable_zwritemask(bool val);
-  INLINE void set_color_writemask(UINT color_writemask);
   INLINE void set_vertex_format(DWORD NewFvfType);
 
   INLINE static D3DTEXTUREADDRESS get_texture_wrap_mode(Texture::WrapMode wm);

+ 2 - 14
panda/src/glstuff/glGraphicsStateGuardian_src.I

@@ -224,7 +224,7 @@ enable_multisample_alpha_mask(bool val) {
 INLINE void CLP(GraphicsStateGuardian)::
 enable_line_smooth(bool val) {
   if (_line_smooth_enabled != val) {
-    _blend_mode_stale = true;
+    _state._transparency = 0;
     _line_smooth_enabled = val;
     if (val) {
       GLP(Enable)(GL_LINE_SMOOTH);
@@ -242,7 +242,7 @@ enable_line_smooth(bool val) {
 INLINE void CLP(GraphicsStateGuardian)::
 enable_point_smooth(bool val) {
   if (_point_smooth_enabled != val) {
-    _blend_mode_stale = true;
+    _state._transparency = 0;
     _point_smooth_enabled = val;
     if (val) {
       GLP(Enable)(GL_POINT_SMOOTH);
@@ -283,10 +283,6 @@ setup_antialias_line() {
     // have multisample available.
     enable_multisample_antialias(false);
     enable_line_smooth(true);
-
-    if (_blend_mode_stale) {
-      set_blend_mode();
-    }
   }
 }
 
@@ -304,10 +300,6 @@ setup_antialias_point() {
     // have multisample available.
     enable_multisample_antialias(false);
     enable_point_smooth(true);
-
-    if (_blend_mode_stale) {
-      set_blend_mode();
-    }
   }
 }
 
@@ -345,10 +337,6 @@ setup_antialias_polygon() {
         enable_polygon_smooth(true);
       }
     }
-
-    if (_blend_mode_stale) {
-      set_blend_mode();
-    }
   }
 }
 

+ 261 - 174
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -819,21 +819,6 @@ reset() {
 
   report_my_gl_errors();
 
-  // Make sure the GL state matches all of our initial attribute
-  // states.
-  CPT(RenderAttrib) dta = DepthTestAttrib::make(DepthTestAttrib::M_less);
-  CPT(RenderAttrib) dwa = DepthWriteAttrib::make(DepthWriteAttrib::M_on);
-  CPT(RenderAttrib) cfa = CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise);
-  CPT(RenderAttrib) ta = TextureAttrib::make_off();
-
-  dta->issue(this);
-  dwa->issue(this);
-  cfa->issue(this);
-  ta->issue(this);
-
-  _pending_material = NULL;
-  do_issue_material();
-
   if (CLP(cheap_textures)) {
     GLCAT.info()
       << "Setting GLP(Hint)() for fastest textures.\n";
@@ -872,14 +857,13 @@ do_clear(const RenderBuffer &buffer) {
   nassertv(buffer._gsg == this);
   int buffer_type = buffer._buffer_type;
   GLbitfield mask = 0;
-  CPT(RenderState) state = RenderState::make_empty();
 
   if (buffer_type & RenderBuffer::T_color) {
     GLP(ClearColor)(_color_clear_value[0],
                     _color_clear_value[1],
                     _color_clear_value[2],
                     _color_clear_value[3]);
-    state = state->add_attrib(ColorWriteAttrib::make(ColorWriteAttrib::M_on));
+    _target._color_write = AttribSlots::get_defaults()._color_write;
     mask |= GL_COLOR_BUFFER_BIT;
 
     set_draw_buffer(buffer);
@@ -891,7 +875,7 @@ do_clear(const RenderBuffer &buffer) {
 
     // In order to clear the depth buffer, the depth mask must enable
     // writing to the depth buffer.
-    state = state->add_attrib(DepthWriteAttrib::make(DepthWriteAttrib::M_on));
+    _target._depth_write = AttribSlots::get_defaults()._depth_write;
   }
 
   if (buffer_type & RenderBuffer::T_stencil) {
@@ -906,7 +890,7 @@ do_clear(const RenderBuffer &buffer) {
                     _accum_clear_value[3]);
     mask |= GL_ACCUM_BUFFER_BIT;
   }
-
+  
   if (GLCAT.is_spam()) {
     GLCAT.spam() << "glClear(";
     if (mask & GL_COLOR_BUFFER_BIT) {
@@ -923,9 +907,9 @@ do_clear(const RenderBuffer &buffer) {
     }
     GLCAT.spam(false) << ")" << endl;
   }
-
-  modify_state(state);
-
+  
+  set_state_and_transform(NULL, _external_transform);
+  
   GLP(Clear)(mask);
   report_my_gl_errors();
 }
@@ -1131,6 +1115,14 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
     case GeomPrimitive::PT_none:
       break;
     }
+    if ((_target._transparency != _state._transparency)||
+        (_target._color_write != _state._color_write)||
+        (_target._color_blend != _state._color_blend)) {
+      do_issue_blending();
+      _state._transparency = _target._transparency;
+      _state._color_write = _target._color_write;
+      _state._color_blend = _target._color_blend;
+    }
   }
 
   const GeomVertexAnimationSpec &animation = 
@@ -2445,8 +2437,9 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
 
   report_my_gl_errors();
 
-  // Clear the internal texture state, since we've just monkeyed with it.
-  modify_state(get_untextured_state());
+  // Force reload of texture state, since we've just monkeyed with it.
+  _last_state = 0;
+  _state._texture = 0;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -2470,8 +2463,9 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
   // for GLP(ReadPixels)() to work
   // NOTE: reading the depth buffer is *much* slower than reading the
   // color buffer
-  modify_state(get_untextured_state());
-
+  _target._texture = AttribSlots::get_defaults()._texture;
+  set_state_and_transform(NULL, _external_transform);
+  
   int xo, yo, w, h;
   dr->get_region_pixels(xo, yo, w, h);
 
@@ -2621,8 +2615,8 @@ apply_fog(Fog *fog) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_transform
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_transform
+//       Access: Protected
 //  Description: Sends the indicated transform matrix to the graphics
 //               API to be applied to future vertices.
 //
@@ -2630,7 +2624,8 @@ apply_fog(Fog *fog) {
 //               converted into the GSG's internal coordinate system.
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_transform(const TransformState *transform) {
+do_issue_transform() {
+  const TransformState *transform = _internal_transform;
   if (GLCAT.is_spam()) {
     GLCAT.spam()
       << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl;
@@ -2652,12 +2647,13 @@ issue_transform(const TransformState *transform) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_shade_model
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_shade_model
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_shade_model(const ShadeModelAttrib *attrib) {
+do_issue_shade_model() {
+  const ShadeModelAttrib *attrib = _target._shade_model;
   switch (attrib->get_mode()) {
   case ShadeModelAttrib::M_smooth:
     GLP(ShadeModel)(GL_SMOOTH);
@@ -2672,12 +2668,13 @@ issue_shade_model(const ShadeModelAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_shader
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_shader
+//       Access: Protected
 //  Description: Bind a shader.
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_shader(const ShaderAttrib *attrib) {
+do_issue_shader() {
+  const ShaderAttrib *attrib = _target._shader;
   ShaderMode *mode = attrib->get_shader_mode();
   if (mode == 0) {
     if (_current_shader_context != 0) {
@@ -2723,12 +2720,13 @@ issue_shader(const ShaderAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_render_mode
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_render_mode
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_render_mode(const RenderModeAttrib *attrib) {
+do_issue_render_mode() {
+  const RenderModeAttrib *attrib = _target._render_mode;
   _render_mode = attrib->get_mode();
   _point_size = attrib->get_thickness();
   _point_perspective = attrib->get_perspective();
@@ -2761,12 +2759,13 @@ issue_render_mode(const RenderModeAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_antialias
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_antialias
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_antialias(const AntialiasAttrib *attrib) {
+do_issue_antialias() {
+  const AntialiasAttrib *attrib = _target._antialias;
   if (attrib->get_mode_type() == AntialiasAttrib::M_auto) {
     // In this special mode, we must enable antialiasing on a
     // case-by-case basis, because we enable it differently for
@@ -2817,12 +2816,13 @@ issue_antialias(const AntialiasAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_rescale_normal
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_rescale_normal
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_rescale_normal(const RescaleNormalAttrib *attrib) {
+do_issue_rescale_normal() {
+  const RescaleNormalAttrib *attrib = _target._rescale_normal;
   RescaleNormalAttrib::Mode mode = attrib->get_mode();
 
   _auto_rescale_normal = false;
@@ -2863,44 +2863,17 @@ issue_rescale_normal(const RescaleNormalAttrib *attrib) {
   report_my_gl_errors();
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_color_write
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void CLP(GraphicsStateGuardian)::
-issue_color_write(const ColorWriteAttrib *attrib) {
-  // If we did not override this function, the default implementation
-  // would achieve turning off color writes by changing the blend mode
-  // in set_blend_mode().  However, since GL does support an easy way
-  // to disable writes to the color buffer, we can take advantage of
-  // it here.
-  if (CLP(color_mask)) {
-    ColorWriteAttrib::Mode mode = attrib->get_mode();
-    if (mode == ColorWriteAttrib::M_off) {
-      GLP(ColorMask)(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-    } else {
-      GLP(ColorMask)(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-    }
-    report_my_gl_errors();
-
-  } else {
-    // Some implementations don't seem to handle GLP(ColorMask)() very
-    // robustly, however, so we provide this fallback.
-    GraphicsStateGuardian::issue_color_write(attrib);
-  }
-}
-
 // PandaCompareFunc - 1 + 0x200 === GL_NEVER, etc.  order is sequential
 #define PANDA_TO_GL_COMPAREFUNC(PANDACMPFUNC) (PANDACMPFUNC-1 +0x200)
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_depth_test
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_depth_test
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_depth_test(const DepthTestAttrib *attrib) {
+do_issue_depth_test() {
+  const DepthTestAttrib *attrib = _target._depth_test;
   DepthTestAttrib::PandaCompareFunc mode = attrib->get_mode();
   if (mode == DepthTestAttrib::M_none) {
     enable_depth_test(false);
@@ -2912,12 +2885,13 @@ issue_depth_test(const DepthTestAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_alpha_test
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_alpha_test
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_alpha_test(const AlphaTestAttrib *attrib) {
+do_issue_alpha_test() {
+  const AlphaTestAttrib *attrib = _target._alpha_test;
   AlphaTestAttrib::PandaCompareFunc mode = attrib->get_mode();
   if (mode == AlphaTestAttrib::M_none) {
     enable_alpha_test(false);
@@ -2929,12 +2903,13 @@ issue_alpha_test(const AlphaTestAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_depth_write
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_depth_write
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_depth_write(const DepthWriteAttrib *attrib) {
+do_issue_depth_write() {
+  const DepthWriteAttrib *attrib = _target._depth_write;
   DepthWriteAttrib::Mode mode = attrib->get_mode();
   if (mode == DepthWriteAttrib::M_off) {
     GLP(DepthMask)(GL_FALSE);
@@ -2945,12 +2920,13 @@ issue_depth_write(const DepthWriteAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_cull_face
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_cull_face
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_cull_face(const CullFaceAttrib *attrib) {
+do_issue_cull_face() {
+  const CullFaceAttrib *attrib = _target._cull_face;
   CullFaceAttrib::Mode mode = attrib->get_effective_mode();
 
   switch (mode) {
@@ -2974,12 +2950,13 @@ issue_cull_face(const CullFaceAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_fog
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_fog
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_fog(const FogAttrib *attrib) {
+do_issue_fog() {
+  const FogAttrib *attrib = _target._fog;
   if (!attrib->is_off()) {
     enable_fog(true);
     Fog *fog = attrib->get_fog();
@@ -2992,12 +2969,13 @@ issue_fog(const FogAttrib *attrib) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_depth_offset
-//       Access: Public, Virtual
+//     Function: GLGraphicsStateGuardian::do_issue_depth_offset
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-issue_depth_offset(const DepthOffsetAttrib *attrib) {
+do_issue_depth_offset() {
+  const DepthOffsetAttrib *attrib = _target._depth_offset;
   int offset = attrib->get_offset();
 
   if (offset != 0) {
@@ -3015,18 +2993,18 @@ issue_depth_offset(const DepthOffsetAttrib *attrib) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::do_issue_material
-//       Access: Public, Virtual
+//       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 do_issue_material() {
   static Material empty;
   const Material *material;
-  if (_pending_material == (MaterialAttrib *)NULL || 
-      _pending_material->is_off()) {
+  if (_target._material == (MaterialAttrib *)NULL || 
+      _target._material->is_off()) {
     material = &empty;
   } else {
-    material = _pending_material->get_material();
+    material = _target._material->get_material();
   }
 
   GLenum face = material->get_twoside() ? GL_FRONT_AND_BACK : GL_FRONT;
@@ -4277,7 +4255,7 @@ get_light_color(Light *light) const {
 //       Access: Protected, Virtual
 //  Description: Intended to be overridden by a derived class to
 //               enable or disable the use of lighting overall.  This
-//               is called by issue_light() according to whether any
+//               is called by do_issue_light() according to whether any
 //               lights are in use or not.
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
@@ -4294,7 +4272,7 @@ enable_lighting(bool enable) {
 //       Access: Protected, Virtual
 //  Description: Intended to be overridden by a derived class to
 //               indicate the color of the ambient light that should
-//               be in effect.  This is called by issue_light() after
+//               be in effect.  This is called by do_issue_light() after
 //               all other lights have been enabled or disabled.
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
@@ -4452,36 +4430,53 @@ end_bind_clip_planes() {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::set_blend_mode
-//       Access: Protected, Virtual
-//  Description: Called after any of the things that might change
-//               blending state have changed, this function is
-//               responsible for setting the appropriate color
-//               blending mode based on the current properties.
+//     Function: GLGraphicsStateGuardian::do_issue_blending
+//       Access: Protected
+//  Description:
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-set_blend_mode() {
-  // If color_write_mode is off, we disable writing to the color using
-  // blending.  This case is only used if we can't use GLP(ColorMask) to
-  // disable the color writing for some reason (usually a driver
+do_issue_blending() {
+
+  // If necessary, we disable writing to the color buffer using
+  // blending.  This case is only used if we can't use GLP(ColorMask)
+  // to disable the color writing for some reason (usually a driver
   // problem).
-  if (_color_write_mode == ColorWriteAttrib::M_off) {
-    enable_multisample_alpha_one(false);
-    enable_multisample_alpha_mask(false);
-    enable_blend(true);
-    _glBlendEquation(GL_FUNC_ADD);
-    GLP(BlendFunc)(GL_ZERO, GL_ONE);
-   return;
+  if (_target._color_write->get_mode() == ColorWriteAttrib::M_off) {
+    if (_target._color_write != _state._color_write) {
+      enable_multisample_alpha_one(false);
+      enable_multisample_alpha_mask(false);
+      if (CLP(color_mask)) {
+        enable_blend(false);
+        GLP(ColorMask)(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+      } else {
+        enable_blend(true);
+        _glBlendEquation(GL_FUNC_ADD);
+        GLP(BlendFunc)(GL_ZERO, GL_ONE);
+      }
+    }
+    return;
+  } else {
+    if (_target._color_write != _state._color_write) {
+      if (CLP(color_mask)) {
+        GLP(ColorMask)(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+      }
+    }
   }
+  
+  CPT(ColorBlendAttrib) color_blend = _target._color_blend;
+  ColorBlendAttrib::Mode color_blend_mode = _target._color_blend->get_mode();
+  TransparencyAttrib::Mode transparency_mode = _target._transparency->get_mode();
+
+  _color_blend_involves_color_scale = color_blend->involves_color_scale();
 
   // Is there a color blend set?
-  if (_color_blend_mode != ColorBlendAttrib::M_none) {
+  if (color_blend_mode != ColorBlendAttrib::M_none) {
     enable_multisample_alpha_one(false);
     enable_multisample_alpha_mask(false);
     enable_blend(true);
-    _glBlendEquation(get_blend_equation_type(_color_blend_mode));
-    GLP(BlendFunc)(get_blend_func(_color_blend->get_operand_a()),
-                   get_blend_func(_color_blend->get_operand_b()));
+    _glBlendEquation(get_blend_equation_type(color_blend_mode));
+    GLP(BlendFunc)(get_blend_func(color_blend->get_operand_a()),
+                   get_blend_func(color_blend->get_operand_b()));
 
     if (_color_blend_involves_color_scale) {
       // Apply the current color scale to the blend mode.
@@ -4489,14 +4484,14 @@ set_blend_mode() {
                     _current_color_scale[2], _current_color_scale[3]);
       
     } else {
-      Colorf c = _color_blend->get_color();
+      Colorf c = color_blend->get_color();
       _glBlendColor(c[0], c[1], c[2], c[3]);
     }
     return;
   }
 
   // No color blend; is there a transparency set?
-  switch (_transparency_mode) {
+  switch (transparency_mode) {
   case TransparencyAttrib::M_none:
   case TransparencyAttrib::M_binary:
     break;
@@ -4525,7 +4520,7 @@ set_blend_mode() {
     
   default:
     GLCAT.error()
-      << "invalid transparency mode " << (int)_transparency_mode << endl;
+      << "invalid transparency mode " << (int)transparency_mode << endl;
     break;
   }
 
@@ -4557,16 +4552,153 @@ set_blend_mode() {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::finish_modify_state
-//       Access: Protected, Virtual
-//  Description: Called after the GSG state has been modified via
-//               modify_state() or set_state(), this hook is provided
-//               for the derived class to do any further state setup
-//               work.
+//     Function: GLGraphicsStateGuardian::set_state_and_transform
+//       Access: Public, Virtual
+//  Description: Simultaneously resets the render state and the
+//               transform state.
+//
+//               This transform specified is the "external" net
+//               transform, expressed in the external coordinate
+//               space; internally, it will be pretransformed by
+//               get_cs_transform() to express it in the GSG's
+//               internal coordinate space.
+//
+//               Special case: if (state==NULL), then the target
+//               state is already stored in _target.
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-finish_modify_state() {
-  GraphicsStateGuardian::finish_modify_state();
+set_state_and_transform(const RenderState *state,
+                        const TransformState *transform) {
+#ifndef NDEBUG
+  if (gsg_cat.is_spam()) {
+    gsg_cat.spam() << "Setting GSG state to " << (void *)state << ":\n";
+    state->write(gsg_cat.spam(false), 2);
+  }
+#endif
+  _state_pcollector.add_level(1);
+
+  if (transform != _external_transform) {
+    _state_pcollector.add_level(1);
+    _external_transform = transform;
+    _internal_transform = _cs_transform->compose(transform);
+    do_issue_transform();
+  }
+  
+  if (state) {
+    if (state == _last_state) {
+      return;
+    }
+    _target.clear_to_defaults();
+    state->store_into_slots(&_target);
+  }
+  _last_state = state;
+  
+  
+  if (_target._alpha_test != _state._alpha_test) {
+    do_issue_alpha_test();
+    _state._alpha_test = _target._alpha_test;
+  }
+  
+  if (_target._antialias != _state._antialias) {
+    do_issue_antialias();
+    _state._antialias = _target._antialias;
+  }
+  
+  if (_target._clip_plane != _state._clip_plane) {
+    do_issue_clip_plane();
+    _state._clip_plane = _target._clip_plane;
+  }
+  
+  if (_target._color != _state._color) {
+    do_issue_color();
+    _state._color = _target._color;
+  }
+  
+  if (_target._color_scale != _state._color_scale) {
+    do_issue_color_scale();
+    _state._color_scale = _target._color_scale;
+  }
+  
+  if (_target._cull_face != _state._cull_face) {
+    do_issue_cull_face();
+    _state._cull_face = _target._cull_face;
+  }
+  
+  if (_target._depth_offset != _state._depth_offset) {
+    do_issue_depth_offset();
+    _state._depth_offset = _target._depth_offset;
+  }
+  
+  if (_target._depth_test != _state._depth_test) {
+    do_issue_depth_test();
+    _state._depth_test = _target._depth_test;
+  }
+  
+  if (_target._depth_write != _state._depth_write) {
+    do_issue_depth_write();
+    _state._depth_write = _target._depth_write;
+  }
+  
+  if (_target._fog != _state._fog) {
+    do_issue_fog();
+    _state._fog = _target._fog;
+  }
+  
+  if (_target._render_mode != _state._render_mode) {
+    do_issue_render_mode();
+    _state._render_mode = _target._render_mode;
+  }
+  
+  if (_target._rescale_normal != _state._rescale_normal) {
+    do_issue_rescale_normal();
+    _state._rescale_normal = _target._rescale_normal;
+  }
+  
+  if (_target._shade_model != _state._shade_model) {
+    do_issue_shade_model();
+    _state._shade_model = _target._shade_model;
+  }
+  
+  if (_target._shader != _state._shader) {
+    do_issue_shader();
+    _state._shader = _target._shader;
+  }
+  
+  if (_target._tex_gen != _state._tex_gen) {
+    _current_tex_gen = _target._tex_gen;
+    _needs_tex_gen = true;
+    _state._tex_gen = _target._tex_gen;
+  }
+  
+  if (_target._tex_matrix != _state._tex_matrix) {
+    _current_tex_mat = _target._tex_matrix;
+    _needs_tex_mat = true;
+    _state._tex_matrix = _target._tex_matrix;
+  }
+  
+  if ((_target._transparency != _state._transparency)||
+      (_target._color_write != _state._color_write)||
+      (_target._color_blend != _state._color_blend)) {
+    do_issue_blending();
+    _state._transparency = _target._transparency;
+    _state._color_write = _target._color_write;
+    _state._color_blend = _target._color_blend;
+  }
+  
+  if (_target._texture != _state._texture) {
+    do_issue_texture();
+    _state._texture = _target._texture;
+  }
+
+  if (_target._material != _state._material) {
+    do_issue_material();
+    _state._material = _target._material;
+  }
+  
+  if (_target._light != _state._light) {
+    do_issue_light();
+    _state._light = _target._light;
+  }
 
   // If one of the previously-loaded TexGen modes modified the texture
   // matrix, then if either state changed, we have to change both of
@@ -4858,51 +4990,6 @@ void CLP(GraphicsStateGuardian)::
 free_pointers() {
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::get_untextured_state
-//       Access: Protected, Static
-//  Description: Returns a RenderState object that represents
-//               texturing off.
-////////////////////////////////////////////////////////////////////
-CPT(RenderState) CLP(GraphicsStateGuardian)::
-get_untextured_state() {
-  static CPT(RenderState) state;
-  if (state == (RenderState *)NULL) {
-    state = RenderState::make(TextureAttrib::make_off());
-  }
-  return state;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::get_smooth_state
-//       Access: Protected, Static
-//  Description: Returns a RenderState object that represents
-//               smooth, per-vertex shading.
-////////////////////////////////////////////////////////////////////
-CPT(RenderState) CLP(GraphicsStateGuardian)::
-get_smooth_state() {
-  static CPT(RenderState) state;
-  if (state == (RenderState *)NULL) {
-    state = RenderState::make(ShadeModelAttrib::make(ShadeModelAttrib::M_smooth));
-  }
-  return state;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::get_flat_state
-//       Access: Protected, Static
-//  Description: Returns a RenderState object that represents
-//               flat, per-primitive shading.
-////////////////////////////////////////////////////////////////////
-CPT(RenderState) CLP(GraphicsStateGuardian)::
-get_flat_state() {
-  static CPT(RenderState) state;
-  if (state == (RenderState *)NULL) {
-    state = RenderState::make(ShadeModelAttrib::make(ShadeModelAttrib::M_flat));
-  }
-  return state;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::do_auto_rescale_normal
 //       Access: Protected
@@ -4947,7 +5034,7 @@ void CLP(GraphicsStateGuardian)::
 do_issue_texture() {
   DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
 
-  CPT(TextureAttrib) new_texture = _pending_texture->filter_to_max(_max_texture_stages);
+  CPT(TextureAttrib) new_texture = _target._texture->filter_to_max(_max_texture_stages);
   
   int num_stages = new_texture->get_num_on_stages();
   int num_old_stages = _current_texture->get_num_on_stages();

+ 20 - 25
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -128,22 +128,6 @@ public:
 
   void apply_fog(Fog *fog);
 
-  virtual void issue_transform(const TransformState *transform);
-  virtual void issue_render_mode(const RenderModeAttrib *attrib);
-  virtual void issue_antialias(const AntialiasAttrib *);
-  virtual void issue_rescale_normal(const RescaleNormalAttrib *attrib);
-  virtual void issue_color_write(const ColorWriteAttrib *attrib);
-  virtual void issue_depth_test(const DepthTestAttrib *attrib);
-  virtual void issue_alpha_test(const AlphaTestAttrib *attrib);
-  virtual void issue_depth_write(const DepthWriteAttrib *attrib);
-  virtual void issue_cull_face(const CullFaceAttrib *attrib);
-  virtual void issue_fog(const FogAttrib *attrib);
-  virtual void issue_depth_offset(const DepthOffsetAttrib *attrib);
-  virtual void issue_shade_model(const ShadeModelAttrib *attrib);
-  virtual void issue_shader(const ShaderAttrib *attrib);
-
-  virtual void do_issue_material();
-
   virtual void bind_light(PointLight *light_obj, const NodePath &light, 
                           int light_id);
   virtual void bind_light(DirectionalLight *light_obj, const NodePath &light, 
@@ -175,7 +159,27 @@ public:
   INLINE int get_gl_version_minor() const;
   INLINE int get_gl_version_release() const;
 
+  virtual void set_state_and_transform(const RenderState *state,
+                                       const TransformState *transform);
+
 protected:
+  void do_issue_transform();
+  void do_issue_render_mode();
+  void do_issue_antialias();
+  void do_issue_rescale_normal();
+  void do_issue_color_write();
+  void do_issue_depth_test();
+  void do_issue_alpha_test();
+  void do_issue_depth_write();
+  void do_issue_cull_face();
+  void do_issue_fog();
+  void do_issue_depth_offset();
+  void do_issue_shade_model();
+  void do_issue_shader();
+  void do_issue_material();
+  void do_issue_texture();
+  void do_issue_blending();
+
   static bool report_errors_loop(int line, const char *source_file, 
                                  GLenum error_code, int &error_count);
   string show_gl_string(const string &name, GLenum id);
@@ -198,10 +202,6 @@ protected:
   virtual void bind_clip_plane(const NodePath &plane, int plane_id);
   virtual void end_bind_clip_planes();
 
-  virtual void set_blend_mode();
-
-  virtual void finish_modify_state();
-
   virtual void free_pointers();
 
   INLINE void enable_multisample_antialias(bool val);
@@ -252,12 +252,7 @@ protected:
   void disable_standard_vertex_arrays();
   void update_standard_vertex_arrays();
 
-  static CPT(RenderState) get_untextured_state();
-  static CPT(RenderState) get_smooth_state();
-  static CPT(RenderState) get_flat_state();
-
   void do_auto_rescale_normal();
-  virtual void do_issue_texture();
   void specify_texture(Texture *tex);
   void apply_texture(TextureContext *tc);
   bool upload_texture(CLP(TextureContext) *gtc);

+ 1 - 0
panda/src/glstuff/glShaderContext_src.cxx

@@ -788,3 +788,4 @@ compile_cg_parameter(CGparameter p)
 }
 #endif
 
+

+ 2 - 0
panda/src/gobj/shader.h

@@ -32,6 +32,8 @@
 
 #include "pandabase.h"
 #include "typedWritableReferenceCount.h"
+#include "namable.h"
+#include "graphicsStateGuardianBase.h"
 #include "internalName.h"
 
 ////////////////////////////////////////////////////////////////////

+ 0 - 24
panda/src/gsgbase/graphicsStateGuardianBase.h

@@ -210,30 +210,6 @@ public:
 
   virtual CoordinateSystem get_internal_coordinate_system() const=0;
 
-  virtual void issue_transform(const TransformState *) { }
-  virtual void issue_alpha_test(const AlphaTestAttrib *) { }
-  virtual void issue_color_scale(const ColorScaleAttrib *) { }
-  virtual void issue_color(const ColorAttrib *) { }
-  virtual void issue_tex_matrix(const TexMatrixAttrib *) { }
-  virtual void issue_texture(const TextureAttrib *) { }
-  virtual void issue_light(const LightAttrib *) { }
-  virtual void issue_material(const MaterialAttrib *) { }
-  virtual void issue_render_mode(const RenderModeAttrib *) { }
-  virtual void issue_antialias(const AntialiasAttrib *) { }
-  virtual void issue_rescale_normal(const RescaleNormalAttrib *) { }
-  virtual void issue_color_write(const ColorWriteAttrib *) { }
-  virtual void issue_depth_test(const DepthTestAttrib *) { }
-  virtual void issue_depth_write(const DepthWriteAttrib *) { }
-  virtual void issue_cull_face(const CullFaceAttrib *) { }
-  virtual void issue_transparency(const TransparencyAttrib *) { }
-  virtual void issue_fog(const FogAttrib *) { }
-  virtual void issue_depth_offset(const DepthOffsetAttrib *) { }
-  virtual void issue_color_blend(const ColorBlendAttrib *) { }
-  virtual void issue_tex_gen(const TexGenAttrib *) { }
-  virtual void issue_shader(const ShaderAttrib *) { }
-  virtual void issue_clip_plane(const ClipPlaneAttrib *) { }
-  virtual void issue_shade_model(const ShadeModelAttrib *) { }
-
   virtual void bind_light(PointLight *light_obj, const NodePath &light, 
                           int light_id) { }
   virtual void bind_light(DirectionalLight *light_obj, const NodePath &light,

+ 13 - 14
panda/src/pgraph/alphaTestAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "alphaTestAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -38,20 +39,6 @@ make(PandaCompareFunc mode, float reference_value) {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: AlphaTestAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void AlphaTestAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_alpha_test(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: AlphaTestAttrib::output
 //       Access: Public, Virtual
@@ -107,6 +94,18 @@ make_default_impl() const {
   return new AlphaTestAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: AlphaTestAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void AlphaTestAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_alpha_test = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: AlphaTestAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -41,8 +41,8 @@ PUBLISHED:
   INLINE PandaCompareFunc get_mode() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/antialiasAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "antialiasAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -68,20 +69,6 @@ make(unsigned short mode) {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: AntialiasAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void AntialiasAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_antialias(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: AntialiasAttrib::output
 //       Access: Public, Virtual
@@ -219,6 +206,18 @@ make_default_impl() const {
   return new AntialiasAttrib(M_none);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: AntialiasAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void AntialiasAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_antialias = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: AntialiasAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -58,8 +58,8 @@ PUBLISHED:
   INLINE unsigned short get_mode_quality() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 74 - 0
panda/src/pgraph/attribSlots.I

@@ -0,0 +1,74 @@
+// Filename: attribSlots.I
+// Created by:  jyelon (01Sep05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: AttribSlots::clear_to_zero
+//       Access: Private
+//  Description: clears all values to zero.
+////////////////////////////////////////////////////////////////////
+INLINE void AttribSlots::
+clear_to_zero() {
+  _alpha_test     = NULL;
+  _antialias      = NULL;
+  _clip_plane     = NULL;
+  _color          = NULL;
+  _color_blend    = NULL;
+  _color_scale    = NULL;
+  _color_write    = NULL;
+  _cull_bin       = NULL;
+  _cull_face      = NULL;
+  _depth_offset   = NULL;
+  _depth_test     = NULL;
+  _depth_write    = NULL;
+  _fog            = NULL;
+  _light          = NULL;
+  _material       = NULL;
+  _render_mode    = NULL;
+  _rescale_normal = NULL;
+  _shade_model    = NULL;
+  _shader         = NULL;
+  _tex_gen        = NULL;
+  _tex_matrix     = NULL;
+  _texture        = NULL;
+  _transparency   = NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AttribSlots::get_defaults
+//       Access: Public
+//  Description: Returns a set of slots containing all the default
+//               attribute values, as defined by make_default_impl.
+////////////////////////////////////////////////////////////////////
+INLINE const AttribSlots &AttribSlots::
+get_defaults() {
+  if (_defvals._alpha_test == 0) {
+    initialize_defvals();
+  }
+  return _defvals;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AttribSlots::clear_to_defaults
+//       Access: Private
+//  Description: clears all values to their default values.
+////////////////////////////////////////////////////////////////////
+INLINE void AttribSlots::
+clear_to_defaults() {
+  (*this) = get_defaults();
+}

+ 231 - 0
panda/src/pgraph/attribSlots.cxx

@@ -0,0 +1,231 @@
+// Filename: attribSlots.h
+// Created by:  jyelon (01Sep05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "attribSlots.h"
+#include "renderAttrib.h"
+
+AttribSlots AttribSlots::_defvals;
+
+////////////////////////////////////////////////////////////////////
+//     Function: AttribSlots::clear_to_defaults
+//       Access: Private
+//  Description: clears all values to their initial defaults.
+////////////////////////////////////////////////////////////////////
+void AttribSlots::
+initialize_defvals() {
+
+  // Step one. Fill slots with any object of right type.
+  // the actual value is totally irrelevant.
+
+  _defvals._alpha_test     = DCAST(AlphaTestAttrib,AlphaTestAttrib::make(AlphaTestAttrib::M_none, 0.0));
+  _defvals._antialias      = DCAST(AntialiasAttrib,AntialiasAttrib::make(AntialiasAttrib::M_none));
+  _defvals._clip_plane     = DCAST(ClipPlaneAttrib,ClipPlaneAttrib::make_all_off());
+  _defvals._color          = DCAST(ColorAttrib,ColorAttrib::make_off());
+  _defvals._color_blend    = DCAST(ColorBlendAttrib,ColorBlendAttrib::make_off());
+  _defvals._color_scale    = DCAST(ColorScaleAttrib,ColorScaleAttrib::make_off());
+  _defvals._color_write    = DCAST(ColorWriteAttrib,ColorWriteAttrib::make(ColorWriteAttrib::M_on));
+  _defvals._cull_bin       = DCAST(CullBinAttrib,CullBinAttrib::make("",0));
+  _defvals._cull_face      = DCAST(CullFaceAttrib,CullFaceAttrib::make(CullFaceAttrib::M_cull_counter_clockwise));
+  _defvals._depth_offset   = DCAST(DepthOffsetAttrib,DepthOffsetAttrib::make(0));
+  _defvals._depth_test     = DCAST(DepthTestAttrib,DepthTestAttrib::make(DepthTestAttrib::M_none));
+  _defvals._depth_write    = DCAST(DepthWriteAttrib,DepthWriteAttrib::make(DepthWriteAttrib::M_on));
+  _defvals._fog            = DCAST(FogAttrib,FogAttrib::make_off());
+  _defvals._light          = DCAST(LightAttrib,LightAttrib::make_all_off());
+  _defvals._material       = DCAST(MaterialAttrib,MaterialAttrib::make_off());
+  _defvals._render_mode    = DCAST(RenderModeAttrib,RenderModeAttrib::make(RenderModeAttrib::M_unchanged));
+  _defvals._rescale_normal = DCAST(RescaleNormalAttrib,RescaleNormalAttrib::make_default());
+  _defvals._shade_model    = DCAST(ShadeModelAttrib,ShadeModelAttrib::make(ShadeModelAttrib::M_smooth));
+  _defvals._shader         = DCAST(ShaderAttrib,ShaderAttrib::make_off());
+  _defvals._tex_gen        = DCAST(TexGenAttrib,TexGenAttrib::make());
+  _defvals._tex_matrix     = DCAST(TexMatrixAttrib,TexMatrixAttrib::make());
+  _defvals._texture        = DCAST(TextureAttrib,TextureAttrib::make_all_off());
+  _defvals._transparency   = DCAST(TransparencyAttrib,TransparencyAttrib::make(TransparencyAttrib::M_none));
+  
+  // Step two. Replace each with make_default_impl.
+  
+  _defvals._alpha_test     = DCAST(AlphaTestAttrib,_defvals._alpha_test->make_default());
+  _defvals._antialias      = DCAST(AntialiasAttrib,_defvals._antialias->make_default());
+  _defvals._clip_plane     = DCAST(ClipPlaneAttrib,_defvals._clip_plane->make_default());
+  _defvals._color          = DCAST(ColorAttrib,_defvals._color->make_default());
+  _defvals._color_blend    = DCAST(ColorBlendAttrib,_defvals._color_blend->make_default());
+  _defvals._color_scale    = DCAST(ColorScaleAttrib,_defvals._color_scale->make_default());
+  _defvals._color_write    = DCAST(ColorWriteAttrib,_defvals._color_write->make_default());
+  _defvals._cull_bin       = DCAST(CullBinAttrib,_defvals._cull_bin->make_default());
+  _defvals._cull_face      = DCAST(CullFaceAttrib,_defvals._cull_face->make_default());
+  _defvals._depth_offset   = DCAST(DepthOffsetAttrib,_defvals._depth_offset->make_default());
+  _defvals._depth_test     = DCAST(DepthTestAttrib,_defvals._depth_test->make_default());
+  _defvals._depth_write    = DCAST(DepthWriteAttrib,_defvals._depth_write->make_default());
+  _defvals._fog            = DCAST(FogAttrib,_defvals._fog->make_default());
+  _defvals._light          = DCAST(LightAttrib,_defvals._light->make_default());
+  _defvals._material       = DCAST(MaterialAttrib,_defvals._material->make_default());
+  _defvals._render_mode    = DCAST(RenderModeAttrib,_defvals._render_mode->make_default());
+  _defvals._rescale_normal = DCAST(RescaleNormalAttrib,_defvals._rescale_normal->make_default());
+  _defvals._shade_model    = DCAST(ShadeModelAttrib,_defvals._shade_model->make_default());
+  _defvals._shader         = DCAST(ShaderAttrib,_defvals._shader->make_default());
+  _defvals._tex_gen        = DCAST(TexGenAttrib,_defvals._tex_gen->make_default());
+  _defvals._tex_matrix     = DCAST(TexMatrixAttrib,_defvals._tex_matrix->make_default());
+  _defvals._texture        = DCAST(TextureAttrib,_defvals._texture->make_default());
+  _defvals._transparency   = DCAST(TransparencyAttrib,_defvals._transparency->make_default());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AttribSlots::Default Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+AttribSlots::
+AttribSlots() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AttribSlots::Copy Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+AttribSlots::
+AttribSlots(const AttribSlots &copy) :
+  _alpha_test(copy._alpha_test),
+  _antialias(copy._antialias),
+  _clip_plane(copy._clip_plane),
+  _color(copy._color),
+  _color_blend(copy._color_blend),
+  _color_scale(copy._color_scale),
+  _color_write(copy._color_write),
+  _cull_bin(copy._cull_bin),
+  _cull_face(copy._cull_face),
+  _depth_offset(copy._depth_offset),
+  _depth_test(copy._depth_test),
+  _depth_write(copy._depth_write),
+  _fog(copy._fog),
+  _light(copy._light),
+  _material(copy._material),
+  _render_mode(copy._render_mode),
+  _rescale_normal(copy._rescale_normal),
+  _shade_model(copy._shade_model),
+  _shader(copy._shader),
+  _tex_gen(copy._tex_gen),
+  _tex_matrix(copy._tex_matrix),
+  _texture(copy._texture),
+  _transparency(copy._transparency)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AttribSlots::Copy Assignment Operator
+//       Access: Public
+//  Description: copy all the slots from source.
+////////////////////////////////////////////////////////////////////
+void AttribSlots::
+operator =(const AttribSlots &src) {
+  _alpha_test     = src._alpha_test;
+  _antialias      = src._antialias;
+  _clip_plane     = src._clip_plane;
+  _color          = src._color;
+  _color_blend    = src._color_blend;
+  _color_scale    = src._color_scale;
+  _color_write    = src._color_write;
+  _cull_bin       = src._cull_bin;
+  _cull_face      = src._cull_face;
+  _depth_offset   = src._depth_offset;
+  _depth_test     = src._depth_test;
+  _depth_write    = src._depth_write;
+  _fog            = src._fog;
+  _light          = src._light;
+  _material       = src._material;
+  _render_mode    = src._render_mode;
+  _rescale_normal = src._rescale_normal;
+  _shade_model    = src._shade_model;
+  _shader         = src._shader;
+  _tex_gen        = src._tex_gen;
+  _tex_matrix     = src._tex_matrix;
+  _texture        = src._texture;
+  _transparency   = src._transparency;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AttribSlots::get_slot
+//       Access: Public
+//  Description: fetch the contents of the nth slot.
+////////////////////////////////////////////////////////////////////
+const RenderAttrib *AttribSlots::
+get_slot(int n) const {
+  switch(n) {
+  case  0: return DCAST(RenderAttrib, _alpha_test);
+  case  1: return DCAST(RenderAttrib, _antialias);
+  case  2: return DCAST(RenderAttrib, _clip_plane);
+  case  3: return DCAST(RenderAttrib, _color);
+  case  4: return DCAST(RenderAttrib, _color_blend);
+  case  5: return DCAST(RenderAttrib, _color_scale);
+  case  6: return DCAST(RenderAttrib, _color_write);
+  case  7: return DCAST(RenderAttrib, _cull_bin);
+  case  8: return DCAST(RenderAttrib, _cull_face);
+  case  9: return DCAST(RenderAttrib, _depth_offset);
+  case 10: return DCAST(RenderAttrib, _depth_test);
+  case 11: return DCAST(RenderAttrib, _depth_write);
+  case 12: return DCAST(RenderAttrib, _fog);
+  case 13: return DCAST(RenderAttrib, _light);
+  case 14: return DCAST(RenderAttrib, _material);
+  case 15: return DCAST(RenderAttrib, _render_mode);
+  case 16: return DCAST(RenderAttrib, _rescale_normal);
+  case 17: return DCAST(RenderAttrib, _shade_model);
+  case 18: return DCAST(RenderAttrib, _shader);
+  case 19: return DCAST(RenderAttrib, _tex_gen);
+  case 20: return DCAST(RenderAttrib, _tex_matrix);
+  case 21: return DCAST(RenderAttrib, _texture);
+  case 22: return DCAST(RenderAttrib, _transparency);
+  default:
+    nassertr(false, NULL);
+    return NULL;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AttribSlots::set_slot
+//       Access: Public
+//  Description: set the contents of the nth slot.
+////////////////////////////////////////////////////////////////////
+void AttribSlots::
+set_slot(int n, const RenderAttrib *val) {
+  switch(n) {
+  case  0: _alpha_test     = DCAST(AlphaTestAttrib, val);     break;
+  case  1: _antialias      = DCAST(AntialiasAttrib, val);     break;
+  case  2: _clip_plane     = DCAST(ClipPlaneAttrib, val);     break;
+  case  3: _color          = DCAST(ColorAttrib, val);         break;
+  case  4: _color_blend    = DCAST(ColorBlendAttrib, val);    break;
+  case  5: _color_scale    = DCAST(ColorScaleAttrib, val);    break;
+  case  6: _color_write    = DCAST(ColorWriteAttrib, val);    break;
+  case  7: _cull_bin       = DCAST(CullBinAttrib, val);       break;
+  case  8: _cull_face      = DCAST(CullFaceAttrib, val);      break;
+  case  9: _depth_offset   = DCAST(DepthOffsetAttrib, val);   break;
+  case 10: _depth_test     = DCAST(DepthTestAttrib, val);     break;
+  case 11: _depth_write    = DCAST(DepthWriteAttrib, val);    break;
+  case 12: _fog            = DCAST(FogAttrib, val);           break;
+  case 13: _light          = DCAST(LightAttrib, val);         break;
+  case 14: _material       = DCAST(MaterialAttrib, val);      break;
+  case 15: _render_mode    = DCAST(RenderModeAttrib, val);    break;
+  case 16: _rescale_normal = DCAST(RescaleNormalAttrib, val); break;
+  case 17: _shade_model    = DCAST(ShadeModelAttrib, val);    break;
+  case 18: _shader         = DCAST(ShaderAttrib, val);        break;
+  case 19: _tex_gen        = DCAST(TexGenAttrib, val);        break;
+  case 20: _tex_matrix     = DCAST(TexMatrixAttrib, val);     break;
+  case 21: _texture        = DCAST(TextureAttrib, val);       break;
+  case 22: _transparency   = DCAST(TransparencyAttrib, val);  break;
+  default: nassertv(false);
+  }
+}
+

+ 105 - 0
panda/src/pgraph/attribSlots.h

@@ -0,0 +1,105 @@
+// Filename: attribSlots.h
+// Created by:  jyelon (01Sep05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef ATTRIBSLOTS_H
+#define ATTRIBSLOTS_H
+
+#include "pandabase.h"
+#include "typedWritableReferenceCount.h"
+#include "pointerTo.h"
+
+#include "renderAttrib.h"
+#include "alphaTestAttrib.h"
+#include "antialiasAttrib.h"
+#include "clipPlaneAttrib.h"
+#include "colorAttrib.h"
+#include "colorBlendAttrib.h"
+#include "colorScaleAttrib.h"
+#include "colorWriteAttrib.h"
+#include "cullBinAttrib.h"
+#include "cullFaceAttrib.h"
+#include "depthOffsetAttrib.h"
+#include "depthTestAttrib.h"
+#include "depthWriteAttrib.h"
+#include "fogAttrib.h"
+#include "lightAttrib.h"
+#include "materialAttrib.h"
+#include "renderModeAttrib.h"
+#include "rescaleNormalAttrib.h"
+#include "shadeModelAttrib.h"
+#include "shaderAttrib.h"
+#include "texMatrixAttrib.h"
+#include "texGenAttrib.h"
+#include "textureAttrib.h"
+#include "transparencyAttrib.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : AttribSlots
+// Description : This is a very simple class: an object full of
+//               render attributes, one per attrib type.
+////////////////////////////////////////////////////////////////////
+
+class EXPCL_PANDA AttribSlots
+{
+ public:
+  CPT(AlphaTestAttrib)       _alpha_test;
+  CPT(AntialiasAttrib)       _antialias;
+  CPT(ClipPlaneAttrib)       _clip_plane;
+  CPT(ColorAttrib)           _color;
+  CPT(ColorBlendAttrib)      _color_blend;
+  CPT(ColorScaleAttrib)      _color_scale;
+  CPT(ColorWriteAttrib)      _color_write;
+  CPT(CullBinAttrib)         _cull_bin;
+  CPT(CullFaceAttrib)        _cull_face;
+  CPT(DepthOffsetAttrib)     _depth_offset;
+  CPT(DepthTestAttrib)       _depth_test;
+  CPT(DepthWriteAttrib)      _depth_write;
+  CPT(FogAttrib)             _fog;
+  CPT(LightAttrib)           _light;
+  CPT(MaterialAttrib)        _material;
+  CPT(RenderModeAttrib)      _render_mode;
+  CPT(RescaleNormalAttrib)   _rescale_normal;
+  CPT(ShadeModelAttrib)      _shade_model;
+  CPT(ShaderAttrib)          _shader;
+  CPT(TexGenAttrib)          _tex_gen;
+  CPT(TexMatrixAttrib)       _tex_matrix;
+  CPT(TextureAttrib)         _texture;
+  CPT(TransparencyAttrib)    _transparency;
+  
+ public:
+  AttribSlots();
+  AttribSlots(const AttribSlots &copy);
+  INLINE void clear_to_zero();
+  INLINE void clear_to_defaults();
+  void operator =(const AttribSlots &src);
+  INLINE static const AttribSlots &get_defaults();
+
+ public:
+  // Each "array" reference requires a switch and a DCAST, so it's not overly fast.
+  enum { slot_count=23 };
+  const RenderAttrib *get_slot(int n) const;
+  void set_slot(int n, const RenderAttrib *attrib);
+  
+ private:
+  static AttribSlots _defvals;
+  static void initialize_defvals();
+};
+
+#include "attribSlots.I"
+
+#endif /* ATTRIBSLOTS_H */

+ 13 - 14
panda/src/pgraph/clipPlaneAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "clipPlaneAttrib.h"
+#include "attribSlots.h"
 #include "pandaNode.h"
 #include "graphicsStateGuardianBase.h"
 #include "bamReader.h"
@@ -593,20 +594,6 @@ compose_off(const RenderAttrib *other) const {
   return return_new(new_attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: ClipPlaneAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void ClipPlaneAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_clip_plane(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: ClipPlaneAttrib::output
 //       Access: Public, Virtual
@@ -895,6 +882,18 @@ make_default_impl() const {
   return new ClipPlaneAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ClipPlaneAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void ClipPlaneAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_clip_plane = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ClipPlaneAttrib::sort_on_planes
 //       Access: Private

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

@@ -97,8 +97,8 @@ PUBLISHED:
 
 public:
   CPT(RenderAttrib) compose_off(const RenderAttrib *other) const;
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/colorAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "colorAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -64,20 +65,6 @@ make_off() {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: ColorAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void ColorAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_color(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorAttrib::output
 //       Access: Public, Virtual
@@ -145,6 +132,18 @@ make_default_impl() const {
   return new ColorAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ColorAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void ColorAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_color = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorAttrib::quantize_color
 //       Access: Private

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

@@ -50,8 +50,8 @@ PUBLISHED:
   INLINE const Colorf &get_color() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/colorBlendAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "colorBlendAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -68,20 +69,6 @@ make(ColorBlendAttrib::Mode mode,
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: ColorBlendAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void ColorBlendAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_color_blend(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorBlendAttrib::output
 //       Access: Public, Virtual
@@ -152,6 +139,18 @@ make_default_impl() const {
   return new ColorBlendAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void ColorBlendAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_color_blend = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorBlendAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -94,8 +94,8 @@ PUBLISHED:
   INLINE static bool involves_color_scale(Operand operand);
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/colorScaleAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "colorScaleAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -87,20 +88,6 @@ set_scale(const LVecBase4f &scale) const {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: ColorScaleAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void ColorScaleAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_color_scale(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorScaleAttrib::lower_attrib_can_override
 //       Access: Public, Virtual
@@ -270,6 +257,18 @@ make_default_impl() const {
   return new ColorScaleAttrib(false, LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f));
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void ColorScaleAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_color_scale = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorScaleAttrib::quantize_scale
 //       Access: Private

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

@@ -48,9 +48,9 @@ PUBLISHED:
   CPT(RenderAttrib) set_scale(const LVecBase4f &scale) const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual bool lower_attrib_can_override() const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/colorWriteAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "colorWriteAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -37,20 +38,6 @@ make(ColorWriteAttrib::Mode mode) {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: ColorWriteAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void ColorWriteAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_color_write(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorWriteAttrib::output
 //       Access: Public, Virtual
@@ -107,6 +94,18 @@ make_default_impl() const {
   return new ColorWriteAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ColorWriteAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void ColorWriteAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_color_write = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ColorWriteAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -48,8 +48,8 @@ PUBLISHED:
   INLINE Mode get_mode() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 0
panda/src/pgraph/cullBinAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "cullBinAttrib.h"
+#include "attribSlots.h"
 #include "bamReader.h"
 #include "bamWriter.h"
 #include "datagram.h"
@@ -99,6 +100,18 @@ make_default_impl() const {
   return new CullBinAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CullBinAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void CullBinAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_cull_bin = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CullBinAttrib::register_with_read_factory
 //       Access: Public, Static

+ 1 - 0
panda/src/pgraph/cullBinAttrib.h

@@ -43,6 +43,7 @@ PUBLISHED:
 
 public:
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/cullFaceAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "cullFaceAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -103,20 +104,6 @@ get_effective_mode() const {
   return M_cull_none;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: CullFaceAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void CullFaceAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_cull_face(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CullFaceAttrib::output
 //       Access: Public, Virtual
@@ -256,6 +243,18 @@ make_default_impl() const {
   return new CullFaceAttrib(M_cull_clockwise, false);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CullFaceAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void CullFaceAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_cull_face = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CullFaceAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -51,8 +51,8 @@ PUBLISHED:
   Mode get_effective_mode() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/depthOffsetAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "depthOffsetAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -39,20 +40,6 @@ make(int offset) {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DepthOffsetAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void DepthOffsetAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_depth_offset(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DepthOffsetAttrib::output
 //       Access: Public, Virtual
@@ -147,6 +134,18 @@ make_default_impl() const {
   return new DepthOffsetAttrib(0);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void DepthOffsetAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_depth_offset = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DepthOffsetAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -64,8 +64,8 @@ PUBLISHED:
   INLINE int get_offset() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/depthTestAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "depthTestAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -37,20 +38,6 @@ make(DepthTestAttrib::PandaCompareFunc mode) {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DepthTestAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void DepthTestAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_depth_test(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DepthTestAttrib::output
 //       Access: Public, Virtual
@@ -100,6 +87,18 @@ make_default_impl() const {
   return new DepthTestAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DepthTestAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void DepthTestAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_depth_test = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DepthTestAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -39,8 +39,8 @@ PUBLISHED:
   INLINE PandaCompareFunc get_mode() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/depthWriteAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "depthWriteAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -37,20 +38,6 @@ make(DepthWriteAttrib::Mode mode) {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DepthWriteAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void DepthWriteAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_depth_write(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DepthWriteAttrib::output
 //       Access: Public, Virtual
@@ -107,6 +94,18 @@ make_default_impl() const {
   return new DepthWriteAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DepthWriteAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void DepthWriteAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_depth_write = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DepthWriteAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -45,8 +45,8 @@ PUBLISHED:
   INLINE Mode get_mode() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/fogAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "fogAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "bamReader.h"
 #include "bamWriter.h"
@@ -50,20 +51,6 @@ make_off() {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: FogAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void FogAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_fog(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: FogAttrib::output
 //       Access: Public, Virtual
@@ -124,6 +111,18 @@ make_default_impl() const {
   return new FogAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void FogAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_fog = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: FogAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -40,8 +40,8 @@ PUBLISHED:
   INLINE Fog *get_fog() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/lightAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "lightAttrib.h"
+#include "attribSlots.h"
 #include "ambientLight.h"
 #include "pandaNode.h"
 #include "nodePath.h"
@@ -572,20 +573,6 @@ get_most_important_light() const {
   return best;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: LightAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void LightAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_light(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: LightAttrib::output
 //       Access: Public, Virtual
@@ -874,6 +861,18 @@ make_default_impl() const {
   return new LightAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: LightAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void LightAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_light = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LightAttrib::sort_on_lights
 //       Access: Private

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

@@ -95,8 +95,8 @@ PUBLISHED:
   NodePath get_most_important_light() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/materialAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "materialAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "bamReader.h"
 #include "bamWriter.h"
@@ -50,20 +51,6 @@ make_off() {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: MaterialAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void MaterialAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_material(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: MaterialAttrib::output
 //       Access: Public, Virtual
@@ -124,6 +111,18 @@ make_default_impl() const {
   return new MaterialAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: MaterialAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void MaterialAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_material = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: MaterialAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -43,8 +43,8 @@ PUBLISHED:
   INLINE const Material *get_material() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

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

@@ -2,6 +2,7 @@
 #include "ambientLight.cxx"
 #include "antialiasAttrib.cxx"
 #include "auxSceneData.cxx"
+#include "attribSlots.cxx"
 #include "bamFile.cxx"
 #include "billboardEffect.cxx"
 #include "binCullHandler.cxx"

+ 1 - 13
panda/src/pgraph/renderAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "renderAttrib.h"
+#include "attribSlots.h"
 #include "bamReader.h"
 #include "indent.h"
 #include "config_pgraph.h"
@@ -92,19 +93,6 @@ RenderAttrib::
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: RenderAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void RenderAttrib::
-issue(GraphicsStateGuardianBase *) const {
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: RenderAttrib::lower_attrib_can_override
 //       Access: Public, Virtual

+ 2 - 1
panda/src/pgraph/renderAttrib.h

@@ -25,6 +25,7 @@
 #include "pointerTo.h"
 #include "pset.h"
 
+class AttribSlots;
 class GraphicsStateGuardianBase;
 
 ////////////////////////////////////////////////////////////////////
@@ -67,10 +68,10 @@ public:
   INLINE CPT(RenderAttrib) compose(const RenderAttrib *other) const;
   INLINE CPT(RenderAttrib) invert_compose(const RenderAttrib *other) const;
   INLINE CPT(RenderAttrib) make_default() const;
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual bool lower_attrib_can_override() const;
 
   INLINE bool always_reissue() const;
+  virtual void store_into_slot(AttribSlots *slots) const=0;
 
 PUBLISHED:
   INLINE int compare_to(const RenderAttrib &other) const;

+ 13 - 14
panda/src/pgraph/renderModeAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "renderModeAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -54,20 +55,6 @@ make(RenderModeAttrib::Mode mode, float thickness, bool perspective) {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: RenderModeAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void RenderModeAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_render_mode(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: RenderModeAttrib::output
 //       Access: Public, Virtual
@@ -177,6 +164,18 @@ make_default_impl() const {
   return new RenderModeAttrib(M_filled, 1.0f, false);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: RenderModeAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void RenderModeAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_render_mode = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: RenderModeAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -53,8 +53,8 @@ PUBLISHED:
   INLINE int get_geom_rendering(int geom_rendering) const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 25 - 134
panda/src/pgraph/renderState.cxx

@@ -252,6 +252,24 @@ make(const RenderAttrib * const *attrib, int num_attribs, int override) {
   return return_new(state);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: RenderState::make
+//       Access: Published, Static
+//  Description: Returns a RenderState made from the specified slots.
+////////////////////////////////////////////////////////////////////
+CPT(RenderState) RenderState::
+make(const AttribSlots *slots, int override) {
+  RenderState *state = new RenderState;
+  for (int i = 0; i < AttribSlots::slot_count; i++) {
+    const RenderAttrib *attrib = slots->get_slot(i);
+    if (attrib != 0) {
+      state->_attributes.push_back(Attribute(attrib, override));
+    }
+  }
+  state->_attributes.reserve(state->_attributes.size());
+  return return_new(state);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: RenderState::compose
 //       Access: Published
@@ -956,143 +974,16 @@ get_geom_rendering(int geom_rendering) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: RenderState::issue_delta_modify
-//       Access: Public
-//  Description: This is intended to be called only from
-//               GraphicsStateGuardian::modify_state().  It calls
-//               issue() for each attribute given in the other state
-//               that differs from the current state (which is assumed
-//               to represent the GSG's current state).  Returns the
-//               RenderState representing the newly composed result.
-////////////////////////////////////////////////////////////////////
-CPT(RenderState) RenderState::
-issue_delta_modify(const RenderState *other, 
-                   GraphicsStateGuardianBase *gsg) const {
-  if (other->is_empty()) {
-    // If the other state is empty, that's a trivial special case.
-    return this;
-  }
-
-  // First, build a new Attributes member that represents the union of
-  // this one and that one.
-  Attributes::const_iterator ai = _attributes.begin();
-  Attributes::const_iterator bi = other->_attributes.begin();
-
-  // Create a new RenderState that will hold the result.
-  RenderState *new_state = new RenderState;
-  back_insert_iterator<Attributes> result = 
-    back_inserter(new_state->_attributes);
-
-  bool any_changed = false;
-
-  while (ai != _attributes.end() && bi != other->_attributes.end()) {
-    if ((*ai) < (*bi)) {
-      // Here is an attribute that we have in the original, which is
-      // not present in the secondary.  Leave it alone.
-      *result = *ai;
-      ++ai;
-      ++result;
-    } else if ((*bi) < (*ai)) {
-      // Here is a new attribute we have in the secondary, that was
-      // not present in the original.  Issue the new one, and save it.
-      (*bi)._attrib->issue(gsg);
-      *result = *bi;
-      ++bi;
-      ++result;
-      any_changed = true;
-    } else {
-      // Here is an attribute we have in both.  Issue the new one if
-      // it's different, and save it.
-      if ((*ai)._attrib != (*bi)._attrib) {
-        any_changed = true;
-        (*bi)._attrib->issue(gsg);
-      }
-      *result = *bi;
-      ++ai;
-      ++bi;
-      ++result;
-    }
-  }
-
-  while (ai != _attributes.end()) {
-    *result = *ai;
-    ++ai;
-    ++result;
-  }
-
-  while (bi != other->_attributes.end()) {
-    (*bi)._attrib->issue(gsg);
-    *result = *bi;
-    ++bi;
-    ++result;
-    any_changed = true;
-  }
-
-  if (any_changed) {
-    return return_new(new_state);
-  } else {
-    delete new_state;
-    return this;
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: RenderState::issue_delta_set
+//     Function: RenderState::store_into_slots
 //       Access: Public
-//  Description: This is intended to be called only from
-//               GraphicsStateGuardian::set_state().  It calls issue()
-//               for each attribute given in the other state that
-//               differs from the current state (which is assumed to
-//               represent the GSG's current state).  Returns the
-//               RenderState representing the newly composed result
-//               (which will be the same as other).
+//  Description: Convert the attribute list into an AttribSlots.
 ////////////////////////////////////////////////////////////////////
-CPT(RenderState) RenderState::
-issue_delta_set(const RenderState *other, 
-                GraphicsStateGuardianBase *gsg) const {
-  if (other == this) {
-    // If the state doesn't change, that's a trivial special case.
-    return other;
-  }
-
-  Attributes::const_iterator ai = _attributes.begin();
-  Attributes::const_iterator bi = other->_attributes.begin();
-
-  while (ai != _attributes.end() && bi != other->_attributes.end()) {
-    if ((*ai) < (*bi)) {
-      // Here is an attribute that we have in the original, which is
-      // not present in the secondary.  Issue the default state instead.
-      (*ai)._attrib->make_default()->issue(gsg);
-      ++ai;
-
-    } else if ((*bi) < (*ai)) {
-      // Here is a new attribute we have in the secondary, that was
-      // not present in the original.  Issue the new one.
-      (*bi)._attrib->issue(gsg);
-      ++bi;
-
-    } else {
-      // Here is an attribute we have in both.  Issue the new one if
-      // it's different.
-      if ((*ai)._attrib != (*bi)._attrib) {
-        (*bi)._attrib->issue(gsg);
-      }
-      ++ai;
-      ++bi;
-    }
-  }
-
-  while (ai != _attributes.end()) {
-    (*ai)._attrib->make_default()->issue(gsg);
-    ++ai;
-  }
-
-  while (bi != other->_attributes.end()) {
-    (*bi)._attrib->issue(gsg);
-    ++bi;
+void RenderState::
+store_into_slots(AttribSlots *output) const {
+  Attributes::const_iterator ai;
+  for (ai = _attributes.begin(); ai != _attributes.end(); ai++) {
+    (*ai)._attrib->store_into_slot(output);
   }
-
-  return other;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 4 - 6
panda/src/pgraph/renderState.h

@@ -90,7 +90,8 @@ PUBLISHED:
                                const RenderAttrib *attrib4, int override = 0);
   static CPT(RenderState) make(const RenderAttrib * const *attrib,
                                int num_attribs, int override = 0);
-
+  static CPT(RenderState) make(const AttribSlots *slots, int override = 0);
+  
   CPT(RenderState) compose(const RenderState *other) const;
   CPT(RenderState) invert_compose(const RenderState *other) const;
 
@@ -141,11 +142,8 @@ PUBLISHED:
   int get_geom_rendering(int geom_rendering) const;
 
 public:
-  CPT(RenderState) issue_delta_modify(const RenderState *other, 
-                                      GraphicsStateGuardianBase *gsg) const;
-  CPT(RenderState) issue_delta_set(const RenderState *other, 
-                                   GraphicsStateGuardianBase *gsg) const;
-
+  void store_into_slots(AttribSlots *slots) const;
+  
   static void bin_removed(int bin_index);
 
 private:

+ 13 - 14
panda/src/pgraph/rescaleNormalAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "rescaleNormalAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "string_utils.h"
 #include "dcast.h"
@@ -67,20 +68,6 @@ make_default() {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: RescaleNormalAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void RescaleNormalAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_rescale_normal(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: RescaleNormalAttrib::output
 //       Access: Public, Virtual
@@ -129,6 +116,18 @@ make_default_impl() const {
   return new RescaleNormalAttrib(M_none);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: RescaleNormalAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void RescaleNormalAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_rescale_normal = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: RescaleNormalAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -58,8 +58,8 @@ PUBLISHED:
   INLINE Mode get_mode() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/shadeModelAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "shadeModelAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -39,20 +40,6 @@ make(ShadeModelAttrib::Mode mode) {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: ShadeModelAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void ShadeModelAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_shade_model(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: ShadeModelAttrib::output
 //       Access: Public, Virtual
@@ -136,6 +123,18 @@ make_default_impl() const {
   return new ShadeModelAttrib(M_smooth);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ShadeModelAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void ShadeModelAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_shade_model = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ShadeModelAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -46,8 +46,8 @@ PUBLISHED:
   INLINE Mode get_mode() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/shaderAttrib.cxx

@@ -18,6 +18,7 @@
 
 #include "pandabase.h"
 #include "shaderAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "bamReader.h"
 #include "bamWriter.h"
@@ -51,20 +52,6 @@ make_off() {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: ShaderAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void ShaderAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_shader(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: ShaderAttrib::make_default_impl
 //       Access: Protected, Virtual
@@ -81,6 +68,18 @@ make_default_impl() const {
   return new ShaderAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ShaderAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void ShaderAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_shader = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ShaderAttrib::compare_to_impl
 //       Access: Protected, Virtual

+ 4 - 3
panda/src/pgraph/shaderAttrib.h

@@ -50,11 +50,12 @@ PUBLISHED:
 
   static void register_with_read_factory();
 
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
+public:
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
-   virtual RenderAttrib *make_default_impl() const;
-   virtual int compare_to_impl(const RenderAttrib *other) const;
+  virtual RenderAttrib *make_default_impl() const;
+  virtual int compare_to_impl(const RenderAttrib *other) const;
 
 private:
   PT(ShaderMode) _shader_mode;

+ 13 - 14
panda/src/pgraph/texGenAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "texGenAttrib.h"
+#include "attribSlots.h"
 #include "texturePool.h"
 #include "graphicsStateGuardianBase.h"
 #include "bamReader.h"
@@ -228,20 +229,6 @@ get_light(TextureStage *stage) const {
   return NodePath();
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: TexGenAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void TexGenAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_tex_gen(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TexGenAttrib::output
 //       Access: Public, Virtual
@@ -550,6 +537,18 @@ make_default_impl() const {
   return new TexGenAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TexGenAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void TexGenAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_tex_gen = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TexGenAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -73,8 +73,8 @@ public:
   typedef pset<TextureStage *> LightVectors;
   INLINE const LightVectors &get_light_vectors() const;
 
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/texMatrixAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "texMatrixAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -210,20 +211,6 @@ get_transform(TextureStage *stage) const {
   return TransformState::make_identity();
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: TexMatrixAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void TexMatrixAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_tex_matrix(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TexMatrixAttrib::output
 //       Access: Public, Virtual
@@ -439,6 +426,18 @@ make_default_impl() const {
   return new TexMatrixAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void TexMatrixAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_tex_matrix = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TexMatrixAttrib::rebuild_stage_list
 //       Access: Private

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

@@ -64,8 +64,8 @@ PUBLISHED:
   INLINE int get_geom_rendering(int geom_rendering) const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/textureAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "textureAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "bamReader.h"
 #include "bamWriter.h"
@@ -338,20 +339,6 @@ filter_to_max(int max_texture_stages) const {
   return tex_attrib;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: TextureAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////a////////////////////
-void TextureAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_texture(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureAttrib::output
 //       Access: Public, Virtual
@@ -650,6 +637,18 @@ make_default_impl() const {
   return new TextureAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TextureAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void TextureAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_texture = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -81,8 +81,8 @@ public:
   INLINE const Geom::ActiveTextureStages &get_on_stages() const;
   CPT(TextureAttrib) filter_to_max(int max_texture_stages) const;
 
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;

+ 13 - 14
panda/src/pgraph/transparencyAttrib.cxx

@@ -17,6 +17,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "transparencyAttrib.h"
+#include "attribSlots.h"
 #include "graphicsStateGuardianBase.h"
 #include "dcast.h"
 #include "bamReader.h"
@@ -37,20 +38,6 @@ make(TransparencyAttrib::Mode mode) {
   return return_new(attrib);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: TransparencyAttrib::issue
-//       Access: Public, Virtual
-//  Description: Calls the appropriate method on the indicated GSG
-//               to issue the graphics commands appropriate to the
-//               given attribute.  This is normally called
-//               (indirectly) only from
-//               GraphicsStateGuardian::set_state() or modify_state().
-////////////////////////////////////////////////////////////////////
-void TransparencyAttrib::
-issue(GraphicsStateGuardianBase *gsg) const {
-  gsg->issue_transparency(this);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: TransparencyAttrib::output
 //       Access: Public, Virtual
@@ -127,6 +114,18 @@ make_default_impl() const {
   return new TransparencyAttrib;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TransparencyAttrib::store_into_slot
+//       Access: Public, Virtual
+//  Description: When attribs are stored in a slot-based attrib array,
+//               this returns the index of the appropriate slot
+//               for this attrib type.
+////////////////////////////////////////////////////////////////////
+void TransparencyAttrib::
+store_into_slot(AttribSlots *slots) const {
+  slots->_transparency = this;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TransparencyAttrib::register_with_read_factory
 //       Access: Public, Static

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

@@ -61,8 +61,8 @@ PUBLISHED:
   INLINE Mode get_mode() const;
 
 public:
-  virtual void issue(GraphicsStateGuardianBase *gsg) const;
   virtual void output(ostream &out) const;
+  virtual void store_into_slot(AttribSlots *slots) const;
 
 protected:
   virtual int compare_to_impl(const RenderAttrib *other) const;