David Rose 25 лет назад
Родитель
Сommit
0a29169b5c

+ 19 - 19
pandatool/src/egg-palettize-old/Sources.pp

@@ -1,22 +1,22 @@
-#begin bin_target
-  #define TARGET egg-palettize-new
-  #define LOCAL_LIBS \
-    eggbase progbase
-  #define OTHER_LIBS \
-    egg:c linmath:c putil:c express:c pnmimage:c pnmimagetypes:c \
-    pandaegg:m panda:m pandaexpress:m \
-    dtoolutil:c dconfig:c dtool:m pystub
+//  #begin bin_target
+//    #define TARGET egg-palettize-new
+//    #define LOCAL_LIBS \
+//      eggbase progbase
+//    #define OTHER_LIBS \
+//      egg:c linmath:c putil:c express:c pnmimage:c pnmimagetypes:c \
+//      pandaegg:m panda:m pandaexpress:m \
+//      dtoolutil:c dconfig:c dtool:m pystub
 
-  #define SOURCES \
-    attribFile.cxx attribFile.h config_egg_palettize.cxx \
-    eggPalettize.cxx eggPalettize.h \
-    palette.cxx palette.h paletteGroup.cxx \
-    paletteGroup.h pTexture.cxx pTexture.h sourceEgg.cxx \
-    sourceEgg.h string_utils.cxx string_utils.h \
-    textureEggRef.cxx textureEggRef.h textureOmitReason.h \
-    texturePacking.cxx \
-    texturePacking.h userAttribLine.cxx userAttribLine.h
+//    #define SOURCES \
+//      attribFile.cxx attribFile.h config_egg_palettize.cxx \
+//      eggPalettize.cxx eggPalettize.h \
+//      palette.cxx palette.h paletteGroup.cxx \
+//      paletteGroup.h pTexture.cxx pTexture.h sourceEgg.cxx \
+//      sourceEgg.h string_utils.cxx string_utils.h \
+//      textureEggRef.cxx textureEggRef.h textureOmitReason.h \
+//      texturePacking.cxx \
+//      texturePacking.h userAttribLine.cxx userAttribLine.h
 
-  #define INSTALL_HEADERS
+//    #define INSTALL_HEADERS
 
-#end bin_target
+//  #end bin_target

+ 27 - 27
pandatool/src/egg-palettize/Sources.pp

@@ -1,30 +1,30 @@
-//  #begin bin_target
-//    #define TARGET egg-palettize
-//    #define LOCAL_LIBS \
-//      eggbase progbase
-//    #define OTHER_LIBS \
-//      egg:c loader:c linmath:c putil:c express:c pnmimage:c pnmimagetypes:c \
-//      pandaegg:m panda:m pandaexpress:m \
-//      dtoolutil:c dconfig:c dtool:m pystub
+#begin bin_target
+  #define TARGET egg-palettize
+  #define LOCAL_LIBS \
+    eggbase progbase
+  #define OTHER_LIBS \
+    egg:c loader:c linmath:c putil:c express:c pnmimage:c pnmimagetypes:c \
+    pandaegg:m panda:m pandaexpress:m \
+    dtoolutil:c dconfig:c dtool:m pystub
 
-//    #define SOURCES \
-//      config_egg_palettize.cxx config_egg_palettize.h \
-//      destTextureImage.cxx destTextureImage.h \
-//      eggFile.cxx eggFile.h eggPalettize.cxx eggPalettize.h \
-//      filenameUnifier.cxx filenameUnifier.h \
-//      imageFile.cxx imageFile.h omitReason.cxx omitReason.h \
-//      paletteGroup.h paletteGroup.cxx \
-//      paletteGroups.h paletteGroups.cxx paletteImage.h paletteImage.cxx \
-//      palettePage.cxx palettePage.h \
-//      palettizer.cxx palettizer.h \
-//      sourceTextureImage.cxx sourceTextureImage.h string_utils.cxx \
-//      string_utils.h textureImage.cxx textureImage.h \
-//      texturePlacement.cxx texturePlacement.h \
-//      texturePosition.cxx texturePosition.h \
-//      textureProperties.cxx textureProperties.h textureReference.cxx \
-//      textureReference.h textureRequest.h textureRequest.cxx \
-//      txaFile.cxx txaFile.h \
-//      txaLine.cxx txaLine.h
+  #define SOURCES \
+    config_egg_palettize.cxx config_egg_palettize.h \
+    destTextureImage.cxx destTextureImage.h \
+    eggFile.cxx eggFile.h eggPalettize.cxx eggPalettize.h \
+    filenameUnifier.cxx filenameUnifier.h \
+    imageFile.cxx imageFile.h omitReason.cxx omitReason.h \
+    paletteGroup.h paletteGroup.cxx \
+    paletteGroups.h paletteGroups.cxx paletteImage.h paletteImage.cxx \
+    palettePage.cxx palettePage.h \
+    palettizer.cxx palettizer.h \
+    sourceTextureImage.cxx sourceTextureImage.h string_utils.cxx \
+    string_utils.h textureImage.cxx textureImage.h \
+    texturePlacement.cxx texturePlacement.h \
+    texturePosition.cxx texturePosition.h \
+    textureProperties.cxx textureProperties.h textureReference.cxx \
+    textureReference.h textureRequest.h textureRequest.cxx \
+    txaFile.cxx txaFile.h \
+    txaLine.cxx txaLine.h
 
