Pārlūkot izejas kodu

latest from glgsg

David Rose 24 gadi atpakaļ
vecāks
revīzija
548b2c871d

+ 5 - 0
panda/src/crgsg/config_crgsg.cxx

@@ -65,6 +65,11 @@ bool cr_save_mipmaps = config_crgsg.GetBool("cr-save-mipmaps", false);
 // variable.
 bool cr_auto_normalize_lighting = config_crgsg.GetBool("auto-normalize-lighting", false);
 
+// Configure this true to try to implement decals using a
+// DepthOffsetAttrib, false to do them with the more reliable 3-pass
+// rendering method instead.
+bool cr_depth_offset_decals = config_crgsg.GetBool("depth-offset-decals", false);
+
 // Configure this true to indicate the current version of GL fully
 // supports textures with B, G, R ordering; false if it only supports
 // R, G, B.  false will always work, but true might be faster if the

+ 1 - 0
panda/src/crgsg/config_crgsg.h

@@ -32,6 +32,7 @@ extern bool cr_force_mipmaps;
 extern bool cr_show_mipmaps;
 extern bool cr_save_mipmaps;
 extern bool cr_auto_normalize_lighting;
+extern bool cr_depth_offset_decals;
 extern bool cr_supports_bgr;
 
 // Ways to implement decals.

+ 0 - 85
panda/src/crgsg/crGraphicsStateGuardian.I

@@ -20,18 +20,6 @@
 
 #include <graphicsWindow.h>
 
