Browse Source

add several more pgraph attribs

David Rose 24 years ago
parent
commit
6bf66170ee
34 changed files with 2774 additions and 162 deletions
  1. 34 0
      panda/src/display/graphicsStateGuardian.cxx
  2. 1 0
      panda/src/display/graphicsStateGuardian.h
  3. 158 28
      panda/src/glgsg/glGraphicsStateGuardian.cxx
  4. 15 2
      panda/src/glgsg/glGraphicsStateGuardian.h
  5. 10 15
      panda/src/gsgbase/graphicsStateGuardianBase.h
  6. 94 76
      panda/src/pgraph/Sources.pp
  7. 40 0
      panda/src/pgraph/colorScaleAttrib.I
  8. 211 0
      panda/src/pgraph/colorScaleAttrib.cxx
  9. 83 0
      panda/src/pgraph/colorScaleAttrib.h
  10. 18 0
      panda/src/pgraph/config_pgraph.cxx
  11. 3 0
      panda/src/pgraph/cullBinManager.cxx
  12. 2 0
      panda/src/pgraph/cullTraverserData.cxx
  13. 40 0
      panda/src/pgraph/depthOffsetAttrib.I
  14. 206 0
      panda/src/pgraph/depthOffsetAttrib.cxx
  15. 106 0
      panda/src/pgraph/depthOffsetAttrib.h
  16. 51 0
      panda/src/pgraph/fogAttrib.I
  17. 196 0
      panda/src/pgraph/fogAttrib.cxx
  18. 83 0
      panda/src/pgraph/fogAttrib.h
  19. 1 1
      panda/src/pgraph/materialAttrib.I
  20. 6 1
      panda/src/pgraph/pgraph_composite1.cxx
  21. 4 4
      panda/src/pgraph/pgraph_composite2.cxx
  22. 1 0
      panda/src/pgraph/qpfindApproxPath.h
  23. 252 0
      panda/src/pgraph/qpfog.I
  24. 262 0
      panda/src/pgraph/qpfog.cxx
  25. 147 0
      panda/src/pgraph/qpfog.h
  26. 60 21
      panda/src/pgraph/qpnodePath.cxx
  27. 5 5
      panda/src/pgraph/qpnodePath.h
  28. 52 0
      panda/src/pgraph/renderModeAttrib.I
  29. 185 0
      panda/src/pgraph/renderModeAttrib.cxx
  30. 90 0
      panda/src/pgraph/renderModeAttrib.h
  31. 40 0
      panda/src/pgraph/texMatrixAttrib.I
  32. 207 0
      panda/src/pgraph/texMatrixAttrib.cxx
  33. 83 0
      panda/src/pgraph/texMatrixAttrib.h
  34. 28 9
      panda/src/testbed/pview.cxx

+ 34 - 0
panda/src/display/graphicsStateGuardian.cxx

@@ -22,6 +22,7 @@
 #include "textureContext.h"
 #include "textureContext.h"
 #include "renderBuffer.h"
 #include "renderBuffer.h"
 #include "colorAttrib.h"
 #include "colorAttrib.h"
+#include "colorScaleAttrib.h"
 #include "renderState.h"
 #include "renderState.h"
 #include "depthWriteAttrib.h"
 #include "depthWriteAttrib.h"
 #include "colorWriteAttrib.h"
 #include "colorWriteAttrib.h"
