Browse Source

Overload added to set_shader_auto to allow any of normal, glow, gloss, ramp, shadow to be turned on or off

Mike Christel 15 years ago
parent
commit
c308b57137

+ 24 - 0
panda/src/pgraph/nodePath.cxx

@@ -2,6 +2,7 @@
 // Created by:  drose (25Feb02)
 // Updated by:  fperazzi, PandaSE (06Apr10) (added more overloads
 //   for set_shader_input)
+// Updated by: weifengh, PandaSE(15Apr10) (added set_shader_auto)
 //
 ////////////////////////////////////////////////////////////////////
 //
@@ -3717,6 +3718,29 @@ set_shader_auto(int priority) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodePath::set_shader_auto
+//       Access: Published
+//  Description: overloaded for auto shader selective on/off of
+//               normal, glow, gloss, ramp, shadow
+////////////////////////////////////////////////////////////////////
+void NodePath::
+set_shader_auto(const char* normal_on, const char* glow_on, const char* gloss_on, const char* ramp_on, const char* shadow_on, int priority) {
+  nassertv_always(!is_empty());
+
+  const RenderAttrib *attrib =
+    node()->get_attrib(ShaderAttrib::get_class_slot());
+  if (attrib != (const RenderAttrib *)NULL) {
+    priority = max(priority,
+                   node()->get_state()->get_override(ShaderAttrib::get_class_slot()));
+    const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib);
+    node()->set_attrib(sa->set_shader_auto(normal_on, glow_on, gloss_on, ramp_on, shadow_on, priority));
+  } else {
+    // Create a new ShaderAttrib for this node.
+    CPT(ShaderAttrib) sa = DCAST(ShaderAttrib, ShaderAttrib::make());
+    node()->set_attrib(sa->set_shader_auto(normal_on, glow_on, gloss_on, ramp_on, shadow_on, priority));
+  }
+}
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePath::clear_shader
 //       Access: Published

+ 2 - 0
panda/src/pgraph/nodePath.h

@@ -2,6 +2,7 @@
 // Created by:  drose (25Feb02)
 // Updated by:  fperazzi, PandaSE (06Apr10) (added more overloads
 //   for set_shader_input)
+// Updated by: weifengh, PandaSE(15Apr10)
 //
 ////////////////////////////////////////////////////////////////////
 //
@@ -604,6 +605,7 @@ PUBLISHED:
   void set_shader(const Shader *sha, int priority = 0);
   void set_shader_off(int priority = 0);
   void set_shader_auto(int priority = 0);
+  void set_shader_auto(const char* normal_on, const char* glow_on, const char* gloss_on, const char* ramp_on, const char* shadow_on, int priority=0);
   void clear_shader();
   
   void set_shader_input(const ShaderInput *inp);

+ 63 - 2
panda/src/pgraph/shaderAttrib.I

@@ -1,5 +1,6 @@
 // Filename: shaderAttrib.I
 // Created by:  sshodhan (10Jul04)
+// Updated by: weifengh, PandaSE(15Apr10)
 //
 ////////////////////////////////////////////////////////////////////
 //
@@ -26,7 +27,12 @@ ShaderAttrib() :
   _has_shader(false),
   _flags(0),
   _has_flags(0),
-  _instance_count(0)
+  _instance_count(0),
+  _auto_normal_on(false),
+  _auto_glow_on(false),
+  _auto_gloss_on(false),
+  _auto_ramp_on(false),
+  _auto_shadow_on(false) 
 {
 }
 
@@ -44,7 +50,12 @@ ShaderAttrib(const ShaderAttrib &copy) :
   _flags(copy._flags),
   _has_flags(copy._has_flags),
   _instance_count(copy._instance_count),