-////////////////////////////////////////////////////////////////////
-//     Function: CRGraphicsStateGuardian::LightInfo::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE CRGraphicsStateGuardian::LightInfo::
-LightInfo() {
-  _light = (Light *)NULL;
-  _enabled = false;
-  _next_enabled = false;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CRGraphicsStateGuardian::activate
 //       Access: Public
@@ -227,24 +215,6 @@ call_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
     }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: CRGraphicsStateGuardian::call_glLightModelAmbient
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void CRGraphicsStateGuardian::
-call_glLightModelAmbient( const Colorf& color )
-{
-  if (_lmodel_ambient != color) {
-    _lmodel_ambient = color;
-#ifdef GSG_VERBOSE
-    crgsg_cat.debug()
-      << "crLightModel(GL_LIGHT_MODEL_AMBIENT, " << color << ")" << endl;
-#endif
-    chromium.LightModelfv(GL_LIGHT_MODEL_AMBIENT, color.get_data());
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CRGraphicsStateGuardian::call_glLightModelLocal
 //       Access:
@@ -733,32 +703,6 @@ enable_point_smooth(bool val) {
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: CRGraphicsStateGuardian::enable_lighting
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void CRGraphicsStateGuardian::
-enable_lighting(bool val) {
-  if (_lighting_enabled != val) {
-    _lighting_enabled = val;
-    if (val) {
-#ifdef GSG_VERBOSE
-      crgsg_cat.debug()
-        << "crEnable(GL_LIGHTING)" << endl;
-#endif
-      chromium.Enable(GL_LIGHTING);
-      _lighting_enabled_this_frame = true;
-    } else {
-#ifdef GSG_VERBOSE
-      crgsg_cat.debug()
-        << "crDisable(GL_LIGHTING)" << endl;
-#endif
-      chromium.Disable(GL_LIGHTING);
-    }
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CRGraphicsStateGuardian::enable_dither
 //       Access:
@@ -809,35 +753,6 @@ enable_stencil_test(bool val) {
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: CRGraphicsStateGuardian::enable_light
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void CRGraphicsStateGuardian::enable_light(int light, bool val)
-{
-    if ( _light_info[light]._enabled != val )
-    {
-        _light_info[light]._enabled = val;
-        if ( val )
-        {
-#ifdef GSG_VERBOSE
-          crgsg_cat.debug()
-            << "crEnable(GL_LIGHT" << light << ")" << endl;
-#endif
-            chromium.Enable( get_light_id( light ) );
-        }
-        else
-        {
-#ifdef GSG_VERBOSE
-          crgsg_cat.debug()
-            << "crDisable(GL_LIGHT" << light << ")" << endl;
-#endif
-            chromium.Disable( get_light_id( light ) );
-        }
-    }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CRGraphicsStateGuardian::enable_texturing
 //       Access:

+ 242 - 378
panda/src/crgsg/crGraphicsStateGuardian.cxx

@@ -36,7 +36,6 @@
 #include "lens.h"
 #include "get_rel_pos.h"
 #include "perspectiveLens.h"
-#include "ambientLight.h"
 #include "directionalLight.h"
 #include "pointLight.h"
 #include "spotlight.h"
@@ -46,7 +45,6 @@
 #include "colorMatrixTransition.h"
 #include "alphaTransformTransition.h"
 #include "colorTransition.h"
-#include "lightTransition.h"
 #include "textureTransition.h"
 #include "renderModeTransition.h"
 #include "materialTransition.h"
@@ -66,6 +64,7 @@
 #include "pointShapeTransition.h"
 #include "polygonOffsetTransition.h"
 #include "textureAttrib.h"
+#include "lightAttrib.h"
 #include "cullFaceAttrib.h"
 #include "transparencyAttrib.h"
 #include "depthTestAttrib.h"
@@ -157,7 +156,6 @@ issue_transformed_color_gl(const Geom *geom, Geom::ColorIterator &citerator,
 ////////////////////////////////////////////////////////////////////
 CRGraphicsStateGuardian::
 CRGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) {
-  _light_info = (LightInfo *)NULL;
   _clip_plane_enabled = (bool *)NULL;
   _cur_clip_plane_enabled = (bool *)NULL;
 
@@ -261,8 +259,6 @@ reset() {
   _line_smooth_enabled = false;
   _point_smooth_enabled = false;
   _scissor_enabled = false;
-  _lighting_enabled = false;
-  _lighting_enabled_this_frame = false;
   _normals_enabled = false;
   _texturing_enabled = false;
   _multisample_alpha_one_enabled = false;
@@ -294,9 +290,8 @@ reset() {
 
   // Set up the light id map
   GLint max_lights;
-  chromium.GetIntegerv( GL_MAX_LIGHTS, &max_lights );
-  _max_lights = max_lights;
-  _light_info = new LightInfo[_max_lights];
+  chromium.GetIntegerv(GL_MAX_LIGHTS, &max_lights);
+  init_lights(max_lights);
 
   // Set up the clip plane id map
   GLint max_clip_planes;
@@ -319,15 +314,16 @@ reset() {
   PT(DepthTestTransition) dta = new DepthTestTransition;
   PT(DepthWriteTransition) dwa = new DepthWriteTransition;
   PT(CullFaceTransition) cfa = new CullFaceTransition;
-  PT(LightTransition) la = new LightTransition;
   PT(TextureTransition) ta = new TextureTransition;
 
   dta->issue(this);
   dwa->issue(this);
   cfa->issue(this);
-  la->issue(this);
   ta->issue(this);
 
+  Material empty;
+  apply_material(&empty);
+
   if (cr_cheap_textures) {
     crgsg_cat.info()
       << "Setting chromium.Hint() for fastest textures.\n";
@@ -531,7 +527,6 @@ render_frame() {
   _win->begin_frame();
   report_errors();
   _decal_level = 0;
-  _lighting_enabled_this_frame = false;
 
 #ifdef DO_PSTATS
   // For Pstats to track our current texture memory usage, we have to
@@ -582,28 +577,6 @@ render_frame() {
 
   // Now we're done with the frame processing.  Clean up.
 
-  if (_lighting_enabled_this_frame) {
-
-    // Let's turn off all the lights we had on, and clear the light
-    // cache--to force the lights to be reissued next frame, in case
-    // their parameters or positions have changed between frames.
-
-    for (int i = 0; i < _max_lights; i++) {
-      enable_light(i, false);
-      _light_info[i]._light = (Light *)NULL;
-    }
-
-    // Also force the lighting state to unlit, so that issue_light()
-    // will be guaranteed to be called next frame even if we have the
-    // same set of light pointers we had this frame.
-    clear_attribute(LightTransition::get_class_type());
-
-    // All this work to undo the lighting state each frame doesn't seem
-    // ideal--there may be a better way.  Maybe if the lights were just
-    // more aware of whether their parameters or positions have changed
-    // at all?
-  }
-
 #ifndef NDEBUG
   report_errors();
 #endif
@@ -1020,16 +993,9 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
   // save the modelview matrix
   const LMatrix4f &modelview_mat = _transform->get_mat();
 
-  // get the camera information
-
-  // Hmm, this doesn't work any more, since we don't store the camera
-  // pointer in new scene graph land.  Need to find a better way to
-  // get the current window's aspect ratio.  Here's a temporary hack
-  // for now.
-
-  //  float aspect_ratio = 
-  //    get_current_camera()->get_lens()->get_aspect_ratio();
-  float aspect_ratio = 1.333333;
+  // We don't need to mess with the aspect ratio, since we are now
+  // using the default projection matrix, which has the right aspect
+  // ratio built in.
 
   // load up our own matrices
   chromium.MatrixMode(GL_MODELVIEW);
@@ -1089,7 +1055,7 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
 
   // y direction
   if (y_overall)
-    scaled_height = geom->_y_texel_ratio[0] * half_height * aspect_ratio;
+    scaled_height = geom->_y_texel_ratio[0] * half_height;
   else {
     nassertv(((int)geom->_y_texel_ratio.size() >= geom->get_num_prims()));
     y_walk = &geom->_y_texel_ratio[0];
@@ -1171,7 +1137,7 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
       scaled_width = cur_image._x_ratio * half_width;
 
     if (y_overall == false)
-      scaled_height = cur_image._y_ratio * half_height * aspect_ratio;
+      scaled_height = cur_image._y_ratio * half_height;
 
     // if not G_OVERALL, do some trig for this z rotate
     if (theta_on) {
@@ -2087,7 +2053,6 @@ draw_texture(TextureContext *tc, const DisplayRegion *dr) {
   TextureApplyTransition *taa = new TextureApplyTransition;
   taa->set_mode(TextureApplyProperty::M_decal);
 
-  state.set_transition(new LightTransition);
   state.set_transition(new ColorMaskTransition);
   state.set_transition(new RenderModeTransition);
   state.set_transition(new TexMatrixTransition);
@@ -2303,7 +2268,6 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
   prepare_display_region();
 
   NodeTransitions state(na);
-  state.set_transition(new LightTransition);
   state.set_transition(new TextureTransition);
   state.set_transition(new TransformTransition);
   //state.set_transition(new ColorBlendTransition);
@@ -2522,196 +2486,6 @@ apply_fog(qpFog *fog) {
   report_errors();
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: CRGraphicsStateGuardian::apply_light
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void CRGraphicsStateGuardian::apply_light( PointLight* light )
-{
-#if 0
-  // The light position will be relative to the current matrix, so
-  // we have to know what the current matrix is.  Find a better
-  // solution later.
-#ifdef GSG_VERBOSE
-  crgsg_cat.debug()
-    << "crMatrixMode(GL_MODELVIEW)" << endl;
-  crgsg_cat.debug()
-    << "crPushMatrix()" << endl;
-  crgsg_cat.debug()
-    << "crLoadIdentity()" << endl;
-#endif
-  chromium.MatrixMode(GL_MODELVIEW);
-  chromium.PushMatrix();
-
-  chromium.LoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_right)
-                .get_data());
-
-  GLenum id = get_light_id( _cur_light_id );
-  Colorf black(0, 0, 0, 1);
-  chromium.Lightfv(id, GL_AMBIENT, black.get_data());
-  chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
-  chromium.Lightfv(id, GL_SPECULAR, light->get_specular().get_data());
-
-    // Position needs to specify x, y, z, and w
-    // w == 1 implies non-infinite position
-  LPoint3f pos = get_rel_pos( light, _current_camera );
-  LPoint4f fpos( pos[0], pos[1], pos[2], 1 );
-  chromium.Lightfv( id, GL_POSITION, fpos.get_data() );
-
-  // GL_SPOT_DIRECTION is not significant when cutoff == 180
-
-    // Exponent == 0 implies uniform light distribution
-  chromium.Lightf( id, GL_SPOT_EXPONENT, 0 );
-
-  // Cutoff == 180 means uniform point light source
-  chromium.Lightf( id, GL_SPOT_CUTOFF, 180.0 );
-
-  chromium.Lightf( id, GL_CONSTANT_ATTENUATION,
-            light->get_constant_attenuation() );
-  chromium.Lightf( id, GL_LINEAR_ATTENUATION,
-            light->get_linear_attenuation() );
-  chromium.Lightf( id, GL_QUADRATIC_ATTENUATION,
-            light->get_quadratic_attenuation() );
-
-  chromium.PopMatrix();
-
-#ifdef GSG_VERBOSE
-  crgsg_cat.debug()
-    << "crPopMatrix()" << endl;
-#endif
-  report_errors();
-#endif
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: CRGraphicsStateGuardian::apply_light
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void CRGraphicsStateGuardian::apply_light( DirectionalLight* light )
-{
-#if 0
-  // The light position will be relative to the current matrix, so
-  // we have to know what the current matrix is.  Find a better
-  // solution later.
-#ifdef GSG_VERBOSE
-  crgsg_cat.debug()
-    << "crMatrixMode(GL_MODELVIEW)" << endl;
-  crgsg_cat.debug()
-    << "crPushMatrix()" << endl;
-  crgsg_cat.debug()
-    << "crLoadIdentity()" << endl;
-#endif
-  chromium.MatrixMode(GL_MODELVIEW);
-  chromium.PushMatrix();
-  chromium.LoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_right)
-                .get_data());
-
-  GLenum id = get_light_id( _cur_light_id );
-  Colorf black(0, 0, 0, 1);
-  chromium.Lightfv(id, GL_AMBIENT, black.get_data());
-  chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
-  chromium.Lightfv(id, GL_SPECULAR, light->get_specular().get_data());
-
-    // Position needs to specify x, y, z, and w
-    // w == 0 implies light is at infinity
-  LPoint3f dir = get_rel_forward( light, _current_camera,
-                                  _coordinate_system );
-  LPoint4f pos( -dir[0], -dir[1], -dir[2], 0 );
-  chromium.Lightfv( id, GL_POSITION, pos.get_data() );
-
-  // GL_SPOT_DIRECTION is not significant when cutoff == 180
-  // In this case, position x, y, z specifies direction
-
-  // Exponent == 0 implies uniform light distribution
-  chromium.Lightf( id, GL_SPOT_EXPONENT, 0 );
-
-  // Cutoff == 180 means uniform point light source
-  chromium.Lightf( id, GL_SPOT_CUTOFF, 180.0 );
-
-  // Default attenuation values (only spotlight can modify these)
-  chromium.Lightf( id, GL_CONSTANT_ATTENUATION, 1 );
-  chromium.Lightf( id, GL_LINEAR_ATTENUATION, 0 );
-  chromium.Lightf( id, GL_QUADRATIC_ATTENUATION, 0 );
-
-  chromium.PopMatrix();
-#ifdef GSG_VERBOSE
-  crgsg_cat.debug()
-    << "crPopMatrix()" << endl;
-#endif
-  report_errors();
-#endif
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: CRGraphicsStateGuardian::apply_light
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void CRGraphicsStateGuardian::apply_light( Spotlight* light )
-{
-#if 0
-  // The light position will be relative to the current matrix, so
-  // we have to know what the current matrix is.  Find a better
-  // solution later.
-#ifdef GSG_VERBOSE
-  crgsg_cat.debug()
-    << "crMatrixMode(GL_MODELVIEW)" << endl;
-  crgsg_cat.debug()
-    << "crPushMatrix()" << endl;
-  crgsg_cat.debug()
-    << "crLoadIdentity()" << endl;
-#endif
-  chromium.MatrixMode(GL_MODELVIEW);
-  chromium.PushMatrix();
-  chromium.LoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_right)
-                .get_data());
-
-  GLenum id = get_light_id( _cur_light_id );
-  Colorf black(0, 0, 0, 1);
-  chromium.Lightfv(id, GL_AMBIENT, black.get_data());
-  chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
-  chromium.Lightfv(id, GL_SPECULAR, light->get_specular().get_data());
-
-    // Position needs to specify x, y, z, and w
-    // w == 1 implies non-infinite position
-  LPoint3f pos = get_rel_pos( light, _current_camera );
-  LPoint4f fpos( pos[0], pos[1], pos[2], 1 );
-  chromium.Lightfv( id, GL_POSITION, fpos.get_data() );
-
-  chromium.Lightfv( id, GL_SPOT_DIRECTION,
-             get_rel_forward( light, _current_camera,
-                              _coordinate_system ).get_data() );
-  chromium.Lightf( id, GL_SPOT_EXPONENT, light->get_exponent() );
-  chromium.Lightf( id, GL_SPOT_CUTOFF,
-            light->get_cutoff_angle() );
-  chromium.Lightf( id, GL_CONSTANT_ATTENUATION,
-            light->get_constant_attenuation() );
-  chromium.Lightf( id, GL_LINEAR_ATTENUATION,
-            light->get_linear_attenuation() );
-  chromium.Lightf( id, GL_QUADRATIC_ATTENUATION,
-            light->get_quadratic_attenuation() );
-
-  chromium.PopMatrix();
-#ifdef GSG_VERBOSE
-  crgsg_cat.debug()
-    << "crPopMatrix()" << endl;
-#endif
-  report_errors();
-#endif
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: CRGraphicsStateGuardian::apply_light
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void CRGraphicsStateGuardian::apply_light( AmbientLight* )
-{
-  // Ambient lights are handled as a special case in issue_light().
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CRGraphicsStateGuardian::issue_transform
 //       Access: Public, Virtual
@@ -2726,36 +2500,6 @@ issue_transform(const TransformTransition *attrib) {
 #endif
   chromium.MatrixMode(GL_MODELVIEW);
   chromium.LoadMatrixf(attrib->get_matrix().get_data());
-
-#ifndef NDEBUG
-  if (cr_show_transforms) {
-    bool lighting_was_enabled = _lighting_enabled;
-    bool texturing_was_enabled = _texturing_enabled;
-    enable_lighting(false);
-    enable_texturing(false);
-
-    chromium.Begin(GL_LINES);
-
-    // X axis in red
-    chromium.Color3f(1.0f, 0.0f, 0.0f);
-    chromium.Vertex3f(0.0f, 0.0f, 0.0f);
-    chromium.Vertex3f(1.0f, 0.0f, 0.0f);
-
-    // Y axis in green
-    chromium.Color3f(0.0f, 1.0f, 0.0f);
-    chromium.Vertex3f(0.0f, 0.0f, 0.0f);
-    chromium.Vertex3f(0.0f, 1.0f, 0.0f);
-
-    // Z axis in blue
-    chromium.Color3f(0.0f, 0.0f, 1.0f);
-    chromium.Vertex3f(0.0f, 0.0f, 0.0f);
-    chromium.Vertex3f(0.0f, 0.0f, 1.0f);
-
-    chromium.End();
-    enable_lighting(lighting_was_enabled);
-    enable_texturing(texturing_was_enabled);
-  }
-#endif
   report_errors();
 }
 
@@ -2984,106 +2728,6 @@ issue_render_mode(const RenderModeTransition *attrib) {
   report_errors();
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: CRGraphicsStateGuardian::issue_light
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void CRGraphicsStateGuardian::issue_light(const LightTransition *attrib )
-{
-  nassertv(attrib->get_default_dir() != TD_on);
-  //  activate();
-
-  // Initialize the current ambient light total and newly enabled
-  // light list
-  Colorf cur_ambient_light(0.0f, 0.0f, 0.0f, 1.0f);
-  int i;
-  for (i = 0; i < _max_lights; i++) {
-    _light_info[i]._next_enabled = false;
-  }
-
-  int num_enabled = 0;
-  LightTransition::const_iterator li;
-  for (li = attrib->begin(); li != attrib->end(); ++li) {
-    Light *light = (*li).first;
-    nassertv(light != (Light *)NULL);
-    TransitionDirection dir = (*li).second;
-
-    if (dir == TD_on) {
-      num_enabled++;
-      enable_lighting(true);
-
-      if (light->get_light_type() == AmbientLight::get_class_type()) {
-        // Ambient lights don't require specific light ids; simply add
-        // in the ambient contribution to the current total
-        cur_ambient_light += light->get_color();
-        
-      } else {
-        // Check to see if this light has already been bound to an id
-        _cur_light_id = -1;
-        for (i = 0; i < _max_lights; i++) {
-          if (_light_info[i]._light == light) {
-            // Light has already been bound to an id, we only need
-            // to enable the light, not apply it
-            _cur_light_id = -2;
-            enable_light(i, true);
-            _light_info[i]._next_enabled = true;
-            break;
-          }
-        }
-        
-        // See if there are any unbound light ids
-        if (_cur_light_id == -1) {
-          for (i = 0; i < _max_lights; i++) {
-            if (_light_info[i]._light == (Light *)NULL) {
-              _light_info[i]._light = light;
-              _cur_light_id = i;
-              break;
-            }
-          }
-        }
-        
-        // If there were no unbound light ids, see if we can replace
-        // a currently unused but previously bound id
-        if (_cur_light_id == -1) {
-          for (i = 0; i < _max_lights; i++) {
-            if (attrib->is_off(_light_info[i]._light)) {
-              _light_info[i]._light = light;
-              _cur_light_id = i;
-              break;
-            }
-          }
-        }
-        
-        if (_cur_light_id >= 0) {
-          enable_light(_cur_light_id, true);
-          _light_info[i]._next_enabled = true;
-          
-          // We need to do something different for each type of light
-          light->apply(this);
-        } else if (_cur_light_id == -1) {
-          crgsg_cat.error()
-            << "issue_light() - failed to bind light to id" << endl;
-        }
-      }
-    }
-  }
-
-  // Disable all unused lights
-  for (i = 0; i < _max_lights; i++) {
-    if (!_light_info[i]._next_enabled)
-      enable_light(i, false);
-  }
-
-  // If no lights were enabled, disable lighting
-  if (num_enabled == 0) {
-    enable_lighting(false);
-  } else {
-    call_glLightModelAmbient(cur_ambient_light);
-  }
-  report_errors();
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CRGraphicsStateGuardian::issue_color_blend
 //       Access: Public, Virtual
@@ -3508,6 +3152,10 @@ issue_material(const MaterialAttrib *attrib) {
   const Material *material = attrib->get_material();
   if (material != (const Material *)NULL) {
     apply_material(material);
+  } else {
+    // Apply a default material when materials are turned off.
+    Material empty;
+    apply_material(&empty);
   }
   report_errors();
 }
@@ -3718,9 +3366,9 @@ issue_depth_offset(const DepthOffsetAttrib *attrib) {
   int offset = attrib->get_offset();
 
   if (offset != 0) {
-    GLfloat newfactor = 1.0f;
-    GLfloat newunits = (GLfloat)offset;
-    chromium.PolygonOffset(newfactor, newunits);
+    // The relationship between these two parameters is a little
+    // unclear and poorly explained in the GL man pages.
+    chromium.PolygonOffset((GLfloat) -offset, (GLfloat) -offset);
     enable_polygon_offset(true);
 
   } else {
@@ -3730,6 +3378,130 @@ issue_depth_offset(const DepthOffsetAttrib *attrib) {
   report_errors();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CRGraphicsStateGuardian::bind_light
+//       Access: Public, Virtual
+//  Description: Called the first time a particular light has been
+//               bound to a given id within a frame, this should set
+//               up the associated hardware light with the light's
+//               properties.
+////////////////////////////////////////////////////////////////////
+void CRGraphicsStateGuardian::
+bind_light(PointLight *light, int light_id) {
+  GLenum id = get_light_id(light_id);
+  static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
+  chromium.Lightfv(id, GL_AMBIENT, black.get_data());
+  chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
+  chromium.Lightfv(id, GL_SPECULAR, light->get_specular_color().get_data());
+
+  // Position needs to specify x, y, z, and w
+  // w == 1 implies non-infinite position
+  qpNodePath light_np(light);
+  const LMatrix4f &light_mat = light_np.get_mat(_scene_setup->get_scene_root());
+  LPoint3f pos = light->get_point() * light_mat;
+
+  LPoint4f fpos(pos[0], pos[1], pos[2], 1.0f);
+  chromium.Lightfv(id, GL_POSITION, fpos.get_data());
+
+  // GL_SPOT_DIRECTION is not significant when cutoff == 180
+
+  // Exponent == 0 implies uniform light distribution
+  chromium.Lightf(id, GL_SPOT_EXPONENT, 0.0f);
+
+  // Cutoff == 180 means uniform point light source
+  chromium.Lightf(id, GL_SPOT_CUTOFF, 180.0f);
+
+  const LVecBase3f &att = light->get_attenuation();
+  chromium.Lightf(id, GL_CONSTANT_ATTENUATION, att[0]);
+  chromium.Lightf(id, GL_LINEAR_ATTENUATION, att[1]);
+  chromium.Lightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
+
+  report_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CRGraphicsStateGuardian::bind_light
+//       Access: Public, Virtual
+//  Description: Called the first time a particular light has been
+//               bound to a given id within a frame, this should set
+//               up the associated hardware light with the light's
+//               properties.
+////////////////////////////////////////////////////////////////////
+void CRGraphicsStateGuardian::
+bind_light(DirectionalLight *light, int light_id) {
+  GLenum id = get_light_id( light_id );
+  static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
+  chromium.Lightfv(id, GL_AMBIENT, black.get_data());
+  chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
+  chromium.Lightfv(id, GL_SPECULAR, light->get_specular_color().get_data());
+
+  // Position needs to specify x, y, z, and w.
+  // w == 0 implies light is at infinity
+  qpNodePath light_np(light);
+  const LMatrix4f &light_mat = light_np.get_mat(_scene_setup->get_scene_root());
+  LVector3f dir = light->get_direction() * light_mat;
+  LPoint4f fdir(-dir[0], -dir[1], -dir[2], 0);
+  chromium.Lightfv(id, GL_POSITION, fdir.get_data());
+
+  // GL_SPOT_DIRECTION is not significant when cutoff == 180
+  // In this case, position x, y, z specifies direction
+
+  // Exponent == 0 implies uniform light distribution
+  chromium.Lightf(id, GL_SPOT_EXPONENT, 0.0f);
+
+  // Cutoff == 180 means uniform point light source
+  chromium.Lightf(id, GL_SPOT_CUTOFF, 180.0f);
+
+  // Default attenuation values (only spotlight and point light can
+  // modify these)
+  chromium.Lightf(id, GL_CONSTANT_ATTENUATION, 1.0f);
+  chromium.Lightf(id, GL_LINEAR_ATTENUATION, 0.0f);
+  chromium.Lightf(id, GL_QUADRATIC_ATTENUATION, 0.0f);
+
+  report_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CRGraphicsStateGuardian::bind_light
+//       Access: Public, Virtual
+//  Description: Called the first time a particular light has been
+//               bound to a given id within a frame, this should set
+//               up the associated hardware light with the light's
+//               properties.
+////////////////////////////////////////////////////////////////////
+void CRGraphicsStateGuardian::
+bind_light(Spotlight *light, int light_id) {
+  Lens *lens = light->get_lens();
+  nassertv(lens != (Lens *)NULL);
+
+  GLenum id = get_light_id(light_id);
+  static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
+  chromium.Lightfv(id, GL_AMBIENT, black.get_data());
+  chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
+  chromium.Lightfv(id, GL_SPECULAR, light->get_specular_color().get_data());
+
+  // Position needs to specify x, y, z, and w
+  // w == 1 implies non-infinite position
+  qpNodePath light_np(light);
+  const LMatrix4f &light_mat = light_np.get_mat(_scene_setup->get_scene_root());
+  LPoint3f pos = lens->get_nodal_point() * light_mat;
+  LVector3f dir = lens->get_view_vector() * light_mat;
+
+  LPoint4f fpos(pos[0], pos[1], pos[2], 1.0f);
+  chromium.Lightfv(id, GL_POSITION, fpos.get_data());
+  chromium.Lightfv(id, GL_SPOT_DIRECTION, dir.get_data());
+
+  chromium.Lightf(id, GL_SPOT_EXPONENT, light->get_exponent());
+  chromium.Lightf(id, GL_SPOT_CUTOFF, lens->get_hfov());
+
+  const LVecBase3f &att = light->get_attenuation();
+  chromium.Lightf(id, GL_CONSTANT_ATTENUATION, att[0]);
+  chromium.Lightf(id, GL_LINEAR_ATTENUATION, att[1]);
+  chromium.Lightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
+
+  report_errors();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CRGraphicsStateGuardian::wants_normals
 //       Access: Public, Virtual
@@ -3895,6 +3667,19 @@ end_decal(GeomNode *base_geom) {
   report_errors();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CRGraphicsStateGuardian::depth_offset_decals
+//       Access: Public, Virtual
+//  Description: Returns true if this GSG can implement decals using a
+//               DepthOffsetAttrib, or false if that is unreliable
+//               and the three-step rendering process should be used
+//               instead.
+////////////////////////////////////////////////////////////////////
+bool CRGraphicsStateGuardian::
+depth_offset_decals() {
+  return cr_depth_offset_decals;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CRGraphicsStateGuardian::get_internal_coordinate_system
 //       Access: Public, Virtual
@@ -4754,6 +4539,93 @@ issue_transformed_color(const Colorf &color) const {
   chromium.Color4fv(transformed.get_data());
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CRGraphicsStateGuardian::enable_lighting
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by a derived class to
+//               enable or disable the use of lighting overall.  This
+//               is called by issue_light() according to whether any
+//               lights are in use or not.
+////////////////////////////////////////////////////////////////////
+void CRGraphicsStateGuardian::
+enable_lighting(bool enable) {
+  if (enable) {
+    chromium.Enable(GL_LIGHTING);
+  } else {
+    chromium.Disable(GL_LIGHTING);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CRGraphicsStateGuardian::set_ambient_light
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by a derived class to
+//               indicate the color of the ambient light that should
+//               be in effect.  This is called by issue_light() after
+//               all other lights have been enabled or disabled.
+////////////////////////////////////////////////////////////////////
+void CRGraphicsStateGuardian::
+set_ambient_light(const Colorf &color) {
+  chromium.LightModelfv(GL_LIGHT_MODEL_AMBIENT, color.get_data());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CRGraphicsStateGuardian::enable_light
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by a derived class to
+//               enable the indicated light id.  A specific Light will
+//               already have been bound to this id via bind_light().
+////////////////////////////////////////////////////////////////////
+void CRGraphicsStateGuardian::
+enable_light(int light_id, bool enable) {
+  if (enable) {
+    chromium.Enable(get_light_id(light_id));
+  } else {
+    chromium.Disable(get_light_id(light_id));
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CRGraphicsStateGuardian::begin_bind_lights
+//       Access: Protected, Virtual
+//  Description: Called immediately before bind_light() is called,
+//               this is intended to provide the derived class a hook
+//               in which to set up some state (like transform) that
+//               might apply to several lights.
+//
+//               The sequence is: begin_bind_lights() will be called,
+//               then one or more bind_light() calls, then
+//               end_bind_lights().
+////////////////////////////////////////////////////////////////////
+void CRGraphicsStateGuardian::
+begin_bind_lights() {
+  // We need to temporarily load a new matrix so we can define the
+  // light in a known coordinate system.  We pick the transform of the
+  // root.  (Alternatively, we could leave the current transform where
+  // it is and compute the light position relative to that transform
+  // instead of relative to the root, by composing with the matrix
+  // computed by _transform->invert_compose(render_transform).  But I
+  // think loading a completely new matrix is simpler.)
+  chromium.MatrixMode(GL_MODELVIEW);
+  chromium.PushMatrix();
+  chromium.LoadMatrixf(_scene_setup->get_render_transform()->get_mat().get_data());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CRGraphicsStateGuardian::end_bind_lights
+//       Access: Protected, Virtual
+//  Description: Called after before bind_light() has been called one
+//               or more times (but before any geometry is issued or
+//               additional state is changed), this is intended to
+//               clean up any temporary changes to the state that may
+//               have been made by begin_bind_lights().
+////////////////////////////////////////////////////////////////////
+void CRGraphicsStateGuardian::
+end_bind_lights() {
+  chromium.MatrixMode(GL_MODELVIEW);
+  chromium.PopMatrix();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CRGraphicsStateGuardian::free_pointers
 //       Access: Protected
@@ -4762,10 +4634,6 @@ issue_transformed_color(const Colorf &color) const {
 ////////////////////////////////////////////////////////////////////
 void CRGraphicsStateGuardian::
 free_pointers() {
-  if (_light_info != (LightInfo *)NULL) {
-    delete[] _light_info;
-    _light_info = (LightInfo *)NULL;
-  }
   if (_clip_plane_enabled != (bool *)NULL) {
     delete[] _clip_plane_enabled;
     _clip_plane_enabled = (bool *)NULL;
@@ -5044,10 +4912,6 @@ dump_state(void)
       dump << "\t\t" << "GL_LINE_SMOOTH " << _line_smooth_enabled << " " << (bool)chromium.IsEnabled(GL_LINE_SMOOTH) << "\n";
       dump << "\t\t" << "GL_POINT_SMOOTH " << _point_smooth_enabled << " " << (bool)chromium.IsEnabled(GL_POINT_SMOOTH) << "\n";
       dump << "\t\t" << "GL_LIGHTING " << _lighting_enabled << " " << (bool)chromium.IsEnabled(GL_LIGHTING) << "\n";
-      for(i = 0; i < _max_lights; i++)
-        {
-          dump << "\t\t\t\t" << "GL_LIGHT" << i << " " << _light_info[i]._enabled << " " << (bool)chromium.IsEnabled(GL_LIGHT0+i) << "\n";
-        }
       dump << "\t\t" << "GL_SCISSOR_TEST " << _scissor_enabled << " " << (bool)chromium.IsEnabled(GL_SCISSOR_TEST) << "\n";
       dump << "\t\t" << "GL_TEXTURE_2D " << _texturing_enabled << " " << (bool)chromium.IsEnabled(GL_TEXTURE_2D) << "\n";
       dump << "\t\t" << "GL_DITHER " << _dither_enabled << " " << (bool)chromium.IsEnabled(GL_DITHER) << "\n";

+ 12 - 26
panda/src/crgsg/crGraphicsStateGuardian.h

@@ -33,7 +33,6 @@
 #include "depthTestProperty.h"
 #include "stencilProperty.h"
 #include "fog.h"
-#include "pt_Light.h"
 #include "depthTestAttrib.h"
 #include "textureApplyAttrib.h"
 #include "pointerToArray.h"
@@ -141,18 +140,12 @@ public:
   virtual void apply_fog(Fog *fog);
   void apply_fog(qpFog *fog);
 
-  virtual void apply_light(PointLight* light);
-  virtual void apply_light(DirectionalLight* light);
-  virtual void apply_light(Spotlight* light);
-  virtual void apply_light(AmbientLight* light);
-
   virtual void issue_transform(const TransformTransition *attrib);
   virtual void issue_color_transform(const ColorMatrixTransition *attrib);
   virtual void issue_alpha_transform(const AlphaTransformTransition *attrib);
   virtual void issue_tex_matrix(const TexMatrixTransition *attrib);
   virtual void issue_color(const ColorTransition *attrib);
   virtual void issue_texture(const TextureTransition *attrib);
-  virtual void issue_light(const LightTransition *attrib);
   virtual void issue_material(const MaterialTransition *attrib);
   virtual void issue_render_mode(const RenderModeTransition *attrib);
   virtual void issue_color_blend(const ColorBlendTransition *attrib);
@@ -171,11 +164,8 @@ public:
   virtual void issue_polygon_offset(const PolygonOffsetTransition *attrib);
 
   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_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);
@@ -191,12 +181,18 @@ public:
   //  virtual void issue_stencil(const StencilAttrib *attrib);
   //  virtual void issue_clip_plane(const ClipPlaneAttrib *attrib);
 
+  virtual void bind_light(PointLight *light, int light_id);
+  virtual void bind_light(DirectionalLight *light, int light_id);
+  virtual void bind_light(Spotlight *light, int light_id);
+
   virtual bool wants_normals(void) const;
   virtual bool wants_texcoords(void) const;
 
   virtual void begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib);
   virtual void end_decal(GeomNode *base_geom);
 
+  virtual bool depth_offset_decals();
+
   virtual CoordinateSystem get_internal_coordinate_system() const;
   virtual float compute_distance_to(const LPoint3f &point) const;
 
@@ -214,6 +210,12 @@ public:
   void issue_transformed_color(const Colorf &color) const;
 
 protected:
+  virtual void enable_lighting(bool enable);
+  virtual void set_ambient_light(const Colorf &color);
+  virtual void enable_light(int light_id, bool enable);
+  virtual void begin_bind_lights();
+  virtual void end_bind_lights();
+
   void free_pointers();
   virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer,
                                                  CPT(DisplayRegion) dr);
@@ -234,7 +236,6 @@ protected:
   INLINE void call_glCullFace(GLenum mode);
   INLINE void call_glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
   INLINE void call_glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
-  INLINE void call_glLightModelAmbient(const Colorf& color);
   INLINE void call_glLightModelLocal(GLboolean local);
   INLINE void call_glLightModelTwoSide(GLboolean twoside);
   INLINE void call_glStencilFunc(GLenum func,GLint refval,GLuint mask);
@@ -256,8 +257,6 @@ protected:
   INLINE void enable_multisample(bool val);
   INLINE void enable_line_smooth(bool val);
   INLINE void enable_point_smooth(bool val);
-  INLINE void enable_lighting(bool val);
-  INLINE void enable_light(int light, bool val);
   INLINE void enable_texturing(bool val);
   INLINE void enable_scissor(bool val);
   INLINE void enable_dither(bool val);
@@ -321,7 +320,6 @@ protected:
   GLsizei _viewport_height;
   GLboolean _lmodel_local;
   GLboolean _lmodel_twoside;
-  Colorf _lmodel_ambient;
   Colorf _material_ambient;
   Colorf _material_diffuse;
   Colorf _material_specular;
@@ -350,8 +348,6 @@ protected:
   bool _line_smooth_enabled;
   bool _point_smooth_enabled;
   bool _scissor_enabled;
-  bool _lighting_enabled;
-  bool _lighting_enabled_this_frame;
   bool _texturing_enabled;
   bool _dither_enabled;
   bool _stencil_test_enabled;
@@ -365,16 +361,6 @@ protected:
   bool _polygon_offset_enabled;
   int _decal_level;
 
-  class LightInfo {
-  public:
-    INLINE LightInfo();
-    PT_Light _light;
-    bool _enabled;
-    bool _next_enabled;
-  };
-
-  int _max_lights;
-  LightInfo *_light_info;          // LightInfo[_max_lights]
   int _cur_light_id;
 
   LMatrix4f _current_projection_mat;