Browse Source

Fix some bugs in the shader generator regarding combine modes.

rdb 16 years ago
parent
commit
87e5347a1e

+ 48 - 7
panda/src/gobj/textureStage.I

@@ -627,6 +627,18 @@ get_combine_alpha_operand2() const {
   return _combine_alpha_operand2;
   return _combine_alpha_operand2;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: TextureStage::involves_color_scale
+//       Access: Published
+//  Description: Returns true if the TextureStage is affected by the
+//               setting of the current ColorScaleAttrib, false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool TextureStage::
+involves_color_scale() const {
+  return _involves_color_scale;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureStage::uses_color
 //     Function: TextureStage::uses_color
 //       Access: Published
 //       Access: Published
@@ -640,15 +652,25 @@ uses_color() const {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: TextureStage::involves_color_scale
+//     Function: TextureStage::uses_primary_color
 //       Access: Published
 //       Access: Published
-//  Description: Returns true if the TextureStage is affected by the
-//               setting of the current ColorScaleAttrib, false
-//               otherwise.
+//  Description: Returns true if the TextureStage makes use of
+//               the CS_primary_color combine source.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool TextureStage::
 INLINE bool TextureStage::
-involves_color_scale() const {
-  return _involves_color_scale;
+uses_primary_color() const {
+  return _uses_primary_color;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextureStage::uses_last_saved_result
+//       Access: Published
+//  Description: Returns true if the TextureStage makes use of
+//               the CS_primary_color combine source.
+////////////////////////////////////////////////////////////////////
+INLINE bool TextureStage::
+uses_last_saved_result() const {
+  return _uses_last_saved_result;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -684,7 +706,8 @@ get_sort_seq() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureStage::update_color_flags
 //     Function: TextureStage::update_color_flags
 //       Access: Private
 //       Access: Private
-//  Description: Updates _uses_color and _involves_color_scale
+//  Description: Updates _uses_color, _involves_color_scale,
+//               _uses_primary_color and _uses_last_saved_result
 //               appropriately.
 //               appropriately.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void TextureStage::
 INLINE void TextureStage::
@@ -709,6 +732,24 @@ update_color_flags() {
        _combine_alpha_source0 == CS_constant ||
        _combine_alpha_source0 == CS_constant ||
        _combine_alpha_source1 == CS_constant ||
        _combine_alpha_source1 == CS_constant ||
        _combine_alpha_source2 == CS_constant)));
        _combine_alpha_source2 == CS_constant)));
+
+  _uses_primary_color = 
+     (_mode == M_combine &&
+      (_combine_rgb_source0 == CS_primary_color ||
+       _combine_rgb_source1 == CS_primary_color ||
+       _combine_rgb_source2 == CS_primary_color ||
+       _combine_alpha_source0 == CS_primary_color ||
+       _combine_alpha_source1 == CS_primary_color ||
+       _combine_alpha_source2 == CS_primary_color));
+
+  _uses_last_saved_result = 
+     (_mode == M_combine &&
+      (_combine_rgb_source0 == CS_last_saved_result ||
+       _combine_rgb_source1 == CS_last_saved_result ||
+       _combine_rgb_source2 == CS_last_saved_result ||
+       _combine_alpha_source0 == CS_last_saved_result ||
+       _combine_alpha_source1 == CS_last_saved_result ||
+       _combine_alpha_source2 == CS_last_saved_result));
 }
 }
 
 
 INLINE ostream &
 INLINE ostream &

+ 6 - 2
panda/src/gobj/textureStage.h

@@ -168,8 +168,10 @@ PUBLISHED:
   INLINE CombineSource get_combine_alpha_source2() const;
   INLINE CombineSource get_combine_alpha_source2() const;
   INLINE CombineOperand get_combine_alpha_operand2() const;
   INLINE CombineOperand get_combine_alpha_operand2() const;
 
 
-  INLINE bool uses_color() const;
   INLINE bool involves_color_scale() const;
   INLINE bool involves_color_scale() const;
+  INLINE bool uses_color() const;
+  INLINE bool uses_primary_color() const;
+  INLINE bool uses_last_saved_result() const;
 
 
   void write(ostream &out) const;
   void write(ostream &out) const;
   void output(ostream &out) const;
   void output(ostream &out) const;
@@ -195,8 +197,10 @@ private:
   int _rgb_scale;
   int _rgb_scale;
   int _alpha_scale;
   int _alpha_scale;
   bool _saved_result;
   bool _saved_result;
-  bool _uses_color;
   bool _involves_color_scale;
   bool _involves_color_scale;
