Browse Source

add TextureStage::CS_crossbar_stage

David Rose 20 years ago
parent
commit
efaa58b52f

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

@@ -233,6 +233,49 @@ get_max_cube_map_dimension() const {
   return _max_cube_map_dimension;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::get_supports_texture_combine
+//       Access: Published
+//  Description: Returns true if this particular GSG can use the
+//               TextureStage::M_combine mode, which includes all of
+//               the texture blend modes specified by
+//               set_combine_rgb() and/or set_combine_alpha().  If
+//               this is false, you must limit yourself to using the
+//               simpler blend modes.
+////////////////////////////////////////////////////////////////////
+INLINE bool GraphicsStateGuardian::
+get_supports_texture_combine() const {
+  return _supports_texture_combine;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::get_supports_texture_crossbar
+//       Access: Published
+//  Description: Returns true if this GSG can use the
+//               TextureStage::CS_crossbar_stage blend source, which
+//               allows you to specify an arbitrary TextureStage as a
+//               source parameter to set_combine_rgb() or
+//               set_combine_alpha().  If this is false, you must use
+//               choose from one of the available enumerated values
+//               for the source of each operand.
+////////////////////////////////////////////////////////////////////
+INLINE bool GraphicsStateGuardian::
+get_supports_texture_crossbar() const {
+  return _supports_texture_crossbar;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::get_supports_texture_dot3
+//       Access: Published
+//  Description: Returns true if this GSG can use the
+//               TextureStage::CM_dot3_rgb or CM_dot3_rgba combine
+//               modes.
+////////////////////////////////////////////////////////////////////
+INLINE bool GraphicsStateGuardian::
+get_supports_texture_dot3() const {
+  return _supports_texture_dot3;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_max_lights
 //       Access: Published

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

@@ -120,6 +120,12 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
   _max_3d_texture_dimension = 0;
   _max_cube_map_dimension = 0;
 
+  // Assume we don't support these fairly advanced texture combiner
+  // modes.
+  _supports_texture_combine = false;
+  _supports_texture_crossbar = false;
+  _supports_texture_dot3 = false;
+
   // Assume no limits on number of lights or clip planes.
   _max_lights = -1;
   _max_clip_planes = -1;

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

@@ -94,6 +94,10 @@ PUBLISHED:
   INLINE int get_max_3d_texture_dimension() const;
   INLINE int get_max_cube_map_dimension() const;
 
+  INLINE bool get_supports_texture_combine() const;
+  INLINE bool get_supports_texture_crossbar() const;
+  INLINE bool get_supports_texture_dot3() const;
+
   INLINE int get_max_lights() const;
   INLINE int get_max_clip_planes() const;
 
@@ -362,6 +366,10 @@ protected:
   int _max_3d_texture_dimension;
   int _max_cube_map_dimension;
 
+  bool _supports_texture_combine;
+  bool _supports_texture_crossbar;
+  bool _supports_texture_dot3;
+
   int _max_lights;
   int _max_clip_planes;
 

+ 114 - 63
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -516,6 +516,13 @@ reset() {
     _glClientActiveTexture = null_glActiveTexture;
   }
 
+  _supports_texture_combine = 
+    has_extension("GL_ARB_texture_env_combine") || is_at_least_version(1, 3);
+  _supports_texture_crossbar =
+    has_extension("GL_ARB_texture_env_crossbar") || is_at_least_version(1, 4);
+  _supports_texture_dot3 =
+    has_extension("GL_ARB_texture_env_dot3") || is_at_least_version(1, 3);
+
   _supports_buffers = false;
     
   if (is_at_least_version(1, 5)) {
@@ -3543,12 +3550,14 @@ get_texture_combine_type(TextureStage::CombineMode cm) {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::get_texture_src_type
-//       Access: Protected, Static
+//       Access: Protected
 //  Description: Maps from the texture stage's CombineSource types
 //               to the corresponding OpenGL ids
 ////////////////////////////////////////////////////////////////////
 GLint CLP(GraphicsStateGuardian)::
-get_texture_src_type(TextureStage::CombineSource cs) {
+get_texture_src_type(TextureStage::CombineSource cs,
+                     const TextureStage *source_stage, 
+                     const TextureAttrib *attrib, int this_stage) const {
   switch (cs) {
   case TextureStage::CS_undefined: // fall through
   case TextureStage::CS_texture: return GL_TEXTURE;
@@ -3556,6 +3565,31 @@ get_texture_src_type(TextureStage::CombineSource cs) {
   case TextureStage::CS_primary_color: return GL_PRIMARY_COLOR;
   case TextureStage::CS_previous: return GL_PREVIOUS;
   case TextureStage::CS_constant_color_scale: return GL_CONSTANT;
+
+  case TextureStage::CS_crossbar_stage:
+    {
+      int n = attrib->find_on_stage(source_stage);
+      if (n >= 0) {
+        if (_supports_texture_crossbar) {
+          return GL_TEXTURE0 + n;
+
+        } else if (n == this_stage) {
+          return GL_TEXTURE;
+
+        } else if (n == this_stage - 1) {
+          return GL_PREVIOUS;
+
+        } else {
+          GLCAT.warning()
+            << "Crossbar blending not supported\n";
+          return GL_PRIMARY_COLOR;
+        }
+      }
+      GLCAT.warning()
+        << "TextureStage " << *attrib->get_on_stage(this_stage)
+        << " sources unused stage: " << *source_stage << "\n";
+      return GL_PRIMARY_COLOR;
+    } 
   }
 
   GLCAT.error()
@@ -4502,7 +4536,7 @@ do_issue_texture() {
       }
 
       if (stage->get_mode() == TextureStage::M_decal) {
-        if (texture->get_num_components() < 3) {
+        if (texture->get_num_components() < 3 && _supports_texture_combine) {
           // Make a special case for 1- and 2-channel decal textures.
           // OpenGL does not define their use with GL_DECAL for some
           // reason, so implement them using the combiner instead.
@@ -4523,67 +4557,84 @@ do_issue_texture() {
         }
 
       } else if (stage->get_mode() == TextureStage::M_combine) {
-        GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
-        GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
-        GLP(TexEnvi)(GL_TEXTURE_ENV, GL_RGB_SCALE, stage->get_rgb_scale());
-        GLP(TexEnvi)(GL_TEXTURE_ENV, GL_ALPHA_SCALE, stage->get_alpha_scale());
-        GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB, 
-                     get_texture_combine_type(stage->get_combine_rgb_mode()));
-
-        switch (stage->get_num_combine_rgb_operands()) {
-        case 3:
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_RGB, 
-                       get_texture_src_type(stage->get_combine_rgb_source2()));
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_RGB, 
-                       get_texture_operand_type(stage->get_combine_rgb_operand2()));
-          // fall through
-
-        case 2:
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_RGB, 
-                       get_texture_src_type(stage->get_combine_rgb_source1()));
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_RGB, 
-                       get_texture_operand_type(stage->get_combine_rgb_operand1()));
-          // fall through
-
-        case 1:
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_RGB, 
-                       get_texture_src_type(stage->get_combine_rgb_source0()));
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND0_RGB, 
-                       get_texture_operand_type(stage->get_combine_rgb_operand0()));
-          // fall through
-
-        default:
-          break;
-        }
-        GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, 
-                     get_texture_combine_type(stage->get_combine_alpha_mode()));
-
-        switch (stage->get_num_combine_alpha_operands()) {
-        case 3:
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_ALPHA, 
-                       get_texture_src_type(stage->get_combine_alpha_source2()));
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, 
-                       get_texture_operand_type(stage->get_combine_alpha_operand2()));
-          // fall through
-
-        case 2:
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_ALPHA, 
-                       get_texture_src_type(stage->get_combine_alpha_source1()));
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, 
-                       get_texture_operand_type(stage->get_combine_alpha_operand1()));
-          // fall through
-
-        case 1:
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_ALPHA, 
-                       get_texture_src_type(stage->get_combine_alpha_source0()));
-          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, 
-                       get_texture_operand_type(stage->get_combine_alpha_operand0()));
-          // fall through
-
-        default:
-          break;
+        if (!_supports_texture_combine) {
+          GLCAT.warning()
+            << "TextureStage::M_combine mode is not supported.\n";
+          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+        } else {
+          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_RGB_SCALE, stage->get_rgb_scale());
+          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_ALPHA_SCALE, stage->get_alpha_scale());
+          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB, 
+                       get_texture_combine_type(stage->get_combine_rgb_mode()));
+          
+          switch (stage->get_num_combine_rgb_operands()) {
+          case 3:
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_RGB, 
+                         get_texture_src_type(stage->get_combine_rgb_source2(),
+                                              stage->get_combine_rgb_source2_stage(), 
+                                              new_texture, i));
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_RGB, 
+                         get_texture_operand_type(stage->get_combine_rgb_operand2()));
+            // fall through
+            
+          case 2:
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_RGB, 
+                         get_texture_src_type(stage->get_combine_rgb_source1(),
+                                              stage->get_combine_rgb_source1_stage(),
+                                              new_texture, i));
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_RGB, 
+                         get_texture_operand_type(stage->get_combine_rgb_operand1()));
+            // fall through
+            
+          case 1:
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_RGB, 
+                         get_texture_src_type(stage->get_combine_rgb_source0(),
+                                              stage->get_combine_rgb_source0_stage(),
+                                              new_texture, i));
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND0_RGB, 
+                         get_texture_operand_type(stage->get_combine_rgb_operand0()));
+            // fall through
+            
+          default:
+            break;
+          }
+          GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, 
+                       get_texture_combine_type(stage->get_combine_alpha_mode()));
+          
+          switch (stage->get_num_combine_alpha_operands()) {
+          case 3:
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_ALPHA, 
+                         get_texture_src_type(stage->get_combine_alpha_source2(),
+                                              stage->get_combine_alpha_source2_stage(),
+                                              new_texture, i));
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, 
+                         get_texture_operand_type(stage->get_combine_alpha_operand2()));
+            // fall through
+            
+          case 2:
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_ALPHA, 
+                         get_texture_src_type(stage->get_combine_alpha_source1(),
+                                              stage->get_combine_alpha_source1_stage(),
+                                              new_texture, i));
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, 
+                         get_texture_operand_type(stage->get_combine_alpha_operand1()));
+            // fall through
+            
+          case 1:
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_ALPHA, 
+                         get_texture_src_type(stage->get_combine_alpha_source0(),
+                                              stage->get_combine_alpha_source0_stage(),
+                                              new_texture, i));
+            GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, 
+                         get_texture_operand_type(stage->get_combine_alpha_operand0()));
+            // fall through
+            
+          default:
+            break;
+          }
         }
