Explorar el Código

*** empty log message ***

David Rose hace 25 años
padre
commit
3af3863cf2

+ 8 - 0
dtool/pptempl/Template.models.pp

@@ -392,6 +392,14 @@ fix-pal :
 pi :
 pi :
 	egg-palettize $[PALETTIZE_OPTS] -a $[texattrib_file] -pi
 	egg-palettize $[PALETTIZE_OPTS] -a $[texattrib_file] -pi
 
 
+#
+# pal-stats : report palettization statistics to standard output for the
+# user's perusal.
+#
+pal-stats :
+	egg-palettize $[PALETTIZE_OPTS] -a $[texattrib_file] -s
+stats-pal : pal-stats
+
 // Somehow, something in the cttools confuses some shells, so that
 // Somehow, something in the cttools confuses some shells, so that
 // when we are attached, 'cd foo' doesn't work, but 'cd ./foo' does.
 // when we are attached, 'cd foo' doesn't work, but 'cd ./foo' does.
 // Weird.  We get around this by putting a ./ in front of each cd
 // Weird.  We get around this by putting a ./ in front of each cd

+ 1 - 0
panda/src/downloader/extractor.cxx

@@ -10,6 +10,7 @@
 #include "config_downloader.h"
 #include "config_downloader.h"
 
 
 #include <filename.h>
 #include <filename.h>
+#include <errno.h>
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 // Defines
 // Defines

+ 50 - 0
panda/src/gobj/config_gobj.cxx

@@ -18,6 +18,7 @@
 #include "texture.h"
 #include "texture.h"
 
 
 #include <dconfig.h>
 #include <dconfig.h>
+#include <string_utils.h>
 
 
 Configure(config_gobj);
 Configure(config_gobj);
 NotifyCategoryDef(gobj, "");
 NotifyCategoryDef(gobj, "");
@@ -30,6 +31,27 @@ NotifyCategoryDef(gobj, "");
 // necessary, so that neither dimension is larger than this value.
 // necessary, so that neither dimension is larger than this value.
 const int max_texture_dimension = config_gobj.GetInt("max-texture-dimension", -1);
 const int max_texture_dimension = config_gobj.GetInt("max-texture-dimension", -1);
 
 
+// Set textures-power-2 to force texture dimensions to a power of two.
+// If this is "up" or "down", the textures will be scaled up or down
+// to the next power of two, as indicated; otherwise, if this is #t,
+// the textures will be scaled down.  If this is #f or unspecified,
+// the textures will be left at whatever size they are.
+
+// These are filled in by the ConfigureFn block, below.
+bool textures_up_power_2 = false;
+bool textures_down_power_2 = false;
+
+// Set textures-square to force texture dimensions to a square aspect
+// ratio.  This works similarly to textures-power-2, above.  If this
+// is "up" or "down", the textures will be scaled up or down to the
+// containing square or the inscribed square, respectively; otherwise,
+// if this is #t, the textures will be scaled down.  If this is #f or
+// unspecified, the textures will be left at whatever size they are.
+
+// These are filled in by the ConfigureFn block, below.
+bool textures_up_square = false;
+bool textures_down_square = false;
+
 // Set this to specify how textures should be written into Bam files.
 // Set this to specify how textures should be written into Bam files.
 // Currently, the options are:
 // Currently, the options are:
 
 
