Преглед на файлове

*** empty log message ***

David Rose преди 25 години
родител
ревизия
61c7b272fd

+ 0 - 33
panda/src/egg/eggExternalReference.I

@@ -3,36 +3,3 @@
 // 
 // 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggExternalReference::Assignment operator
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE EggExternalReference &EggExternalReference::
-operator = (const string &filename) {
-  EggFilenameNode::operator = (filename);
-  return *this;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggExternalReference::Assignment operator
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE EggExternalReference &EggExternalReference::
-operator = (const char *filename) {
-  EggFilenameNode::operator = (filename);
-  return *this;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggExternalReference::Assignment operator
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE EggExternalReference &EggExternalReference::
-operator = (const Filename &filename) {
-  EggFilenameNode::operator = (filename);
-  return *this;
-}

+ 1 - 1
panda/src/egg/eggExternalReference.cxx

@@ -52,7 +52,7 @@ operator = (const EggExternalReference &copy) {
 void EggExternalReference::
 void EggExternalReference::
 write(ostream &out, int indent_level) const {
 write(ostream &out, int indent_level) const {
   write_header(out, indent_level, "<File>");
   write_header(out, indent_level, "<File>");
-  enquote_string(out, get_fullpath(), indent_level + 2) << "\n";
+  enquote_string(out, get_filename(), indent_level + 2) << "\n";
   indent(out, indent_level) << "}\n";
   indent(out, indent_level) << "}\n";
 }
 }
 
 

+ 0 - 4
panda/src/egg/eggExternalReference.h

@@ -21,10 +21,6 @@ public:
   EggExternalReference(const EggExternalReference &copy);
   EggExternalReference(const EggExternalReference &copy);
   EggExternalReference &operator = (const EggExternalReference &copy);
   EggExternalReference &operator = (const EggExternalReference &copy);
 
 
-  INLINE EggExternalReference &operator = (const string &filename);
-  INLINE EggExternalReference &operator = (const char *filename);
-  INLINE EggExternalReference &operator = (const Filename &copy);
-
   virtual void write(ostream &out, int indent_level) const;
   virtual void write(ostream &out, int indent_level) const;
 
 
   virtual string get_default_extension() const;
   virtual string get_default_extension() const;

+ 22 - 22
panda/src/egg/eggFilenameNode.I

@@ -19,8 +19,10 @@ EggFilenameNode() {
 //  Description: 
 //  Description: 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE EggFilenameNode::
 INLINE EggFilenameNode::
-EggFilenameNode(const string &node_name, const string &filename) : 
-  EggNode(node_name), Filename(filename) {
+EggFilenameNode(const string &node_name, const Filename &filename) : 
+  EggNode(node_name),
+  _filename(filename)
+{
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -30,7 +32,9 @@ EggFilenameNode(const string &node_name, const string &filename) :
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE EggFilenameNode::
 INLINE EggFilenameNode::
 EggFilenameNode(const EggFilenameNode &copy) :
 EggFilenameNode(const EggFilenameNode &copy) :
-  EggNode(copy), Filename(copy) {
+  EggNode(copy),
+  _filename(copy._filename)
+{
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -41,40 +45,36 @@ EggFilenameNode(const EggFilenameNode &copy) :
 INLINE EggFilenameNode &EggFilenameNode::
 INLINE EggFilenameNode &EggFilenameNode::
 operator = (const EggFilenameNode &copy) {
 operator = (const EggFilenameNode &copy) {
   EggNode::operator = (copy);
   EggNode::operator = (copy);
-  Filename::operator = (copy);
+  _filename = copy._filename;
   return *this;
   return *this;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: EggFilenameNode::Assignment operator
+//     Function: EggFilenameNode::get_filename
 //       Access: Public
 //       Access: Public
-//  Description: 
+//  Description: Returns a nonmodifiable reference to the filename.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE EggFilenameNode &EggFilenameNode::
-operator = (const string &filename) {
-  Filename::operator = (filename);
-  return *this;
+INLINE const Filename &EggFilenameNode::
+get_filename() const {
+  return _filename;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: EggFilenameNode::Assignment operator
+//     Function: EggFilenameNode::set_filename
 //       Access: Public
 //       Access: Public
 //  Description: 
 //  Description: 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE EggFilenameNode &EggFilenameNode::
-operator = (const char *filename) {
-  Filename::operator = (filename);
-  return *this;
+INLINE void EggFilenameNode::
+set_filename(const Filename &filename) {
+  _filename = filename;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: EggFilenameNode::Assignment operator
+//     Function: EggFilenameNode::update_filename
 //       Access: Public
 //       Access: Public
-//  Description: 
+//  Description: Returns a modifiable reference to the filename.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE EggFilenameNode &EggFilenameNode::
-operator = (const Filename &filename) {
-  Filename::operator = (filename);
-  return *this;
+INLINE Filename &EggFilenameNode::
+update_filename() {
+  return _filename;
 }
 }
-

+ 9 - 6
panda/src/egg/eggFilenameNode.h

@@ -18,19 +18,22 @@
 //               the egg file was loaded in.  It is a base class for
 //               the egg file was loaded in.  It is a base class for
 //               EggTexture and EggExternalReference.
 //               EggTexture and EggExternalReference.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-class EXPCL_PANDAEGG EggFilenameNode : public EggNode, public Filename {
+class EXPCL_PANDAEGG EggFilenameNode : public EggNode {
 public:
 public:
   INLINE EggFilenameNode();
   INLINE EggFilenameNode();
-  INLINE EggFilenameNode(const string &node_name, const string &filename);
+  INLINE EggFilenameNode(const string &node_name, const Filename &filename);
   INLINE EggFilenameNode(const EggFilenameNode &copy);
   INLINE EggFilenameNode(const EggFilenameNode &copy);
   INLINE EggFilenameNode &operator = (const EggFilenameNode &copy);
   INLINE EggFilenameNode &operator = (const EggFilenameNode &copy);
 
 
-  INLINE EggFilenameNode &operator = (const string &filename);
-  INLINE EggFilenameNode &operator = (const char *filename);
-  INLINE EggFilenameNode &operator = (const Filename &copy);
-
   virtual string get_default_extension() const;
   virtual string get_default_extension() const;
 
 
+  INLINE const Filename &get_filename() const;
+  INLINE void set_filename(const Filename &filename);
+  INLINE Filename &update_filename();
+
+private:
+  Filename _filename;
+
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {
     return _type_handle;
     return _type_handle;

+ 19 - 10
panda/src/egg/eggGroupNode.cxx

@@ -153,11 +153,19 @@ resolve_filenames(const DSearchPath &searchpath) {
        ci != _children.end();
        ci != _children.end();
        ++ci) {
        ++ci) {
     EggNode *child = *ci;
     EggNode *child = *ci;
-    if (child->is_of_type(EggFilenameNode::get_class_type())) {
-      EggFilenameNode *filename = DCAST(EggFilenameNode, child);
+    if (child->is_of_type(EggTexture::get_class_type())) {
+      EggTexture *tex = DCAST(EggTexture, child);
+      tex->update_filename().
+	resolve_filename(searchpath, tex->get_default_extension());
+      if (tex->has_alpha_file()) {
+	tex->update_alpha_file().
+	  resolve_filename(searchpath, tex->get_default_extension());
+      }
 
 
-      filename->resolve_filename(searchpath, 
-				 filename->get_default_extension());
+    } else if (child->is_of_type(EggFilenameNode::get_class_type())) {
+      EggFilenameNode *fnode = DCAST(EggFilenameNode, child);
+      fnode->update_filename().
+	resolve_filename(searchpath, fnode->get_default_extension());
 
 
     } else if (child->is_of_type(EggGroupNode::get_class_type())) {
     } else if (child->is_of_type(EggGroupNode::get_class_type())) {
       DCAST(EggGroupNode, child)->resolve_filenames(searchpath);
       DCAST(EggGroupNode, child)->resolve_filenames(searchpath);
@@ -386,20 +394,21 @@ r_resolve_externals(const DSearchPath &searchpath,
 
 
       // Replace the reference with an empty group node.  When we load
       // Replace the reference with an empty group node.  When we load
       // the external file successfully, we'll put its contents here.
       // the external file successfully, we'll put its contents here.
+      Filename filename = ref->get_filename();
       EggGroupNode *new_node = 
       EggGroupNode *new_node = 
-	new EggGroupNode(ref->get_basename_wo_extension());
+	new EggGroupNode(filename.get_basename_wo_extension());
       replace(ci, new_node);
       replace(ci, new_node);
-
-      if (!EggData::resolve_egg_filename(*ref, searchpath)) {
+      
+      if (!EggData::resolve_egg_filename(filename, searchpath)) {
 	egg_cat.error()
 	egg_cat.error()
-	  << "Could not locate " << ref->get_fullpath() << " in "
+	  << "Could not locate " << filename << " in "
 	  << searchpath << "\n";
 	  << searchpath << "\n";
       } else {
       } else {
 	// Now define a new EggData structure to hold the external
 	// Now define a new EggData structure to hold the external
 	// reference, and load it.
 	// reference, and load it.
 	EggData ext_data;
 	EggData ext_data;
 	ext_data.set_coordinate_system(coordsys);
 	ext_data.set_coordinate_system(coordsys);
-	if (ext_data.read(*ref)) {
+	if (ext_data.read(filename)) {
 	  // The external file was read correctly.  Add its contents
 	  // The external file was read correctly.  Add its contents
 	  // into the tree at this point.
 	  // into the tree at this point.
 	  success =
 	  success =
@@ -408,7 +417,7 @@ r_resolve_externals(const DSearchPath &searchpath,
 	  new_node->steal_children(ext_data);
 	  new_node->steal_children(ext_data);
 	}
 	}
       }
       }
-
+	
     } else if (child->is_of_type(EggGroupNode::get_class_type())) {
     } else if (child->is_of_type(EggGroupNode::get_class_type())) {
       EggGroupNode *group_child = DCAST(EggGroupNode, child);
       EggGroupNode *group_child = DCAST(EggGroupNode, child);
       success =
       success =

+ 71 - 39
panda/src/egg/eggTexture.I

@@ -4,39 +4,6 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: EggTexture::Assignment operator
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE EggTexture &EggTexture::
-operator = (const string &filename) {
-  EggFilenameNode::operator = (filename);
-  return *this;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggTexture::Assignment operator
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE EggTexture &EggTexture::
-operator = (const char *filename) {
-  EggFilenameNode::operator = (filename);
-  return *this;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: EggTexture::Assignment operator
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE EggTexture &EggTexture::
-operator = (const Filename &filename) {
-  EggFilenameNode::operator = (filename);
-  return *this;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: EggTexture::set_format
 //     Function: EggTexture::set_format
 //       Access: Public
 //       Access: Public
@@ -254,7 +221,7 @@ get_env_type() const {
 INLINE void EggTexture::
 INLINE void EggTexture::
 set_transform(const LMatrix3d &transform) {
 set_transform(const LMatrix3d &transform) {
   _transform = transform;
   _transform = transform;
-  _has_transform = true;
+  _flags |= F_has_transform;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -265,7 +232,7 @@ set_transform(const LMatrix3d &transform) {
 INLINE void EggTexture::
 INLINE void EggTexture::
 clear_transform() {
 clear_transform() {
   _transform = LMatrix3d::ident_mat();
   _transform = LMatrix3d::ident_mat();
-  _has_transform = false;
+  _flags &= ~F_has_transform;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -277,7 +244,7 @@ clear_transform() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool EggTexture::
 INLINE bool EggTexture::
 has_transform() const {
 has_transform() const {
-  return _has_transform;
+  return (_flags & F_has_transform) != 0;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -287,7 +254,7 @@ has_transform() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE LMatrix3d EggTexture::
 INLINE LMatrix3d EggTexture::
 get_transform() const {
 get_transform() const {
-  nassertr(_has_transform, LMatrix3d::ident_mat());
+  nassertr(has_transform(), LMatrix3d::ident_mat());
   return _transform;
   return _transform;
 }
 }
 
 
@@ -301,10 +268,76 @@ get_transform() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool EggTexture::
 INLINE bool EggTexture::
 transform_is_identity() const {
 transform_is_identity() const {
-  return (!_has_transform || 
+  return (!has_transform() || 
 	  _transform.almost_equal(LMatrix3d::ident_mat(), 0.0001));
 	  _transform.almost_equal(LMatrix3d::ident_mat(), 0.0001));
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggTexture::set_alpha_file
+//       Access: Public
+//  Description: Specifies a separate file that will be loaded in with
+//               the 1- or 3-component texture and applied as the
+//               alpha channel.  This is useful when loading textures
+//               from file formats that do not support alpha, for
+//               instance jpg.
+////////////////////////////////////////////////////////////////////
+INLINE void EggTexture::
+set_alpha_file(const Filename &alpha_file) {
+  _alpha_file = alpha_file;
+  _flags |= F_has_alpha_file;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggTexture::clear_alpha_file
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE void EggTexture::
+clear_alpha_file() {
+  _alpha_file = Filename();
+  _flags &= ~F_has_alpha_file;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggTexture::has_alpha_file
+//       Access: Public
+//  Description: Returns true if a separate file for the alpha
+//               component has been applied, false otherwise.  See
+//               set_alpha_file().
+////////////////////////////////////////////////////////////////////
+INLINE bool EggTexture::
+has_alpha_file() const {
+  return (_flags & F_has_alpha_file) != 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggTexture::get_alpha_file
+//       Access: Public
+//  Description: Returns the separate file assigned for the alpha
+//               channel.  It is an error to call this unless
+//               has_alpha_file() returns true.  See set_alpha_file().
+////////////////////////////////////////////////////////////////////
+INLINE const Filename &EggTexture::
+get_alpha_file() const {
+  nassertr(has_alpha_file(), _alpha_file);
+  return _alpha_file;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggTexture::update_alpha_file
+//       Access: Public
+//  Description: Returns a modifiable reference to the separate file
+//               assigned for the alpha channel.  If an alpha file has
+//               not yet been added, this adds an empty one.
+////////////////////////////////////////////////////////////////////
+INLINE Filename &EggTexture::
+update_alpha_file() {
+  if (!has_alpha_file()) {
+    set_alpha_file(Filename());
+  }
+  return _alpha_file;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: UniqueEggTextures::Constructor
 //     Function: UniqueEggTextures::Constructor
 //       Access: Public
 //       Access: Public
@@ -324,4 +357,3 @@ operator ()(const EggTexture *t1, const EggTexture *t2) const {
   return t1->sorts_less_than(*t2, _eq);
   return t1->sorts_less_than(*t2, _eq);
 }
 }
 
 
-

+ 30 - 17
panda/src/egg/eggTexture.cxx

@@ -30,7 +30,7 @@ EggTexture(const string &tref_name, const string &filename)
   _magfilteralpha = FT_unspecified;
   _magfilteralpha = FT_unspecified;
   _magfiltercolor = FT_unspecified;
   _magfiltercolor = FT_unspecified;
   _env_type = ET_unspecified;
   _env_type = ET_unspecified;
-  _has_transform = false;
+  _flags = 0;
   _transform = LMatrix3d::ident_mat();
   _transform = LMatrix3d::ident_mat();
 }
 }
 
 
@@ -63,7 +63,7 @@ operator = (const EggTexture &copy) {
   _magfilteralpha = copy._magfilteralpha;
   _magfilteralpha = copy._magfilteralpha;
   _magfiltercolor = copy._magfiltercolor;
   _magfiltercolor = copy._magfiltercolor;
   _env_type = copy._env_type;
   _env_type = copy._env_type;
-  _has_transform = copy._has_transform;
+  _flags = copy._flags;
   _transform = copy._transform;
   _transform = copy._transform;
 
 
   return *this;
   return *this;
@@ -78,7 +78,7 @@ operator = (const EggTexture &copy) {
 void EggTexture::
 void EggTexture::
 write(ostream &out, int indent_level) const {
 write(ostream &out, int indent_level) const {
   write_header(out, indent_level, "<Texture>");
   write_header(out, indent_level, "<Texture>");
-  enquote_string(out, get_fullpath(), indent_level + 2) << "\n";
+  enquote_string(out, get_filename(), indent_level + 2) << "\n";
 
 
   if (get_format() != F_unspecified) {
   if (get_format() != F_unspecified) {
     indent(out, indent_level + 2)
     indent(out, indent_level + 2)
@@ -125,6 +125,13 @@ write(ostream &out, int indent_level) const {
       << "<Scalar> envtype { " << get_env_type() << " }\n";
       << "<Scalar> envtype { " << get_env_type() << " }\n";
   }
   }
 
 
+  if (has_alpha_file()) {
+    indent(out, indent_level + 2)
+      << "<Scalar> alpha-file { ";
+    enquote_string(out, get_alpha_file());
+    out << " }\n";
+  }
+
   EggAlphaMode::write(out, indent_level + 2);
   EggAlphaMode::write(out, indent_level + 2);
 
 
   if (has_transform()) {
   if (has_transform()) {
@@ -172,22 +179,25 @@ write(ostream &out, int indent_level) const {
 bool EggTexture::
 bool EggTexture::
 is_equivalent_to(const EggTexture &other, int eq) const {
 is_equivalent_to(const EggTexture &other, int eq) const {
   if ((eq & E_complete_filename) == E_complete_filename) {
   if ((eq & E_complete_filename) == E_complete_filename) {
-    if (get_fullpath() != other.get_fullpath()) {
+    if (get_filename() != other.get_filename()) {
       return false;
       return false;
     }
     }
   } else {
   } else {
+    const Filename &a = get_filename();
+    const Filename &b = other.get_filename();
+
     if (eq & E_basename) {
     if (eq & E_basename) {
-      if (get_basename_wo_extension() != other.get_basename_wo_extension()) {
+      if (a.get_basename_wo_extension() != b.get_basename_wo_extension()) {
 	return false;
 	return false;
       }
       }
     }
     }
     if (eq & E_extension) {
     if (eq & E_extension) {
-      if (get_extension() != other.get_extension()) {
+      if (a.get_extension() != b.get_extension()) {
 	return false;
 	return false;
       }
       }
     }
     }
     if (eq & E_dirname) {
     if (eq & E_dirname) {
-      if (get_dirname() != other.get_dirname()) {
+      if (a.get_dirname() != b.get_dirname()) {
 	return false;
 	return false;
       }
       }
     }
     }
@@ -198,7 +208,7 @@ is_equivalent_to(const EggTexture &other, int eq) const {
       return false;
       return false;
     }
     }
     
     
-    if (_has_transform && other._has_transform) {
+    if (has_transform() && other.has_transform()) {
       if (!_transform.almost_equal(other._transform, 0.0001)) {
       if (!_transform.almost_equal(other._transform, 0.0001)) {
 	return false;
 	return false;
       }
       }
@@ -243,23 +253,26 @@ is_equivalent_to(const EggTexture &other, int eq) const {
 bool EggTexture::
 bool EggTexture::
 sorts_less_than(const EggTexture &other, int eq) const {
 sorts_less_than(const EggTexture &other, int eq) const {
   if ((eq & E_complete_filename) == E_complete_filename) {
   if ((eq & E_complete_filename) == E_complete_filename) {
-    if (get_fullpath() != other.get_fullpath()) {
-      return get_fullpath() < other.get_fullpath();
+    if (get_filename() != other.get_filename()) {
+      return get_filename() < other.get_filename();
     }
     }
   } else {
   } else {
+    const Filename &a = get_filename();
+    const Filename &b = other.get_filename();
+
     if (eq & E_basename) {
     if (eq & E_basename) {
-      if (get_basename_wo_extension() != other.get_basename_wo_extension()) {
-	return get_basename_wo_extension() < other.get_basename_wo_extension();
+      if (a.get_basename_wo_extension() != b.get_basename_wo_extension()) {
+	return a.get_basename_wo_extension() < b.get_basename_wo_extension();
       }
       }
     }
     }
     if (eq & E_extension) {
     if (eq & E_extension) {
-      if (get_extension() != other.get_extension()) {
-	return get_extension() < other.get_extension();
+      if (a.get_extension() != b.get_extension()) {
+	return a.get_extension() < b.get_extension();
       }
       }
     }
     }
     if (eq & E_dirname) {
     if (eq & E_dirname) {
-      if (get_dirname() != other.get_dirname()) {
-	return get_dirname() < other.get_dirname();
+      if (a.get_dirname() != b.get_dirname()) {
+	return a.get_dirname() < b.get_dirname();
       }
       }
     }
     }
   }
   }
@@ -271,7 +284,7 @@ sorts_less_than(const EggTexture &other, int eq) const {
       return (int)is_identity < (int)other_is_identity;
       return (int)is_identity < (int)other_is_identity;
     }
     }
 
 
-    if (_has_transform && other._has_transform) {
+    if (has_transform() && other.has_transform()) {
       int compare = _transform.compare_to(other._transform);
       int compare = _transform.compare_to(other._transform);
       if (compare != 0) {
       if (compare != 0) {
 	return compare < 0;
 	return compare < 0;

+ 13 - 5
panda/src/egg/eggTexture.h

@@ -24,10 +24,6 @@ public:
   EggTexture(const string &tref_name, const string &filename);
   EggTexture(const string &tref_name, const string &filename);
   EggTexture(const EggTexture &copy);
   EggTexture(const EggTexture &copy);
   EggTexture &operator = (const EggTexture &copy);
   EggTexture &operator = (const EggTexture &copy);
-
-  INLINE EggTexture &operator = (const string &filename);
-  INLINE EggTexture &operator = (const char *filename);
-  INLINE EggTexture &operator = (const Filename &copy);
  
  
   virtual void write(ostream &out, int indent_level) const;
   virtual void write(ostream &out, int indent_level) const;
 
 
@@ -100,18 +96,30 @@ public:
   INLINE LMatrix3d get_transform() const;
   INLINE LMatrix3d get_transform() const;
   INLINE bool transform_is_identity() const;
   INLINE bool transform_is_identity() const;
 
 
+  INLINE void set_alpha_file(const Filename &filename);
+  INLINE void clear_alpha_file();
+  INLINE bool has_alpha_file() const;
+  INLINE const Filename &get_alpha_file() const;
+  INLINE Filename &update_alpha_file();
+
   static Format string_format(const string &string);
   static Format string_format(const string &string);
   static WrapMode string_wrap_mode(const string &string);
   static WrapMode string_wrap_mode(const string &string);
   static FilterType string_filter_type(const string &string);
   static FilterType string_filter_type(const string &string);
   static EnvType string_env_type(const string &string);
   static EnvType string_env_type(const string &string);
 
 
 private:
 private:
+  enum Flags {
+    F_has_transform   = 0x0001,
+    F_has_alpha_file  = 0x0002
+  };
+
   Format _format;
   Format _format;
   WrapMode _wrap_mode, _wrap_u, _wrap_v;
   WrapMode _wrap_mode, _wrap_u, _wrap_v;
   FilterType _minfilter, _magfilter, _magfilteralpha, _magfiltercolor;
   FilterType _minfilter, _magfilter, _magfilteralpha, _magfiltercolor;
   EnvType _env_type;
   EnvType _env_type;
-  bool _has_transform;
+  int _flags;
   LMatrix3d _transform;
   LMatrix3d _transform;
+  Filename _alpha_file;
 
 
 
 
 public:
 public:

+ 2 - 2
panda/src/egg/eggTextureCollection.cxx

@@ -443,7 +443,7 @@ find_tref(const string &tref_name) const {
 //               NULL if no texture matches.
 //               NULL if no texture matches.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 EggTexture *EggTextureCollection::
 EggTexture *EggTextureCollection::
-find_filename(const string &filename) const {
+find_filename(const Filename &filename) const {
   // This requires a complete linear traversal, not terribly
   // This requires a complete linear traversal, not terribly
   // efficient.
   // efficient.
   OrderedTextures::const_iterator oti;
   OrderedTextures::const_iterator oti;
@@ -451,7 +451,7 @@ find_filename(const string &filename) const {
        oti != _ordered_textures.end(); 
        oti != _ordered_textures.end(); 
        ++oti) {
        ++oti) {
     EggTexture *tex = (*oti);
     EggTexture *tex = (*oti);
-    if (tex->get_fullpath() == filename) {
+    if (tex->get_filename() == filename) {
       return tex;
       return tex;
     }
     }
   }
   }

+ 1 - 1
panda/src/egg/eggTextureCollection.h

@@ -83,7 +83,7 @@ public:
   EggTexture *find_tref(const string &tref_name) const;
   EggTexture *find_tref(const string &tref_name) const;
 
 
   // Find a texture with a particular filename.
   // Find a texture with a particular filename.
-  EggTexture *find_filename(const string &filename) const;
+  EggTexture *find_filename(const Filename &filename) const;
 
 
 private:
 private:
   Textures _textures;
   Textures _textures;

+ 1 - 1
panda/src/egg/eggUtilities.cxx

@@ -24,7 +24,7 @@ get_textures_by_filename(const EggNode *node, EggTextureFilenames &result) {
 
 
     if (prim->has_texture()) {
     if (prim->has_texture()) {
       PT(EggTexture) tex = prim->get_texture();
       PT(EggTexture) tex = prim->get_texture();
-      result[tex->get_fullpath()].insert(tex);
+      result[tex->get_filename()].insert(tex);
     }
     }
 
 
   } else if (node->is_of_type(EggGroupNode::get_class_type())) {
   } else if (node->is_of_type(EggGroupNode::get_class_type())) {

+ 21 - 5
panda/src/egg/parser.yxx

@@ -28,6 +28,7 @@
 #include "eggData.h"
 #include "eggData.h"
 
 
 #include <string_utils.h>
 #include <string_utils.h>
+#include <filename.h>
 #include <luse.h>
 #include <luse.h>
 #include <lmatrix.h>
 #include <lmatrix.h>
 #include <coordinateSystem.h>
 #include <coordinateSystem.h>
@@ -266,7 +267,7 @@ texture:
 	TEXTURE required_name '{' required_string
 	TEXTURE required_name '{' required_string
 {
 {
   string tref_name = $2;
   string tref_name = $2;
-  string filename = $4;
+  Filename filename = $4;
   EggTexture *texture = new EggTexture(tref_name, filename);
   EggTexture *texture = new EggTexture(tref_name, filename);
 
 
   if (textures.find(tref_name) != textures.end()) {
   if (textures.find(tref_name) != textures.end()) {
@@ -306,6 +307,7 @@ texture_body:
     } else {
     } else {
       texture->set_format(f);
       texture->set_format(f);
     }
     }
+
   } else if (cmp_nocase_uh(name, "wrap") == 0) {
   } else if (cmp_nocase_uh(name, "wrap") == 0) {
     EggTexture::WrapMode w = EggTexture::string_wrap_mode(strval);
     EggTexture::WrapMode w = EggTexture::string_wrap_mode(strval);
     if (w == EggTexture::WM_unspecified) {
     if (w == EggTexture::WM_unspecified) {
@@ -313,6 +315,7 @@ texture_body:
     } else {
     } else {
       texture->set_wrap_mode(w);
       texture->set_wrap_mode(w);
     }
     }
+
   } else if (cmp_nocase_uh(name, "wrapu") == 0) {
   } else if (cmp_nocase_uh(name, "wrapu") == 0) {
     EggTexture::WrapMode w = EggTexture::string_wrap_mode(strval);
     EggTexture::WrapMode w = EggTexture::string_wrap_mode(strval);
     if (w == EggTexture::WM_unspecified) {
     if (w == EggTexture::WM_unspecified) {
@@ -320,6 +323,7 @@ texture_body:
     } else {
     } else {
       texture->set_wrap_u(w);
       texture->set_wrap_u(w);
     }
     }
+
   } else if (cmp_nocase_uh(name, "wrapv") == 0) {
   } else if (cmp_nocase_uh(name, "wrapv") == 0) {
     EggTexture::WrapMode w = EggTexture::string_wrap_mode(strval);
     EggTexture::WrapMode w = EggTexture::string_wrap_mode(strval);
     if (w == EggTexture::WM_unspecified) {
     if (w == EggTexture::WM_unspecified) {
@@ -327,6 +331,7 @@ texture_body:
     } else {
     } else {
       texture->set_wrap_v(w);
       texture->set_wrap_v(w);
     }
     }
+
   } else if (cmp_nocase_uh(name, "minfilter") == 0) {
   } else if (cmp_nocase_uh(name, "minfilter") == 0) {
     EggTexture::FilterType f = EggTexture::string_filter_type(strval);
     EggTexture::FilterType f = EggTexture::string_filter_type(strval);
     if (f == EggTexture::FT_unspecified) {
     if (f == EggTexture::FT_unspecified) {
@@ -334,6 +339,7 @@ texture_body:
     } else {
     } else {
       texture->set_minfilter(f);
       texture->set_minfilter(f);
     }
     }
+
   } else if (cmp_nocase_uh(name, "magfilter") == 0) {
   } else if (cmp_nocase_uh(name, "magfilter") == 0) {
     EggTexture::FilterType f = EggTexture::string_filter_type(strval);
     EggTexture::FilterType f = EggTexture::string_filter_type(strval);
     if (f == EggTexture::FT_unspecified) {
     if (f == EggTexture::FT_unspecified) {
@@ -341,6 +347,7 @@ texture_body:
     } else {
     } else {
       texture->set_magfilter(f);
       texture->set_magfilter(f);
     }
     }
+
   } else if (cmp_nocase_uh(name, "magfilteralpha") == 0) {
   } else if (cmp_nocase_uh(name, "magfilteralpha") == 0) {
     EggTexture::FilterType f = EggTexture::string_filter_type(strval);
     EggTexture::FilterType f = EggTexture::string_filter_type(strval);
     if (f == EggTexture::FT_unspecified) {
     if (f == EggTexture::FT_unspecified) {
@@ -348,6 +355,7 @@ texture_body:
     } else {
     } else {
       texture->set_magfilteralpha(f);
       texture->set_magfilteralpha(f);
     }
     }
+
   } else if (cmp_nocase_uh(name, "magfiltercolor") == 0) {
   } else if (cmp_nocase_uh(name, "magfiltercolor") == 0) {
     EggTexture::FilterType f = EggTexture::string_filter_type(strval);
     EggTexture::FilterType f = EggTexture::string_filter_type(strval);
     if (f == EggTexture::FT_unspecified) {
     if (f == EggTexture::FT_unspecified) {
@@ -355,6 +363,7 @@ texture_body:
     } else {
     } else {
       texture->set_magfiltercolor(f);
       texture->set_magfiltercolor(f);
     }
     }
+
   } else if (cmp_nocase_uh(name, "envtype") == 0) {
   } else if (cmp_nocase_uh(name, "envtype") == 0) {
     EggTexture::EnvType e = EggTexture::string_env_type(strval);
     EggTexture::EnvType e = EggTexture::string_env_type(strval);
     if (e == EggTexture::ET_unspecified) {
     if (e == EggTexture::ET_unspecified) {
@@ -362,6 +371,7 @@ texture_body:
     } else {
     } else {
       texture->set_env_type(e);
       texture->set_env_type(e);
     }
     }
+
   } else if (cmp_nocase_uh(name, "alpha") == 0) {
   } else if (cmp_nocase_uh(name, "alpha") == 0) {
     EggAlphaMode::AlphaMode a = EggAlphaMode::string_alpha_mode(strval);
     EggAlphaMode::AlphaMode a = EggAlphaMode::string_alpha_mode(strval);
     if (a == EggAlphaMode::AM_unspecified) {
     if (a == EggAlphaMode::AM_unspecified) {
@@ -369,8 +379,13 @@ texture_body:
     } else {
     } else {
       texture->set_alpha_mode(a);
       texture->set_alpha_mode(a);
     }
     }
+
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
   } else if (cmp_nocase_uh(name, "draw_order") == 0) {
     texture->set_draw_order(value);
     texture->set_draw_order(value);
+
+  } else if (cmp_nocase_uh(name, "alpha_file") == 0) {
+    texture->set_alpha_file(strval);
+
   } else {
   } else {
     eggyywarning("Unsupported texture scalar: " + name);
     eggyywarning("Unsupported texture scalar: " + name);
   }
   }
@@ -450,7 +465,7 @@ external_reference:
 	EXTERNAL_FILE optional_name '{' required_string '}'
 	EXTERNAL_FILE optional_name '{' required_string '}'
 {
 {
   string node_name = $2;
   string node_name = $2;
-  string filename = $4;
+  Filename filename = $4;
   EggExternalReference *ref = new EggExternalReference(node_name, filename);
   EggExternalReference *ref = new EggExternalReference(node_name, filename);
   $$ = ref;
   $$ = ref;
 }
 }
@@ -460,7 +475,7 @@ external_reference:
     eggyyerror("keyword 'group' expected");
     eggyyerror("keyword 'group' expected");
   }
   }
   string node_name = $3;
   string node_name = $3;
-  string filename = $5;
+  Filename filename = $5;
   EggExternalReference *ref = new EggExternalReference(node_name, filename);
   EggExternalReference *ref = new EggExternalReference(node_name, filename);
   $$ = ref;
   $$ = ref;
 }
 }
@@ -1463,8 +1478,9 @@ primitive_texture_body:
   } else {
   } else {
     // The texture already existed.  Use it.
     // The texture already existed.  Use it.
     texture = (*vpi).second;
     texture = (*vpi).second;
-    if (!(filename == texture->get_fullpath())) {
-      eggyywarning("Using previous path: " + texture->get_fullpath());
+    if (filename != texture->get_filename()) {
+      eggyywarning(string("Using previous path: ") + 
+		   texture->get_filename().get_fullpath());
     }
     }
   }
   }
 
 

+ 8 - 2
panda/src/egg2sg/eggLoader.cxx

@@ -505,7 +505,13 @@ load_textures() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool EggLoader::
 bool EggLoader::
 load_texture(TextureDef &def, const EggTexture *egg_tex) {
 load_texture(TextureDef &def, const EggTexture *egg_tex) {
-  Texture *tex = TexturePool::load_texture(egg_tex->get_fullpath());
+  Texture *tex;
+  if (egg_tex->has_alpha_file()) {
+    tex = TexturePool::load_texture(egg_tex->get_filename(),
+				    egg_tex->get_alpha_file());
+  } else {
+    tex = TexturePool::load_texture(egg_tex->get_filename());
+  }
   if (tex == (Texture *)NULL) {
   if (tex == (Texture *)NULL) {
     return false;
     return false;
   }
   }
@@ -529,7 +535,7 @@ load_texture(TextureDef &def, const EggTexture *egg_tex) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void EggLoader::
 void EggLoader::
 apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
 apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
-  tex->set_name(egg_tex->get_fullpath().c_str());
+  tex->set_name(egg_tex->get_filename().get_fullpath());
 
 
   switch (egg_tex->determine_wrap_u()) {
   switch (egg_tex->determine_wrap_u()) {
   case EggTexture::WM_repeat:
   case EggTexture::WM_repeat:

+ 39 - 4
panda/src/glgsg/glGraphicsStateGuardian.cxx

@@ -702,11 +702,20 @@ draw_point(const GeomPoint *geom) {
   Geom::TexCoordIterator ti = geom->make_texcoord_iterator();
   Geom::TexCoordIterator ti = geom->make_texcoord_iterator();
   Geom::ColorIterator ci = geom->make_color_iterator();
   Geom::ColorIterator ci = geom->make_color_iterator();
 
 
+  GeomIssuer::IssueColor *issue_color;
+
+  if (!_color_transform_enabled && !_alpha_transform_enabled) {
+    issue_color = issue_color_gl;
+  }
+  else {
+    issue_color = issue_transformed_color_gl;
+  }
+
   GeomIssuer issuer(geom, this,
   GeomIssuer issuer(geom, this,
 		    issue_vertex_gl,
 		    issue_vertex_gl,
 		    issue_normal_gl,
 		    issue_normal_gl,
 		    issue_texcoord_gl,
 		    issue_texcoord_gl,
-		    issue_color_gl);
+		    issue_color);
 
 
   // Draw overall
   // Draw overall
   issuer.issue_color(G_OVERALL, ci);
   issuer.issue_color(G_OVERALL, ci);
@@ -748,11 +757,20 @@ draw_line(const GeomLine* geom) {
   Geom::VertexIterator vi = geom->make_vertex_iterator();
   Geom::VertexIterator vi = geom->make_vertex_iterator();
   Geom::ColorIterator ci = geom->make_color_iterator();
   Geom::ColorIterator ci = geom->make_color_iterator();
 
 
+  GeomIssuer::IssueColor *issue_color;
+
+  if (!_color_transform_enabled && !_alpha_transform_enabled) {
+    issue_color = issue_color_gl;
+  }
+  else {
+    issue_color = issue_transformed_color_gl;
+  }
+
   GeomIssuer issuer(geom, this,
   GeomIssuer issuer(geom, this,
                     issue_vertex_gl,
                     issue_vertex_gl,
                     issue_normal_gl,
                     issue_normal_gl,
                     issue_texcoord_gl,
                     issue_texcoord_gl,
-                    issue_color_gl);
+                    issue_color);
 
 
   if (geom->get_binding(G_COLOR) == G_PER_VERTEX) {
   if (geom->get_binding(G_COLOR) == G_PER_VERTEX) {
     call_glShadeModel(GL_SMOOTH);
     call_glShadeModel(GL_SMOOTH);
@@ -799,11 +817,20 @@ draw_linestrip(const GeomLinestrip* geom) {
   Geom::VertexIterator vi = geom->make_vertex_iterator();
   Geom::VertexIterator vi = geom->make_vertex_iterator();
   Geom::ColorIterator ci = geom->make_color_iterator();
   Geom::ColorIterator ci = geom->make_color_iterator();
 
 
+  GeomIssuer::IssueColor *issue_color;
+
+  if (!_color_transform_enabled && !_alpha_transform_enabled) {
+    issue_color = issue_color_gl;
+  }
+  else {
+    issue_color = issue_transformed_color_gl;
+  }
+
   GeomIssuer issuer(geom, this,
   GeomIssuer issuer(geom, this,
                     issue_vertex_gl,
                     issue_vertex_gl,
                     issue_normal_gl,
                     issue_normal_gl,
                     issue_texcoord_gl,
                     issue_texcoord_gl,
-                    issue_color_gl);
+                    issue_color);
 
 
   if (geom->get_binding(G_COLOR) == G_PER_VERTEX) {
   if (geom->get_binding(G_COLOR) == G_PER_VERTEX) {
     call_glShadeModel(GL_SMOOTH);
     call_glShadeModel(GL_SMOOTH);
@@ -1154,12 +1181,20 @@ draw_polygon(const GeomPolygon *geom) {
   Geom::TexCoordIterator ti = geom->make_texcoord_iterator();
   Geom::TexCoordIterator ti = geom->make_texcoord_iterator();
   Geom::ColorIterator ci = geom->make_color_iterator();
   Geom::ColorIterator ci = geom->make_color_iterator();
 
 
+  GeomIssuer::IssueColor *issue_color;
+
+  if (!_color_transform_enabled && !_alpha_transform_enabled) {
+    issue_color = issue_color_gl;
+  }
+  else {
+    issue_color = issue_transformed_color_gl;
+  }
 
 
   GeomIssuer issuer(geom, this,
   GeomIssuer issuer(geom, this,
 		    issue_vertex_gl,
 		    issue_vertex_gl,
 		    issue_normal_gl,
 		    issue_normal_gl,
 		    issue_texcoord_gl,
 		    issue_texcoord_gl,
-		    issue_color_gl);
+		    issue_color);
 
 
   // If we have per-vertex colors or normals, we need smooth shading.
   // If we have per-vertex colors or normals, we need smooth shading.
   // Otherwise we want flat shading for performance reasons.
   // Otherwise we want flat shading for performance reasons.

+ 0 - 2
panda/src/gobj/drawable.h

@@ -65,8 +65,6 @@ public:
 		  WriteableConfigurable::get_class_type(),
 		  WriteableConfigurable::get_class_type(),
 		  BoundedObject::get_class_type());
 		  BoundedObject::get_class_type());
   }
   }
-
-PUBLISHED: // Temporary kludge around ffi bug
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {
     return get_class_type();
     return get_class_type();
   }
   }

+ 3 - 0
panda/src/gobj/texturePool.cxx

@@ -71,6 +71,9 @@ ns_load_texture(Filename filename, Filename grayfilename) {
   filename.resolve_filename(get_texture_path());
   filename.resolve_filename(get_texture_path());
   filename.resolve_filename(get_model_path());
   filename.resolve_filename(get_model_path());
 
 
+  grayfilename.resolve_filename(get_texture_path());
+  grayfilename.resolve_filename(get_model_path());
+
   Textures::const_iterator ti;
   Textures::const_iterator ti;
   ti = _textures.find(filename);
   ti = _textures.find(filename);
   if (ti != _textures.end()) {
   if (ti != _textures.end()) {