-
       } else {
         GLint glmode = get_texture_apply_mode_type(stage->get_mode());
         GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);

+ 3 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -223,7 +223,9 @@ protected:
                                         GLenum component_type);
   static GLint get_texture_apply_mode_type(TextureStage::Mode am);
   static GLint get_texture_combine_type(TextureStage::CombineMode cm);
-  static GLint get_texture_src_type(TextureStage::CombineSource cs);
+  GLint get_texture_src_type(TextureStage::CombineSource cs,
+                             const TextureStage *source_stage, 
+                             const TextureAttrib *attrib, int this_stage) const;
   static GLint get_texture_operand_type(TextureStage::CombineOperand co);
   static GLenum get_fog_mode_type(Fog::Mode m);
   static GLenum get_blend_equation_type(ColorBlendAttrib::Mode mode);

File diff suppressed because it is too large
+ 810 - 110
panda/src/gobj/textureStage.I


+ 104 - 13
panda/src/gobj/textureStage.cxx

@@ -117,35 +117,41 @@ write(ostream &out) const {
   if (get_mode() == M_combine) {
     out << "  RGB combine mode =  " << get_combine_rgb_mode() << "\n";
     if (get_num_combine_rgb_operands() >= 1) {
-      out << "    0: " << get_combine_rgb_source0() << ", "
-          << get_combine_rgb_operand0() << "\n";
+      write_operand(out, 0, get_combine_rgb_source0(), 
+                    get_combine_rgb_source0_stage(), 
+                    get_combine_rgb_operand0());
     }
     if (get_num_combine_rgb_operands() >= 2) {
-      out << "    1: " << get_combine_rgb_source1() << ", "
-          << get_combine_rgb_operand1() << "\n";
+      write_operand(out, 1, get_combine_rgb_source1(), 
+                    get_combine_rgb_source1_stage(), 
+                    get_combine_rgb_operand1());
     }
     if (get_num_combine_rgb_operands() >= 3) {
-      out << "    2: " << get_combine_rgb_source2() << ", "
-          << get_combine_rgb_operand2() << "\n";
+      write_operand(out, 2, get_combine_rgb_source2(), 
+                    get_combine_rgb_source2_stage(), 
+                    get_combine_rgb_operand2());
     }
     out << "  alpha combine mode =  " << get_combine_alpha_mode() << "\n";
     if (get_num_combine_alpha_operands() >= 1) {
-      out << "    0: " << get_combine_alpha_source0() << ", "
-          << get_combine_alpha_operand0() << "\n";
+      write_operand(out, 0, get_combine_alpha_source0(), 
+                    get_combine_alpha_source0_stage(), 
+                    get_combine_alpha_operand0());
     }
     if (get_num_combine_alpha_operands() >= 2) {
-      out << "    1: " << get_combine_alpha_source1() << ", "
-          << get_combine_alpha_operand1() << "\n";
+      write_operand(out, 1, get_combine_alpha_source1(), 
+                    get_combine_alpha_source1_stage(), 
+                    get_combine_alpha_operand1());
     }
     if (get_num_combine_alpha_operands() >= 3) {
-      out << "    2: " << get_combine_alpha_source2() << ", "
-          << get_combine_alpha_operand2() << "\n";
+      write_operand(out, 2, get_combine_alpha_source2(), 
+                    get_combine_alpha_source2_stage(), 
+                    get_combine_alpha_operand2());
     }
   }
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: TextureStage::Destructor
+//     Function: TextureStage::output
 //       Access: Published
 //  Description: Just a single line output
 ////////////////////////////////////////////////////////////////////
@@ -154,6 +160,25 @@ output(ostream &out) const {
   out << "TextureStage " << get_name();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TextureStage::write_operand
+//       Access: Private, Static
+//  Description: Used by write() to simply describe a single operand
+//               of the CM_combine mode (one of up to 3 defined by the
+//               stage).
+////////////////////////////////////////////////////////////////////
+void TextureStage::
+write_operand(ostream &out, int operand_index, CombineSource source, 
+              const TextureStage *source_stage, CombineOperand operand) {
+  if (source == CS_crossbar_stage) {
+    out << "    " << operand_index << ": " 
+        << *source_stage << ", " << operand << "\n";
+  } else {
+    out << "    " << operand_index << ": " 
+        << source << ", " << operand << "\n";
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureStage::get_expected_num_combine_operands
 //       Access: Private, Static
@@ -300,6 +325,27 @@ fillin(DatagramIterator &scan, BamReader *manager) {
   _combine_alpha_source2 = (TextureStage::CombineSource) scan.get_uint8();
   _combine_alpha_operand2 = (TextureStage::CombineOperand) scan.get_uint8();
 
+  // We only read these pointers if the source types indicate they are
+  // defined.
+  if (_combine_rgb_source0 == CS_crossbar_stage) {
+    manager->read_pointer(scan);
+  }
+  if (_combine_rgb_source1 == CS_crossbar_stage) {
+    manager->read_pointer(scan);
+  }
+  if (_combine_rgb_source2 == CS_crossbar_stage) {
+    manager->read_pointer(scan);
+  }
+  if (_combine_alpha_source0 == CS_crossbar_stage) {
+    manager->read_pointer(scan);
+  }
+  if (_combine_alpha_source1 == CS_crossbar_stage) {
+    manager->read_pointer(scan);
+  }
+  if (_combine_alpha_source2 == CS_crossbar_stage) {
+    manager->read_pointer(scan);
+  }
+
   set_involves_color_scale();
 }
 
@@ -316,6 +362,27 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
 
   _texcoord_name = DCAST(InternalName, p_list[pi++]);
 
+  // We only read these pointers if the source types indicate they are
+  // defined.
+  if (_combine_rgb_source0 == CS_crossbar_stage) {
+    _combine_rgb_source0_stage = DCAST(TextureStage, p_list[pi++]);
+  }
+  if (_combine_rgb_source1 == CS_crossbar_stage) {
+    _combine_rgb_source1_stage = DCAST(TextureStage, p_list[pi++]);
+  }
+  if (_combine_rgb_source2 == CS_crossbar_stage) {
+    _combine_rgb_source2_stage = DCAST(TextureStage, p_list[pi++]);
+  }
+  if (_combine_alpha_source0 == CS_crossbar_stage) {
+    _combine_alpha_source0_stage = DCAST(TextureStage, p_list[pi++]);
+  }
+  if (_combine_alpha_source1 == CS_crossbar_stage) {
+    _combine_alpha_source1_stage = DCAST(TextureStage, p_list[pi++]);
+  }
+  if (_combine_alpha_source2 == CS_crossbar_stage) {
+    _combine_alpha_source2_stage = DCAST(TextureStage, p_list[pi++]);
+  }
+
   return pi;
 }
 
@@ -360,6 +427,27 @@ write_datagram(BamWriter *manager, Datagram &me) {
     me.add_uint8(_combine_alpha_operand1);
     me.add_uint8(_combine_alpha_source2);
     me.add_uint8(_combine_alpha_operand2);
+
+    // We only write these pointers if the source types indicate they
+    // are defined.
+    if (_combine_rgb_source0 == CS_crossbar_stage) {
+      manager->write_pointer(me, _combine_rgb_source0_stage);
+    }
+    if (_combine_rgb_source1 == CS_crossbar_stage) {
+      manager->write_pointer(me, _combine_rgb_source1_stage);
+    }
+    if (_combine_rgb_source2 == CS_crossbar_stage) {
+      manager->write_pointer(me, _combine_rgb_source2_stage);
+    }
+    if (_combine_alpha_source0 == CS_crossbar_stage) {
+      manager->write_pointer(me, _combine_alpha_source0_stage);
+    }
+    if (_combine_alpha_source1 == CS_crossbar_stage) {
+      manager->write_pointer(me, _combine_alpha_source1_stage);
+    }
+    if (_combine_alpha_source2 == CS_crossbar_stage) {
+      manager->write_pointer(me, _combine_alpha_source2_stage);
+    }
   }
 }
 
@@ -445,6 +533,9 @@ operator << (ostream &out, TextureStage::CombineSource cs) {
 
   case TextureStage::CS_constant_color_scale:
     return out << "constant_color_scale";
+
+  case TextureStage::CS_crossbar_stage:
+    return out << "crossbar_stage";
   }
 
   return out << "**invalid CombineSource(" << (int)cs << ")**";

+ 106 - 8
panda/src/gobj/textureStage.h

@@ -59,17 +59,17 @@ PUBLISHED:
 
   enum CombineMode {
     CM_undefined,
-    CM_replace,
-    CM_modulate,
-    CM_add,
-    CM_add_signed,
-    CM_interpolate,
-    CM_subtract,
+    CM_replace,      // 1 operand
+    CM_modulate,     // 2 operands
+    CM_add,          // 2 operands
+    CM_add_signed,   // 2 operands
+    CM_interpolate,  // 3 operands
+    CM_subtract,     // 2 operands
 
     // The following are valid only for combine_rgb, not
     // combine_alpha.
-    CM_dot3_rgb,
-    CM_dot3_rgba,
+    CM_dot3_rgb,     // 2 operands
+    CM_dot3_rgba,    // 2 operands
   };
 
   enum CombineSource {
@@ -79,6 +79,7 @@ PUBLISHED:
     CS_primary_color,
     CS_previous,
     CS_constant_color_scale,
+    CS_crossbar_stage,
   };
 
   enum CombineOperand {
@@ -118,38 +119,124 @@ PUBLISHED:
 
   INLINE void set_combine_rgb(CombineMode mode, 
                               CombineSource source0, CombineOperand operand0);
+  INLINE void set_combine_rgb(CombineMode mode, 
+                              const TextureStage *source0, CombineOperand operand0);
   INLINE void set_combine_rgb(CombineMode mode, 
                               CombineSource source0, CombineOperand operand0,
                               CombineSource source1, CombineOperand operand1);
+  INLINE void set_combine_rgb(CombineMode mode, 
+                              const TextureStage *source0, CombineOperand operand0,
+                              CombineSource source1, CombineOperand operand1);
+  INLINE void set_combine_rgb(CombineMode mode, 
+                              CombineSource source0, CombineOperand operand0,
+                              const TextureStage *source1, CombineOperand operand1);
+  INLINE void set_combine_rgb(CombineMode mode, 
+                              const TextureStage *source0, CombineOperand operand0,
+                              const TextureStage *source1, CombineOperand operand1);
+  INLINE void set_combine_rgb(CombineMode mode, 
+                              CombineSource source0, CombineOperand operand0,
+                              CombineSource source1, CombineOperand operand1,
+                              CombineSource source2, CombineOperand operand2);
+  INLINE void set_combine_rgb(CombineMode mode, 
+                              const TextureStage *source0, CombineOperand operand0,
+                              CombineSource source1, CombineOperand operand1,
+                              CombineSource source2, CombineOperand operand2);
+  INLINE void set_combine_rgb(CombineMode mode, 
+                              CombineSource source0, CombineOperand operand0,
+                              const TextureStage *source1, CombineOperand operand1,
+                              CombineSource source2, CombineOperand operand2);
+  INLINE void set_combine_rgb(CombineMode mode, 
+                              CombineSource source0, CombineOperand operand0,
+                              CombineSource source1, CombineOperand operand1,
+                              const TextureStage *source2, CombineOperand operand2);
   INLINE void set_combine_rgb(CombineMode mode, 
                               CombineSource source0, CombineOperand operand0,
+                              const TextureStage *source1, CombineOperand operand1,
+                              const TextureStage *source2, CombineOperand operand2);
+  INLINE void set_combine_rgb(CombineMode mode, 
+                              const TextureStage *source0, CombineOperand operand0,
                               CombineSource source1, CombineOperand operand1,
+                              const TextureStage *source2, CombineOperand operand2);
+  INLINE void set_combine_rgb(CombineMode mode, 
+                              const TextureStage *source0, CombineOperand operand0,
+                              const TextureStage *source1, CombineOperand operand1,
                               CombineSource source2, CombineOperand operand2);
+  INLINE void set_combine_rgb(CombineMode mode, 
+                              const TextureStage *source0, CombineOperand operand0,
+                              const TextureStage *source1, CombineOperand operand1,
+                              const TextureStage *source2, CombineOperand operand2);
+
   INLINE CombineMode get_combine_rgb_mode() const;
   INLINE int get_num_combine_rgb_operands() const;
   INLINE CombineSource get_combine_rgb_source0() const;
+  INLINE const TextureStage *get_combine_rgb_source0_stage() const;
   INLINE CombineOperand get_combine_rgb_operand0() const;
   INLINE CombineSource get_combine_rgb_source1() const;
+  INLINE const TextureStage *get_combine_rgb_source1_stage() const;
   INLINE CombineOperand get_combine_rgb_operand1() const;
   INLINE CombineSource get_combine_rgb_source2() const;
+  INLINE const TextureStage *get_combine_rgb_source2_stage() const;
   INLINE CombineOperand get_combine_rgb_operand2() const;
 
   INLINE void set_combine_alpha(CombineMode mode, 
                                 CombineSource source0, CombineOperand operand0);
+  INLINE void set_combine_alpha(CombineMode mode, 
+                                const TextureStage *source0, CombineOperand operand0);
   INLINE void set_combine_alpha(CombineMode mode, 
                                 CombineSource source0, CombineOperand operand0,
                                 CombineSource source1, CombineOperand operand1);
+  INLINE void set_combine_alpha(CombineMode mode, 
+                                const TextureStage *source0, CombineOperand operand0,
+                                CombineSource source1, CombineOperand operand1);
+  INLINE void set_combine_alpha(CombineMode mode, 
+                                CombineSource source0, CombineOperand operand0,
+                                const TextureStage *source1, CombineOperand operand1);
+  INLINE void set_combine_alpha(CombineMode mode, 
+                                const TextureStage *source0, CombineOperand operand0,
+                                const TextureStage *source1, CombineOperand operand1);
   INLINE void set_combine_alpha(CombineMode mode, 
                                 CombineSource source0, CombineOperand operand0,
                                 CombineSource source1, CombineOperand operand1,
                                 CombineSource source2, CombineOperand operand2);
+  INLINE void set_combine_alpha(CombineMode mode, 
+                                const TextureStage *source0, CombineOperand operand0,
+                                CombineSource source1, CombineOperand operand1,
+                                CombineSource source2, CombineOperand operand2);
+  INLINE void set_combine_alpha(CombineMode mode, 
+                                CombineSource source0, CombineOperand operand0,
+                                const TextureStage *source1, CombineOperand operand1,
+                                CombineSource source2, CombineOperand operand2);
+  INLINE void set_combine_alpha(CombineMode mode, 
+                                CombineSource source0, CombineOperand operand0,
+                                CombineSource source1, CombineOperand operand1,
+                                const TextureStage *source2, CombineOperand operand2);
+  INLINE void set_combine_alpha(CombineMode mode, 
+                                CombineSource source0, CombineOperand operand0,
+                                const TextureStage *source1, CombineOperand operand1,
+                                const TextureStage *source2, CombineOperand operand2);
+  INLINE void set_combine_alpha(CombineMode mode, 
+                                const TextureStage *source0, CombineOperand operand0,
+                                CombineSource source1, CombineOperand operand1,
+                                const TextureStage *source2, CombineOperand operand2);
+  INLINE void set_combine_alpha(CombineMode mode, 
+                                const TextureStage *source0, CombineOperand operand0,
+                                const TextureStage *source1, CombineOperand operand1,
+                                CombineSource source2, CombineOperand operand2);
+  INLINE void set_combine_alpha(CombineMode mode, 
+                                const TextureStage *source0, CombineOperand operand0,
+                                const TextureStage *source1, CombineOperand operand1,
+                                const TextureStage *source2, CombineOperand operand2);
+  
   INLINE CombineMode get_combine_alpha_mode() const;
   INLINE int get_num_combine_alpha_operands() const;
   INLINE CombineSource get_combine_alpha_source0() const;
+  INLINE const TextureStage *get_combine_alpha_source0_stage() const;
   INLINE CombineOperand get_combine_alpha_operand0() const;
   INLINE CombineSource get_combine_alpha_source1() const;
+  INLINE const TextureStage *get_combine_alpha_source1_stage() const;
   INLINE CombineOperand get_combine_alpha_operand1() const;
   INLINE CombineSource get_combine_alpha_source2() const;
+  INLINE const TextureStage *get_combine_alpha_source2_stage() const;
   INLINE CombineOperand get_combine_alpha_operand2() const;
 
   INLINE bool involves_color_scale() const;
@@ -165,6 +252,11 @@ public:
 private:
   INLINE void set_involves_color_scale();
 
+  static void write_operand(ostream &out, int operand_index, 
+                            CombineSource source, 
+                            const TextureStage *source_stage,
+                            CombineOperand operand);
+
   static int get_expected_num_combine_operands(CombineMode cm);
   static bool operand_valid_for_rgb(CombineOperand co);
   static bool operand_valid_for_alpha(CombineOperand co);
@@ -182,19 +274,25 @@ private:
   CombineMode _combine_rgb_mode;
   int _num_combine_rgb_operands;
   CombineSource _combine_rgb_source0;
+  CPT(TextureStage) _combine_rgb_source0_stage;
   CombineOperand _combine_rgb_operand0;
   CombineSource _combine_rgb_source1;
+  CPT(TextureStage) _combine_rgb_source1_stage;
   CombineOperand _combine_rgb_operand1;
   CombineSource _combine_rgb_source2;
+  CPT(TextureStage) _combine_rgb_source2_stage;
   CombineOperand _combine_rgb_operand2;
 
   CombineMode _combine_alpha_mode;
   int _num_combine_alpha_operands;
   CombineSource _combine_alpha_source0;
+  CPT(TextureStage) _combine_alpha_source0_stage;
   CombineOperand _combine_alpha_operand0;
   CombineSource _combine_alpha_source1;
+  CPT(TextureStage) _combine_alpha_source1_stage;
   CombineOperand _combine_alpha_operand1;
   CombineSource _combine_alpha_source2;
+  CPT(TextureStage) _combine_alpha_source2_stage;
   CombineOperand _combine_alpha_operand2;
 
   static PT(TextureStage) _default_stage;

+ 19 - 0
panda/src/pgraph/textureAttrib.cxx

@@ -109,6 +109,25 @@ make_all_off() {
   return _all_off_attrib;
 }
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextureAttrib::find_on_stage
+//       Access: Published
+//  Description: Returns the index number of the indicated
+//               TextureStage within the list of on_stages, or -1 if
+//               the indicated stage is not listed.
+////////////////////////////////////////////////////////////////////
+int TextureAttrib::
+find_on_stage(const TextureStage *stage) const {
+  for (int n = 0; n < (int)_on_stages.size(); ++n) {
+    if (_on_stages[n] == stage) {
+      return n;
+    }
+  }
+
+  return -1;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureAttrib::add_on_stage
 //       Access: Published

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

@@ -62,6 +62,8 @@ PUBLISHED:
   INLINE bool has_on_stage(TextureStage *stage) const;
   INLINE Texture *get_on_texture(TextureStage *stage) const;
 
+  int find_on_stage(const TextureStage *stage) const;
+
   INLINE int get_num_off_stages() const;
   INLINE TextureStage *get_off_stage(int n) const;
   INLINE bool has_off_stage(TextureStage *stage) const;

Some files were not shown because too many files changed in this diff