@@ -1018,6 +1019,39 @@ void GraphicsStateGuardian::
 issue_transform(const TransformState *) {
 issue_transform(const TransformState *) {
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::issue_color_scale
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardian::
+issue_color_scale(const ColorScaleAttrib *attrib) {
+  const LVecBase4f &scale = attrib->get_scale();
+
+  // For now, we set a full-featured matrix, even though we only use
+  // the scale part of it.  Soon we will strip this down.
+  LVecBase3f color_scale(scale[0], scale[1], scale[2]);
+  float alpha_scale = scale[3];
+
+  _current_color_mat = LMatrix4f::scale_mat(color_scale);
+  _current_alpha_offset= 0.0f;
+  _current_alpha_scale = alpha_scale;
+
+  if (color_scale == LVecBase3f(1.0f, 1.0f, 1.0f)) {
+    _color_transform_enabled = false;
+  } else {
+    _color_transform_enabled = true;
+  }
+
+  if (_current_alpha_scale == 1.0f) {
+    _alpha_transform_enabled = false;
+  } else {
+    _alpha_transform_enabled = true;
+  }
+
+  _issued_color_stale = _has_scene_graph_color;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::issue_color
 //     Function: GraphicsStateGuardian::issue_color
 //       Access: Public, Virtual
 //       Access: Public, Virtual

+ 1 - 0
panda/src/display/graphicsStateGuardian.h

@@ -179,6 +179,7 @@ public:
   INLINE void clear_cached_state(void) { _state.clear(); };  
   INLINE void clear_cached_state(void) { _state.clear(); };  
 
 
   virtual void issue_transform(const TransformState *transform);
   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_color(const ColorAttrib *attrib);
 
 
 protected:
 protected:

+ 158 - 28
panda/src/glgsg/glGraphicsStateGuardian.cxx

@@ -71,8 +71,15 @@
 #include "depthTestAttrib.h"
 #include "depthTestAttrib.h"
 #include "depthWriteAttrib.h"
 #include "depthWriteAttrib.h"
 #include "colorWriteAttrib.h"
 #include "colorWriteAttrib.h"
+#include "texMatrixAttrib.h"
+#include "materialAttrib.h"
+#include "renderModeAttrib.h"
+#include "fogAttrib.h"
+#include "depthOffsetAttrib.h"
+#include "qpfog.h"
 #include "clockObject.h"
 #include "clockObject.h"
 #include "string_utils.h"
 #include "string_utils.h"
+#include "qpnodePath.h"
 #include "dcast.h"
 #include "dcast.h"
 #include "pvector.h"
 #include "pvector.h"
 
 
@@ -2497,6 +2504,37 @@ apply_fog(Fog *fog) {
   report_errors();
   report_errors();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::apply_fog
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void GLGraphicsStateGuardian::
+apply_fog(qpFog *fog) {
+  qpFog::Mode fmode = fog->get_mode();
+  call_glFogMode(get_fog_mode_type((Fog::Mode)fmode));
+
+  if (fmode == qpFog::M_linear) {
+    // Linear fog may be world-relative or camera-relative.  The fog
+    // object knows how to decode its parameters into camera-relative
+    // properties.
+    float onset, opaque;
+    fog->compute_linear_range(onset, opaque, 
+                              qpNodePath(),
+                              // _current_camera,
+                              _coordinate_system);
+    call_glFogStart(onset);
+    call_glFogEnd(opaque);
+
+  } else {
+    // Exponential fog is always camera-relative.
+    call_glFogDensity(fog->get_exp_density());
+  }
+
+  call_glFogColor(fog->get_color());
+  report_errors();
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::apply_light
 //     Function: GLGraphicsStateGuardian::apply_light
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -3437,6 +3475,18 @@ issue_transform(const TransformState *transform) {
   report_errors();
   report_errors();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::issue_tex_matrix
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void GLGraphicsStateGuardian::
+issue_tex_matrix(const TexMatrixAttrib *attrib) {
+  glMatrixMode(GL_TEXTURE);
+  glLoadMatrixf(attrib->get_mat().get_data());
+  report_errors();
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::issue_texture
 //     Function: GLGraphicsStateGuardian::issue_texture
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -3455,6 +3505,46 @@ issue_texture(const TextureAttrib *attrib) {
   report_errors();
   report_errors();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::issue_material
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void GLGraphicsStateGuardian::
+issue_material(const MaterialAttrib *attrib) {
+  const Material *material = attrib->get_material();
+  if (material != (const Material *)NULL) {
+    apply_material(material);
+  }
+  report_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::issue_render_mode
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void GLGraphicsStateGuardian::
+issue_render_mode(const RenderModeAttrib *attrib) {
+  RenderModeAttrib::Mode mode = attrib->get_mode();
+
+  switch (mode) {
+  case RenderModeAttrib::M_filled:
+    call_glPolygonMode(GL_FILL);
+    break;
+
+  case RenderModeAttrib::M_wireframe:
+    call_glLineWidth(attrib->get_line_width());
+    call_glPolygonMode(GL_LINE);
+    break;
+
+  default:
+    glgsg_cat.error()
+      << "Unknown render mode " << (int)mode << endl;
+  }
+  report_errors();
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::issue_texture_apply
 //     Function: GLGraphicsStateGuardian::issue_texture_apply
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -3467,6 +3557,55 @@ issue_texture_apply(const TextureApplyAttrib *attrib) {
   report_errors();
   report_errors();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::issue_color_write
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void GLGraphicsStateGuardian::
+issue_color_write(const ColorWriteAttrib *attrib) {
+  ColorWriteAttrib::Mode mode = attrib->get_mode();
+  if (mode == ColorWriteAttrib::M_off) {
+    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+  } else {
+    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+  }
+  report_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::issue_depth_test
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void GLGraphicsStateGuardian::
+issue_depth_test(const DepthTestAttrib *attrib) {
+  DepthTestAttrib::Mode mode = attrib->get_mode();
+  if (mode == DepthTestAttrib::M_none) {
+    enable_depth_test(false);
+  } else {
+    enable_depth_test(true);
+    glDepthFunc(get_depth_func_type(mode));
+  }
+  report_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::issue_depth_write
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void GLGraphicsStateGuardian::
+issue_depth_write(const DepthWriteAttrib *attrib) {
+  DepthWriteAttrib::Mode mode = attrib->get_mode();
+  if (mode == DepthWriteAttrib::M_off) {
+    glDepthMask(GL_FALSE);
+  } else {
+    glDepthMask(GL_TRUE);
+  }
+  report_errors();
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::issue_cull_face
 //     Function: GLGraphicsStateGuardian::issue_cull_face
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -3559,51 +3698,42 @@ issue_transparency(const TransparencyAttrib *attrib) {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_color_write
+//     Function: GLGraphicsStateGuardian::issue_fog
 //       Access: Public, Virtual
 //       Access: Public, Virtual
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_color_write(const ColorWriteAttrib *attrib) {
-  ColorWriteAttrib::Mode mode = attrib->get_mode();
-  if (mode == ColorWriteAttrib::M_off) {
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+issue_fog(const FogAttrib *attrib) {
+  if (!attrib->is_off()) {
+    enable_fog(true);
+    qpFog *fog = attrib->get_fog();
+    nassertv(fog != (qpFog *)NULL);
+    apply_fog(fog);
   } else {
   } else {
-    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+    enable_fog(false);
   }
   }
   report_errors();
   report_errors();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_depth_test
+//     Function: GLGraphicsStateGuardian::issue_depth_offset
 //       Access: Public, Virtual
 //       Access: Public, Virtual
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
-issue_depth_test(const DepthTestAttrib *attrib) {
-  DepthTestAttrib::Mode mode = attrib->get_mode();
-  if (mode == DepthTestAttrib::M_none) {
-    enable_depth_test(false);
-  } else {
-    enable_depth_test(true);
-    glDepthFunc(get_depth_func_type(mode));
-  }
-  report_errors();
-}
+issue_depth_offset(const DepthOffsetAttrib *attrib) {
+  int offset = attrib->get_offset();
+
+  if (offset != 0) {
+    GLfloat newfactor = 1.0f;
+    GLfloat newunits = (GLfloat)offset;
+    glPolygonOffset(newfactor, newunits);
+    enable_polygon_offset(true);
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_depth_write
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void GLGraphicsStateGuardian::
-issue_depth_write(const DepthWriteAttrib *attrib) {
-  DepthWriteAttrib::Mode mode = attrib->get_mode();
-  if (mode == DepthWriteAttrib::M_off) {
-    glDepthMask(GL_FALSE);
   } else {
   } else {
-    glDepthMask(GL_TRUE);
+    enable_polygon_offset(false);
   }
   }
+
   report_errors();
   report_errors();
 }
 }
 
 

+ 15 - 2
panda/src/glgsg/glGraphicsStateGuardian.h

@@ -128,6 +128,7 @@ public:
 
 
   virtual void apply_material(const Material *material);
   virtual void apply_material(const Material *material);
   virtual void apply_fog(Fog *fog);
   virtual void apply_fog(Fog *fog);
+  void apply_fog(qpFog *fog);
 
 
   virtual void apply_light(PointLight* light);
   virtual void apply_light(PointLight* light);
   virtual void apply_light(DirectionalLight* light);
   virtual void apply_light(DirectionalLight* light);
@@ -159,13 +160,25 @@ public:
   virtual void issue_polygon_offset(const PolygonOffsetTransition *attrib);
   virtual void issue_polygon_offset(const PolygonOffsetTransition *attrib);
 
 
   virtual void issue_transform(const TransformState *transform);
   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_texture(const TextureAttrib *attrib);
   virtual void issue_texture(const TextureAttrib *attrib);
+  //  virtual void issue_light(const LightAttrib *attrib);
+  virtual void issue_material(const MaterialAttrib *attrib);
+  virtual void issue_render_mode(const RenderModeAttrib *attrib);
   virtual void issue_texture_apply(const TextureApplyAttrib *attrib);
   virtual void issue_texture_apply(const TextureApplyAttrib *attrib);
-  virtual void issue_cull_face(const CullFaceAttrib *attrib);
-  virtual void issue_transparency(const TransparencyAttrib *attrib);
   virtual void issue_color_write(const ColorWriteAttrib *attrib);
   virtual void issue_color_write(const ColorWriteAttrib *attrib);
   virtual void issue_depth_test(const DepthTestAttrib *attrib);
   virtual void issue_depth_test(const DepthTestAttrib *attrib);
   virtual void issue_depth_write(const DepthWriteAttrib *attrib);
   virtual void issue_depth_write(const DepthWriteAttrib *attrib);
+  virtual void issue_cull_face(const CullFaceAttrib *attrib);
+  virtual void issue_transparency(const TransparencyAttrib *attrib);
+  virtual void issue_fog(const FogAttrib *attrib);
+  virtual void issue_depth_offset(const DepthOffsetAttrib *attrib);
+  //  virtual void issue_color_blend(const ColorBlendAttrib *attrib);
+  //  virtual void issue_tex_gen(const TexGenAttrib *attrib);
+  //  virtual void issue_stencil(const StencilAttrib *attrib);
+  //  virtual void issue_clip_plane(const ClipPlaneAttrib *attrib);
 
 
   virtual bool wants_normals(void) const;
   virtual bool wants_normals(void) const;
   virtual bool wants_texcoords(void) const;
   virtual bool wants_texcoords(void) const;

+ 10 - 15
panda/src/gsgbase/graphicsStateGuardianBase.h

@@ -78,9 +78,7 @@ class LinesmoothTransition;
 class PointShapeTransition;
 class PointShapeTransition;
 class PolygonOffsetTransition;
 class PolygonOffsetTransition;
 
 
-class TransformAttrib;
-class ColorMatrixAttrib;
-class AlphaTransformAttrib;
+class ColorScaleAttrib;
 class TexMatrixAttrib;
 class TexMatrixAttrib;
 class ColorAttrib;
 class ColorAttrib;
 class TextureAttrib;
 class TextureAttrib;
@@ -100,7 +98,7 @@ class TransparencyAttrib;
 class FogAttrib;
 class FogAttrib;
 class LinesmoothAttrib;
 class LinesmoothAttrib;
 class PointShapeAttrib;
 class PointShapeAttrib;
-class PolygonOffsetAttrib;
+class DepthOffsetAttrib;
 
 
 class Node;
 class Node;
 class GeomNode;
 class GeomNode;
@@ -237,29 +235,26 @@ public:
   virtual void issue_point_shape(const PointShapeTransition *) { }
   virtual void issue_point_shape(const PointShapeTransition *) { }
   virtual void issue_polygon_offset(const PolygonOffsetTransition *) { }
   virtual void issue_polygon_offset(const PolygonOffsetTransition *) { }
 
 
-  virtual void issue_transform(const TransformAttrib *) { }
-  virtual void issue_color_transform(const ColorMatrixAttrib *) { }
-  virtual void issue_alpha_transform(const AlphaTransformAttrib *) { }
-  virtual void issue_tex_matrix(const TexMatrixAttrib *) { }
+  virtual void issue_transform(const TransformState *) { }
+  virtual void issue_color_scale(const ColorScaleAttrib *) { }
   virtual void issue_color(const ColorAttrib *) { }
   virtual void issue_color(const ColorAttrib *) { }
+  virtual void issue_tex_matrix(const TexMatrixAttrib *) { }
   virtual void issue_texture(const TextureAttrib *) { }
   virtual void issue_texture(const TextureAttrib *) { }
   virtual void issue_light(const LightAttrib *) { }
   virtual void issue_light(const LightAttrib *) { }
   virtual void issue_material(const MaterialAttrib *) { }
   virtual void issue_material(const MaterialAttrib *) { }
   virtual void issue_render_mode(const RenderModeAttrib *) { }
   virtual void issue_render_mode(const RenderModeAttrib *) { }
-  virtual void issue_color_blend(const ColorBlendAttrib *) { }
   virtual void issue_texture_apply(const TextureApplyAttrib *) { }
   virtual void issue_texture_apply(const TextureApplyAttrib *) { }
   virtual void issue_color_write(const ColorWriteAttrib *) { }
   virtual void issue_color_write(const ColorWriteAttrib *) { }
   virtual void issue_depth_test(const DepthTestAttrib *) { }
   virtual void issue_depth_test(const DepthTestAttrib *) { }
   virtual void issue_depth_write(const DepthWriteAttrib *) { }
   virtual void issue_depth_write(const DepthWriteAttrib *) { }
-  virtual void issue_tex_gen(const TexGenAttrib *) { }
   virtual void issue_cull_face(const CullFaceAttrib *) { }
   virtual void issue_cull_face(const CullFaceAttrib *) { }
-  virtual void issue_stencil(const StencilAttrib *) { }
-  virtual void issue_clip_plane(const ClipPlaneAttrib *) { }
   virtual void issue_transparency(const TransparencyAttrib *) { }
   virtual void issue_transparency(const TransparencyAttrib *) { }
   virtual void issue_fog(const FogAttrib *) { }
   virtual void issue_fog(const FogAttrib *) { }
-  virtual void issue_linesmooth(const LinesmoothAttrib *) { }
-  virtual void issue_point_shape(const PointShapeAttrib *) { }
-  virtual void issue_polygon_offset(const PolygonOffsetAttrib *) { }
+  virtual void issue_depth_offset(const DepthOffsetAttrib *) { }
+  virtual void issue_color_blend(const ColorBlendAttrib *) { }
+  virtual void issue_tex_gen(const TexGenAttrib *) { }
+  virtual void issue_stencil(const StencilAttrib *) { }
+  virtual void issue_clip_plane(const ClipPlaneAttrib *) { }
 
 
 PUBLISHED:
 PUBLISHED:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {

+ 94 - 76
panda/src/pgraph/Sources.pp

@@ -6,48 +6,54 @@
   #define TARGET pgraph
   #define TARGET pgraph
   
   
   #define SOURCES \
   #define SOURCES \
-    billboardEffect.h billboardEffect.I \
-    binCullHandler.h binCullHandler.I \
-    qpcamera.h qpcamera.I \
-    colorAttrib.h colorAttrib.I \
-    colorWriteAttrib.h colorWriteAttrib.I \
+    billboardEffect.I billboardEffect.h \
+    binCullHandler.I binCullHandler.h \
+    qpcamera.I qpcamera.h \
+    colorAttrib.I colorAttrib.h \
+    colorScaleAttrib.I colorScaleAttrib.h \
+    colorWriteAttrib.I colorWriteAttrib.h \
     config_pgraph.h \
     config_pgraph.h \
-    cullBin.h cullBin.I \
-    cullBinAttrib.h cullBinAttrib.I \
-    cullBinBackToFront.h cullBinBackToFront.I \
-    cullBinManager.h cullBinManager.I \
-    cullBinUnsorted.h cullBinUnsorted.I \
-    cullFaceAttrib.h cullFaceAttrib.I \
-    cullHandler.h cullHandler.I \
-    cullResult.h cullResult.I \
-    qpcullTraverser.h qpcullTraverser.I \
-    cullTraverserData.h cullTraverserData.I \
-    cullableObject.h cullableObject.I \
-    decalEffect.h decalEffect.I \
-    depthTestAttrib.h depthTestAttrib.I \
-    depthWriteAttrib.h depthWriteAttrib.I \
-    drawCullHandler.h drawCullHandler.I \
+    cullBin.I cullBin.h \
+    cullBinAttrib.I cullBinAttrib.h \
+    cullBinBackToFront.I cullBinBackToFront.h \
+    cullBinManager.I cullBinManager.h \
+    cullBinUnsorted.I cullBinUnsorted.h \
+    cullFaceAttrib.I cullFaceAttrib.h \
+    cullHandler.I cullHandler.h \
+    cullResult.I cullResult.h \
+    qpcullTraverser.I qpcullTraverser.h \
+    cullTraverserData.I cullTraverserData.h \
+    cullableObject.I cullableObject.h \
+    decalEffect.I decalEffect.h \
+    depthOffsetAttrib.I depthOffsetAttrib.h \
+    depthTestAttrib.I depthTestAttrib.h \
+    depthWriteAttrib.I depthWriteAttrib.h \
+    drawCullHandler.I drawCullHandler.h \
     qpfindApproxLevel.I qpfindApproxLevel.h \
     qpfindApproxLevel.I qpfindApproxLevel.h \
     qpfindApproxLevelEntry.I qpfindApproxLevelEntry.h \
     qpfindApproxLevelEntry.I qpfindApproxLevelEntry.h \
     qpfindApproxPath.I qpfindApproxPath.h \
     qpfindApproxPath.I qpfindApproxPath.h \
-    qpgeomNode.h qpgeomNode.I \
-    qplensNode.h qplensNode.I \
-    qplodNode.h qplodNode.I \
-    materialAttrib.h materialAttrib.I \
-    qpnodePath.h qpnodePath.I \
-    qpnodePathCollection.h qpnodePathCollection.I \
-    qpnodePathComponent.h qpnodePathComponent.I \
-    pandaNode.h pandaNode.I \
-    renderAttrib.h renderAttrib.I \
-    renderEffect.h renderEffect.I \
-    renderEffects.h renderEffects.I \
-    renderState.h renderState.I \
-    selectiveChildNode.h selectiveChildNode.I \
-    qpsequenceNode.h qpsequenceNode.I \
-    textureApplyAttrib.h textureApplyAttrib.I \
-    textureAttrib.h textureAttrib.I \
-    transformState.h transformState.I \
-    transparencyAttrib.h transparencyAttrib.I
+    qpfog.I qpfog.h \
+    fogAttrib.I fogAttrib.h \
+    qpgeomNode.I qpgeomNode.h \
+    qplensNode.I qplensNode.h \
+    qplodNode.I qplodNode.h \
+    materialAttrib.I materialAttrib.h \
+    qpnodePath.I qpnodePath.h \
+    qpnodePathCollection.I qpnodePathCollection.h \
+    qpnodePathComponent.I qpnodePathComponent.h \
+    pandaNode.I pandaNode.h \
+    renderAttrib.I renderAttrib.h \
+    renderEffect.I renderEffect.h \
+    renderEffects.I renderEffects.h \
+    renderModeAttrib.I renderModeAttrib.h \
+    renderState.I renderState.h \
+    selectiveChildNode.I selectiveChildNode.h \
+    qpsequenceNode.I qpsequenceNode.h \
+    texMatrixAttrib.I texMatrixAttrib.h \
+    textureApplyAttrib.I textureApplyAttrib.h \
+    textureAttrib.I textureAttrib.h \
+    transformState.I transformState.h \
+    transparencyAttrib.I transparencyAttrib.h
 
 
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx    
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx    
   #define INCLUDED_SOURCES \
   #define INCLUDED_SOURCES \
@@ -55,6 +61,7 @@
     binCullHandler.cxx \
     binCullHandler.cxx \
     qpcamera.cxx \
     qpcamera.cxx \
     colorAttrib.cxx \
     colorAttrib.cxx \
+    colorScaleAttrib.cxx \
     colorWriteAttrib.cxx \
     colorWriteAttrib.cxx \
     config_pgraph.cxx \
     config_pgraph.cxx \
     cullBin.cxx \
     cullBin.cxx \
@@ -69,12 +76,15 @@
     cullTraverserData.cxx \
     cullTraverserData.cxx \
     cullableObject.cxx \
     cullableObject.cxx \
     decalEffect.cxx \
     decalEffect.cxx \
+    depthOffsetAttrib.cxx \
     depthTestAttrib.cxx \
     depthTestAttrib.cxx \
     depthWriteAttrib.cxx \
     depthWriteAttrib.cxx \
     drawCullHandler.cxx \
     drawCullHandler.cxx \
     qpfindApproxLevel.cxx \
     qpfindApproxLevel.cxx \
     qpfindApproxLevelEntry.cxx \
     qpfindApproxLevelEntry.cxx \
     qpfindApproxPath.cxx \
     qpfindApproxPath.cxx \
+    qpfog.cxx \
+    fogAttrib.cxx \
     qpgeomNode.cxx \
     qpgeomNode.cxx \
     qplensNode.cxx \
     qplensNode.cxx \
     qplodNode.cxx \
     qplodNode.cxx \
@@ -86,9 +96,11 @@
     renderAttrib.cxx \
     renderAttrib.cxx \
     renderEffect.cxx \
     renderEffect.cxx \
     renderEffects.cxx \
     renderEffects.cxx \
+    renderModeAttrib.cxx \
     renderState.cxx \
     renderState.cxx \
     selectiveChildNode.cxx \
     selectiveChildNode.cxx \
     qpsequenceNode.cxx \
     qpsequenceNode.cxx \
+    texMatrixAttrib.cxx \
     textureApplyAttrib.cxx \
     textureApplyAttrib.cxx \
     textureAttrib.cxx \
     textureAttrib.cxx \
     transformState.cxx \
     transformState.cxx \
@@ -101,45 +113,51 @@
   #endif
   #endif
 
 
   #define INSTALL_HEADERS \
   #define INSTALL_HEADERS \
-    billboardEffect.h billboardEffect.I \
-    binCullHandler.h binCullHandler.I \
-    qpcamera.h qpcamera.I \
-    colorAttrib.h colorAttrib.I \
-    colorWriteAttrib.h colorWriteAttrib.I \
+    billboardEffect.I billboardEffect.h \
+    binCullHandler.I binCullHandler.h \
+    qpcamera.I qpcamera.h \
+    colorAttrib.I colorAttrib.h \
+    colorScaleAttrib.I colorScaleAttrib.h \
+    colorWriteAttrib.I colorWriteAttrib.h \
     config_pgraph.h \
     config_pgraph.h \
-    cullBin.h cullBin.I \
-    cullBinAttrib.h cullBinAttrib.I \
-    cullBinBackToFront.h cullBinBackToFront.I \
-    cullBinManager.h cullBinManager.I \
-    cullBinUnsorted.h cullBinUnsorted.I \
-    cullFaceAttrib.h cullFaceAttrib.I \
-    cullHandler.h cullHandler.I \
-    cullResult.h cullResult.I \
-    qpcullTraverser.h qpcullTraverser.I \
-    cullTraverserData.h cullTraverserData.I \
-    cullableObject.h cullableObject.I \
-    decalEffect.h decalEffect.I \
-    depthTestAttrib.h depthTestAttrib.I \
-    depthWriteAttrib.h depthWriteAttrib.I \
-    drawCullHandler.h drawCullHandler.I \
-    qpgeomNode.h qpgeomNode.I \
-    qplensNode.h qplensNode.I \
-    qplodNode.h qplodNode.I \
-    materialAttrib.h materialAttrib.I \
-    qpnodePath.h qpnodePath.I \
-    qpnodePathCollection.h qpnodePathCollection.I \
-    qpnodePathComponent.h qpnodePathComponent.I \
-    pandaNode.h pandaNode.I \
-    renderAttrib.h renderAttrib.I \
-    renderEffect.h renderEffect.I \
-    renderEffects.h renderEffects.I \
-    renderState.h renderState.I \
-    selectiveChildNode.h selectiveChildNode.I \
-    qpsequenceNode.h qpsequenceNode.I \
-    textureApplyAttrib.h textureApplyAttrib.I \
-    textureAttrib.h textureAttrib.I \
-    transformState.h transformState.I \
-    transparencyAttrib.h transparencyAttrib.I
+    cullBin.I cullBin.h \
+    cullBinAttrib.I cullBinAttrib.h \
+    cullBinBackToFront.I cullBinBackToFront.h \
+    cullBinManager.I cullBinManager.h \
+    cullBinUnsorted.I cullBinUnsorted.h \
+    cullFaceAttrib.I cullFaceAttrib.h \
+    cullHandler.I cullHandler.h \
+    cullResult.I cullResult.h \
+    qpcullTraverser.I qpcullTraverser.h \
+    cullTraverserData.I cullTraverserData.h \
+    cullableObject.I cullableObject.h \
+    decalEffect.I decalEffect.h \
+    depthOffsetAttrib.I depthOffsetAttrib.h \
+    depthTestAttrib.I depthTestAttrib.h \
+    depthWriteAttrib.I depthWriteAttrib.h \
+    drawCullHandler.I drawCullHandler.h \
+    qpfog.I qpfog.h \
+    fogAttrib.I fogAttrib.h \
+    qpgeomNode.I qpgeomNode.h \
+    qplensNode.I qplensNode.h \
+    qplodNode.I qplodNode.h \
+    materialAttrib.I materialAttrib.h \
+    qpnodePath.I qpnodePath.h \
+    qpnodePathCollection.I qpnodePathCollection.h \
+    qpnodePathComponent.I qpnodePathComponent.h \
+    pandaNode.I pandaNode.h \
+    renderAttrib.I renderAttrib.h \
+    renderEffect.I renderEffect.h \
+    renderEffects.I renderEffects.h \
+    renderModeAttrib.I renderModeAttrib.h \
+    renderState.I renderState.h \
+    selectiveChildNode.I selectiveChildNode.h \
+    qpsequenceNode.I qpsequenceNode.h \
+    texMatrixAttrib.I texMatrixAttrib.h \
+    textureApplyAttrib.I textureApplyAttrib.h \
+    textureAttrib.I textureAttrib.h \
+    transformState.I transformState.h \
+    transparencyAttrib.I transparencyAttrib.h
 
 
 // No need to install these.
 // No need to install these.
 //    qpfindApproxLevel.I qpfindApproxLevel.h \
 //    qpfindApproxLevel.I qpfindApproxLevel.h \

+ 40 - 0
panda/src/pgraph/colorScaleAttrib.I

@@ -0,0 +1,40 @@
+// Filename: colorScaleAttrib.I
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::Constructor
+//       Access: Private
+//  Description: Use ColorScaleAttrib::make() to construct a new
+//               ColorScaleAttrib object.
+////////////////////////////////////////////////////////////////////
+INLINE ColorScaleAttrib::
+ColorScaleAttrib(const LVecBase4f &scale) :
+  _scale(scale)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::get_scale
+//       Access: Published
+//  Description: Returns the scale to be applied to colors.
+////////////////////////////////////////////////////////////////////
+INLINE const LVecBase4f &ColorScaleAttrib::
+get_scale() const {
+  return _scale;
+}

+ 211 - 0
panda/src/pgraph/colorScaleAttrib.cxx

@@ -0,0 +1,211 @@
+// Filename: colorScaleAttrib.cxx
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "colorScaleAttrib.h"
+#include "graphicsStateGuardianBase.h"
+#include "dcast.h"
+#include "bamReader.h"
+#include "bamWriter.h"
+#include "datagram.h"
+#include "datagramIterator.h"
+
+TypeHandle ColorScaleAttrib::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::make
+//       Access: Published, Static
+//  Description: Constructs a new ColorScaleAttrib object that indicates
+//               geometry should be scaled by the indicated factor.
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) ColorScaleAttrib::
+make(const LVecBase4f &scale) {
+  ColorScaleAttrib *attrib = new ColorScaleAttrib(scale);
+  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::output
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void ColorScaleAttrib::
+output(ostream &out) const {
+  out << get_type() << ":(" << get_scale() << ")";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::compare_to_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived ColorScaleAttrib
+//               types to return a unique number indicating whether
+//               this ColorScaleAttrib is equivalent to the other one.
+//
+//               This should return 0 if the two ColorScaleAttrib objects
+//               are equivalent, a number less than zero if this one
+//               should be sorted before the other one, and a number
+//               greater than zero otherwise.
+//
+//               This will only be called with two ColorScaleAttrib
+//               objects whose get_type() functions return the same.
+////////////////////////////////////////////////////////////////////
+int ColorScaleAttrib::
+compare_to_impl(const RenderAttrib *other) const {
+  const ColorScaleAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  return _scale.compare_to(ta->_scale);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::compose_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived RenderAttrib
+//               types to specify how two consecutive RenderAttrib
+//               objects of the same type interact.
+//
+//               This should return the result of applying the other
+//               RenderAttrib to a node in the scene graph below this
+//               RenderAttrib, which was already applied.  In most
+//               cases, the result is the same as the other
+//               RenderAttrib (that is, a subsequent RenderAttrib
+//               completely replaces the preceding one).  On the other
+//               hand, some kinds of RenderAttrib (for instance,
+//               ColorTransformAttrib) might combine in meaningful
+//               ways.
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) ColorScaleAttrib::
+compose_impl(const RenderAttrib *other) const {
+  const ColorScaleAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  LVecBase4f new_scale(ta->_scale[0] * _scale[0],
+                       ta->_scale[1] * _scale[1],
+                       ta->_scale[2] * _scale[2],
+                       ta->_scale[3] * _scale[3]);
+
+  ColorScaleAttrib *attrib = new ColorScaleAttrib(new_scale);
+  return return_new(attrib);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::invert_compose_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived RenderAttrib
+//               types to specify how two consecutive RenderAttrib
+//               objects of the same type interact.
+//
+//               See invert_compose() and compose_impl().
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) ColorScaleAttrib::
+invert_compose_impl(const RenderAttrib *other) const {
+  const ColorScaleAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  LVecBase4f new_scale(ta->_scale[0] / _scale[0],
+                       ta->_scale[1] / _scale[1],
+                       ta->_scale[2] / _scale[2],
+                       ta->_scale[3] / _scale[3]);
+
+  ColorScaleAttrib *attrib = new ColorScaleAttrib(new_scale);
+  return return_new(attrib);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::make_default_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived ColorScaleAttrib
+//               types to specify what the default property for a
+//               ColorScaleAttrib of this type should be.
+//
+//               This should return a newly-allocated ColorScaleAttrib of
+//               the same type that corresponds to whatever the
+//               standard default for this kind of ColorScaleAttrib is.
+////////////////////////////////////////////////////////////////////
+RenderAttrib *ColorScaleAttrib::
+make_default_impl() const {
+  return new ColorScaleAttrib(LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::register_with_read_factory
+//       Access: Public, Static
+//  Description: Tells the BamReader how to create objects of type
+//               ColorScaleAttrib.
+////////////////////////////////////////////////////////////////////
+void ColorScaleAttrib::
+register_with_read_factory() {
+  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::write_datagram
+//       Access: Public, Virtual
+//  Description: Writes the contents of this object to the datagram
+//               for shipping out to a Bam file.
+////////////////////////////////////////////////////////////////////
+void ColorScaleAttrib::
+write_datagram(BamWriter *manager, Datagram &dg) {
+  RenderAttrib::write_datagram(manager, dg);
+
+  _scale.write_datagram(dg);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::make_from_bam
+//       Access: Protected, Static
+//  Description: This function is called by the BamReader's factory
+//               when a new object of type ColorScaleAttrib is encountered
+//               in the Bam file.  It should create the ColorScaleAttrib
+//               and extract its information from the file.
+////////////////////////////////////////////////////////////////////
+TypedWritable *ColorScaleAttrib::
+make_from_bam(const FactoryParams &params) {
+  ColorScaleAttrib *attrib = new ColorScaleAttrib(LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f));
+  DatagramIterator scan;
+  BamReader *manager;
+
+  parse_params(params, scan, manager);
+  attrib->fillin(scan, manager);
+
+  return attrib;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorScaleAttrib::fillin
+//       Access: Protected
+//  Description: This internal function is called by make_from_bam to
+//               read in all of the relevant data from the BamFile for
+//               the new ColorScaleAttrib.
+////////////////////////////////////////////////////////////////////
+void ColorScaleAttrib::
+fillin(DatagramIterator &scan, BamReader *manager) {
+  RenderAttrib::fillin(scan, manager);
+
+  _scale.read_datagram(scan);
+}

+ 83 - 0
panda/src/pgraph/colorScaleAttrib.h

@@ -0,0 +1,83 @@
+// Filename: colorScaleAttrib.h
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef COLORSCALEATTRIB_H
+#define COLORSCALEATTRIB_H
+
+#include "pandabase.h"
+
+#include "renderAttrib.h"
+#include "luse.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : ColorScaleAttrib
+// Description : Applies a scale to colors in the scene graph and on
+//               vertices.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA ColorScaleAttrib : public RenderAttrib {
+private:
+  INLINE ColorScaleAttrib(const LVecBase4f &scale);
+
+PUBLISHED:
+  static CPT(RenderAttrib) make(const LVecBase4f &scale);
+
+  INLINE const LVecBase4f &get_scale() const;
+
+public:
+  virtual void issue(GraphicsStateGuardianBase *gsg) const;
+  virtual void output(ostream &out) const;
+
+protected:
+  virtual int compare_to_impl(const RenderAttrib *other) const;
+  virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const;
+  virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const;
+  virtual RenderAttrib *make_default_impl() const;
+
+private:
+  LVecBase4f _scale;
+
+public:
+  static void register_with_read_factory();
+  virtual void write_datagram(BamWriter *manager, Datagram &dg);
+
+protected:
+  static TypedWritable *make_from_bam(const FactoryParams &params);
+  void fillin(DatagramIterator &scan, BamReader *manager);
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    RenderAttrib::init_type();
+    register_type(_type_handle, "ColorScaleAttrib",
+                  RenderAttrib::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "colorScaleAttrib.I"
+
+#endif
+

+ 18 - 0
panda/src/pgraph/config_pgraph.cxx

@@ -21,6 +21,7 @@
 #include "billboardEffect.h"
 #include "billboardEffect.h"
 #include "qpcamera.h"
 #include "qpcamera.h"
 #include "colorAttrib.h"
 #include "colorAttrib.h"
+#include "colorScaleAttrib.h"
 #include "colorWriteAttrib.h"
 #include "colorWriteAttrib.h"
 #include "cullFaceAttrib.h"
 #include "cullFaceAttrib.h"
 #include "cullBin.h"
 #include "cullBin.h"
@@ -30,8 +31,11 @@
 #include "qpcullTraverser.h"
 #include "qpcullTraverser.h"
 #include "cullableObject.h"
 #include "cullableObject.h"
 #include "decalEffect.h"
 #include "decalEffect.h"
+#include "depthOffsetAttrib.h"
 #include "depthTestAttrib.h"
 #include "depthTestAttrib.h"
 #include "depthWriteAttrib.h"
 #include "depthWriteAttrib.h"
+#include "qpfog.h"
+#include "fogAttrib.h"
 #include "qpgeomNode.h"
 #include "qpgeomNode.h"
 #include "qplensNode.h"
 #include "qplensNode.h"
 #include "qplodNode.h"
 #include "qplodNode.h"
@@ -42,9 +46,11 @@
 #include "renderAttrib.h"
 #include "renderAttrib.h"
 #include "renderEffect.h"
 #include "renderEffect.h"
 #include "renderEffects.h"
 #include "renderEffects.h"
+#include "renderModeAttrib.h"
 #include "renderState.h"
 #include "renderState.h"
 #include "selectiveChildNode.h"
 #include "selectiveChildNode.h"
 #include "qpsequenceNode.h"
 #include "qpsequenceNode.h"
+#include "texMatrixAttrib.h"
 #include "textureApplyAttrib.h"
 #include "textureApplyAttrib.h"
 #include "textureAttrib.h"
 #include "textureAttrib.h"
 #include "transformState.h"
 #include "transformState.h"
@@ -84,6 +90,7 @@ init_libpgraph() {
   BillboardEffect::init_type();
   BillboardEffect::init_type();
   qpCamera::init_type();
   qpCamera::init_type();
   ColorAttrib::init_type();
   ColorAttrib::init_type();
+  ColorScaleAttrib::init_type();
   ColorWriteAttrib::init_type();
   ColorWriteAttrib::init_type();
   CullFaceAttrib::init_type();
   CullFaceAttrib::init_type();
   CullBin::init_type();
   CullBin::init_type();
@@ -93,8 +100,11 @@ init_libpgraph() {
   qpCullTraverser::init_type();
   qpCullTraverser::init_type();
   CullableObject::init_type();
   CullableObject::init_type();
   DecalEffect::init_type();
   DecalEffect::init_type();
+  DepthOffsetAttrib::init_type();
   DepthTestAttrib::init_type();
   DepthTestAttrib::init_type();
   DepthWriteAttrib::init_type();
   DepthWriteAttrib::init_type();
+  qpFog::init_type();
+  FogAttrib::init_type();
   qpGeomNode::init_type();
   qpGeomNode::init_type();
   qpLensNode::init_type();
   qpLensNode::init_type();
   qpLODNode::init_type();
   qpLODNode::init_type();
@@ -105,9 +115,11 @@ init_libpgraph() {
   RenderAttrib::init_type();
   RenderAttrib::init_type();
   RenderEffect::init_type();
   RenderEffect::init_type();
   RenderEffects::init_type();
   RenderEffects::init_type();
+  RenderModeAttrib::init_type();
   RenderState::init_type();
   RenderState::init_type();
   SelectiveChildNode::init_type();
   SelectiveChildNode::init_type();
   qpSequenceNode::init_type();
   qpSequenceNode::init_type();
+  TexMatrixAttrib::init_type();
   TextureApplyAttrib::init_type();
   TextureApplyAttrib::init_type();
   TextureAttrib::init_type();
   TextureAttrib::init_type();
   TransformState::init_type();
   TransformState::init_type();
@@ -116,20 +128,26 @@ init_libpgraph() {
   BillboardEffect::register_with_read_factory();
   BillboardEffect::register_with_read_factory();
   qpCamera::register_with_read_factory();
   qpCamera::register_with_read_factory();
   ColorAttrib::register_with_read_factory();
   ColorAttrib::register_with_read_factory();
+  ColorScaleAttrib::register_with_read_factory();
   ColorWriteAttrib::register_with_read_factory();
   ColorWriteAttrib::register_with_read_factory();
   CullBinAttrib::register_with_read_factory();
   CullBinAttrib::register_with_read_factory();
   CullFaceAttrib::register_with_read_factory();
   CullFaceAttrib::register_with_read_factory();
   DecalEffect::register_with_read_factory();
   DecalEffect::register_with_read_factory();
+  DepthOffsetAttrib::register_with_read_factory();
   DepthTestAttrib::register_with_read_factory();
   DepthTestAttrib::register_with_read_factory();
   DepthWriteAttrib::register_with_read_factory();
   DepthWriteAttrib::register_with_read_factory();
+  qpFog::register_with_read_factory();
+  FogAttrib::register_with_read_factory();
   qpGeomNode::register_with_read_factory();
   qpGeomNode::register_with_read_factory();
   qpLensNode::register_with_read_factory();
   qpLensNode::register_with_read_factory();
   qpLODNode::register_with_read_factory();
   qpLODNode::register_with_read_factory();
   MaterialAttrib::register_with_read_factory();
   MaterialAttrib::register_with_read_factory();
   PandaNode::register_with_read_factory();
   PandaNode::register_with_read_factory();
   RenderEffects::register_with_read_factory();
   RenderEffects::register_with_read_factory();
+  RenderModeAttrib::register_with_read_factory();
   RenderState::register_with_read_factory();
   RenderState::register_with_read_factory();
   qpSequenceNode::register_with_read_factory();
   qpSequenceNode::register_with_read_factory();
+  TexMatrixAttrib::register_with_read_factory();
   TextureApplyAttrib::register_with_read_factory();
   TextureApplyAttrib::register_with_read_factory();
   TextureAttrib::register_with_read_factory();
   TextureAttrib::register_with_read_factory();
   TransformState::register_with_read_factory();
   TransformState::register_with_read_factory();

+ 3 - 0
panda/src/pgraph/cullBinManager.cxx

@@ -281,6 +281,9 @@ setup_initial_bins() {
   if (find_bin("fixed") == -1) {
   if (find_bin("fixed") == -1) {
     add_bin("fixed", BT_fixed, 40);
     add_bin("fixed", BT_fixed, 40);
   }
   }
+  if (find_bin("unsorted") == -1) {
+    add_bin("unsorted", BT_unsorted, 50);
+  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 2 - 0
panda/src/pgraph/cullTraverserData.cxx

@@ -22,6 +22,7 @@
 #include "pandaNode.h"
 #include "pandaNode.h"
 #include "colorAttrib.h"
 #include "colorAttrib.h"
 #include "textureAttrib.h"
 #include "textureAttrib.h"
+#include "renderModeAttrib.h"
 #include "billboardEffect.h"
 #include "billboardEffect.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -153,6 +154,7 @@ get_fake_view_frustum_cull_effect() {
     effect = RenderState::make
     effect = RenderState::make
       (ColorAttrib::make_flat(Colorf(1.0f, 0.0f, 0.0f, 1.0f)),
       (ColorAttrib::make_flat(Colorf(1.0f, 0.0f, 0.0f, 1.0f)),
        TextureAttrib::make_off(),
        TextureAttrib::make_off(),
+       RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
        1000);
        1000);
   }
   }
   return effect;
   return effect;

+ 40 - 0
panda/src/pgraph/depthOffsetAttrib.I

@@ -0,0 +1,40 @@
+// Filename: depthOffsetAttrib.I
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::Constructor
+//       Access: Private
+//  Description: Use DepthOffsetAttrib::make() to construct a new
+//               DepthOffsetAttrib object.
+////////////////////////////////////////////////////////////////////
+INLINE DepthOffsetAttrib::
+DepthOffsetAttrib(int offset) :
+  _offset(offset)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::get_offset
+//       Access: Published
+//  Description: Returns the depth offset represented by this attrib.
+////////////////////////////////////////////////////////////////////
+INLINE int DepthOffsetAttrib::
+get_offset() const {
+  return _offset;
+}

+ 206 - 0
panda/src/pgraph/depthOffsetAttrib.cxx

@@ -0,0 +1,206 @@
+// Filename: depthOffsetAttrib.cxx
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "depthOffsetAttrib.h"
+#include "graphicsStateGuardianBase.h"
+#include "dcast.h"
+#include "bamReader.h"
+#include "bamWriter.h"
+#include "datagram.h"
+#include "datagramIterator.h"
+
+TypeHandle DepthOffsetAttrib::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::make
+//       Access: Published, Static
+//  Description: Constructs a new DepthOffsetAttrib object that
+//               indicates the relative amount of bias to write to the
+//               depth buffer for subsequent geometry.
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) DepthOffsetAttrib::
+make(int offset) {
+  DepthOffsetAttrib *attrib = new DepthOffsetAttrib(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
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void DepthOffsetAttrib::
+output(ostream &out) const {
+  out << get_type() << ":(" << get_offset() << ")";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::compare_to_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived DepthOffsetAttrib
+//               types to return a unique number indicating whether
+//               this DepthOffsetAttrib is equivalent to the other one.
+//
+//               This should return 0 if the two DepthOffsetAttrib objects
+//               are equivalent, a number less than zero if this one
+//               should be sorted before the other one, and a number
+//               greater than zero otherwise.
+//
+//               This will only be called with two DepthOffsetAttrib
+//               objects whose get_type() functions return the same.
+////////////////////////////////////////////////////////////////////
+int DepthOffsetAttrib::
+compare_to_impl(const RenderAttrib *other) const {
+  const DepthOffsetAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  return _offset - ta->_offset;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::compose_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived RenderAttrib
+//               types to specify how two consecutive RenderAttrib
+//               objects of the same type interact.
+//
+//               This should return the result of applying the other
+//               RenderAttrib to a node in the scene graph below this
+//               RenderAttrib, which was already applied.  In most
+//               cases, the result is the same as the other
+//               RenderAttrib (that is, a subsequent RenderAttrib
+//               completely replaces the preceding one).  On the other
+//               hand, some kinds of RenderAttrib (for instance,
+//               ColorTransformAttrib) might combine in meaningful
+//               ways.
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) DepthOffsetAttrib::
+compose_impl(const RenderAttrib *other) const {
+  const DepthOffsetAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  int new_offset = ta->_offset + _offset;
+
+  DepthOffsetAttrib *attrib = new DepthOffsetAttrib(new_offset);
+  return return_new(attrib);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::invert_compose_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived RenderAttrib
+//               types to specify how two consecutive RenderAttrib
+//               objects of the same type interact.
+//
+//               See invert_compose() and compose_impl().
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) DepthOffsetAttrib::
+invert_compose_impl(const RenderAttrib *other) const {
+  const DepthOffsetAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  int new_offset = ta->_offset - _offset;
+
+  DepthOffsetAttrib *attrib = new DepthOffsetAttrib(new_offset);
+  return return_new(attrib);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::make_default_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived DepthOffsetAttrib
+//               types to specify what the default property for a
+//               DepthOffsetAttrib of this type should be.
+//
+//               This should return a newly-allocated DepthOffsetAttrib of
+//               the same type that corresponds to whatever the
+//               standard default for this kind of DepthOffsetAttrib is.
+////////////////////////////////////////////////////////////////////
+RenderAttrib *DepthOffsetAttrib::
+make_default_impl() const {
+  return new DepthOffsetAttrib(0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::register_with_read_factory
+//       Access: Public, Static
+//  Description: Tells the BamReader how to create objects of type
+//               DepthOffsetAttrib.
+////////////////////////////////////////////////////////////////////
+void DepthOffsetAttrib::
+register_with_read_factory() {
+  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::write_datagram
+//       Access: Public, Virtual
+//  Description: Writes the contents of this object to the datagram
+//               for shipping out to a Bam file.
+////////////////////////////////////////////////////////////////////
+void DepthOffsetAttrib::
+write_datagram(BamWriter *manager, Datagram &dg) {
+  RenderAttrib::write_datagram(manager, dg);
+
+  dg.add_int32(_offset);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::make_from_bam
+//       Access: Protected, Static
+//  Description: This function is called by the BamReader's factory
+//               when a new object of type DepthOffsetAttrib is encountered
+//               in the Bam file.  It should create the DepthOffsetAttrib
+//               and extract its information from the file.
+////////////////////////////////////////////////////////////////////
+TypedWritable *DepthOffsetAttrib::
+make_from_bam(const FactoryParams &params) {
+  DepthOffsetAttrib *attrib = new DepthOffsetAttrib(0);
+  DatagramIterator scan;
+  BamReader *manager;
+
+  parse_params(params, scan, manager);
+  attrib->fillin(scan, manager);
+
+  return attrib;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DepthOffsetAttrib::fillin
+//       Access: Protected
+//  Description: This internal function is called by make_from_bam to
+//               read in all of the relevant data from the BamFile for
+//               the new DepthOffsetAttrib.
+////////////////////////////////////////////////////////////////////
+void DepthOffsetAttrib::
+fillin(DatagramIterator &scan, BamReader *manager) {
+  RenderAttrib::fillin(scan, manager);
+
+  _offset = scan.get_int32();
+}

+ 106 - 0
panda/src/pgraph/depthOffsetAttrib.h

@@ -0,0 +1,106 @@
+// Filename: depthOffsetAttrib.h
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DEPTHOFFSETATTRIB_H
+#define DEPTHOFFSETATTRIB_H
+
+#include "pandabase.h"
+
+#include "renderAttrib.h"
+#include "luse.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : DepthOffsetAttrib
+// Description : This is a special kind of attribute that instructs
+//               the graphics driver to apply an offset or bias to the
+//               generated depth values for rendered polygons, before
+//               they are written to the depth buffer.
+//
+//               This can be used to shift polygons forward slightly,
+//               to resolve depth conflicts.  The cull traverser may
+//               optionally use this, for instance, to implement
+//               decals.  However, driver support for this feature
+//               seems to be spotty, so use with caution.
+//
+//               The bias is always an integer number, and each
+//               integer increment represents the smallest possible
+//               increment in Z that is sufficient to completely
+//               resolve two coplanar polygons.  Positive numbers are
+//               closer towards the camera.
+//
+//               Nested DepthOffsetAttrib values accumulate; that is,
+//               a DepthOffsetAttrib with a value of 1 beneath another
+//               DepthOffsetAttrib with a value of 2 presents a net
+//               offset of 3.  (A DepthOffsetAttrib will not, however,
+//               combine with any other DepthOffsetAttribs with a
+//               lower override parameter.)  The net value should
+//               probably not exceed 16 or drop below 0 for maximum
+//               portability.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA DepthOffsetAttrib : public RenderAttrib {
+private:
+  INLINE DepthOffsetAttrib(int offset);
+
+PUBLISHED:
+  static CPT(RenderAttrib) make(int offset = 1);
+
+  INLINE int get_offset() const;
+
+public:
+  virtual void issue(GraphicsStateGuardianBase *gsg) const;
+  virtual void output(ostream &out) const;
+
+protected:
+  virtual int compare_to_impl(const RenderAttrib *other) const;
+  virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const;
+  virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const;
+  virtual RenderAttrib *make_default_impl() const;
+
+private:
+  int _offset;
+
+public:
+  static void register_with_read_factory();
+  virtual void write_datagram(BamWriter *manager, Datagram &dg);
+
+protected:
+  static TypedWritable *make_from_bam(const FactoryParams &params);
+  void fillin(DatagramIterator &scan, BamReader *manager);
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    RenderAttrib::init_type();
+    register_type(_type_handle, "DepthOffsetAttrib",
+                  RenderAttrib::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "depthOffsetAttrib.I"
+
+#endif
+

+ 51 - 0
panda/src/pgraph/fogAttrib.I

@@ -0,0 +1,51 @@
+// Filename: fogAttrib.I
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::Constructor
+//       Access: Private
+//  Description: Use FogAttrib::make() to construct a new FogAttrib
+//               object.
+////////////////////////////////////////////////////////////////////
+INLINE FogAttrib::
+FogAttrib() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::is_off
+//       Access: Published
+//  Description: Returns true if the FogAttrib is an 'off' FogAttrib,
+//               indicating that it should disable fog.
+////////////////////////////////////////////////////////////////////
+INLINE bool FogAttrib::
+is_off() const {
+  return _fog == (const qpFog *)NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::get_fog
+//       Access: Published
+//  Description: If the FogAttrib is not an 'off' FogAttrib,
+//               returns the fog that is associated.  Otherwise,
+//               return NULL.
+////////////////////////////////////////////////////////////////////
+INLINE qpFog *FogAttrib::
+get_fog() const {
+  return _fog;
+}

+ 196 - 0
panda/src/pgraph/fogAttrib.cxx

@@ -0,0 +1,196 @@
+// Filename: fogAttrib.cxx
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "fogAttrib.h"
+#include "graphicsStateGuardianBase.h"
+#include "bamReader.h"
+#include "bamWriter.h"
+#include "datagram.h"
+#include "datagramIterator.h"
+
+TypeHandle FogAttrib::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::make
+//       Access: Published, Static
+//  Description: Constructs a new FogAttrib object suitable for
+//               rendering the indicated fog onto geometry.
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) FogAttrib::
+make(qpFog *fog) {
+  FogAttrib *attrib = new FogAttrib;
+  attrib->_fog = fog;
+  return return_new(attrib);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::make_off
+//       Access: Published, Static
+//  Description: Constructs a new FogAttrib object suitable for
+//               rendering unfogd geometry.
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) FogAttrib::
+make_off() {
+  FogAttrib *attrib = new FogAttrib;
+  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
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void FogAttrib::
+output(ostream &out) const {
+  out << get_type() << ":";
+  if (is_off()) {
+    out << "(off)";
+  } else {
+    out << *_fog;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::compare_to_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived FogAttrib
+//               types to return a unique number indicating whether
+//               this FogAttrib is equivalent to the other one.
+//
+//               This should return 0 if the two FogAttrib objects
+//               are equivalent, a number less than zero if this one
+//               should be sorted before the other one, and a number
+//               greater than zero otherwise.
+//
+//               This will only be called with two FogAttrib
+//               objects whose get_type() functions return the same.
+////////////////////////////////////////////////////////////////////
+int FogAttrib::
+compare_to_impl(const RenderAttrib *other) const {
+  const FogAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  return (int)(_fog - ta->_fog);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::make_default_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived FogAttrib
+//               types to specify what the default property for a
+//               FogAttrib of this type should be.
+//
+//               This should return a newly-allocated FogAttrib of
+//               the same type that corresponds to whatever the
+//               standard default for this kind of FogAttrib is.
+////////////////////////////////////////////////////////////////////
+RenderAttrib *FogAttrib::
+make_default_impl() const {
+  return new FogAttrib;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::register_with_read_factory
+//       Access: Public, Static
+//  Description: Tells the BamReader how to create objects of type
+//               FogAttrib.
+////////////////////////////////////////////////////////////////////
+void FogAttrib::
+register_with_read_factory() {
+  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::write_datagram
+//       Access: Public, Virtual
+//  Description: Writes the contents of this object to the datagram
+//               for shipping out to a Bam file.
+////////////////////////////////////////////////////////////////////
+void FogAttrib::
+write_datagram(BamWriter *manager, Datagram &dg) {
+  RenderAttrib::write_datagram(manager, dg);
+
+  manager->write_pointer(dg, _fog);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::complete_pointers
+//       Access: Public, Virtual
+//  Description: Receives an array of pointers, one for each time
+//               manager->read_pointer() was called in fillin().
+//               Returns the number of pointers processed.
+////////////////////////////////////////////////////////////////////
+int FogAttrib::
+complete_pointers(TypedWritable **p_list, BamReader *manager) {
+  int pi = RenderAttrib::complete_pointers(p_list, manager);
+
+  TypedWritable *fog = p_list[pi++];
+  if (fog != (TypedWritable *)NULL) {
+    _fog = DCAST(qpFog, fog);
+  }
+
+  return pi;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::make_from_bam
+//       Access: Protected, Static
+//  Description: This function is called by the BamReader's factory
+//               when a new object of type FogAttrib is encountered
+//               in the Bam file.  It should create the FogAttrib
+//               and extract its information from the file.
+////////////////////////////////////////////////////////////////////
+TypedWritable *FogAttrib::
+make_from_bam(const FactoryParams &params) {
+  FogAttrib *attrib = new FogAttrib;
+  DatagramIterator scan;
+  BamReader *manager;
+
+  parse_params(params, scan, manager);
+  attrib->fillin(scan, manager);
+
+  return attrib;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FogAttrib::fillin
+//       Access: Protected
+//  Description: This internal function is called by make_from_bam to
+//               read in all of the relevant data from the BamFile for
+//               the new FogAttrib.
+////////////////////////////////////////////////////////////////////
+void FogAttrib::
+fillin(DatagramIterator &scan, BamReader *manager) {
+  RenderAttrib::fillin(scan, manager);
+
+  // Read the _fog pointer.
+  manager->read_pointer(scan);
+}

+ 83 - 0
panda/src/pgraph/fogAttrib.h

@@ -0,0 +1,83 @@
+// Filename: fogAttrib.h
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef FOGATTRIB_H
+#define FOGATTRIB_H
+
+#include "pandabase.h"
+
+#include "renderAttrib.h"
+#include "qpfog.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : FogAttrib
+// Description : Applies a Fog to the geometry at and below this node.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA FogAttrib : public RenderAttrib {
+private:
+  INLINE FogAttrib();
+
+PUBLISHED:
+  static CPT(RenderAttrib) make(qpFog *fog);
+  static CPT(RenderAttrib) make_off();
+
+  INLINE bool is_off() const;
+  INLINE qpFog *get_fog() const;
+
+public:
+  virtual void issue(GraphicsStateGuardianBase *gsg) const;
+  virtual void output(ostream &out) const;
+
+protected:
+  virtual int compare_to_impl(const RenderAttrib *other) const;
+  virtual RenderAttrib *make_default_impl() const;
+
+private:
+  PT(qpFog) _fog;
+
+public:
+  static void register_with_read_factory();
+  virtual void write_datagram(BamWriter *manager, Datagram &dg);
+  virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
+
+protected:
+  static TypedWritable *make_from_bam(const FactoryParams &params);
+  void fillin(DatagramIterator &scan, BamReader *manager);
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    RenderAttrib::init_type();
+    register_type(_type_handle, "FogAttrib",
+                  RenderAttrib::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "fogAttrib.I"
+
+#endif
+

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

@@ -32,7 +32,7 @@ MaterialAttrib() {
 //       Access: Published
 //       Access: Published
 //  Description: Returns true if the MaterialAttrib is an 'off'
 //  Description: Returns true if the MaterialAttrib is an 'off'
 //               MaterialAttrib, indicating that it should disable
 //               MaterialAttrib, indicating that it should disable
-//               texturing.
+//               the use of materials.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool MaterialAttrib::
 INLINE bool MaterialAttrib::
 is_off() const {
 is_off() const {

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

@@ -2,6 +2,7 @@
 #include "binCullHandler.cxx"
 #include "binCullHandler.cxx"
 #include "qpcamera.cxx"
 #include "qpcamera.cxx"
 #include "colorAttrib.cxx"
 #include "colorAttrib.cxx"
+#include "colorScaleAttrib.cxx"
 #include "colorWriteAttrib.cxx"
 #include "colorWriteAttrib.cxx"
 #include "config_pgraph.cxx"
 #include "config_pgraph.cxx"
 #include "cullBin.cxx"
 #include "cullBin.cxx"
@@ -15,4 +16,8 @@
 #include "qpcullTraverser.cxx"
 #include "qpcullTraverser.cxx"
 #include "cullTraverserData.cxx"
 #include "cullTraverserData.cxx"
 #include "cullableObject.cxx"
 #include "cullableObject.cxx"
-
+#include "decalEffect.cxx"
+#include "depthOffsetAttrib.cxx"
+#include "depthTestAttrib.cxx"
+#include "depthWriteAttrib.cxx"
+#include "drawCullHandler.cxx"

+ 4 - 4
panda/src/pgraph/pgraph_composite2.cxx

@@ -1,10 +1,8 @@
-#include "decalEffect.cxx"
-#include "depthTestAttrib.cxx"
-#include "depthWriteAttrib.cxx"
-#include "drawCullHandler.cxx"
 #include "qpfindApproxPath.cxx"
 #include "qpfindApproxPath.cxx"
 #include "qpfindApproxLevel.cxx"
 #include "qpfindApproxLevel.cxx"
 #include "qpfindApproxLevelEntry.cxx"
 #include "qpfindApproxLevelEntry.cxx"
+#include "qpfog.cxx"
+#include "fogAttrib.cxx"
 #include "qpgeomNode.cxx"
 #include "qpgeomNode.cxx"
 #include "qplensNode.cxx"
 #include "qplensNode.cxx"
 #include "qplodNode.cxx"
 #include "qplodNode.cxx"
@@ -16,10 +14,12 @@
 #include "renderAttrib.cxx"
 #include "renderAttrib.cxx"
 #include "renderEffect.cxx"
 #include "renderEffect.cxx"
 #include "renderEffects.cxx"
 #include "renderEffects.cxx"
+#include "renderModeAttrib.cxx"
 #include "renderState.cxx"
 #include "renderState.cxx"
 #include "selectiveChildNode.cxx"
 #include "selectiveChildNode.cxx"
 #include "qpsequenceNode.cxx"
 #include "qpsequenceNode.cxx"
 #include "test_pgraph.cxx"
 #include "test_pgraph.cxx"
+#include "texMatrixAttrib.cxx"
 #include "textureApplyAttrib.cxx"
 #include "textureApplyAttrib.cxx"
 #include "textureAttrib.cxx"
 #include "textureAttrib.cxx"
 #include "transformState.cxx"
 #include "transformState.cxx"

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

@@ -21,6 +21,7 @@
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 
 
+#include "typeHandle.h"
 #include "pvector.h"
 #include "pvector.h"
 
 
 class PandaNode;
 class PandaNode;

+ 252 - 0
panda/src/pgraph/qpfog.I

@@ -0,0 +1,252 @@
+// Filename: qpfog.I
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::get_mode
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE qpFog::Mode qpFog::
+get_mode() const {
+  return _mode;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::set_mode
+//       Access: Published
+//  Description: Specifies the computation that is used to determine
+//               the fog effect.  If this is M_linear, then the fog
+//               will range from linearly from the onset point to the
+//               opaque point (or for the distances specified in
+//               set_linear_range), and the fog object should be
+//               parented into the scene graph, or to the camera.
+//
+//               If this is anything else, the onset point and opaque
+//               point are not used, and the fog effect is based on
+//               the value specified to set_exp_density(), and it
+//               doesn't matter to which node the fog object is
+//               parented, or if it is parented anywhere at all.
+////////////////////////////////////////////////////////////////////
+INLINE void qpFog::
+set_mode(Mode mode) {
+  _mode = mode;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::get_color
+//       Access: Published
+//  Description: Returns the color of the fog.
+////////////////////////////////////////////////////////////////////
+INLINE const Colorf &qpFog::
+get_color() const {
+  return _color;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::set_color
+//       Access: Published
+//  Description: Sets the color of the fog.
+////////////////////////////////////////////////////////////////////
+INLINE void qpFog::
+set_color(float r, float g, float b) {
+  _color[0] = r;
+  _color[1] = g;
+  _color[2] = b;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::set_color
+//       Access: Published
+//  Description: Sets the color of the fog.  The alpha component is
+//               not used.
+////////////////////////////////////////////////////////////////////
+INLINE void qpFog::
+set_color(const Colorf &color) {
+  _color = color;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::set_linear_range
+//       Access: Published
+//  Description: Specifies the effects of the fog in linear distance
+//               units.  This is only used if the mode is M_linear.
+//
+//               This specifies a fog that begins at distance onset
+//               units from the origin, and becomes totally opaque at
+//               distance opaque units from the origin, along the
+//               forward axis (usually Y).
+//
+//               This function also implicitly sets the mode the
+//               M_linear, if it is not already set.
+////////////////////////////////////////////////////////////////////
+INLINE void qpFog::
+set_linear_range(float onset, float opaque, CoordinateSystem cs) {
+  LVector3f forward = LVector3f::forward(cs);
+  _linear_onset_point = onset * forward;
+  _linear_opaque_point = opaque * forward;
+  _mode = M_linear;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::get_linear_onset_point
+//       Access: Published
+//  Description: Returns the point in space at which the fog begins.
+//               This is only used if the mode is M_linear.
+////////////////////////////////////////////////////////////////////
+INLINE const LPoint3f &qpFog::
+get_linear_onset_point() const {
+  return _linear_onset_point;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::set_linear_onset_point
+//       Access: Published
+//  Description: Specifies the point in space at which the fog begins.
+//               This is only used if the mode is M_linear.
+////////////////////////////////////////////////////////////////////
+INLINE void qpFog::
+set_linear_onset_point(float x, float y, float z) {
+  _linear_onset_point.set(x, y, z);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::set_linear_onset_point
+//       Access: Published
+//  Description: Specifies the point in space at which the fog begins.
+//               This is only used if the mode is M_linear.
+////////////////////////////////////////////////////////////////////
+INLINE void qpFog::
+set_linear_onset_point(const LPoint3f &linear_onset_point) {
+  _linear_onset_point = linear_onset_point;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::get_linear_opaque_point
+//       Access: Published
+//  Description: Returns the point in space at which the fog
+//               completely obscures geometry.  This is only used if
+//               the mode is M_linear.
+////////////////////////////////////////////////////////////////////
+INLINE const LPoint3f &qpFog::
+get_linear_opaque_point() const {
+  return _linear_opaque_point;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::set_linear_opaque_point
+//       Access: Published
+//  Description: Specifies the point in space at which the fog
+//               completely obscures geometry.  This is only used if
+//               the mode is M_linear.
+////////////////////////////////////////////////////////////////////
+INLINE void qpFog::
+set_linear_opaque_point(float x, float y, float z) {
+  _linear_opaque_point.set(x, y, z);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::set_linear_opaque_point
+//       Access: Published
+//  Description: Specifies the point in space at which the fog
+//               completely obscures geometry.  This is only used if
+//               the mode is M_linear.
+////////////////////////////////////////////////////////////////////
+INLINE void qpFog::
+set_linear_opaque_point(const LPoint3f &linear_opaque_point) {
+  _linear_opaque_point = linear_opaque_point;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::set_linear_fallback
+//       Access: Published
+//  Description: Fog effects are traditionally defined in
+//               camera-relative space, but the Panda Fog node has a
+//               special mode in which it can define a linear fog
+//               effect in an arbitrary coordinate space.
+//
+//               This is done by specifying 3-d onset and opaque
+//               points, and parenting the Fog object somewhere within
+//               the scene graph.  In this mode, the fog will be
+//               rendered as if it extended along the vector from the
+//               onset point to the opaque point, in 3-d space.
+//
+//               However, the underlying fog effect supported by
+//               hardware is generally only one-dimensional, and must
+//               be rendered based on linear distance from the camera
+//               plane.  Thus, this in-the-world effect is most
+//               effective when the fog vector from onset point to
+//               opaque point is most nearly parallel to the camera's
+//               eye vector.
+//
+//               As the angle between the fog vector and the eye
+//               vector increases, the accuracy of the effect
+//               diminishes, up to a complete breakdown of the effect
+//               at a 90 degree angle.
+//
+//               This function exists to define the workaround to this
+//               problem.  The linear fallback parameters given here
+//               specify how the fog should be rendered when the
+//               parameters are exceeded in this way.
+//
+//               The angle parameter is the minimum angle, in degrees,
+//               of the fog vector to the eye vector, at which the
+//               fallback effect should be employed.  The onset and
+//               opaque parameters specify the camera-relative onset
+//               and opaque distances to pass to the rendering
+//               hardware when employing the fallback effect.  This
+//               supercedes the 3-d onset point and opaque points.
+////////////////////////////////////////////////////////////////////
+INLINE void qpFog::
+set_linear_fallback(float angle, float onset, float opaque) {
+  _linear_fallback_cosa = ccos(deg_2_rad(angle));
+  _linear_fallback_onset = onset;
+  _linear_fallback_opaque = opaque;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::get_exp_density
+//       Access: Published
+//  Description: Returns the density of the fog for exponential
+//               calculations.  This is only used if the mode is not
+//               M_linear.
+////////////////////////////////////////////////////////////////////
+INLINE float qpFog::
+get_exp_density() const {
+  return _exp_density;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::set_exp_density
+//       Access: Published
+//  Description: Sets the density of the fog for exponential
+//               calculations.  This is only used if the mode is not
+//               M_linear.
+//
+//               If the mode is currently set to M_linear, this
+//               function implicitly sets it to M_exponential.
+////////////////////////////////////////////////////////////////////
+INLINE void qpFog::
+set_exp_density(float exp_density) {
+  nassertv((exp_density >= 0.0) && (exp_density <= 1.0));
+  _exp_density = exp_density;
+
+  if (_mode == M_linear) {
+    _mode = M_exponential;
+  }
+}

+ 262 - 0
panda/src/pgraph/qpfog.cxx

@@ -0,0 +1,262 @@
+// Filename: qpfog.cxx
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "pandabase.h"
+
+#include "qpfog.h"
+
+#include "mathNumbers.h"
+#include "qpnodePath.h"
+#include "bamReader.h"
+#include "bamWriter.h"
+#include "datagram.h"
+#include "datagramIterator.h"
+
+#include <stddef.h>
+
+TypeHandle qpFog::_type_handle;
+
+ostream &
+operator << (ostream &out, qpFog::Mode mode) {
+  switch (mode) {
+  case qpFog::M_linear:
+    return out << "linear";
+
+  case qpFog::M_exponential:
+    return out << "exponential";
+
+  case qpFog::M_exponential_squared:
+    return out << "exponential-squared";
+  }
+
+  return out << "**invalid**(" << (int)mode << ")";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::Constructor
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+qpFog::
+qpFog(const string &name) : 
+  PandaNode(name) 
+{
+  _mode = M_linear;
+  _color.set(1.0f, 1.0f, 1.0f, 1.0f);
+  _linear_onset_point.set(0.0f, 0.0f, 0.0f);
+  _linear_opaque_point.set(0.0f, 100.0f, 0.0f);
+  _exp_density = 0.5f;
+  _linear_fallback_cosa = -1.0f;
+  _linear_fallback_onset = 0.0f;
+  _linear_fallback_opaque = 0.0f;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::Copy Constructor
+//       Access: Protected
+//  Description:
+////////////////////////////////////////////////////////////////////
+qpFog::
+qpFog(const qpFog &copy) :
+  PandaNode(copy)
+{
+  _mode = copy._mode;
+  _color = copy._color;
+  _linear_onset_point = copy._linear_onset_point;
+  _linear_opaque_point = copy._linear_opaque_point;
+  _exp_density = copy._exp_density;
+  _linear_fallback_cosa = copy._linear_fallback_cosa;
+  _linear_fallback_onset = copy._linear_fallback_onset;
+  _linear_fallback_opaque = copy._linear_fallback_opaque;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+qpFog::
+~qpFog() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::make_copy
+//       Access: Public, Virtual
+//  Description: Returns a newly-allocated Node that is a shallow copy
+//               of this one.  It will be a different Node pointer,
+//               but its internal data may or may not be shared with
+//               that of the original Node.
+////////////////////////////////////////////////////////////////////
+PandaNode *qpFog::
+make_copy() const {
+  return new qpFog(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::xform
+//       Access: Public, Virtual
+//  Description: Transforms the contents of this node by the indicated
+//               matrix, if it means anything to do so.  For most
+//               kinds of nodes, this does nothing.
+////////////////////////////////////////////////////////////////////
+void qpFog::
+xform(const LMatrix4f &mat) {
+  _linear_onset_point = _linear_onset_point * mat;
+  _linear_opaque_point = _linear_opaque_point * mat;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::output
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+void qpFog::
+output(ostream &out) const {
+  out << "fog: " << _mode;
+  switch (_mode) {
+  case M_linear:
+    out << "(" << _linear_onset_point << ") -> ("
+        << _linear_opaque_point << ")";
+    break;
+
+  case M_exponential:
+  case M_exponential_squared:
+    out << _exp_density;
+    break;
+  };
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::compute_linear_range
+//       Access: Public
+//  Description: This function is intended to be called by GSG's to
+//               compute the appropriate camera-relative onset and
+//               opaque distances, based on the fog node's position
+//               within the scene graph (if linear fog is in effect).
+////////////////////////////////////////////////////////////////////
+void qpFog::
+compute_linear_range(float &onset, float &opaque,
+                     const qpNodePath &camera, CoordinateSystem cs) {
+  LVector3f forward = LVector3f::forward(cs);
+
+  LPoint3f onset_point, opaque_point;
+  if (get_num_parents() != 0) {
+    // Linear fog is relative to the fog's net transform in the scene
+    // graph.
+    qpNodePath this_np(this);
+
+    const LMatrix4f &mat = this_np.get_mat(camera);
+
+    // How far out of whack are we?
+    LVector3f fog_vector = (_linear_opaque_point - _linear_onset_point) * mat;
+    fog_vector.normalize();
+    float cosa = fog_vector.dot(forward);
+    if (cabs(cosa) < _linear_fallback_cosa) {
+      // The fog vector is too far from the eye vector; use the
+      // fallback mode.
+      onset = _linear_fallback_onset;
+      opaque = _linear_fallback_opaque;
+      //cerr << "fallback! " << cosa << " vs. " << _linear_fallback_cosa << "\n";
+      return;
+    }
+
+    onset_point = _linear_onset_point * mat;
+    opaque_point = _linear_opaque_point * mat;
+
+  } else {
+    // If the fog object has no parents, we assume the user meant
+    // camera-relative fog.
+    onset_point = _linear_onset_point;
+    opaque_point = _linear_opaque_point;
+  }
+  
+  onset = onset_point.dot(forward);
+  opaque = opaque_point.dot(forward);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::register_with_read_factory
+//       Access: Public, Static
+//  Description: Tells the BamReader how to create objects of type
+//               qpFog.
+////////////////////////////////////////////////////////////////////
+void qpFog::
+register_with_read_factory() {
+  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::write_datagram
+//       Access: Public, Virtual
+//  Description: Writes the contents of this object to the datagram
+//               for shipping out to a Bam file.
+////////////////////////////////////////////////////////////////////
+void qpFog::
+write_datagram(BamWriter *manager, Datagram &dg) {
+  PandaNode::write_datagram(manager, dg);
+
+  dg.add_int8(_mode);
+  _color.write_datagram(dg);
+  _linear_onset_point.write_datagram(dg);
+  _linear_opaque_point.write_datagram(dg);
+  dg.add_float32(_exp_density);
+  dg.add_float32(_linear_fallback_cosa);
+  dg.add_float32(_linear_fallback_onset);
+  dg.add_float32(_linear_fallback_opaque);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::make_from_bam
+//       Access: Protected, Static
+//  Description: This function is called by the BamReader's factory
+//               when a new object of type qpFog is encountered
+//               in the Bam file.  It should create the qpFog
+//               and extract its information from the file.
+////////////////////////////////////////////////////////////////////
+TypedWritable *qpFog::
+make_from_bam(const FactoryParams &params) {
+  qpFog *node = new qpFog("");
+  DatagramIterator scan;
+  BamReader *manager;
+
+  parse_params(params, scan, manager);
+  node->fillin(scan, manager);
+
+  return node;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::fillin
+//       Access: Protected
+//  Description: This internal function is called by make_from_bam to
+//               read in all of the relevant data from the BamFile for
+//               the new qpFog.
+////////////////////////////////////////////////////////////////////
+void qpFog::
+fillin(DatagramIterator &scan, BamReader *manager) {
+  PandaNode::fillin(scan, manager);
+
+  _mode = (Mode)scan.get_int8();
+  _color.read_datagram(scan);
+  _linear_onset_point.read_datagram(scan);
+  _linear_opaque_point.read_datagram(scan);
+  _exp_density = scan.get_float32();
+  _linear_fallback_cosa = scan.get_float32();
+  _linear_fallback_onset = scan.get_float32();
+  _linear_fallback_opaque = scan.get_float32();
+}

+ 147 - 0
panda/src/pgraph/qpfog.h

@@ -0,0 +1,147 @@
+// Filename: qpfog.h
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef qpFOG_H
+#define qpFOG_H
+
+#include "pandabase.h"
+
+#include "pandaNode.h"
+#include "luse.h"
+#include "cmath.h"
+#include "deg_2_rad.h"
+
+class qpNodePath;
+
+////////////////////////////////////////////////////////////////////
+//       Class : Fog
+// Description : Specifies how atmospheric fog effects are applied to
+//               geometry.  The Fog object is now a PandaNode, which
+//               means it can be used similarly to a Light to define
+//               effects relative to a particular coordinate system
+//               within the scene graph.
+//
+//               In exponential mode, the fog effects are always
+//               camera-relative, and it does not matter where the Fog
+//               node is parented.  However, in linear mode, the onset
+//               and opaque distances are defined as offsets along the
+//               local forward axis (e.g. the Y axis).  This allows
+//               the fog effect to be localized to a particular region
+//               in space, rather than always camera-relative.  If the
+//               fog object is not parented to any node, it is used to
+//               generate traditonal camera-relative fog, as if it
+//               were parented to the camera.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA qpFog : public PandaNode {
+PUBLISHED:
+  qpFog(const string &name);
+
+protected:
+  qpFog(const qpFog &copy);
+
+public:
+  virtual ~qpFog();
+
+  virtual PandaNode *make_copy() const;
+  virtual void xform(const LMatrix4f &mat);
+
+PUBLISHED:
+  enum Mode {
+    M_linear,                   // f = (end - z) / (end - start)
+    M_exponential,              // f = e^(-density * z)
+    M_exponential_squared       // f = e^((-density * z)^2)
+  };
+
+  INLINE Mode get_mode() const;
+  INLINE void set_mode(Mode mode);
+
+  INLINE const Colorf &get_color() const;
+  INLINE void set_color(float r, float g, float b);
+  INLINE void set_color(const Colorf &color);
+
+  INLINE void set_linear_range(float onset, float opaque,
+                               CoordinateSystem cs = CS_default);
+
+  INLINE const LPoint3f &get_linear_onset_point() const;
+  INLINE void set_linear_onset_point(float x, float y, float z);
+  INLINE void set_linear_onset_point(const LPoint3f &linear_onset_point);
+
+  INLINE const LPoint3f &get_linear_opaque_point() const;
+  INLINE void set_linear_opaque_point(const LPoint3f &linear_opaque_point);
+  INLINE void set_linear_opaque_point(float x, float y, float z);
+
+  INLINE void set_linear_fallback(float angle, float onset, float opaque);
+
+  INLINE float get_exp_density() const;
+  INLINE void set_exp_density(float exp_density);
+
+  void output(ostream &out) const;
+
+public:
+  void compute_linear_range(float &onset, float &opaque, 
+                            const qpNodePath &camera, CoordinateSystem cs);
+
+protected:
+  void compute_density();
+
+public:
+  static void register_with_read_factory();
+  virtual void write_datagram(BamWriter *manager, Datagram &dg);
+
+protected:
+  static TypedWritable *make_from_bam(const FactoryParams &params);
+  void fillin(DatagramIterator &scan, BamReader *manager);
+
+protected:
+  Mode _mode;
+  Colorf _color;
+  LPoint3f _linear_onset_point;
+  LPoint3f _linear_opaque_point;
+  float _exp_density;
+
+  float _linear_fallback_cosa;
+  float _linear_fallback_onset, _linear_fallback_opaque;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    TypedReferenceCount::init_type();
+    register_type(_type_handle, "qpFog",
+                  TypedReferenceCount::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+EXPCL_PANDA ostream &operator << (ostream &out, qpFog::Mode mode);
+
+INLINE ostream &operator << (ostream &out, const qpFog &fog) {
+  fog.output(out);
+  return out;
+}
+
+#include "qpfog.I"
+
+#endif

+ 60 - 21
panda/src/pgraph/qpnodePath.cxx

@@ -23,9 +23,12 @@
 #include "qpfindApproxLevel.h"
 #include "qpfindApproxLevel.h"
 #include "config_pgraph.h"
 #include "config_pgraph.h"
 #include "colorAttrib.h"
 #include "colorAttrib.h"
+#include "colorScaleAttrib.h"
 #include "cullBinAttrib.h"
 #include "cullBinAttrib.h"
 #include "textureAttrib.h"
 #include "textureAttrib.h"
 #include "materialAttrib.h"
 #include "materialAttrib.h"
+#include "fogAttrib.h"
+#include "renderModeAttrib.h"
 #include "cullFaceAttrib.h"
 #include "cullFaceAttrib.h"
 #include "billboardEffect.h"
 #include "billboardEffect.h"
 #include "transparencyAttrib.h"
 #include "transparencyAttrib.h"
@@ -677,21 +680,30 @@ set_mat(const LMatrix4f &mat) {
 //               leaving translation and rotation untouched.
 //               leaving translation and rotation untouched.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void qpNodePath::
 void qpNodePath::
-set_color_scale(const LVecBase4f &sv4) {
-  nassertv(false);
+set_color_scale(const LVecBase4f &scale) {
+  nassertv_always(!is_empty());
+  node()->set_attrib(ColorScaleAttrib::make(scale));
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: qpNodePath::get_color_scale
 //     Function: qpNodePath::get_color_scale
 //       Access: Published
 //       Access: Published
-//  Description: Returns the complete transform vector that has been
-//               applied to the bottom node, or the all 1's if no
-//               scale has been applied
+//  Description: Returns the complete color scale vector that has been
+//               applied to the bottom node, or all 1's (identity) if
+//               no scale has been applied.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-LVecBase4f qpNodePath::
+const LVecBase4f &qpNodePath::
 get_color_scale() const {
 get_color_scale() const {
-  nassertr(false, LVecBase4f(1.0f,1.0f,1.0f,1.0f));
-  return LVecBase4f(1.0f,1.0f,1.0f,1.0f);
+  static const LVecBase4f ident_scale(1.0f, 1.0f, 1.0f, 1.0f);
+  nassertr(!is_empty(), ident_scale);
+  const RenderAttrib *attrib =
+    node()->get_attrib(ColorScaleAttrib::get_class_type());
+  if (attrib != (const RenderAttrib *)NULL) {
+    const ColorScaleAttrib *csa = DCAST(ColorScaleAttrib, attrib);
+    return csa->get_scale();
+  }
+
+  return ident_scale;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1664,8 +1676,9 @@ get_material() const {
 //               using the indicated fog.
 //               using the indicated fog.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void qpNodePath::
 void qpNodePath::
-set_fog(Fog *fog, int priority) {
-  nassertv(false);
+set_fog(qpFog *fog, int priority) {
+  nassertv_always(!is_empty());
+  node()->set_attrib(FogAttrib::make(fog), priority);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1680,7 +1693,8 @@ set_fog(Fog *fog, int priority) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void qpNodePath::
 void qpNodePath::
 set_fog_off(int priority) {
 set_fog_off(int priority) {
-  nassertv(false);
+  nassertv_always(!is_empty());
+  node()->set_attrib(FogAttrib::make_off(), priority);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1694,7 +1708,8 @@ set_fog_off(int priority) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void qpNodePath::
 void qpNodePath::
 clear_fog() {
 clear_fog() {
-  nassertv(false);
+  nassertv(!is_empty());
+  node()->clear_attrib(FogAttrib::get_class_type());
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1709,7 +1724,14 @@ clear_fog() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool qpNodePath::
 bool qpNodePath::
 has_fog() const {
 has_fog() const {
-  nassertr(false, false);
+  nassertr(!is_empty(), false);
+  const RenderAttrib *attrib =
+    node()->get_attrib(FogAttrib::get_class_type());
+  if (attrib != (const RenderAttrib *)NULL) {
+    const FogAttrib *fa = DCAST(FogAttrib, attrib);
+    return !fa->is_off();
+  }
+
   return false;
   return false;
 }
 }
 
 
@@ -1725,7 +1747,14 @@ has_fog() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool qpNodePath::
 bool qpNodePath::
 has_fog_off() const {
 has_fog_off() const {
-  nassertr(false, false);
+  nassertr(!is_empty(), false);
+  const RenderAttrib *attrib =
+    node()->get_attrib(FogAttrib::get_class_type());
+  if (attrib != (const RenderAttrib *)NULL) {
+    const FogAttrib *fa = DCAST(FogAttrib, attrib);
+    return fa->is_off();
+  }
+
   return false;
   return false;
 }
 }
 
 
@@ -1739,9 +1768,16 @@ has_fog_off() const {
 //               another fog at a higher or lower level may
 //               another fog at a higher or lower level may
 //               override.
 //               override.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-Fog *qpNodePath::
+qpFog *qpNodePath::
 get_fog() const {
 get_fog() const {
-  nassertr(false, NULL);
+  nassertr(!is_empty(), NULL);
+  const RenderAttrib *attrib =
+    node()->get_attrib(FogAttrib::get_class_type());
+  if (attrib != (const RenderAttrib *)NULL) {
+    const FogAttrib *fa = DCAST(FogAttrib, attrib);
+    return fa->get_fog();
+  }
+
   return NULL;
   return NULL;
 }
 }
 
 
@@ -1753,7 +1789,8 @@ get_fog() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void qpNodePath::
 void qpNodePath::
 set_render_mode_wireframe(int priority) {
 set_render_mode_wireframe(int priority) {
-  nassertv(false);
+  nassertv_always(!is_empty());
+  node()->set_attrib(RenderModeAttrib::make(RenderModeAttrib::M_wireframe), priority);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1765,7 +1802,8 @@ set_render_mode_wireframe(int priority) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void qpNodePath::
 void qpNodePath::
 set_render_mode_filled(int priority) {
 set_render_mode_filled(int priority) {
-  nassertv(false);
+  nassertv_always(!is_empty());
+  node()->set_attrib(RenderModeAttrib::make(RenderModeAttrib::M_filled), priority);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1778,7 +1816,8 @@ set_render_mode_filled(int priority) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void qpNodePath::
 void qpNodePath::
 clear_render_mode() {
 clear_render_mode() {
-  nassertv(false);
+  nassertv(!is_empty());
+  node()->clear_attrib(RenderModeAttrib::get_class_type());
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1791,8 +1830,8 @@ clear_render_mode() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool qpNodePath::
 bool qpNodePath::
 has_render_mode() const {
 has_render_mode() const {
-  nassertr(false, false);
-  return false;
+  nassertr(!is_empty(), false);
+  return node()->has_attrib(RenderModeAttrib::get_class_type());
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 5 - 5
panda/src/pgraph/qpnodePath.h

@@ -36,7 +36,7 @@ class qpFindApproxLevel;
 class qpFindApproxPath;
 class qpFindApproxPath;
 class Texture;
 class Texture;
 class Material;
 class Material;
-class Fog;
+class qpFog;
 
 
 //
 //
 // A NodePath is the fundamental unit of high-level interaction with
 // A NodePath is the fundamental unit of high-level interaction with
@@ -275,14 +275,14 @@ PUBLISHED:
   INLINE bool has_color_scale() const;
   INLINE bool has_color_scale() const;
   INLINE void clear_color_scale();
   INLINE void clear_color_scale();
 
 
-  void set_color_scale(const LVecBase4f &sv4);
+  void set_color_scale(const LVecBase4f &scale);
   INLINE void set_color_scale(float sx, float sy, float sz, float sa);
   INLINE void set_color_scale(float sx, float sy, float sz, float sa);
   INLINE void set_sr(float sr);
   INLINE void set_sr(float sr);
   INLINE void set_sg(float sg);
   INLINE void set_sg(float sg);
   INLINE void set_sb(float sb);
   INLINE void set_sb(float sb);
   INLINE void set_sa(float sa);
   INLINE void set_sa(float sa);
 
 
-  LVecBase4f get_color_scale() const;
+  const LVecBase4f &get_color_scale() const;
   INLINE float get_sr() const;
   INLINE float get_sr() const;
   INLINE float get_sg() const;
   INLINE float get_sg() const;
   INLINE float get_sb() const;
   INLINE float get_sb() const;
@@ -413,12 +413,12 @@ PUBLISHED:
   bool has_material() const;
   bool has_material() const;
   PT(Material) get_material() const;
   PT(Material) get_material() const;
 
 
-  void set_fog(Fog *fog, int priority = 0);
+  void set_fog(qpFog *fog, int priority = 0);
   void set_fog_off(int priority = 0);
   void set_fog_off(int priority = 0);
   void clear_fog();
   void clear_fog();
   bool has_fog() const;
   bool has_fog() const;
   bool has_fog_off() const;
   bool has_fog_off() const;
-  Fog *get_fog() const;
+  qpFog *get_fog() const;
 
 
   void set_render_mode_wireframe(int priority = 0);
   void set_render_mode_wireframe(int priority = 0);
   void set_render_mode_filled(int priority = 0);
   void set_render_mode_filled(int priority = 0);

+ 52 - 0
panda/src/pgraph/renderModeAttrib.I

@@ -0,0 +1,52 @@
+// Filename: renderModeAttrib.I
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderModeAttrib::Constructor
+//       Access: Private
+//  Description: Use RenderModeAttrib::make() to construct a new
+//               RenderModeAttrib object.
+////////////////////////////////////////////////////////////////////
+INLINE RenderModeAttrib::
+RenderModeAttrib(RenderModeAttrib::Mode mode, float line_width) :
+  _mode(mode),
+  _line_width(line_width)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderModeAttrib::get_mode
+//       Access: Published
+//  Description: Returns the render mode.
+////////////////////////////////////////////////////////////////////
+INLINE RenderModeAttrib::Mode RenderModeAttrib::
+get_mode() const {
+  return _mode;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderModeAttrib::get_line_width
+//       Access: Published
+//  Description: Returns the line width.  This is only relevant when
+//               the mode is M_wireframe.
+////////////////////////////////////////////////////////////////////
+INLINE float RenderModeAttrib::
+get_line_width() const {
+  return _line_width;
+}

+ 185 - 0
panda/src/pgraph/renderModeAttrib.cxx

@@ -0,0 +1,185 @@
+// Filename: renderModeAttrib.cxx
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "renderModeAttrib.h"
+#include "graphicsStateGuardianBase.h"
+#include "dcast.h"
+#include "bamReader.h"
+#include "bamWriter.h"
+#include "datagram.h"
+#include "datagramIterator.h"
+
+TypeHandle RenderModeAttrib::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderModeAttrib::make
+//       Access: Published, Static
+//  Description: Constructs a new RenderModeAttrib object that specifies
+//               whether to draw polygons in the normal, filled mode,
+//               or wireframe mode, or in some other yet-to-be-defined
+//               mode.
+//
+//               The line_width is relevant only if mode is
+//               M_wireframe, and specifies the thickness of the
+//               lines, in pixels, to use for wireframe.
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) RenderModeAttrib::
+make(RenderModeAttrib::Mode mode, float line_width) {
+  if (mode != M_wireframe) {
+    line_width = 0.0f;
+  }
+  RenderModeAttrib *attrib = new RenderModeAttrib(mode, line_width);
+  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
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void RenderModeAttrib::
+output(ostream &out) const {
+  out << get_type() << ":";
+  switch (get_mode()) {
+  case M_filled:
+    out << "filled";
+    break;
+
+  case M_wireframe:
+    out << "wireframe(" << get_line_width() << ")";
+    break;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderModeAttrib::compare_to_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived RenderModeAttrib
+//               types to return a unique number indicating whether
+//               this RenderModeAttrib is equivalent to the other one.
+//
+//               This should return 0 if the two RenderModeAttrib objects
+//               are equivalent, a number less than zero if this one
+//               should be sorted before the other one, and a number
+//               greater than zero otherwise.
+//
+//               This will only be called with two RenderModeAttrib
+//               objects whose get_type() functions return the same.
+////////////////////////////////////////////////////////////////////
+int RenderModeAttrib::
+compare_to_impl(const RenderAttrib *other) const {
+  const RenderModeAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  if (_mode != ta->_mode) {
+    return (int)_mode - (int)ta->_mode;
+  }
+  if (_line_width != ta->_line_width) {
+    return _line_width < ta->_line_width ? -1 : 1;
+  }
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderModeAttrib::make_default_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived RenderModeAttrib
+//               types to specify what the default property for a
+//               RenderModeAttrib of this type should be.
+//
+//               This should return a newly-allocated RenderModeAttrib of
+//               the same type that corresponds to whatever the
+//               standard default for this kind of RenderModeAttrib is.
+////////////////////////////////////////////////////////////////////
+RenderAttrib *RenderModeAttrib::
+make_default_impl() const {
+  return new RenderModeAttrib(M_filled, 0.0f);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderModeAttrib::register_with_read_factory
+//       Access: Public, Static
+//  Description: Tells the BamReader how to create objects of type
+//               RenderModeAttrib.
+////////////////////////////////////////////////////////////////////
+void RenderModeAttrib::
+register_with_read_factory() {
+  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderModeAttrib::write_datagram
+//       Access: Public, Virtual
+//  Description: Writes the contents of this object to the datagram
+//               for shipping out to a Bam file.
+////////////////////////////////////////////////////////////////////
+void RenderModeAttrib::
+write_datagram(BamWriter *manager, Datagram &dg) {
+  RenderAttrib::write_datagram(manager, dg);
+
+  dg.add_int8(_mode);
+  dg.add_float32(_line_width);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderModeAttrib::make_from_bam
+//       Access: Protected, Static
+//  Description: This function is called by the BamReader's factory
+//               when a new object of type RenderModeAttrib is encountered
+//               in the Bam file.  It should create the RenderModeAttrib
+//               and extract its information from the file.
+////////////////////////////////////////////////////////////////////
+TypedWritable *RenderModeAttrib::
+make_from_bam(const FactoryParams &params) {
+  RenderModeAttrib *attrib = new RenderModeAttrib(M_filled, 0.0f);
+  DatagramIterator scan;
+  BamReader *manager;
+
+  parse_params(params, scan, manager);
+  attrib->fillin(scan, manager);
+
+  return attrib;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderModeAttrib::fillin
+//       Access: Protected
+//  Description: This internal function is called by make_from_bam to
+//               read in all of the relevant data from the BamFile for
+//               the new RenderModeAttrib.
+////////////////////////////////////////////////////////////////////
+void RenderModeAttrib::
+fillin(DatagramIterator &scan, BamReader *manager) {
+  RenderAttrib::fillin(scan, manager);
+
+  _mode = (Mode)scan.get_int8();
+  _line_width = scan.get_float32();
+}

+ 90 - 0
panda/src/pgraph/renderModeAttrib.h

@@ -0,0 +1,90 @@
+// Filename: renderModeAttrib.h
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef RENDERMODEATTRIB_H
+#define RENDERMODEATTRIB_H
+
+#include "pandabase.h"
+
+#include "renderAttrib.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : RenderModeAttrib
+// Description : Enables or disables writing to the depth buffer.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA RenderModeAttrib : public RenderAttrib {
+PUBLISHED:
+  enum Mode {
+    M_filled,
+    M_wireframe,
+    // M_point
+
+    // Perhaps others to be added later.
+  };
+
+private:
+  INLINE RenderModeAttrib(Mode mode, float line_width);
+
+PUBLISHED:
+  static CPT(RenderAttrib) make(Mode mode, float line_width = 1.0f);
+
+  INLINE Mode get_mode() const;
+  INLINE float get_line_width() const;
+
+public:
+  virtual void issue(GraphicsStateGuardianBase *gsg) const;
+  virtual void output(ostream &out) const;
+
+protected:
+  virtual int compare_to_impl(const RenderAttrib *other) const;
+  virtual RenderAttrib *make_default_impl() const;
+
+private:
+  Mode _mode;
+  float _line_width;
+
+public:
+  static void register_with_read_factory();
+  virtual void write_datagram(BamWriter *manager, Datagram &dg);
+
+protected:
+  static TypedWritable *make_from_bam(const FactoryParams &params);
+  void fillin(DatagramIterator &scan, BamReader *manager);
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    RenderAttrib::init_type();
+    register_type(_type_handle, "RenderModeAttrib",
+                  RenderAttrib::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "renderModeAttrib.I"
+
+#endif
+

+ 40 - 0
panda/src/pgraph/texMatrixAttrib.I

@@ -0,0 +1,40 @@
+// Filename: texMatrixAttrib.I
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::Constructor
+//       Access: Private
+//  Description: Use TexMatrixAttrib::make() to construct a new
+//               TexMatrixAttrib object.
+////////////////////////////////////////////////////////////////////
+INLINE TexMatrixAttrib::
+TexMatrixAttrib(const LMatrix4f &mat) :
+  _mat(mat)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::get_mat
+//       Access: Published
+//  Description: Returns the UV transformation matrix.
+////////////////////////////////////////////////////////////////////
+INLINE const LMatrix4f &TexMatrixAttrib::
+get_mat() const {
+  return _mat;
+}

+ 207 - 0
panda/src/pgraph/texMatrixAttrib.cxx

@@ -0,0 +1,207 @@
+// Filename: texMatrixAttrib.cxx
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "texMatrixAttrib.h"
+#include "graphicsStateGuardianBase.h"
+#include "dcast.h"
+#include "bamReader.h"
+#include "bamWriter.h"
+#include "datagram.h"
+#include "datagramIterator.h"
+
+TypeHandle TexMatrixAttrib::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::make
+//       Access: Published, Static
+//  Description: Constructs a new TexMatrixAttrib object that indicates
+//               geometry should be scaled by the indicated factor.
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) TexMatrixAttrib::
+make(const LMatrix4f &mat) {
+  TexMatrixAttrib *attrib = new TexMatrixAttrib(mat);
+  return return_new(attrib);
+}
+
+////////////////////////////////////////////////////////////////////
+//     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
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void TexMatrixAttrib::
+output(ostream &out) const {
+  out << get_type() << ":(" << get_mat() << ")";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::compare_to_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived TexMatrixAttrib
+//               types to return a unique number indicating whether
+//               this TexMatrixAttrib is equivalent to the other one.
+//
+//               This should return 0 if the two TexMatrixAttrib objects
+//               are equivalent, a number less than zero if this one
+//               should be sorted before the other one, and a number
+//               greater than zero otherwise.
+//
+//               This will only be called with two TexMatrixAttrib
+//               objects whose get_type() functions return the same.
+////////////////////////////////////////////////////////////////////
+int TexMatrixAttrib::
+compare_to_impl(const RenderAttrib *other) const {
+  const TexMatrixAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  return _mat.compare_to(ta->_mat);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::compose_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived RenderAttrib
+//               types to specify how two consecutive RenderAttrib
+//               objects of the same type interact.
+//
+//               This should return the result of applying the other
+//               RenderAttrib to a node in the scene graph below this
+//               RenderAttrib, which was already applied.  In most
+//               cases, the result is the same as the other
+//               RenderAttrib (that is, a subsequent RenderAttrib
+//               completely replaces the preceding one).  On the other
+//               hand, some kinds of RenderAttrib (for instance,
+//               ColorTransformAttrib) might combine in meaningful
+//               ways.
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) TexMatrixAttrib::
+compose_impl(const RenderAttrib *other) const {
+  const TexMatrixAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  LMatrix4f new_mat = ta->_mat * _mat;
+
+  TexMatrixAttrib *attrib = new TexMatrixAttrib(new_mat);
+  return return_new(attrib);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::invert_compose_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived RenderAttrib
+//               types to specify how two consecutive RenderAttrib
+//               objects of the same type interact.
+//
+//               See invert_compose() and compose_impl().
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) TexMatrixAttrib::
+invert_compose_impl(const RenderAttrib *other) const {
+  const TexMatrixAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  LMatrix4f new_mat;
+  new_mat.invert_from(_mat);
+  new_mat = ta->_mat * new_mat;
+
+  TexMatrixAttrib *attrib = new TexMatrixAttrib(new_mat);
+  return return_new(attrib);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::make_default_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived TexMatrixAttrib
+//               types to specify what the default property for a
+//               TexMatrixAttrib of this type should be.
+//
+//               This should return a newly-allocated TexMatrixAttrib of
+//               the same type that corresponds to whatever the
+//               standard default for this kind of TexMatrixAttrib is.
+////////////////////////////////////////////////////////////////////
+RenderAttrib *TexMatrixAttrib::
+make_default_impl() const {
+  return new TexMatrixAttrib(LMatrix4f::ident_mat());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::register_with_read_factory
+//       Access: Public, Static
+//  Description: Tells the BamReader how to create objects of type
+//               TexMatrixAttrib.
+////////////////////////////////////////////////////////////////////
+void TexMatrixAttrib::
+register_with_read_factory() {
+  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::write_datagram
+//       Access: Public, Virtual
+//  Description: Writes the contents of this object to the datagram
+//               for shipping out to a Bam file.
+////////////////////////////////////////////////////////////////////
+void TexMatrixAttrib::
+write_datagram(BamWriter *manager, Datagram &dg) {
+  RenderAttrib::write_datagram(manager, dg);
+
+  _mat.write_datagram(dg);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::make_from_bam
+//       Access: Protected, Static
+//  Description: This function is called by the BamReader's factory
+//               when a new object of type TexMatrixAttrib is encountered
+//               in the Bam file.  It should create the TexMatrixAttrib
+//               and extract its information from the file.
+////////////////////////////////////////////////////////////////////
+TypedWritable *TexMatrixAttrib::
+make_from_bam(const FactoryParams &params) {
+  TexMatrixAttrib *attrib = new TexMatrixAttrib(LMatrix4f::ident_mat());
+  DatagramIterator scan;
+  BamReader *manager;
+
+  parse_params(params, scan, manager);
+  attrib->fillin(scan, manager);
+
+  return attrib;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TexMatrixAttrib::fillin
+//       Access: Protected
+//  Description: This internal function is called by make_from_bam to
+//               read in all of the relevant data from the BamFile for
+//               the new TexMatrixAttrib.
+////////////////////////////////////////////////////////////////////
+void TexMatrixAttrib::
+fillin(DatagramIterator &scan, BamReader *manager) {
+  RenderAttrib::fillin(scan, manager);
+
+  _mat.read_datagram(scan);
+}

+ 83 - 0
panda/src/pgraph/texMatrixAttrib.h

@@ -0,0 +1,83 @@
+// Filename: texMatrixAttrib.h
+// Created by:  drose (14Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef TEXMATRIXATTRIB_H
+#define TEXMATRIXATTRIB_H
+
+#include "pandabase.h"
+
+#include "renderAttrib.h"
+#include "luse.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : TexMatrixAttrib
+// Description : Applies a transform matrix to UV's before they are
+//               rendered.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA TexMatrixAttrib : public RenderAttrib {
+private:
+  INLINE TexMatrixAttrib(const LMatrix4f &mat);
+
+PUBLISHED:
+  static CPT(RenderAttrib) make(const LMatrix4f &mat);
+
+  INLINE const LMatrix4f &get_mat() const;
+
+public:
+  virtual void issue(GraphicsStateGuardianBase *gsg) const;
+  virtual void output(ostream &out) const;
+
+protected:
+  virtual int compare_to_impl(const RenderAttrib *other) const;
+  virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const;
+  virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const;
+  virtual RenderAttrib *make_default_impl() const;
+
+private:
+  LMatrix4f _mat;
+
+public:
+  static void register_with_read_factory();
+  virtual void write_datagram(BamWriter *manager, Datagram &dg);
+
+protected:
+  static TypedWritable *make_from_bam(const FactoryParams &params);
+  void fillin(DatagramIterator &scan, BamReader *manager);
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    RenderAttrib::init_type();
+    register_type(_type_handle, "TexMatrixAttrib",
+                  RenderAttrib::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "texMatrixAttrib.I"
+
+#endif
+

+ 28 - 9
panda/src/testbed/pview.cxx

@@ -61,9 +61,14 @@ static const int win_height = config_pview.GetInt("win-height", 480);
 // As long as this is true, the main loop will continue running.
 // As long as this is true, the main loop will continue running.
 bool run_flag = true;
 bool run_flag = true;
 
 
+// These are referenced in both event_w() and in event_b().
+bool wireframe = false;
+bool two_sided = false;
+
+
 // These are used by report_frame_rate().
 // These are used by report_frame_rate().
-static double start_time = 0.0;
-static int start_frame_count = 0;
+double start_time = 0.0;
+int start_frame_count = 0;
 
 
 // A priority number high enough to override any model file settings.
 // A priority number high enough to override any model file settings.
 static const int override_priority = 100;
 static const int override_priority = 100;
@@ -286,21 +291,38 @@ event_t(CPT_Event) {
 void
 void
 event_w(CPT_Event) {
 event_w(CPT_Event) {
   // 'w' : toggle wireframe.
   // 'w' : toggle wireframe.
-  static bool wireframe = false;
-
   wireframe = !wireframe;
   wireframe = !wireframe;
   if (wireframe) {
   if (wireframe) {
     nout << "Setting wireframe mode.\n";
     nout << "Setting wireframe mode.\n";
     render.set_render_mode_wireframe(override_priority);
     render.set_render_mode_wireframe(override_priority);
+    render.set_two_sided(true, override_priority);
   } else {
   } else {
     nout << "Clearing wireframe mode.\n";
     nout << "Clearing wireframe mode.\n";
     render.clear_render_mode();
     render.clear_render_mode();
+    if (!two_sided) {
+      render.clear_two_sided();
+    }
+  }
+}
+
+void
+event_b(CPT_Event) {
+  // 'b' : toggle backfacing.
+  two_sided = !two_sided;
+  if (two_sided) {
+    nout << "Showing back-facing polygons.\n";
+    render.set_two_sided(true, override_priority);
+  } else {
+    nout << "Hiding back-facing polygons.\n";
+    if (!wireframe) {
+      render.clear_two_sided();
+    }
   }
   }
 }
 }
 
 
 void
 void
 event_s(CPT_Event) {
 event_s(CPT_Event) {
-  // 's' : toggle state sorting by putting everything into an 'unsorted' bin.
+  // 's' : toggle state sorting by putting everything into the 'unsorted' bin.
   static bool sorting_off = false;
   static bool sorting_off = false;
 
 
   sorting_off = !sorting_off;
   sorting_off = !sorting_off;
@@ -356,10 +378,6 @@ main(int argc, char *argv[]) {
   render.attach_new_node(camera);
   render.attach_new_node(camera);
   camera->set_scene(render);
   camera->set_scene(render);
 
 
-  // We will take advantage of this bin if the user toggles state
-  // sorting, above, in event_s().
-  CullBinManager::get_global_ptr()->add_bin("unsorted", CullBinManager::BT_unsorted, 0);
-
   // Set up a data graph for tracking user input.
   // Set up a data graph for tracking user input.
   PT(PandaNode) data_root = new PandaNode("data_root");
   PT(PandaNode) data_root = new PandaNode("data_root");
   PandaNode *mouse = setup_mouse(data_root, window);
   PandaNode *mouse = setup_mouse(data_root, window);
@@ -373,6 +391,7 @@ main(int argc, char *argv[]) {
   event_handler.add_hook("f", event_f);
   event_handler.add_hook("f", event_f);
   event_handler.add_hook("t", event_t);
   event_handler.add_hook("t", event_t);
   event_handler.add_hook("w", event_w);
   event_handler.add_hook("w", event_w);
+  event_handler.add_hook("b", event_b);
   event_handler.add_hook("s", event_s);
   event_handler.add_hook("s", event_s);
   event_handler.add_hook("shift-s", event_S);
   event_handler.add_hook("shift-s", event_S);
   event_handler.add_hook("shift-a", event_A);
   event_handler.add_hook("shift-a", event_A);