mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
*** empty log message ***
This commit is contained in:
parent
417ed7154a
commit
8735480f77
@ -22,6 +22,7 @@
|
|||||||
palettizer.cxx palettizer.h \
|
palettizer.cxx palettizer.h \
|
||||||
sourceTextureImage.cxx sourceTextureImage.h \
|
sourceTextureImage.cxx sourceTextureImage.h \
|
||||||
textureImage.cxx textureImage.h \
|
textureImage.cxx textureImage.h \
|
||||||
|
textureMemoryCounter.cxx textureMemoryCounter.h \
|
||||||
texturePlacement.cxx texturePlacement.h \
|
texturePlacement.cxx texturePlacement.h \
|
||||||
texturePosition.cxx texturePosition.h \
|
texturePosition.cxx texturePosition.h \
|
||||||
textureProperties.cxx textureProperties.h textureReference.cxx \
|
textureProperties.cxx textureProperties.h textureReference.cxx \
|
||||||
|
@ -69,7 +69,7 @@ EggPalettize() : EggMultiFilter(true) {
|
|||||||
("s", "", 0,
|
("s", "", 0,
|
||||||
"Do not process anything, but report statistics on palette "
|
"Do not process anything, but report statistics on palette "
|
||||||
"and texture utilization.",
|
"and texture utilization.",
|
||||||
&EggPalettize::dispatch_none, &_statistics_only);
|
&EggPalettize::dispatch_none, &_report_statistics);
|
||||||
|
|
||||||
// We redefine -d using add_option() instead of redescribe_option()
|
// We redefine -d using add_option() instead of redescribe_option()
|
||||||
// so it gets listed along with these other options that relate.
|
// so it gets listed along with these other options that relate.
|
||||||
@ -515,6 +515,11 @@ run() {
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_report_statistics) {
|
||||||
|
pal->report_statistics();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
bool okflag = true;
|
bool okflag = true;
|
||||||
|
|
||||||
pal->read_txa_file(_txa_filename);
|
pal->read_txa_file(_txa_filename);
|
||||||
|
@ -44,7 +44,7 @@ private:
|
|||||||
// The following values control behavior specific to this session.
|
// The following values control behavior specific to this session.
|
||||||
// They're not saved for future sessions.
|
// They're not saved for future sessions.
|
||||||
bool _report_pi;
|
bool _report_pi;
|
||||||
bool _statistics_only;
|
bool _report_statistics;
|
||||||
bool _all_textures;
|
bool _all_textures;
|
||||||
bool _optimal;
|
bool _optimal;
|
||||||
bool _redo_all;
|
bool _redo_all;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "palettePage.h"
|
#include "palettePage.h"
|
||||||
#include "texturePlacement.h"
|
#include "texturePlacement.h"
|
||||||
#include "textureImage.h"
|
#include "textureImage.h"
|
||||||
|
#include "palettizer.h"
|
||||||
|
|
||||||
#include <indent.h>
|
#include <indent.h>
|
||||||
#include <datagram.h>
|
#include <datagram.h>
|
||||||
@ -25,6 +26,7 @@ PaletteGroup::
|
|||||||
PaletteGroup() {
|
PaletteGroup() {
|
||||||
_egg_count = 0;
|
_egg_count = 0;
|
||||||
_dependency_level = 0;
|
_dependency_level = 0;
|
||||||
|
_dependency_order = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -73,6 +75,7 @@ void PaletteGroup::
|
|||||||
clear_depends() {
|
clear_depends() {
|
||||||
_dependent.clear();
|
_dependent.clear();
|
||||||
_dependency_level = 0;
|
_dependency_level = 0;
|
||||||
|
_dependency_order = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -102,6 +105,59 @@ get_groups() const {
|
|||||||
return _dependent;
|
return _dependent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PaletteGroup::get_placements
|
||||||
|
// Access: Public
|
||||||
|
// Description: Adds the set of TexturePlacements associated with
|
||||||
|
// this group to the indicated vector. The vector is
|
||||||
|
// not cleared before this operation; if the user wants
|
||||||
|
// to retrieve the set of placements particular to this
|
||||||
|
// group only, it is the user's responsibility to clear
|
||||||
|
// the vector first.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PaletteGroup::
|
||||||
|
get_placements(vector<TexturePlacement *> &placements) const {
|
||||||
|
Placements::iterator pi;
|
||||||
|
for (pi = _placements.begin(); pi != _placements.end(); ++pi) {
|
||||||
|
placements.push_back(*pi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PaletteGroup::get_complete_placements
|
||||||
|
// Access: Public
|
||||||
|
// Description: Adds the set of TexturePlacements associated with
|
||||||
|
// this group and all dependent groups to the indicated
|
||||||
|
// vector. See get_placements().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PaletteGroup::
|
||||||
|
get_complete_placements(vector<TexturePlacement *> &placements) const {
|
||||||
|
PaletteGroups complete;
|
||||||
|
complete.make_complete(_dependent);
|
||||||
|
|
||||||
|
PaletteGroups::iterator gi;
|
||||||
|
for (gi = complete.begin(); gi != complete.end(); ++gi) {
|
||||||
|
PaletteGroup *group = (*gi);
|
||||||
|
group->get_placements(placements);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_placements(placements);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PaletteGroup::reset_dependency_level
|
||||||
|
// Access: Public
|
||||||
|
// Description: Unconditionally sets the dependency level and order
|
||||||
|
// of this group to zero, in preparation for a later
|
||||||
|
// call to set_dependency_level(). See
|
||||||
|
// set_dependency_level().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PaletteGroup::
|
||||||
|
reset_dependency_level() {
|
||||||
|
_dependency_level = 0;
|
||||||
|
_dependency_order = 0;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PaletteGroup::set_dependency_level
|
// Function: PaletteGroup::set_dependency_level
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -120,11 +176,44 @@ set_dependency_level(int level) {
|
|||||||
_dependency_level = level;
|
_dependency_level = level;
|
||||||
PaletteGroups::iterator gi;
|
PaletteGroups::iterator gi;
|
||||||
for (gi = _dependent.begin(); gi != _dependent.end(); ++gi) {
|
for (gi = _dependent.begin(); gi != _dependent.end(); ++gi) {
|
||||||
(*gi)->set_dependency_level(level + 1);
|
PaletteGroup *group = (*gi);
|
||||||
|
group->set_dependency_level(level + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PaletteGroup::set_dependency_order
|
||||||
|
// Access: Public
|
||||||
|
// Description: Updates the dependency order of this group. This
|
||||||
|
// number is the inverse of the dependency level, and
|
||||||
|
// can be used to rank the groups in order so that all
|
||||||
|
// the groups that a given group depends on will appear
|
||||||
|
// first in the list. See get_dependency_order().
|
||||||
|
//
|
||||||
|
// This function returns true if anything was changed,
|
||||||
|
// false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool PaletteGroup::
|
||||||
|
set_dependency_order() {
|
||||||
|
bool any_changed = false;
|
||||||
|
|
||||||
|
PaletteGroups::iterator gi;
|
||||||
|
for (gi = _dependent.begin(); gi != _dependent.end(); ++gi) {
|
||||||
|
PaletteGroup *group = (*gi);
|
||||||
|
if (group->set_dependency_order()) {
|
||||||
|
any_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_dependency_order <= group->get_dependency_order()) {
|
||||||
|
_dependency_order = group->get_dependency_order() + 1;
|
||||||
|
any_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return any_changed;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PaletteGroup::get_dependency_level
|
// Function: PaletteGroup::get_dependency_level
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -151,6 +240,26 @@ get_dependency_level() const {
|
|||||||
return _dependency_level;
|
return _dependency_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PaletteGroup::get_dependency_order
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the dependency order of this group. This is
|
||||||
|
// similar in principle to the dependency level, but it
|
||||||
|
// represents the inverse concept: if group a depends on
|
||||||
|
// group b, then a->get_dependency_order() >
|
||||||
|
// b->get_dependency_order().
|
||||||
|
//
|
||||||
|
// This is not exactly the same thing as n -
|
||||||
|
// get_dependency_level(). In particular, this can be
|
||||||
|
// used to sort the groups into an ordering such that
|
||||||
|
// all the groups that group a depends on appear before
|
||||||
|
// group a in the list.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int PaletteGroup::
|
||||||
|
get_dependency_order() const {
|
||||||
|
return _dependency_order;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PaletteGroup::increment_egg_count
|
// Function: PaletteGroup::increment_egg_count
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -392,8 +501,8 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||||||
datagram.add_string(_dirname);
|
datagram.add_string(_dirname);
|
||||||
_dependent.write_datagram(writer, datagram);
|
_dependent.write_datagram(writer, datagram);
|
||||||
|
|
||||||
// We don't write out _dependency_level. It's best to recompute
|
datagram.add_int32(_dependency_level);
|
||||||
// that each time.
|
datagram.add_int32(_dependency_order);
|
||||||
|
|
||||||
datagram.add_uint32(_placements.size());
|
datagram.add_uint32(_placements.size());
|
||||||
Placements::const_iterator pli;
|
Placements::const_iterator pli;
|
||||||
@ -504,6 +613,11 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
|||||||
_dirname = scan.get_string();
|
_dirname = scan.get_string();
|
||||||
_dependent.fillin(scan, manager);
|
_dependent.fillin(scan, manager);
|
||||||
|
|
||||||
|
if (Palettizer::_read_pi_version >= 3) {
|
||||||
|
_dependency_level = scan.get_int32();
|
||||||
|
_dependency_order = scan.get_int32();
|
||||||
|
}
|
||||||
|
|
||||||
_num_placements = scan.get_uint32();
|
_num_placements = scan.get_uint32();
|
||||||
manager->read_pointers(scan, this, _num_placements);
|
manager->read_pointers(scan, this, _num_placements);
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <typedWriteable.h>
|
#include <typedWriteable.h>
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class EggFile;
|
class EggFile;
|
||||||
class TexturePlacement;
|
class TexturePlacement;
|
||||||
@ -44,8 +45,14 @@ public:
|
|||||||
void group_with(PaletteGroup *other);
|
void group_with(PaletteGroup *other);
|
||||||
const PaletteGroups &get_groups() const;
|
const PaletteGroups &get_groups() const;
|
||||||
|
|
||||||
|
void get_placements(vector<TexturePlacement *> &placements) const;
|
||||||
|
void get_complete_placements(vector<TexturePlacement *> &placements) const;
|
||||||
|
|
||||||
|
void reset_dependency_level();
|
||||||
void set_dependency_level(int level);
|
void set_dependency_level(int level);
|
||||||
|
bool set_dependency_order();
|
||||||
int get_dependency_level() const;
|
int get_dependency_level() const;
|
||||||
|
int get_dependency_order() const;
|
||||||
|
|
||||||
void increment_egg_count();
|
void increment_egg_count();
|
||||||
int get_egg_count() const;
|
int get_egg_count() const;
|
||||||
@ -69,6 +76,7 @@ private:
|
|||||||
int _egg_count;
|
int _egg_count;
|
||||||
PaletteGroups _dependent;
|
PaletteGroups _dependent;
|
||||||
int _dependency_level;
|
int _dependency_level;
|
||||||
|
int _dependency_order;
|
||||||
|
|
||||||
typedef set<TexturePlacement *> Placements;
|
typedef set<TexturePlacement *> Placements;
|
||||||
Placements _placements;
|
Placements _placements;
|
||||||
|
@ -207,6 +207,31 @@ is_empty() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PaletteImage::count_utilization
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the fraction of the PaletteImage that is
|
||||||
|
// actually used by any textures. This is 1.0 if every
|
||||||
|
// pixel in the PaletteImage is used, or 0.0 if none
|
||||||
|
// are. Normally it will be somewhere in between.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
double PaletteImage::
|
||||||
|
count_utilization() const {
|
||||||
|
int used_pixels = 0;
|
||||||
|
|
||||||
|
Placements::const_iterator pi;
|
||||||
|
for (pi = _placements.begin(); pi != _placements.end(); ++pi) {
|
||||||
|
TexturePlacement *placement = (*pi);
|
||||||
|
|
||||||
|
int texture_pixels = placement->get_x_size() * placement->get_y_size();
|
||||||
|
used_pixels += texture_pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
int total_pixels = get_x_size() * get_y_size();
|
||||||
|
|
||||||
|
return (double)used_pixels / (double)total_pixels;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PaletteImage::place
|
// Function: PaletteImage::place
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -34,6 +34,7 @@ public:
|
|||||||
PalettePage *get_page() const;
|
PalettePage *get_page() const;
|
||||||
|
|
||||||
bool is_empty() const;
|
bool is_empty() const;
|
||||||
|
double count_utilization() const;
|
||||||
|
|
||||||
bool place(TexturePlacement *placement);
|
bool place(TexturePlacement *placement);
|
||||||
void unplace(TexturePlacement *placement);
|
void unplace(TexturePlacement *placement);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "pal_string_utils.h"
|
#include "pal_string_utils.h"
|
||||||
#include "paletteGroup.h"
|
#include "paletteGroup.h"
|
||||||
#include "filenameUnifier.h"
|
#include "filenameUnifier.h"
|
||||||
|
#include "textureMemoryCounter.h"
|
||||||
|
|
||||||
#include <pnmImage.h>
|
#include <pnmImage.h>
|
||||||
#include <pnmFileTypeRegistry.h>
|
#include <pnmFileTypeRegistry.h>
|
||||||
@ -18,6 +19,7 @@
|
|||||||
#include <datagramIterator.h>
|
#include <datagramIterator.h>
|
||||||
#include <bamReader.h>
|
#include <bamReader.h>
|
||||||
#include <bamWriter.h>
|
#include <bamWriter.h>
|
||||||
|
#include <indent.h>
|
||||||
|
|
||||||
Palettizer *pal = (Palettizer *)NULL;
|
Palettizer *pal = (Palettizer *)NULL;
|
||||||
|
|
||||||
@ -26,9 +28,10 @@ Palettizer *pal = (Palettizer *)NULL;
|
|||||||
// allows us to easily update egg-palettize to write out additional
|
// allows us to easily update egg-palettize to write out additional
|
||||||
// information to its pi file, without having it increment the bam
|
// information to its pi file, without having it increment the bam
|
||||||
// version number for all bam and boo files anywhere in the world.
|
// version number for all bam and boo files anywhere in the world.
|
||||||
int Palettizer::_pi_version = 2;
|
int Palettizer::_pi_version = 3;
|
||||||
// Updated to version 1 on 12/11/00 to add _remap_char_uv.
|
// Updated to version 1 on 12/11/00 to add _remap_char_uv.
|
||||||
// Updated to version 2 on 12/19/00 to add TexturePlacement::_dest.
|
// Updated to version 2 on 12/19/00 to add TexturePlacement::_dest.
|
||||||
|
// Updated to version 3 on 12/19/00 to add PaletteGroup::_dependency_order.
|
||||||
|
|
||||||
int Palettizer::_read_pi_version = 0;
|
int Palettizer::_read_pi_version = 0;
|
||||||
|
|
||||||
@ -52,6 +55,18 @@ ostream &operator << (ostream &out, Palettizer::RemapUV remap) {
|
|||||||
return out << "**invalid**(" << (int)remap << ")";
|
return out << "**invalid**(" << (int)remap << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This STL function object is used in report_statistics(), below.
|
||||||
|
class SortGroupsByDependencyOrder {
|
||||||
|
public:
|
||||||
|
bool operator ()(PaletteGroup *a, PaletteGroup *b) {
|
||||||
|
if (a->get_dependency_order() != b->get_dependency_order()) {
|
||||||
|
return a->get_dependency_order() < b->get_dependency_order();
|
||||||
|
}
|
||||||
|
return a->get_name() < b->get_name();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Palettizer::Constructor
|
// Function: Palettizer::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -178,6 +193,63 @@ report_pi() const {
|
|||||||
cout << "\n";
|
cout << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Palettizer::report_statistics
|
||||||
|
// Access: Public
|
||||||
|
// Description: Output a report of the palettization effectiveness,
|
||||||
|
// texture memory utilization, and so on.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Palettizer::
|
||||||
|
report_statistics() const {
|
||||||
|
// Sort the groups into order by dependency order, for the user's
|
||||||
|
// convenience.
|
||||||
|
vector<PaletteGroup *> sorted_groups;
|
||||||
|
|
||||||
|
Groups::const_iterator gi;
|
||||||
|
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
|
||||||
|
sorted_groups.push_back((*gi).second);
|
||||||
|
}
|
||||||
|
|
||||||
|
sort(sorted_groups.begin(), sorted_groups.end(),
|
||||||
|
SortGroupsByDependencyOrder());
|
||||||
|
|
||||||
|
Placements overall_placements;
|
||||||
|
|
||||||
|
vector<PaletteGroup *>::const_iterator sgi;
|
||||||
|
for (sgi = sorted_groups.begin();
|
||||||
|
sgi != sorted_groups.end();
|
||||||
|
++sgi) {
|
||||||
|
PaletteGroup *group = (*sgi);
|
||||||
|
|
||||||
|
Placements placements;
|
||||||
|
group->get_placements(placements);
|
||||||
|
if (!placements.empty()) {
|
||||||
|
group->get_placements(overall_placements);
|
||||||
|
|
||||||
|
cout << "\n" << group->get_name() << ", by itself:\n";
|
||||||
|
compute_statistics(cout, 2, placements);
|
||||||
|
|
||||||
|
PaletteGroups complete;
|
||||||
|
complete.make_complete(group->get_groups());
|
||||||
|
|
||||||
|
if (complete.size() > 1) {
|
||||||
|
Placements complete_placements;
|
||||||
|
group->get_complete_placements(complete_placements);
|
||||||
|
if (complete_placements.size() != placements.size()) {
|
||||||
|
cout << "\n" << group->get_name()
|
||||||
|
<< ", with dependents (" << complete << "):\n";
|
||||||
|
compute_statistics(cout, 2, complete_placements);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "\nOverall:\n";
|
||||||
|
compute_statistics(cout, 2, overall_placements);
|
||||||
|
|
||||||
|
cout << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Palettizer::read_txa_file
|
// Function: Palettizer::read_txa_file
|
||||||
@ -209,12 +281,28 @@ read_txa_file(const Filename &txa_filename) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the correct dependency level for each group. This will
|
// Compute the correct dependency level and order for each group.
|
||||||
// help us when we assign the textures to their groups.
|
// This will help us when we assign the textures to their groups.
|
||||||
|
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
|
||||||
|
PaletteGroup *group = (*gi).second;
|
||||||
|
group->reset_dependency_level();
|
||||||
|
}
|
||||||
|
|
||||||
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->set_dependency_level(1);
|
group->set_dependency_level(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool any_changed;
|
||||||
|
do {
|
||||||
|
any_changed = false;
|
||||||
|
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
|
||||||
|
PaletteGroup *group = (*gi).second;
|
||||||
|
if (group->set_dependency_order()) {
|
||||||
|
any_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (any_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -617,6 +705,17 @@ get_texture(const string &name) {
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Palettizer::yesno
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: A silly function to return "yes" or "no" based on a
|
||||||
|
// bool flag for nicely formatted output.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const char *Palettizer::
|
||||||
|
yesno(bool flag) {
|
||||||
|
return flag ? "yes" : "no";
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Palettizer::string_remap
|
// Function: Palettizer::string_remap
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
@ -641,14 +740,24 @@ string_remap(const string &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Palettizer::yesno
|
// Function: Palettizer::compute_statistics
|
||||||
// Access: Private, Static
|
// Access: Private
|
||||||
// Description: A silly function to return "yes" or "no" based on a
|
// Description: Determines how much memory, etc. is required by the
|
||||||
// bool flag for nicely formatted output.
|
// indicated set of texture placements, and reports this
|
||||||
|
// to the indicated output stream.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
const char *Palettizer::
|
void Palettizer::
|
||||||
yesno(bool flag) {
|
compute_statistics(ostream &out, int indent_level,
|
||||||
return flag ? "yes" : "no";
|
const Palettizer::Placements &placements) const {
|
||||||
|
TextureMemoryCounter counter;
|
||||||
|
|
||||||
|
Placements::const_iterator pi;
|
||||||
|
for (pi = placements.begin(); pi != placements.end(); ++pi) {
|
||||||
|
TexturePlacement *placement = (*pi);
|
||||||
|
counter.add_placement(placement);
|
||||||
|
}
|
||||||
|
|
||||||
|
counter.report(out, indent_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -20,6 +20,7 @@ class PNMFileType;
|
|||||||
class EggFile;
|
class EggFile;
|
||||||
class PaletteGroup;
|
class PaletteGroup;
|
||||||
class TextureImage;
|
class TextureImage;
|
||||||
|
class TexturePlacement;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : Palettizer
|
// Class : Palettizer
|
||||||
@ -34,6 +35,8 @@ public:
|
|||||||
Palettizer();
|
Palettizer();
|
||||||
|
|
||||||
void report_pi() const;
|
void report_pi() const;
|
||||||
|
void report_statistics() const;
|
||||||
|
|
||||||
void read_txa_file(const Filename &txa_filename);
|
void read_txa_file(const Filename &txa_filename);
|
||||||
void all_params_set();
|
void all_params_set();
|
||||||
void process_command_line_eggs(bool force_texture_read);
|
void process_command_line_eggs(bool force_texture_read);
|
||||||
@ -94,6 +97,10 @@ public:
|
|||||||
PNMFileType *_shadow_alpha_type;
|
PNMFileType *_shadow_alpha_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef vector<TexturePlacement *> Placements;
|
||||||
|
void compute_statistics(ostream &out, int indent_level,
|
||||||
|
const Placements &placements) const;
|
||||||
|
|
||||||
typedef map<string, EggFile *> EggFiles;
|
typedef map<string, EggFile *> EggFiles;
|
||||||
EggFiles _egg_files;
|
EggFiles _egg_files;
|
||||||
|
|
||||||
|
233
pandatool/src/egg-palettize/textureMemoryCounter.cxx
Normal file
233
pandatool/src/egg-palettize/textureMemoryCounter.cxx
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
// Filename: textureMemoryCounter.cxx
|
||||||
|
// Created by: drose (19Dec00)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "textureMemoryCounter.h"
|
||||||
|
#include "paletteImage.h"
|
||||||
|
#include "textureImage.h"
|
||||||
|
#include "destTextureImage.h"
|
||||||
|
#include "omitReason.h"
|
||||||
|
#include "texturePlacement.h"
|
||||||
|
|
||||||
|
#include <indent.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextureMemoryCounter::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
TextureMemoryCounter::
|
||||||
|
TextureMemoryCounter() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextureMemoryCounter::reset
|
||||||
|
// Access: Public
|
||||||
|
// Description: Resets the count to zero.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void TextureMemoryCounter::
|
||||||
|
reset() {
|
||||||
|
_num_textures = 0;
|
||||||
|
_num_unplaced = 0;
|
||||||
|
_num_placed = 0;
|
||||||
|
_num_palettes = 0;
|
||||||
|
|
||||||
|
_bytes = 0;
|
||||||
|
_unused_bytes = 0;
|
||||||
|
_duplicate_bytes = 0;
|
||||||
|
_textures.clear();
|
||||||
|
_palettes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextureMemoryCounter::add_placement
|
||||||
|
// Access: Public
|
||||||
|
// Description: Adds the indicated TexturePlacement to the counter.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void TextureMemoryCounter::
|
||||||
|
add_placement(TexturePlacement *placement) {
|
||||||
|
TextureImage *texture = placement->get_texture();
|
||||||
|
nassertv(texture != (TextureImage *)NULL);
|
||||||
|
|
||||||
|
if (placement->get_omit_reason() == OR_none) {
|
||||||
|
PaletteImage *image = placement->get_image();
|
||||||
|
nassertv(image != (PaletteImage *)NULL);
|
||||||
|
add_palette(image);
|
||||||
|
|
||||||
|
int bytes = count_bytes(image, placement->get_placed_x_size(),
|
||||||
|
placement->get_placed_y_size());
|
||||||
|
add_texture(texture, bytes);
|
||||||
|
_num_placed++;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
DestTextureImage *dest = placement->get_dest();
|
||||||
|
nassertv(dest != (DestTextureImage *)NULL);
|
||||||
|
|
||||||
|
int bytes = count_bytes(dest);
|
||||||
|
add_texture(texture, bytes);
|
||||||
|
|
||||||
|
_bytes += bytes;
|
||||||
|
_num_unplaced++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextureMemoryCounter::report
|
||||||
|
// Access: Public
|
||||||
|
// Description: Reports the measured texture memory usage.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void TextureMemoryCounter::
|
||||||
|
report(ostream &out, int indent_level) {
|
||||||
|
indent(out, indent_level)
|
||||||
|
<< _num_placed << " of " << _num_textures << " textures appear on "
|
||||||
|
<< _num_palettes << " palette images with " << _num_unplaced
|
||||||
|
<< " unplaced.\n";
|
||||||
|
|
||||||
|
indent(out, indent_level)
|
||||||
|
<< (_bytes + 512) / 1024 << "k estimated texture memory required.\n";
|
||||||
|
|
||||||
|
if (_bytes != 0) {
|
||||||
|
indent(out, indent_level + 2)
|
||||||
|
<< "Of this, "
|
||||||
|
<< floor(1000.0 * (double)_unused_bytes / (double)_bytes + 0.5) / 10.0
|
||||||
|
<< "% is wasted because of unused palette space.\n";
|
||||||
|
|
||||||
|
if (_duplicate_bytes != 0) {
|
||||||
|
indent(out, indent_level + 2)
|
||||||
|
<< "And " << 100.0 * (double)_duplicate_bytes / (double)_bytes
|
||||||
|
<< "% is wasted because of a texture appearing in multiple places.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextureMemoryCounter::add_palette
|
||||||
|
// Access: Private
|
||||||
|
// Description: Adds the indicated PaletteImage to the count. If
|
||||||
|
// this is called twice for a given PaletteImage it does
|
||||||
|
// nothing.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void TextureMemoryCounter::
|
||||||
|
add_palette(PaletteImage *image) {
|
||||||
|
bool inserted = _palettes.insert(image).second;
|
||||||
|
if (!inserted) {
|
||||||
|
// We've already added this palette image.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bytes = count_bytes(image);
|
||||||
|
double wasted = 1.0 - image->count_utilization();
|
||||||
|
|
||||||
|
_bytes += bytes;
|
||||||
|
_unused_bytes += (int)(wasted * bytes);
|
||||||
|
_num_palettes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextureMemoryCounter::add_texture
|
||||||
|
// Access: Private
|
||||||
|
// Description: Adds the given TextureImage to the counter. If the
|
||||||
|
// texture image has already been added, this counts the
|
||||||
|
// smaller of the two as duplicate bytes.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void TextureMemoryCounter::
|
||||||
|
add_texture(TextureImage *texture, int bytes) {
|
||||||
|
pair<Textures::iterator, bool> result;
|
||||||
|
result = _textures.insert(Textures::value_type(texture, bytes));
|
||||||
|
if (result.second) {
|
||||||
|
// If it was inserted, no problem--no duplicates.
|
||||||
|
_num_textures++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it was not inserted, we have a duplicate.
|
||||||
|
Textures::iterator ti = result.first;
|
||||||
|
|
||||||
|
_duplicate_bytes += min(bytes, (*ti).second);
|
||||||
|
(*ti).second = max(bytes, (*ti).second);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextureMemoryCounter::count_bytes
|
||||||
|
// Access: Private
|
||||||
|
// Description: Attempts to estimate the number of bytes the given
|
||||||
|
// image file will use in texture memory.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int TextureMemoryCounter::
|
||||||
|
count_bytes(ImageFile *image) {
|
||||||
|
return count_bytes(image, image->get_x_size(), image->get_y_size());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextureMemoryCounter::count_bytes
|
||||||
|
// Access: Private
|
||||||
|
// Description: Attempts to estimate the number of bytes the given
|
||||||
|
// image file will use in texture memory.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int TextureMemoryCounter::
|
||||||
|
count_bytes(ImageFile *image, int x_size, int y_size) {
|
||||||
|
int pixels = x_size * y_size;
|
||||||
|
|
||||||
|
// Try to guess the number of bytes per pixel this texture will
|
||||||
|
// consume in texture memory, based on its requested format. This
|
||||||
|
// is only a loose guess, because this depends of course on the
|
||||||
|
// pecularities of the particular rendering engine.
|
||||||
|
int bpp = 0;
|
||||||
|
switch (image->get_properties()._format) {
|
||||||
|
case EggTexture::F_rgba12:
|
||||||
|
bpp = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EggTexture::F_rgba:
|
||||||
|
case EggTexture::F_rgbm:
|
||||||
|
case EggTexture::F_rgba8:
|
||||||
|
bpp = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EggTexture::F_rgb:
|
||||||
|
case EggTexture::F_rgb12:
|
||||||
|
bpp = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EggTexture::F_rgba4:
|
||||||
|
case EggTexture::F_rgba5:
|
||||||
|
case EggTexture::F_rgb8:
|
||||||
|
case EggTexture::F_rgb5:
|
||||||
|
case EggTexture::F_luminance_alpha:
|
||||||
|
case EggTexture::F_luminance_alphamask:
|
||||||
|
bpp = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EggTexture::F_rgb332:
|
||||||
|
case EggTexture::F_red:
|
||||||
|
case EggTexture::F_green:
|
||||||
|
case EggTexture::F_blue:
|
||||||
|
case EggTexture::F_alpha:
|
||||||
|
case EggTexture::F_luminance:
|
||||||
|
bpp = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
bpp = image->get_num_channels();
|
||||||
|
}
|
||||||
|
|
||||||
|
int bytes = pixels * bpp;
|
||||||
|
|
||||||
|
// If we're mipmapping, it's worth 1/3 more bytes.
|
||||||
|
switch (image->get_properties()._magfilter) {
|
||||||
|
case EggTexture::FT_nearest_mipmap_nearest:
|
||||||
|
case EggTexture::FT_linear_mipmap_nearest:
|
||||||
|
case EggTexture::FT_nearest_mipmap_linear:
|
||||||
|
case EggTexture::FT_linear_mipmap_linear:
|
||||||
|
bytes = (bytes * 4) / 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
58
pandatool/src/egg-palettize/textureMemoryCounter.h
Normal file
58
pandatool/src/egg-palettize/textureMemoryCounter.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Filename: textureMemoryCounter.h
|
||||||
|
// Created by: drose (19Dec00)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TEXTUREMEMORYCOUNTER_H
|
||||||
|
#define TEXTUREMEMORYCOUNTER_H
|
||||||
|
|
||||||
|
#include <pandatoolbase.h>
|
||||||
|
|
||||||
|
class ImageFile;
|
||||||
|
class PaletteImage;
|
||||||
|
class TextureImage;
|
||||||
|
class DestTextureImage;
|
||||||
|
class TexturePlacement;
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : TextureMemoryCounter
|
||||||
|
// Description : This class is used to gather statistics on texture
|
||||||
|
// memory usage, etc. It adds up the total texture
|
||||||
|
// memory required by a number of image files, and
|
||||||
|
// reports it at the end.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class TextureMemoryCounter {
|
||||||
|
public:
|
||||||
|
TextureMemoryCounter();
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
void add_placement(TexturePlacement *placement);
|
||||||
|
|
||||||
|
void report(ostream &out, int indent_level);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void add_palette(PaletteImage *image);
|
||||||
|
void add_texture(TextureImage *texture, int bytes);
|
||||||
|
int count_bytes(ImageFile *image);
|
||||||
|
int count_bytes(ImageFile *image, int x_size, int y_size);
|
||||||
|
|
||||||
|
int _num_textures;
|
||||||
|
int _num_placed;
|
||||||
|
int _num_unplaced;
|
||||||
|
int _num_palettes;
|
||||||
|
|
||||||
|
int _bytes;
|
||||||
|
int _unused_bytes;
|
||||||
|
int _duplicate_bytes;
|
||||||
|
|
||||||
|
typedef map<TextureImage *, int> Textures;
|
||||||
|
Textures _textures;
|
||||||
|
|
||||||
|
typedef set<PaletteImage *> Palettes;
|
||||||
|
Palettes _palettes;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user