@@ -59,6 +81,34 @@ parse_texture_mode(const string &mode) {
 ConfigureFn(config_gobj) {
 ConfigureFn(config_gobj) {
   string texture_mode = config_util.GetString("bam-texture-mode", "relative");
   string texture_mode = config_util.GetString("bam-texture-mode", "relative");
   bam_texture_mode = parse_texture_mode(texture_mode);
   bam_texture_mode = parse_texture_mode(texture_mode);
+
+  string textures_power_2 = config_gobj.GetString("textures-power-2", "");
+  if (cmp_nocase(textures_power_2, "up") == 0) {
+    textures_up_power_2 = true;
+    textures_down_power_2 = false;
+
+  } else if (cmp_nocase(textures_power_2, "down") == 0) {
+    textures_up_power_2 = false;
+    textures_down_power_2 = true;
+
+  } else {
+    textures_up_power_2 = false;
+    textures_down_power_2 = config_gobj.GetBool("textures-power-2", false);
+  }
+
+  string textures_square = config_gobj.GetString("textures-square", "");
+  if (cmp_nocase(textures_square, "up") == 0) {
+    textures_up_square = true;
+    textures_down_square = false;
+
+  } else if (cmp_nocase(textures_square, "down") == 0) {
+    textures_up_square = false;
+    textures_down_square = true;
+
+  } else {
+    textures_up_square = false;
+    textures_down_square = config_gobj.GetBool("textures-square", false);
+  }
   
   
   Fog::init_type();
   Fog::init_type();
   Geom::init_type();
   Geom::init_type();

+ 4 - 0
panda/src/gobj/config_gobj.h

@@ -13,6 +13,10 @@ NotifyCategoryDecl(gobj, EXPCL_PANDA, EXPTP_PANDA);
 
 
 // Configure variables for gobj package.
 // Configure variables for gobj package.
 extern EXPCL_PANDA const int max_texture_dimension;
 extern EXPCL_PANDA const int max_texture_dimension;
+extern EXPCL_PANDA bool textures_up_power_2;
+extern EXPCL_PANDA bool textures_down_power_2;
+extern EXPCL_PANDA bool textures_up_square;
+extern EXPCL_PANDA bool textures_down_square;
 
 
 enum BamTextureMode {
 enum BamTextureMode {
   BTM_fullpath,
   BTM_fullpath,

+ 91 - 59
panda/src/gobj/texture.cxx

@@ -24,6 +24,78 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 TypeHandle Texture::_type_handle;
 TypeHandle Texture::_type_handle;
 
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: up_to_power_2
+//  Description: Returns the smallest power of 2 greater than or equal
+//               to value.
+////////////////////////////////////////////////////////////////////
+static int
+up_to_power_2(int value) {
+  int x = 1;
+  while (x < value) {
+    x = (x << 1);
+  }
+  return x;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: down_to_power_2
+//  Description: Returns the largest power of 2 less than or equal
+//               to value.
+////////////////////////////////////////////////////////////////////
+static int
+down_to_power_2(int value) {
+  int x = 1;
+  while ((x << 1) <= value) {
+    x = (x << 1);
+  }
+  return x;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: consider_rescale
+//  Description: Scales the PNMImage according to the whims of the
+//               Configrc file.
+////////////////////////////////////////////////////////////////////
+static void
+consider_rescale(PNMImage &pnmimage, const string &name) {
+  int new_x_size = pnmimage.get_x_size();
+  int new_y_size = pnmimage.get_y_size();
+
+  if (textures_down_power_2) {
+    new_x_size = down_to_power_2(new_x_size);
+    new_y_size = down_to_power_2(new_y_size);
+  } else if (textures_up_power_2) {
+    new_x_size = up_to_power_2(new_x_size);
+    new_y_size = up_to_power_2(new_y_size);
+  }
+
+  if (textures_down_square) {
+    new_x_size = new_y_size = min(new_x_size, new_y_size);
+  } else if (textures_up_square) {
+    new_x_size = new_y_size = max(new_x_size, new_y_size);
+  }
+
+  if (max_texture_dimension > 0) {
+    new_x_size = min(new_x_size, max_texture_dimension);
+    new_y_size = min(new_y_size, max_texture_dimension);
+  }
+
+  if (pnmimage.get_x_size() != new_x_size ||
+      pnmimage.get_y_size() != new_y_size) {
+    gobj_cat.info()
+      << "Automatically rescaling " << name << " from " 
+      << pnmimage.get_x_size() << " by " << pnmimage.get_y_size() << " to "
+      << new_x_size << " by " << new_y_size << "\n";
+
+    PNMImage scaled(new_x_size, new_y_size, pnmimage.get_num_channels(),
+		    pnmimage.get_maxval(), pnmimage.get_type());
+    scaled.quick_filter_from(pnmimage);
+    pnmimage = scaled;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Constructor
 //     Function: Constructor
 //       Access:
 //       Access:
@@ -56,8 +128,8 @@ Texture::
 //       Access:
 //       Access:
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-bool Texture::read(const string& name)
-{
+bool Texture::
+read(const string& name) {
   PNMImage pnmimage;
   PNMImage pnmimage;
 
 
   if (!pnmimage.read(name)) {
   if (!pnmimage.read(name)) {
@@ -66,21 +138,8 @@ bool Texture::read(const string& name)
     return false;
     return false;
   }
   }
 
 
-  if (max_texture_dimension > 0 &&
-      (pnmimage.get_x_size() > max_texture_dimension ||
-       pnmimage.get_y_size() > max_texture_dimension)) {
-    int new_xsize = min(pnmimage.get_x_size(), max_texture_dimension);
-    int new_ysize = min(pnmimage.get_y_size(), max_texture_dimension);
-    gobj_cat.info()
-      << "Automatically rescaling " << name << " from " 
-      << pnmimage.get_x_size() << " by " << pnmimage.get_y_size() << " to "
-      << new_xsize << " by " << new_ysize << "\n";
-
-    PNMImage scaled(new_xsize, new_ysize, pnmimage.get_num_channels(),
-		    pnmimage.get_maxval(), pnmimage.get_type());
-    scaled.gaussian_filter_from(0.5, pnmimage);
-    pnmimage = scaled;
-  }
+  // Check to see if we need to scale it.
+  consider_rescale(pnmimage, name);
 
 
   set_name(name);
   set_name(name);
   clear_alpha_name();
   clear_alpha_name();
@@ -93,7 +152,8 @@ bool Texture::read(const string& name)
 //  Description: Combine a 3-component image with a grayscale image
 //  Description: Combine a 3-component image with a grayscale image
 //		 to get a 4-component image
 //		 to get a 4-component image
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-bool Texture::read(const string &name, const string &gray) {
+bool Texture::
+read(const string &name, const string &gray) {
   PNMImage pnmimage;
   PNMImage pnmimage;
   if (!pnmimage.read(name)) {
   if (!pnmimage.read(name)) {
     gobj_cat.error()
     gobj_cat.error()
@@ -108,56 +168,28 @@ bool Texture::read(const string &name, const string &gray) {
     return false;
     return false;
   }
   }
 
 
-  if (max_texture_dimension > 0 &&
-      (pnmimage.get_x_size() > max_texture_dimension ||
-       pnmimage.get_y_size() > max_texture_dimension)) {
-    int new_xsize = min(pnmimage.get_x_size(), max_texture_dimension);
-    int new_ysize = min(pnmimage.get_y_size(), max_texture_dimension);
-    gobj_cat.info()
-      << "Automatically rescaling " << name << " from " 
-      << pnmimage.get_x_size() << " by " << pnmimage.get_y_size() << " to "
-      << new_xsize << " by " << new_ysize << "\n";
-
-    PNMImage scaled(new_xsize, new_ysize, pnmimage.get_num_channels(),
-		    pnmimage.get_maxval(), pnmimage.get_type());
-    scaled.gaussian_filter_from(0.5, pnmimage);
-    pnmimage = scaled;
-  }
+  consider_rescale(pnmimage, name);
 
 
-  // Now do the same for the grayscale image
-  if (max_texture_dimension > 0 &&
-      (grayimage.get_x_size() > max_texture_dimension ||
-       grayimage.get_y_size() > max_texture_dimension)) {
-    int new_xsize = min(grayimage.get_x_size(), max_texture_dimension);
-    int new_ysize = min(grayimage.get_y_size(), max_texture_dimension);
+  // The grayscale (alpha channel) image must be the same size as the
+  // main image.
+  if (pnmimage.get_x_size() != grayimage.get_x_size() ||
+      pnmimage.get_y_size() != grayimage.get_y_size()) {
     gobj_cat.info()
     gobj_cat.info()
       << "Automatically rescaling " << gray << " from " 
       << "Automatically rescaling " << gray << " from " 
       << grayimage.get_x_size() << " by " << grayimage.get_y_size() << " to "
       << grayimage.get_x_size() << " by " << grayimage.get_y_size() << " to "
-      << new_xsize << " by " << new_ysize << "\n";
+      << pnmimage.get_x_size() << " by " << pnmimage.get_y_size() << "\n";
 
 
-    PNMImage scaled(new_xsize, new_ysize, pnmimage.get_num_channels(),
-		    pnmimage.get_maxval(), pnmimage.get_type());
-    scaled.gaussian_filter_from(0.5, pnmimage);
-    pnmimage = scaled;
-  }
-
-  // Make sure the 2 images are the same size
-  int xsize = pnmimage.get_x_size();
-  int ysize = pnmimage.get_y_size();
-  int gxsize = grayimage.get_x_size();
-  int gysize = grayimage.get_y_size();
-  if ((xsize != gxsize) || (ysize != gysize)) {
-    gobj_cat.error()
-      << "Texture::read() - grayscale image not the same size as original - "
-      << "orig = " << xsize << "x" << ysize << " - gray = " << gxsize
-      << "x" << gysize << endl;
-    return false;
+    PNMImage scaled(pnmimage.get_x_size(), pnmimage.get_y_size(), 
+		    grayimage.get_num_channels(),
+		    grayimage.get_maxval(), grayimage.get_type());
+    scaled.quick_filter_from(grayimage);
+    grayimage = scaled;
   }
   }
   
   
   // Make the original image a 4-component image
   // Make the original image a 4-component image
   pnmimage.add_alpha();
   pnmimage.add_alpha();
-  for (int x = 0; x < xsize; x++) {
-    for (int y = 0; y < ysize; y++) { 
+  for (int x = 0; x < pnmimage.get_x_size(); x++) {
+    for (int y = 0; y < pnmimage.get_y_size(); y++) { 
       pnmimage.set_alpha(x, y, grayimage.get_gray(x, y));
       pnmimage.set_alpha(x, y, grayimage.get_gray(x, y));
     }
     }
   }
   }

+ 2 - 1
pandatool/src/egg-palettize/paletteImage.cxx

@@ -636,7 +636,8 @@ get_image() {
     }
     }
   }
   }
 
 
-  nout << "Generating new " << FilenameUnifier::make_user_filename(get_filename()) << "\n";
+  nout << "Generating new "
+       << FilenameUnifier::make_user_filename(get_filename()) << "\n";
 
 
   // We won't be using this any more.
   // We won't be using this any more.
   _cleared_regions.clear();
   _cleared_regions.clear();

+ 13 - 8
pandatool/src/egg-palettize/textureImage.cxx

@@ -530,6 +530,9 @@ copy_unplaced(bool redo_all) {
       }
       }
 
 
       placement->set_dest(dest);
       placement->set_dest(dest);
+
+    } else {
+      placement->set_dest((DestTextureImage *)NULL);
     }
     }
   }
   }
 
 
@@ -643,15 +646,17 @@ write_scale_info(ostream &out, int indent_level) {
 	<< " " << source->get_num_channels();
 	<< " " << source->get_num_channels();
   }
   }
 
 
-  out << " new " << get_x_size() << " " << get_y_size()
-      << " " << get_num_channels();
+  if (!_placement.empty()) {
+    out << " new " << get_x_size() << " " << get_y_size()
+	<< " " << get_num_channels();
 
 
-  if (source != (SourceTextureImage *)NULL &&
-      source->is_size_known()) {
-    double scale = 
-      100.0 * (((double)get_x_size() / (double)source->get_x_size()) +
-	       ((double)get_y_size() / (double)source->get_y_size())) / 2.0;
-    out << " scale " << scale << "%";
+    if (source != (SourceTextureImage *)NULL &&
+	source->is_size_known()) {
+      double scale = 
+	100.0 * (((double)get_x_size() / (double)source->get_x_size()) +
+		 ((double)get_y_size() / (double)source->get_y_size())) / 2.0;
+      out << " scale " << scale << "%";
+    }
   }
   }
   out << "\n";
   out << "\n";