-  _inputs(copy._inputs)
+  _inputs(copy._inputs),
+  _auto_normal_on(copy._auto_normal_on),
+  _auto_glow_on(copy._auto_glow_on),
+  _auto_gloss_on(copy._auto_gloss_on),
+  _auto_ramp_on(copy._auto_ramp_on),
+  _auto_shadow_on(copy._auto_shadow_on)
 {
 }
 
@@ -102,3 +113,53 @@ get_flag(int index) const {
   return (_flags & (1<<index)) ? true:false;
 }
 
+//weifengh
+////////////////////////////////////////////////////////////////////
+//     Function: ShaderAttrib::auto_normal_on
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE bool ShaderAttrib::
+auto_normal_on() const {
+  return _auto_normal_on;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ShaderAttrib::auto_glow_on
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE bool ShaderAttrib::
+auto_glow_on() const {
+  return _auto_glow_on;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ShaderAttrib::auto_gloss_on
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE bool ShaderAttrib::
+auto_gloss_on() const {
+  return _auto_gloss_on;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ShaderAttrib::auto_ramp_on
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE bool ShaderAttrib::
+auto_ramp_on() const {
+  return _auto_ramp_on;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ShaderAttrib::auto_shadow_on
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE bool ShaderAttrib::
+auto_shadow_on() const {
+  return _auto_shadow_on;
+}

+ 70 - 1
panda/src/pgraph/shaderAttrib.cxx

@@ -2,6 +2,8 @@
 // Created by:  sshodhan (10Jul04)
 // Updated by:  fperazzi, PandaSE (06Apr10) (added more overloads
 //   for set_shader_input)
+// Updated by: weifengh, PandaSE(15Apr10) (added overload for
+//   set_shader_auto)
 //
 ////////////////////////////////////////////////////////////////////
 //
@@ -97,6 +99,12 @@ set_shader_off(int priority) const {
   result->_shader = NULL;
   result->_shader_priority = priority;
   result->_auto_shader = false;
+  result->_auto_normal_on = false;
+  result->_auto_glow_on = false;
+  result->_auto_gloss_on = false;
+  result->_auto_ramp_on = false;
+  result->_auto_shadow_on = false;
+
   result->_has_shader = true;
   return return_new(result);
 }
@@ -113,6 +121,42 @@ set_shader_auto(int priority) const {
   result->_shader_priority = priority;
   result->_auto_shader = true;
   result->_has_shader = true;
+  result->_auto_normal_on = true;
+  result->_auto_glow_on = true;
+  result->_auto_gloss_on = true;
+  result->_auto_ramp_on = true;
+  result->_auto_shadow_on = true;
+  return return_new(result);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ShaderAttrib::set_shader_auto
+//       Access: Published
+//  Description: Set auto shader with control over whether to keep
+//               normal, glow, etc., on or off (e.g., all on via
+//               "normal-on","glow-on","gloss-on","ramp-on","shadow-on")
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) ShaderAttrib::
+set_shader_auto(const char* normal_on, const char* glow_on, const char* gloss_on, const char* ramp_on, const char* shadow_on, int priority) const {
+  
+  ShaderAttrib *result = new ShaderAttrib(*this);
+  result->_shader = NULL;
+  result->_shader_priority = priority;
+  result->_auto_shader = true;
+  result->_has_shader = true;
+  string cleanedFlag;
+
+  cleanedFlag = downcase(normal_on);
+  result->_auto_normal_on = (cleanedFlag == "normal_on");
+  cleanedFlag = downcase(glow_on);
+  result->_auto_glow_on = (cleanedFlag == "glow_on");
+  cleanedFlag = downcase(gloss_on);
+  result->_auto_gloss_on = (cleanedFlag == "gloss_on");
+  cleanedFlag = downcase(ramp_on);
+  result->_auto_ramp_on = (cleanedFlag == "ramp_on");
+  cleanedFlag = downcase(shadow_on);
+  result->_auto_shadow_on = (cleanedFlag == "shadow_on");
+
   return return_new(result);
 }
 
@@ -128,6 +172,11 @@ clear_shader() const {
   result->_shader_priority = 0;
   result->_auto_shader = false;
   result->_has_shader = false;
+  result->_auto_normal_on = false;
+  result->_auto_glow_on = false;
+  result->_auto_gloss_on = false;
+  result->_auto_ramp_on = false;
+  result->_auto_shadow_on = false;
   return return_new(result);
 }
 
@@ -723,7 +772,22 @@ compare_to_impl(const RenderAttrib *other) const {
   if (this->_instance_count != that->_instance_count) {
     return (this->_instance_count < that->_instance_count) ? -1 : 1;
   }
-  
+  if (this->_auto_normal_on != that->_auto_normal_on) {
+    return (this->_auto_normal_on < that->_auto_normal_on) ? -1 : 1;
+  }
+  if (this->_auto_glow_on != that->_auto_glow_on) {
+    return (this->_auto_glow_on < that->_auto_glow_on) ? -1 : 1;
+  }
+  if (this->_auto_gloss_on != that->_auto_gloss_on) {
+    return (this->_auto_gloss_on < that->_auto_gloss_on) ? -1 : 1;
+  }
+  if (this->_auto_ramp_on != that->_auto_ramp_on) {
+    return (this->_auto_ramp_on < that->_auto_ramp_on) ? -1 : 1;
+  }
+  if (this->_auto_shadow_on != that->_auto_shadow_on) {
+    return (this->_auto_shadow_on < that->_auto_shadow_on) ? -1 : 1;
+  }
+
   Inputs::const_iterator i1 = this->_inputs.begin();
   Inputs::const_iterator i2 = that->_inputs.begin();
   while ((i1 != this->_inputs.end()) && (i2 != that->_inputs.end())) {
@@ -761,6 +825,11 @@ compose_impl(const RenderAttrib *other) const {
       attr->_shader_priority = over->_shader_priority;
       attr->_auto_shader = over->_auto_shader;
       attr->_has_shader = over->_has_shader;
+      attr->_auto_normal_on = over->_auto_normal_on;
+      attr->_auto_glow_on = over->_auto_glow_on;
+      attr->_auto_gloss_on = over->_auto_gloss_on;
+      attr->_auto_ramp_on = over->_auto_ramp_on;
+      attr->_auto_shadow_on = over->_auto_shadow_on;
     }
   }
   // Update the shader-data portion.

+ 17 - 1
panda/src/pgraph/shaderAttrib.h

@@ -2,6 +2,7 @@
 // Created by: jyelon (01Sep05)
 // Updated by:  fperazzi, PandaSE (06Apr10) (added more overloads
 //   for set_shader_input)
+// Updated by: weifengh, PandaSE(15Apr10)
 //
 ////////////////////////////////////////////////////////////////////
 //
@@ -55,10 +56,18 @@ PUBLISHED:
   INLINE bool               auto_shader() const;
   INLINE int                get_shader_priority() const;
   INLINE int                get_instance_count() const;
-  
+  INLINE bool               auto_normal_on() const;
+  INLINE bool               auto_glow_on() const;
+  INLINE bool               auto_gloss_on() const;
+  INLINE bool               auto_ramp_on() const;
+  INLINE bool               auto_shadow_on() const;
+
   CPT(RenderAttrib) set_shader(const Shader *s, int priority=0) const;
   CPT(RenderAttrib) set_shader_off(int priority=0) const;
   CPT(RenderAttrib) set_shader_auto(int priority=0) const;
+
+  CPT(RenderAttrib) set_shader_auto(const char* normal_on, const char* glow_on, const char* gloss_on, const char* ramp_on, const char* shadow_on, int priority=0) const;
+
   CPT(RenderAttrib) clear_shader() const;
   // Shader Inputs
   CPT(RenderAttrib) set_shader_input(const ShaderInput *inp) const;
@@ -136,6 +145,13 @@ private:
   int         _flags;
   int         _has_flags;
   int         _instance_count;
+
+  bool        _auto_normal_on;
+  bool        _auto_glow_on;
+  bool        _auto_gloss_on;
+  bool        _auto_ramp_on;
+  bool        _auto_shadow_on;
+
   typedef pmap < CPT(InternalName), CPT(ShaderInput) > Inputs;
   Inputs _inputs;
 

+ 73 - 55
panda/src/pgraphnodes/shaderGenerator.cxx

@@ -1,5 +1,6 @@
 // Filename: shaderGenerator.cxx
 // Created by: jyelon (15Dec07)
+// Updated by: weifengh, PandaSE(15Apr10)
 //
 ////////////////////////////////////////////////////////////////////
 //
@@ -427,6 +428,15 @@ analyze_renderstate(const RenderState *rs) {
     _need_world_position = true;
   }
 
+  const ShaderAttrib *shader_attrib = DCAST(ShaderAttrib, rs->get_attrib_def(ShaderAttrib::get_class_slot()));
+  if (shader_attrib->auto_shader()) {
+    _auto_normal_on = shader_attrib->auto_normal_on();
+    _auto_glow_on   = shader_attrib->auto_glow_on();
+    _auto_gloss_on  = shader_attrib->auto_gloss_on();
+    _auto_ramp_on   = shader_attrib->auto_ramp_on();
+    _auto_shadow_on = shader_attrib->auto_shadow_on();
+  }
+
   // Check for unimplemented features and issue warnings.
   const FogAttrib *fog = DCAST(FogAttrib, rs->get_attrib_def(FogAttrib::get_class_slot()));
   if (!fog->is_off()) {
@@ -474,6 +484,12 @@ clear_analysis() {
   _need_world_normal = false;
   _need_eye_position = false;
   _need_eye_normal = false;
+  _auto_normal_on = false;
+  _auto_glow_on   = false;
+  _auto_gloss_on  = false;
+  _auto_ramp_on   = false;
+  _auto_shadow_on = false;
+
   _alights.clear();
   _dlights.clear();
   _plights.clear();
@@ -682,7 +698,7 @@ synthesize_shader(const RenderState *rs) {
     text << "\t out float3 l_eyevec,\n";
   }
   if (_lighting) {
-    if (_map_index_normal >= 0) {
+    if (_map_index_normal >= 0 && _auto_normal_on) {
       // If we had a height map and it used the same stage, that means we already have those inputs.
       if (_map_index_normal != _map_index_height) {
         ntangent_vreg = alloc_vreg();
@@ -695,7 +711,7 @@ synthesize_shader(const RenderState *rs) {
       text << "\t out float4 l_tangent : " << ntangent_freg << ",\n";
       text << "\t out float4 l_binormal : " << nbinormal_freg << ",\n";
     }
-    if (_shadows) {
+    if (_shadows && _auto_shadow_on) {
       for (int i=0; i<(int)_dlights.size(); i++) {
         if (_dlights[i]->_shadow_caster) {
           text << "\t uniform float4x4 trans_model_to_clip_of_dlight" << i << ",\n";
@@ -737,13 +753,13 @@ synthesize_shader(const RenderState *rs) {
   if (_vertex_colors) {
     text << "\t l_color = vtx_color;\n";
   }
-  if (_lighting && (_map_index_normal >= 0)) {
+  if (_lighting && (_map_index_normal >= 0 && _auto_normal_on)) {
     text << "\t l_tangent.xyz = mul((float3x3)tpose_view_to_model, vtx_tangent" << _map_index_normal << ".xyz);\n";
     text << "\t l_tangent.w = 0;\n";
     text << "\t l_binormal.xyz = mul((float3x3)tpose_view_to_model, -vtx_binormal" << _map_index_normal << ".xyz);\n";
     text << "\t l_binormal.w = 0;\n";
   }
-  if (_shadows) {
+  if (_shadows && _auto_shadow_on) {
     text << "\t float4x4 biasmat = {0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f};\n";
     for (int i=0; i<(int)_dlights.size(); i++) {
       if (_dlights[i]->_shadow_caster) {
@@ -791,7 +807,7 @@ synthesize_shader(const RenderState *rs) {
       text << "\t uniform float4x4 texmat_" << i << ",\n";
     }
   }
-  if (_lighting && (_map_index_normal >= 0)) {
+  if (_lighting && (_map_index_normal >= 0 && _auto_normal_on)) {
     text << "\t in float3 l_tangent : " << ntangent_freg << ",\n";
     text << "\t in float3 l_binormal : " << nbinormal_freg << ",\n";
   }
@@ -801,7 +817,7 @@ synthesize_shader(const RenderState *rs) {
     }
     for (int i=0; i<(int)_dlights.size(); i++) {
       text << "\t uniform float4x4 dlight_dlight" << i << "_rel_view,\n";
-      if (_shadows && _dlights[i]->_shadow_caster) {
+      if (_shadows && _dlights[i]->_shadow_caster && _auto_shadow_on) {
         if (_use_shadow_filter) {
           text << "\t uniform sampler2DShadow k_dlighttex" << i << ",\n";
         } else {
@@ -816,7 +832,7 @@ synthesize_shader(const RenderState *rs) {
     for (int i=0; i<(int)_slights.size(); i++) {
       text << "\t uniform float4x4 slight_slight" << i << "_rel_view,\n";
       text << "\t uniform float4   satten_slight" << i << ",\n";
-      if (_shadows && _slights[i]->_shadow_caster) {
+      if (_shadows && _slights[i]->_shadow_caster && _auto_shadow_on) {
         if (_use_shadow_filter) {
           text << "\t uniform sampler2DShadow k_slighttex" << i << ",\n";
         } else {
@@ -942,7 +958,7 @@ synthesize_shader(const RenderState *rs) {
     }
   }
   if (_lighting) {
-    if (_map_index_normal >= 0) {
+    if (_map_index_normal >= 0 && _auto_normal_on) {
       text << "\t // Translate tangent-space normal in map to view-space.\n";
       text << "\t float3 tsnormal = ((float3)tex" << _map_index_normal << " * 2) - 1;\n";
       text << "\t l_eye_normal.xyz *= tsnormal.z;\n";
@@ -962,7 +978,7 @@ synthesize_shader(const RenderState *rs) {
     text << "\t // Begin view-space light calculations\n";
     text << "\t float ldist,lattenv,langle;\n";
     text << "\t float4 lcolor,lspec,lvec,lpoint,latten,ldir,leye,lhalf;";
-    if (_shadows) {
+    if (_shadows && _auto_shadow_on) {
       text << "\t float lshad;\n";
     }
     if (_separate_ambient_diffuse) {
@@ -1000,7 +1016,7 @@ synthesize_shader(const RenderState *rs) {
       text << "\t lspec  = dlight_dlight" << i << "_rel_view[1];\n";
       text << "\t lvec   = dlight_dlight" << i << "_rel_view[2];\n";
       text << "\t lcolor *= saturate(dot(l_eye_normal.xyz, lvec.xyz));\n";
-      if (_shadows && _dlights[i]->_shadow_caster) {
+      if (_shadows && _dlights[i]->_shadow_caster && _auto_shadow_on) {
         if (_use_shadow_filter) {
           text << "\t lshad = shadow2DProj(k_dlighttex" << i << ", l_dlightcoord" << i << ").r;\n";
         } else {
@@ -1062,7 +1078,7 @@ synthesize_shader(const RenderState *rs) {
       text << "\t lattenv *= pow(langle, latten.w);\n";
       text << "\t if (langle < ldir.w) lattenv = 0;\n";
       text << "\t lcolor *= lattenv * saturate(dot(l_eye_normal.xyz, lvec.xyz));\n";
-      if (_shadows && _slights[i]->_shadow_caster) {
+      if (_shadows && _slights[i]->_shadow_caster && _auto_shadow_on) {
         if (_use_shadow_filter) {
           text << "\t lshad = shadow2DProj(k_slighttex" << i << ", l_slightcoord" << i << ").r;\n";
         } else {
@@ -1086,44 +1102,45 @@ synthesize_shader(const RenderState *rs) {
         text << "\t tot_specular += lspec;\n";
       }
     }
-
     const LightRampAttrib *light_ramp = DCAST(LightRampAttrib, rs->get_attrib_def(LightRampAttrib::get_class_slot()));
-    switch (light_ramp->get_mode()) {
-    case LightRampAttrib::LRT_single_threshold:
-      {
-        float t = light_ramp->get_threshold(0);
-        float l0 = light_ramp->get_level(0);
-        text << "\t // Single-threshold light ramp\n";
-        text << "\t float lr_in = dot(tot_diffuse.rgb, float3(0.33,0.34,0.33));\n";
-        text << "\t float lr_scale = (lr_in < " << t << ") ? 0.0 : (" << l0 << "/lr_in);\n";
-        text << "\t tot_diffuse = tot_diffuse * lr_scale;\n";
-        break;
-      }
-    case LightRampAttrib::LRT_double_threshold:
-      {
-        float t0 = light_ramp->get_threshold(0);
-        float t1 = light_ramp->get_threshold(1);
-        float l0 = light_ramp->get_level(0);
-        float l1 = light_ramp->get_level(1);
-        float l2 = light_ramp->get_level(2);
-        text << "\t // Double-threshold light ramp\n";
-        text << "\t float lr_in = dot(tot_diffuse.rgb, float3(0.33,0.34,0.33));\n";
-        text << "\t float lr_out = " << l0 << "\n";
-        text << "\t if (lr_in > " << t0 << ") lr_out=" << l1 << ";\n";
-        text << "\t if (lr_in > " << t1 << ") lr_out=" << l2 << ";\n";
-        text << "\t tot_diffuse = tot_diffuse * (lr_out / lr_in);\n";
-        break;
+    if(_auto_ramp_on) {
+      switch (light_ramp->get_mode()) {
+      case LightRampAttrib::LRT_single_threshold:
+        {
+          float t = light_ramp->get_threshold(0);
+          float l0 = light_ramp->get_level(0);
+          text << "\t // Single-threshold light ramp\n";
+          text << "\t float lr_in = dot(tot_diffuse.rgb, float3(0.33,0.34,0.33));\n";
+          text << "\t float lr_scale = (lr_in < " << t << ") ? 0.0 : (" << l0 << "/lr_in);\n";
+          text << "\t tot_diffuse = tot_diffuse * lr_scale;\n";
+          break;
+        }
+      case LightRampAttrib::LRT_double_threshold:
+        {
+          float t0 = light_ramp->get_threshold(0);
+          float t1 = light_ramp->get_threshold(1);
+          float l0 = light_ramp->get_level(0);
+          float l1 = light_ramp->get_level(1);
+          float l2 = light_ramp->get_level(2);
+          text << "\t // Double-threshold light ramp\n";
+          text << "\t float lr_in = dot(tot_diffuse.rgb, float3(0.33,0.34,0.33));\n";
+          text << "\t float lr_out = " << l0 << "\n";
+          text << "\t if (lr_in > " << t0 << ") lr_out=" << l1 << ";\n";
+          text << "\t if (lr_in > " << t1 << ") lr_out=" << l2 << ";\n";
+          text << "\t tot_diffuse = tot_diffuse * (lr_out / lr_in);\n";
+          break;
+        }
       }
     }
     text << "\t // Begin view-space light summation\n";
     if (_have_emission) {
-      if (_map_index_glow >= 0) {
+      if (_map_index_glow >= 0 && _auto_glow_on) {
         text << "\t result = attr_material[2] * saturate(2 * (tex" << _map_index_glow << ".a - 0.5));\n";
       } else {
         text << "\t result = attr_material[2];\n";
       }
     } else {
-      if (_map_index_glow >= 0) {
+      if (_map_index_glow >= 0 && _auto_glow_on) {
         text << "\t result = saturate(2 * (tex" << _map_index_glow << ".a - 0.5));\n";
       } else {
         text << "\t result = float4(0,0,0,0);\n";
@@ -1269,14 +1286,14 @@ synthesize_shader(const RenderState *rs) {
   }
 
   if (_out_primary_glow) {
-    if (_map_index_glow >= 0) {
+    if (_map_index_glow >= 0 && _auto_glow_on) {
       text << "\t result.a = tex" << _map_index_glow << ".a;\n";
     } else {
       text << "\t result.a = 0.5;\n";
     }
   }
   if (_out_aux_glow) {
-    if (_map_index_glow >= 0) {
+    if (_map_index_glow >= 0 && _auto_glow_on) {
       text << "\t o_aux.a = tex" << _map_index_glow << ".a;\n";
     } else {
       text << "\t o_aux.a = 0.5;\n";
@@ -1288,25 +1305,26 @@ synthesize_shader(const RenderState *rs) {
       if (_material->has_specular()) {
         text << "\t tot_specular *= attr_material[3];\n";
       }
-      if (_map_index_gloss >= 0) {
+      if (_map_index_gloss >= 0 && _auto_gloss_on) {
         text << "\t tot_specular *= tex" << _map_index_gloss << ".a;\n";
       }
       text << "\t result.rgb = result.rgb + tot_specular.rgb;\n";
     }
   }
-
-  const LightRampAttrib *light_ramp = DCAST(LightRampAttrib, rs->get_attrib_def(LightRampAttrib::get_class_slot()));
-  switch (light_ramp->get_mode()) {
-  case LightRampAttrib::LRT_hdr0:
-    text << "\t result.rgb = (result*result*result + result*result + result) / (result*result*result + result*result + result + 1);\n";
-    break;
-  case LightRampAttrib::LRT_hdr1:
-    text << "\t result.rgb = (result*result + result) / (result*result + result + 1);\n";
-    break;
-  case LightRampAttrib::LRT_hdr2:
-    text << "\t result.rgb = result / (result + 1);\n";
-    break;
-  default: break;
+  if(_auto_ramp_on) {
+    const LightRampAttrib *light_ramp = DCAST(LightRampAttrib, rs->get_attrib_def(LightRampAttrib::get_class_slot()));
+    switch (light_ramp->get_mode()) {
+    case LightRampAttrib::LRT_hdr0:
+      text << "\t result.rgb = (result*result*result + result*result + result) / (result*result*result + result*result + result + 1);\n";
+      break;
+    case LightRampAttrib::LRT_hdr1:
+      text << "\t result.rgb = (result*result + result) / (result*result + result + 1);\n";
+      break;
+    case LightRampAttrib::LRT_hdr2:
+      text << "\t result.rgb = result / (result + 1);\n";
+      break;
+    default: break;
+    }
   }
 
   // The multiply is a workaround for a radeon driver bug.

+ 6 - 0
panda/src/pgraphnodes/shaderGenerator.h

@@ -1,5 +1,6 @@
 // Filename: shaderGenerator.h
 // Created by: jyelon (15Dec07)
+// Updated by: weifengh, PandaSE(15Apr10)
 //
 ////////////////////////////////////////////////////////////////////
 //
@@ -141,6 +142,11 @@ protected:
   bool _need_world_normal;
   bool _need_eye_position;
   bool _need_eye_normal;
+  bool _auto_normal_on;
+  bool _auto_glow_on;
+  bool _auto_gloss_on;
+  bool _auto_ramp_on;
+  bool _auto_shadow_on;
 
   void analyze_renderstate(const RenderState *rs);
   void clear_analysis();