-//  #end bin_target
+#end bin_target
 

+ 20 - 1
pandatool/src/egg-palettize/eggFile.cxx

@@ -16,6 +16,8 @@
 #include <datagramIterator.h>
 #include <bamReader.h>
 #include <bamWriter.h>
+#include <executionEnvironment.h>
+#include <dSearchPath.h>
 
 TypeHandle EggFile::_type_handle;
 
@@ -44,6 +46,12 @@ from_command_line(EggData *data,
 		  const Filename &source_filename, 
 		  const Filename &dest_filename) {
   _data = data;
+
+  // We save the current directory at the time the egg file appeared
+  // on the command line, so that we'll later be able to properly
+  // resolve external references (like textures) that might be
+  // relative to this directory.
+  _current_directory = ExecutionEnvironment::get_cwd();
   _source_filename = source_filename;
   _dest_filename = dest_filename;
 
@@ -367,6 +375,14 @@ read_egg() {
     return false;
   }
 
+  // We also want to search for filenames based on our current
+  // directory from which we originally loaded the egg file.  This is
+  // important because it's possible the egg file referenced some
+  // textures or something relative to that directory.
+  DSearchPath dir;
+  dir.append_directory(_current_directory);
+  data->resolve_filenames(dir);
+
   if (!data->resolve_externals()) {
     // Failure reading an external.
     delete data;
@@ -390,7 +406,8 @@ write_egg() {
   nassertr(!_dest_filename.empty(), false);
 
   _dest_filename.make_dir();
-  nout << "Writing " << _dest_filename << "\n";
+  nout << "Writing " << FilenameUnifier::make_user_filename(_dest_filename)
+       << "\n";
   if (!_data->write_egg(_dest_filename)) {
     // Some error while writing.  Most unusual.
     _is_stale = true;
@@ -464,6 +481,7 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
 
   // We don't write out _data; that needs to be reread each session.
 
+  datagram.add_string(FilenameUnifier::make_bam_filename(_current_directory));
   datagram.add_string(FilenameUnifier::make_bam_filename(_source_filename));
   datagram.add_string(FilenameUnifier::make_bam_filename(_dest_filename));
 
@@ -545,6 +563,7 @@ make_EggFile(const FactoryParams &params) {
 void EggFile::
 fillin(DatagramIterator &scan, BamReader *manager) {
   set_name(scan.get_string());
+  _current_directory = FilenameUnifier::get_bam_filename(scan.get_string());
   _source_filename = FilenameUnifier::get_bam_filename(scan.get_string());
   _dest_filename = FilenameUnifier::get_bam_filename(scan.get_string());
 

+ 1 - 0
pandatool/src/egg-palettize/eggFile.h

@@ -67,6 +67,7 @@ public:
 
 private:
   EggData *_data;
+  Filename _current_directory;
   Filename _source_filename;
   Filename _dest_filename;
 

+ 2 - 2
pandatool/src/egg-palettize/eggPalettize.cxx

@@ -335,9 +335,9 @@ run() {
   }
 
   if (_all_textures) {
-    pal->process_all();
+    pal->process_all(_redo_all);
   } else {
-    pal->process_command_line_eggs();
+    pal->process_command_line_eggs(_redo_all);
   }
 
   if (_force_optimal) {

+ 3 - 0
pandatool/src/egg-palettize/filenameUnifier.cxx

@@ -25,6 +25,9 @@ void FilenameUnifier::
 set_txa_filename(const Filename &txa_filename) {
   _txa_filename = txa_filename;
   _txa_dir = txa_filename.get_dirname();
+  if (_txa_dir.empty()) {
+    _txa_dir = ".";
+  }
   _txa_dir.make_canonical();
 }
 

+ 18 - 2
pandatool/src/egg-palettize/palettizer.cxx

@@ -193,9 +193,13 @@ read_txa_file(const Filename &txa_filename) {
 //  Description: Processes all the textures named in the
 //               _command_line_eggs, placing them on the appropriate
 //               palettes or whatever needs to be done with them.
+//
+//               If force_texture_read is true, it forces each texture
+//               image file to be read (and thus legitimately checked
+//               for grayscaleness etc.) before placing.
 ////////////////////////////////////////////////////////////////////
 void Palettizer::
-process_command_line_eggs() {
+process_command_line_eggs(bool force_texture_read) {
   _command_line_textures.clear();
 
   // Start by scanning all the egg files we read up on the command
@@ -222,6 +226,10 @@ process_command_line_eggs() {
        ++ti) {
     TextureImage *texture = *ti;
 
+    if (force_texture_read) {
+      texture->read_source_image();
+    }
+
     texture->pre_txa_file();
     _txa_file.match_texture(texture);
     texture->post_txa_file();
@@ -273,9 +281,13 @@ process_command_line_eggs() {
 //     Function: Palettizer::process_all
 //       Access: Public
 //  Description: Reprocesses all textures known.
+//
+//               If force_texture_read is true, it forces each texture
+//               image file to be read (and thus legitimately checked
+//               for grayscaleness etc.) before placing.
 ////////////////////////////////////////////////////////////////////
 void Palettizer::
-process_all() {
+process_all(bool force_texture_read) {
   // If there *were* any egg files on the command line, deal with
   // them.
   CommandLineEggs::const_iterator ei;
@@ -304,6 +316,10 @@ process_all() {
   for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
     TextureImage *texture = (*ti).second;
 
+    if (force_texture_read) {
+      texture->read_source_image();
+    }
+
     texture->pre_txa_file();
     _txa_file.match_texture(texture);
     texture->post_txa_file();

+ 2 - 2
pandatool/src/egg-palettize/palettizer.h

@@ -35,8 +35,8 @@ public:
 
   void report_pi() const;
   void read_txa_file(const Filename &txa_filename);
-  void process_command_line_eggs();
-  void process_all();
+  void process_command_line_eggs(bool force_texture_read);
+  void process_all(bool force_texture_read);
   void optimal_resize();
   void reset_images();
   void generate_images(bool redo_all);

+ 63 - 4
pandatool/src/egg-palettize/textureImage.cxx

@@ -29,6 +29,9 @@ TextureImage() {
   _read_source_image = false;
   _got_dest_image = false;
   _is_surprise = true;
+  _ever_read_image = false;
+  _forced_grayscale = false;
+  _forced_unalpha = false;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -55,7 +58,13 @@ note_egg_file(EggFile *egg_file) {
 ////////////////////////////////////////////////////////////////////
 void TextureImage::
 assign_groups() {
-  nassertv(!_egg_files.empty());
+  if (_egg_files.empty()) {
+    // If we're not referenced by any egg files any more, assign us to
+    // no groups.
+    PaletteGroups empty;
+    assign_to_groups(empty);
+    return;
+  }
 
   PaletteGroups definitely_in;
 
@@ -265,12 +274,12 @@ post_txa_file() {
   } else {
     // If we didn't request a particular number of channels, examine
     // the image to determine if we can downgrade it, for instance
-    // from color to grayscale.
+    // from color to grayscale.  
     if (_properties._got_num_channels &&
 	(_properties._num_channels == 3 || _properties._num_channels == 4)) {
       consider_grayscale();
     }
-
+    
     // Also consider downgrading from alpha to non-alpha.
     if (_properties._got_num_channels &&
 	(_properties._num_channels == 2 || _properties._num_channels == 4)) {
@@ -504,6 +513,7 @@ read_source_image() {
       source->read(_source_image);
     }
     _read_source_image = true;
+    _ever_read_image = true;
   }
 
   return _source_image;
@@ -570,7 +580,24 @@ write_source_pathnames(ostream &out, int indent_level) const {
 void TextureImage::
 write_scale_info(ostream &out, int indent_level) {
   SourceTextureImage *source = get_preferred_source();
-  indent(out, indent_level) << get_name() << " orig ";
+  indent(out, indent_level) << get_name();
+
+  // Write the list of groups we're placed in.
+  if (_placement.empty()) {
+    out << " (not used)";
+  } else {
+    Placement::const_iterator pi;
+    pi = _placement.begin();
+    out << " (" << (*pi).second->get_group()->get_name();
+    ++pi;
+    while (pi != _placement.end()) {
+      out << " " << (*pi).second->get_group()->get_name();
+      ++pi;
+    }
+    out << ")";
+  }
+
+  out << " orig ";
 
   if (source == (SourceTextureImage *)NULL ||
       !source->is_size_known()) {
@@ -694,6 +721,19 @@ assign_to_groups(const PaletteGroups &groups) {
 ////////////////////////////////////////////////////////////////////
 void TextureImage::
 consider_grayscale() {
+  // Since this isn't likely to change for a particular texture after
+  // its creation, we save a bit of time by not performing this check
+  // unless this is the first time we've ever seen this texture.  This
+  // will save us from having to load the texture images time we look
+  // at them.  On the other hand, if we've already loaded up the
+  // image, then go ahead.
+  if (!_read_source_image && _ever_read_image) {
+    if (_forced_grayscale) {
+      _properties._num_channels -= 2;
+    }
+    return;
+  }
+
   const PNMImage &source = read_source_image();
   if (!source.is_valid()) {
     return;
@@ -704,6 +744,7 @@ consider_grayscale() {
       const xel &v = source.get_xel_val(x, y);
       if (PPM_GETR(v) != PPM_GETG(v) || PPM_GETR(v) != PPM_GETB(v)) {
 	// Here's a colored pixel.  We can't go grayscale.
+	_forced_grayscale = false;
 	return;
       }
     }
@@ -711,6 +752,7 @@ consider_grayscale() {
 
   // All pixels in the image were grayscale!
   _properties._num_channels -= 2;
+  _forced_grayscale = true;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -723,6 +765,15 @@ consider_grayscale() {
 ////////////////////////////////////////////////////////////////////
 void TextureImage::
 consider_unalpha() {
+  // As above, we don't bother doing this if we've already done this
+  // in a previous session.
+  if (!_read_source_image && _ever_read_image) {
+    if (_forced_unalpha) {
+      _properties._num_channels--;
+    }
+    return;
+  }
+
   const PNMImage &source = read_source_image();
   if (!source.is_valid()) {
     return;
@@ -736,6 +787,7 @@ consider_unalpha() {
     for (int x = 0; x < source.get_x_size(); x++) {
       if (source.get_alpha_val(x, y) != source.get_maxval()) {
 	// Here's a non-white pixel; the alpha channel is meaningful.
+	_forced_unalpha = false;
 	return;
       }
     }
@@ -743,6 +795,7 @@ consider_unalpha() {
 
   // All alpha pixels in the image were white!
   _properties._num_channels--;
+  _forced_unalpha = true;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -860,6 +913,9 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
   // session.
 
   datagram.add_bool(_is_surprise);
+  datagram.add_bool(_ever_read_image);
+  datagram.add_bool(_forced_grayscale);
+  datagram.add_bool(_forced_unalpha);
 
   // We don't write out _explicitly_assigned_groups; this is re-read
   // from the .txa file each time.
@@ -971,6 +1027,9 @@ fillin(DatagramIterator &scan, BamReader *manager) {
   set_name(scan.get_string());
 
   _is_surprise = scan.get_bool();
+  _ever_read_image = scan.get_bool();
+  _forced_grayscale = scan.get_bool();
+  _forced_unalpha = scan.get_bool();
 
   _actual_assigned_groups.fillin(scan, manager);
 

+ 4 - 0
pandatool/src/egg-palettize/textureImage.h

@@ -92,6 +92,10 @@ private:
   TextureProperties _pre_txa_properties;
   SourceTextureImage *_preferred_source;
   bool _is_surprise;
+ 
+  bool _ever_read_image;
+  bool _forced_grayscale;
+  bool _forced_unalpha;
 
   PaletteGroups _explicitly_assigned_groups;
   PaletteGroups _actual_assigned_groups;

+ 12 - 1
pandatool/src/egg-palettize/texturePlacement.cxx

@@ -123,6 +123,9 @@ get_group() const {
 void TexturePlacement::
 add_egg(TextureReference *reference) {
   reference->mark_egg_stale();
+
+  // Turns out that turning these off is a bad idea, because it may
+  // make us forget the size information halfway through processing.
   /*
   _has_uvs = false;
   _size_known = false;
@@ -207,11 +210,17 @@ determine_size() {
     return false;
   }
 
+  // This seems to be unnecessary (because of omit_solitary() and
+  // not_solitary()), and in fact bitches the logic in omit_solitary()
+  // and not_solitary() so that we call mark_egg_stale()
+  // unnecessarily.
+  /*
   if (_omit_reason == OR_solitary) {
     // If the texture was previously 'omitted' for being solitary, we
     // give it a second chance now.
     _omit_reason = OR_none;
   }
+  */
 
   // Determine the actual minmax of the UV's in use, as well as
   // whether we should wrap or clamp.
@@ -552,8 +561,10 @@ force_replace() {
     _image->unplace(this);
     _image = (PaletteImage *)NULL;
   }
+  if (_omit_reason == OR_none) {
+    mark_eggs_stale();
+  }
   _omit_reason = OR_working;
-  mark_eggs_stale();
 }
 
 ////////////////////////////////////////////////////////////////////