*** empty log message ***

This commit is contained in:
David Rose 2000-12-06 19:22:19 +00:00
parent aae1dbd84d
commit 397f403188
13 changed files with 198 additions and 49 deletions

View File

@ -103,6 +103,17 @@ EggPalettize() : EggMultiFilter(true) {
"ever been palettized, not just the egg files that appear on " "ever been palettized, not just the egg files that appear on "
"the command line.", "the command line.",
&EggPalettize::dispatch_none, &_all_textures); &EggPalettize::dispatch_none, &_all_textures);
add_option
("egg", "", 0,
"Regenerate all egg files that need modification, even those that "
"aren't named on the command line.",
&EggPalettize::dispatch_none, &_redo_eggs);
add_option
("redo", "", 0,
"Force a regeneration of each image from its original source(s). "
"When used in conjunction with -egg, this also forces each egg file to "
"be regenerated.",
&EggPalettize::dispatch_none, &_redo_all);
add_option add_option
("opt", "", 0, ("opt", "", 0,
"Force an optimal packing. By default, textures are added to " "Force an optimal packing. By default, textures are added to "
@ -111,20 +122,6 @@ EggPalettize() : EggMultiFilter(true) {
"to be rebuilt if necessary to optimize the packing, but this " "to be rebuilt if necessary to optimize the packing, but this "
"may invalidate other egg files which share this palette.", "may invalidate other egg files which share this palette.",
&EggPalettize::dispatch_none, &_force_optimal); &EggPalettize::dispatch_none, &_force_optimal);
add_option
("redo", "", 0,
"Force a redo of everything. This is useful in case something "
"has gotten out of sync and the old palettes are just bad.",
&EggPalettize::dispatch_none, &_force_redo_all);
add_option
("R", "", 0,
"Resize mostly-empty palettes to their minimal size.",
&EggPalettize::dispatch_none, &_optimal_resize);
add_option
("egg", "", 0,
"Regenerate all egg files that need modification, even those that "
"aren't named on the command line.",
&EggPalettize::dispatch_none, &_redo_eggs);
add_option add_option
("nolock", "", 0, ("nolock", "", 0,
@ -327,6 +324,16 @@ run() {
pal->_command_line_eggs.push_back(egg_file); pal->_command_line_eggs.push_back(egg_file);
} }
if (_force_optimal) {
// If we're asking for an optimal packing, throw away the old
// packing and start fresh.
pal->reset_images();
_all_textures = true;
// Also turn off the rounding-up of UV's for this purpose.
pal->_round_uvs = false;
}
if (_all_textures) { if (_all_textures) {
pal->process_all(); pal->process_all();
} else { } else {
@ -334,12 +341,12 @@ run() {
} }
if (_redo_eggs) { if (_redo_eggs) {
if (!pal->read_stale_eggs()) { if (!pal->read_stale_eggs(_redo_all)) {
okflag = false; okflag = false;
} }
} }
pal->generate_images(); pal->generate_images(_redo_all);
if (!pal->write_eggs()) { if (!pal->write_eggs()) {
okflag = false; okflag = false;

View File

@ -45,8 +45,7 @@ private:
bool _statistics_only; bool _statistics_only;
bool _all_textures; bool _all_textures;
bool _force_optimal; bool _force_optimal;
bool _force_redo_all; bool _redo_all;
bool _optimal_resize;
bool _redo_eggs; bool _redo_eggs;
bool _dont_lock_pi; bool _dont_lock_pi;

View File

@ -196,8 +196,9 @@ exists() const {
return false; return false;
} }
if (_properties._alpha_type != (PNMFileType *)NULL && if (_properties._alpha_type != (PNMFileType *)NULL &&
_properties.uses_alpha()) { _properties.uses_alpha() &&
if (_alpha_filename.exists()) { !_alpha_filename.empty()) {
if (!_alpha_filename.exists()) {
return false; return false;
} }
} }

View File

@ -306,6 +306,22 @@ write_image_info(ostream &out, int indent_level) const {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: PaletteGroup::reset_images
// Access: Public
// Description: Throws away all of the current PaletteImages, so that
// new ones may be created (and the packing made more
// optimal).
////////////////////////////////////////////////////////////////////
void PaletteGroup::
reset_images() {
Pages::iterator pai;
for (pai = _pages.begin(); pai != _pages.end(); ++pai) {
PalettePage *page = (*pai).second;
page->reset_images();
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PaletteGroup::update_images // Function: PaletteGroup::update_images
// Access: Public // Access: Public
@ -313,11 +329,11 @@ write_image_info(ostream &out, int indent_level) const {
// it. // it.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void PaletteGroup:: void PaletteGroup::
update_images() { update_images(bool redo_all) {
Pages::iterator pai; Pages::iterator pai;
for (pai = _pages.begin(); pai != _pages.end(); ++pai) { for (pai = _pages.begin(); pai != _pages.end(); ++pai) {
PalettePage *page = (*pai).second; PalettePage *page = (*pai).second;
page->update_images(); page->update_images(redo_all);
} }
} }

View File

@ -59,7 +59,8 @@ public:
void place_all(); void place_all();
void write_image_info(ostream &out, int indent_level = 0) const; void write_image_info(ostream &out, int indent_level = 0) const;
void update_images(); void reset_images();
void update_images(bool redo_all);
private: private:
string _dirname; string _dirname;

View File

@ -9,6 +9,7 @@
#include "texturePlacement.h" #include "texturePlacement.h"
#include "palettizer.h" #include "palettizer.h"
#include "textureImage.h" #include "textureImage.h"
#include "filenameUnifier.h"
#include <indent.h> #include <indent.h>
#include <datagram.h> #include <datagram.h>
@ -245,6 +246,7 @@ check_solitary() {
placement->omit_solitary(); placement->omit_solitary();
} else { } else {
// Zero or multiple.
Placements::const_iterator pi; Placements::const_iterator pi;
for (pi = _placements.begin(); pi != _placements.end(); ++pi) { for (pi = _placements.begin(); pi != _placements.end(); ++pi) {
TexturePlacement *placement = (*pi); TexturePlacement *placement = (*pi);
@ -271,14 +273,38 @@ write_placements(ostream &out, int indent_level) const {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: PaletteImage::reset_image
// Access: Public
// Description: Unpacks each texture that has been placed on this
// image, resetting the image to empty.
////////////////////////////////////////////////////////////////////
void PaletteImage::
reset_image() {
// We need a copy so we can modify this list as we traverse it.
Placements copy_placements = _placements;
Placements::const_iterator pi;
for (pi = copy_placements.begin(); pi != copy_placements.end(); ++pi) {
TexturePlacement *placement = (*pi);
placement->force_replace();
}
_placements.clear();
_cleared_regions.clear();
unlink();
_new_image = true;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PaletteImage::update_image // Function: PaletteImage::update_image
// Access: Public // Access: Public
// Description: If the palette has changed since it was last written // Description: If the palette has changed since it was last written
// out, updates the image and writes out a new one. // out, updates the image and writes out a new one. If
// redo_all is true, regenerates the image from scratch
// and writes it out again, whether it needed it or not.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void PaletteImage:: void PaletteImage::
update_image() { update_image(bool redo_all) {
if (is_empty() && pal->_aggressively_clean_mapdir) { if (is_empty() && pal->_aggressively_clean_mapdir) {
// If the palette image is 'empty', ensure that it doesn't exist. // If the palette image is 'empty', ensure that it doesn't exist.
// No need to clutter up the map directory. // No need to clutter up the map directory.
@ -287,6 +313,12 @@ update_image() {
return; return;
} }
if (redo_all) {
// If we're redoing everything, throw out the old image anyway.
unlink();
_new_image = true;
}
// Do we need to update? // Do we need to update?
bool needs_update = bool needs_update =
_new_image || !exists() || _new_image || !exists() ||
@ -411,7 +443,7 @@ get_image() {
} }
} }
nout << "Generating new " << 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();

View File

@ -40,7 +40,8 @@ public:
void check_solitary(); void check_solitary();
void write_placements(ostream &out, int indent_level = 0) const; void write_placements(ostream &out, int indent_level = 0) const;
void update_image(); void reset_image();
void update_image(bool redo_all);
private: private:
bool find_hole(int &x, int &y, int x_size, int y_size) const; bool find_hole(int &x, int &y, int x_size, int y_size) const;

View File

@ -190,6 +190,25 @@ write_image_info(ostream &out, int indent_level) const {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: PalettePage::reset_images
// Access: Public
// Description: Throws away all of the current PaletteImages, so that
// new ones may be created (and the packing made more
// optimal).
////////////////////////////////////////////////////////////////////
void PalettePage::
reset_images() {
Images::iterator ii;
for (ii = _images.begin(); ii != _images.end(); ++ii) {
PaletteImage *image = (*ii);
image->reset_image();
delete image;
}
_images.clear();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PalettePage::update_images // Function: PalettePage::update_images
// Access: Public // Access: Public
@ -197,11 +216,11 @@ write_image_info(ostream &out, int indent_level) const {
// it. // it.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void PalettePage:: void PalettePage::
update_images() { update_images(bool redo_all) {
Images::iterator ii; Images::iterator ii;
for (ii = _images.begin(); ii != _images.end(); ++ii) { for (ii = _images.begin(); ii != _images.end(); ++ii) {
PaletteImage *image = (*ii); PaletteImage *image = (*ii);
image->update_image(); image->update_image(redo_all);
} }
} }

View File

@ -41,7 +41,8 @@ public:
void unplace(TexturePlacement *placement); void unplace(TexturePlacement *placement);
void write_image_info(ostream &out, int indent_level = 0) const; void write_image_info(ostream &out, int indent_level = 0) const;
void update_images(); void reset_images();
void update_images(bool redo_all);
private: private:
PaletteGroup *_group; PaletteGroup *_group;

View File

@ -346,23 +346,41 @@ process_all() {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Palettizer::generate_images // Function: Palettizer::reset_images
// Access: Public // Access: Public
// Description: Actually generates the appropriate palette and // Description: Throws away all of the current PaletteImages, so that
// unplaced texture images into the map directories. // new ones may be created (and the packing made more
// optimal).
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void Palettizer:: void Palettizer::
generate_images() { reset_images() {
Groups::iterator gi; Groups::iterator gi;
for (gi = _groups.begin(); gi != _groups.end(); ++gi) { for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
PaletteGroup *group = (*gi).second; PaletteGroup *group = (*gi).second;
group->update_images(); group->reset_images();
}
}
////////////////////////////////////////////////////////////////////
// Function: Palettizer::generate_images
// Access: Public
// Description: Actually generates the appropriate palette and
// unplaced texture images into the map directories. If
// redo_all is true, this forces a regeneration of each
// image file.
////////////////////////////////////////////////////////////////////
void Palettizer::
generate_images(bool redo_all) {
Groups::iterator gi;
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
PaletteGroup *group = (*gi).second;
group->update_images(redo_all);
} }
Textures::iterator ti; Textures::iterator ti;
for (ti = _textures.begin(); ti != _textures.end(); ++ti) { for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
TextureImage *texture = (*ti).second; TextureImage *texture = (*ti).second;
texture->copy_unplaced(); texture->copy_unplaced(redo_all);
} }
} }
@ -372,17 +390,21 @@ generate_images() {
// Description: Reads in any egg file that is known to be stale, even // Description: Reads in any egg file that is known to be stale, even
// if it was not listed on the command line, so that it // if it was not listed on the command line, so that it
// may be updated and written out when write_eggs() is // may be updated and written out when write_eggs() is
// called. Returns true if successful, or false if // called. If redo_all is true, this even reads egg
// there was some error. // files that were not flagged as stale.
//
// Returns true if successful, or false if there was
// some error.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool Palettizer:: bool Palettizer::
read_stale_eggs() { read_stale_eggs(bool redo_all) {
bool okflag = true; bool okflag = true;
EggFiles::iterator ei; EggFiles::iterator ei;
for (ei = _egg_files.begin(); ei != _egg_files.end(); ++ei) { for (ei = _egg_files.begin(); ei != _egg_files.end(); ++ei) {
EggFile *egg_file = (*ei).second; EggFile *egg_file = (*ei).second;
if (!egg_file->has_data() && egg_file->is_stale()) { if (!egg_file->has_data() &&
(egg_file->is_stale() || redo_all)) {
if (!egg_file->read_egg()) { if (!egg_file->read_egg()) {
okflag = false; okflag = false;

View File

@ -37,8 +37,9 @@ public:
void read_txa_file(const Filename &txa_filename); void read_txa_file(const Filename &txa_filename);
void process_command_line_eggs(); void process_command_line_eggs();
void process_all(); void process_all();
void generate_images(); void reset_images();
bool read_stale_eggs(); void generate_images(bool redo_all);
bool read_stale_eggs(bool redo_all);
bool write_eggs(); bool write_eggs();
EggFile *get_egg_file(const string &name); EggFile *get_egg_file(const string &name);

View File

@ -270,6 +270,12 @@ post_txa_file() {
(_properties._num_channels == 3 || _properties._num_channels == 4)) { (_properties._num_channels == 3 || _properties._num_channels == 4)) {
consider_grayscale(); consider_grayscale();
} }
// Also consider downgrading from alpha to non-alpha.
if (_properties._got_num_channels &&
(_properties._num_channels == 2 || _properties._num_channels == 4)) {
consider_unalpha();
}
} }
if (_request._format != EggTexture::F_unspecified) { if (_request._format != EggTexture::F_unspecified) {
@ -426,9 +432,12 @@ get_preferred_source() {
// it has been unplaced. Also removes the old filenames // it has been unplaced. Also removes the old filenames
// for previous sessions where it was unplaced, but is // for previous sessions where it was unplaced, but is
// no longer. // no longer.
//
// If redo_all is true, this recopies the texture
// whether it needed to or not.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void TextureImage:: void TextureImage::
copy_unplaced() { copy_unplaced(bool redo_all) {
// First, we need to build up the set of DestTextureImages that // First, we need to build up the set of DestTextureImages that
// represents the files we need to generate. // represents the files we need to generate.
Dests generate; Dests generate;
@ -458,12 +467,19 @@ copy_unplaced() {
} }
} }
// Now remove the old files that we previously generated, but we if (redo_all) {
// don't need any more. // If we're redoing everything, we remove everything first and
remove_old_dests(generate, _dests); // then recopy it again.
Dests empty;
remove_old_dests(empty, _dests);
copy_new_dests(generate, empty);
// And then copy in the new ones. } else {
// Otherwise, we only remove and recopy the things that changed
// between this time and last time.
remove_old_dests(generate, _dests);
copy_new_dests(generate, _dests); copy_new_dests(generate, _dests);
}
// Clean up the old set. // Clean up the old set.
Dests::iterator di; Dests::iterator di;
@ -697,6 +713,38 @@ consider_grayscale() {
_properties._num_channels -= 2; _properties._num_channels -= 2;
} }
////////////////////////////////////////////////////////////////////
// Function: TextureImage::consider_unalpha
// Access: Private
// Description: Examines the actual contents of the image to
// determine if its alpha channel should be eliminated
// (e.g. it's completely white, and therefore
// pointless).
////////////////////////////////////////////////////////////////////
void TextureImage::
consider_unalpha() {
const PNMImage &source = read_source_image();
if (!source.is_valid()) {
return;
}
if (!source.has_alpha()) {
return;
}
for (int y = 0; y < source.get_y_size(); y++) {
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.
return;
}
}
}
// All alpha pixels in the image were white!
_properties._num_channels--;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: TextureImage::remove_old_dests // Function: TextureImage::remove_old_dests
// Access: Private // Access: Private

View File

@ -63,7 +63,7 @@ public:
SourceTextureImage *get_preferred_source(); SourceTextureImage *get_preferred_source();
void copy_unplaced(); void copy_unplaced(bool redo_all);
const PNMImage &read_source_image(); const PNMImage &read_source_image();
const PNMImage &get_dest_image(); const PNMImage &get_dest_image();
@ -82,6 +82,7 @@ private:
void assign_to_groups(const PaletteGroups &groups); void assign_to_groups(const PaletteGroups &groups);
void consider_grayscale(); void consider_grayscale();
void consider_unalpha();
void remove_old_dests(const Dests &a, const Dests &b); void remove_old_dests(const Dests &a, const Dests &b);
void copy_new_dests(const Dests &a, const Dests &b); void copy_new_dests(const Dests &a, const Dests &b);