+  bool _uses_color;
+  bool _uses_primary_color;
+  bool _uses_last_saved_result;
 
 
   CombineMode _combine_rgb_mode;
   CombineMode _combine_rgb_mode;
   int _num_combine_rgb_operands;
   int _num_combine_rgb_operands;

+ 59 - 34
panda/src/pgraphnodes/shaderGenerator.cxx

@@ -1127,8 +1127,21 @@ synthesize_shader(const RenderState *rs) {
     }
     }
   }
   }
 
 
-  text << "\t float4 primary_color = result;\n";
+  // Loop first to see if something is using primary_color or last_saved_result.
   bool have_saved_result = false;
   bool have_saved_result = false;
+  for (int i=0; i<_num_textures; i++) {
+    TextureStage *stage = texture->get_on_stage(i);
+    if (stage->get_mode() != TextureStage::M_combine) continue;
+    if (stage->uses_primary_color()) {
+      text << "\t float4 primary_color = result;\n";
+    }
+    if (stage->uses_last_saved_result()) {
+      text << "\t float4 last_saved_result = result;\n";
+      have_saved_result = true;
+    }
+  }
+
+  // Now loop through the textures to compose our magic blending formulas.
   for (int i=0; i<_num_textures; i++) {
   for (int i=0; i<_num_textures; i++) {
     TextureStage *stage = texture->get_on_stage(i);
     TextureStage *stage = texture->get_on_stage(i);
     switch (stage->get_mode()) {
     switch (stage->get_mode()) {
@@ -1167,13 +1180,8 @@ synthesize_shader(const RenderState *rs) {
     default:
     default:
       break;
       break;
     }
     }
-    if (stage->get_saved_result()) {
-      if (have_saved_result) {
-        text << "\t last_saved_result = result;\n";
-      } else {
-        text << "\t float4 last_saved_result = result;\n";
-        have_saved_result = true;
-      }
+    if (stage->get_saved_result() && have_saved_result) {
+      text << "\t last_saved_result = result;\n";
     }
     }
   }
   }
   // Apply the color scale.
   // Apply the color scale.
@@ -1265,35 +1273,35 @@ synthesize_shader(const RenderState *rs) {
 //  Description: This 'synthesizes' a combine mode into a string.
 //  Description: This 'synthesizes' a combine mode into a string.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 const string ShaderGenerator::
 const string ShaderGenerator::
-combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode, bool single_value, short texindex) {
+combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode, bool alpha, short texindex) {
   ostringstream text;
   ostringstream text;
   switch (c_mode) {
   switch (c_mode) {
     case TextureStage::CM_modulate:
     case TextureStage::CM_modulate:
-      text << combine_source_as_string(stage, 0, single_value, texindex);
+      text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
       text << " * ";
       text << " * ";
-      text << combine_source_as_string(stage, 1, single_value, texindex);
+      text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
       break;
       break;
     case TextureStage::CM_add:
     case TextureStage::CM_add:
-      text << combine_source_as_string(stage, 0, single_value, texindex);
+      text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
       text << " + ";
       text << " + ";
-      text << combine_source_as_string(stage, 1, single_value, texindex);
+      text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
       break;
       break;
     case TextureStage::CM_add_signed:
     case TextureStage::CM_add_signed:
       pgraph_cat.error() << "TextureStage::CombineMode ADD_SIGNED not yet supported in per-pixel mode.\n";
       pgraph_cat.error() << "TextureStage::CombineMode ADD_SIGNED not yet supported in per-pixel mode.\n";
       break;
       break;
     case TextureStage::CM_interpolate:
     case TextureStage::CM_interpolate:
       text << "lerp(";
       text << "lerp(";
-      text << combine_source_as_string(stage, 1, single_value, texindex);
+      text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
       text << ", ";
       text << ", ";
-      text << combine_source_as_string(stage, 0, single_value, texindex);
+      text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
       text << ", ";
       text << ", ";
-      text << combine_source_as_string(stage, 2, true, texindex);
+      text << combine_source_as_string(stage, 2, alpha, true, texindex);
       text << ")";
       text << ")";
       break;
       break;
     case TextureStage::CM_subtract:
     case TextureStage::CM_subtract:
-      text << combine_source_as_string(stage, 0, single_value, texindex);
+      text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
       text << " + ";
       text << " + ";
-      text << combine_source_as_string(stage, 1, single_value, texindex);
+      text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
       break;
       break;
     case TextureStage::CM_dot3_rgb:
     case TextureStage::CM_dot3_rgb:
       pgraph_cat.error() << "TextureStage::CombineMode DOT3_RGB not yet supported in per-pixel mode.\n";
       pgraph_cat.error() << "TextureStage::CombineMode DOT3_RGB not yet supported in per-pixel mode.\n";
@@ -1303,7 +1311,7 @@ combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode
       break;
       break;
     case TextureStage::CM_replace:
     case TextureStage::CM_replace:
     default: // Not sure if this is correct as default value.
     default: // Not sure if this is correct as default value.
-      text << combine_source_as_string(stage, 0, single_value, texindex);
+      text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
       break;
       break;
   }
   }
   return text.str();
   return text.str();
@@ -1315,22 +1323,39 @@ combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode
 //  Description: This 'synthesizes' a combine source into a string.
 //  Description: This 'synthesizes' a combine source into a string.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 const string ShaderGenerator::
 const string ShaderGenerator::
-combine_source_as_string(CPT(TextureStage) stage, short num, bool single_value, short texindex) {
+combine_source_as_string(CPT(TextureStage) stage, short num, bool alpha, bool single_value, short texindex) {
   TextureStage::CombineSource c_src = TextureStage::CS_undefined;
   TextureStage::CombineSource c_src = TextureStage::CS_undefined;
   TextureStage::CombineOperand c_op = TextureStage::CO_undefined;
   TextureStage::CombineOperand c_op = TextureStage::CO_undefined;
-  switch (num) {
-    case 0:
-      c_src = stage->get_combine_rgb_source0();
-      c_op = stage->get_combine_rgb_operand0();
-      break;
-    case 1:
-      c_src = stage->get_combine_rgb_source1();
-      c_op = stage->get_combine_rgb_operand1();
-      break;
-    case 2:
-      c_src = stage->get_combine_rgb_source2();
-      c_op = stage->get_combine_rgb_operand2();
-      break;
+  if (alpha) {
+    switch (num) {
+      case 0:
+        c_src = stage->get_combine_alpha_source0();
+        c_op = stage->get_combine_alpha_operand0();
+        break;
+      case 1:
+        c_src = stage->get_combine_alpha_source1();
+        c_op = stage->get_combine_alpha_operand1();
+        break;
+      case 2:
+        c_src = stage->get_combine_alpha_source2();
+        c_op = stage->get_combine_alpha_operand2();
+        break;
+    }
+  } else {
+    switch (num) {
+      case 0:
+        c_src = stage->get_combine_rgb_source0();
+        c_op = stage->get_combine_rgb_operand0();
+        break;
+      case 1:
+        c_src = stage->get_combine_rgb_source1();
+        c_op = stage->get_combine_rgb_operand1();
+        break;
+      case 2:
+        c_src = stage->get_combine_rgb_source2();
+        c_op = stage->get_combine_rgb_operand2();
+        break;
+    }
   }
   }
   ostringstream csource;
   ostringstream csource;
   if (c_op == TextureStage::CO_one_minus_src_color ||
   if (c_op == TextureStage::CO_one_minus_src_color ||
@@ -1368,7 +1393,7 @@ combine_source_as_string(CPT(TextureStage) stage, short num, bool single_value,
   } else {
   } else {
     csource << ".a";
     csource << ".a";
     if (!single_value) {
     if (!single_value) {
-      // Dunno if it's legal at all, but let's just allow it.
+      // Dunno if it's legal in the FPP at all, but let's just allow it.
       return "float3(" + csource.str() + ")";
       return "float3(" + csource.str() + ")";
     }
     }
   }
   }

+ 2 - 2
panda/src/pgraphnodes/shaderGenerator.h

@@ -73,9 +73,9 @@ protected:
   CPT(RenderAttrib) create_shader_attrib(const string &txt);
   CPT(RenderAttrib) create_shader_attrib(const string &txt);
   PT(Texture) update_shadow_buffer(NodePath light_np);
   PT(Texture) update_shadow_buffer(NodePath light_np);
   static const string combine_mode_as_string(CPT(TextureStage) stage,
   static const string combine_mode_as_string(CPT(TextureStage) stage,
-               TextureStage::CombineMode c_mode, bool single_value, short texindex);
+                      TextureStage::CombineMode c_mode, bool alpha, short texindex);
   static const string combine_source_as_string(CPT(TextureStage) stage,
   static const string combine_source_as_string(CPT(TextureStage) stage,
-                                      short num, bool single_value, short texindex);
+                         short num, bool alpha, bool single_value, short texindex);
   static const string texture_type_as_string(Texture::TextureType ttype);
   static const string texture_type_as_string(Texture::TextureType ttype);
 
 
   // Shader register allocation:
   // Shader register allocation: