My shader system operates on many types of maps: color(RGB), alpha,

bump, lumma, specular, nomral(UVW), damage, team color ... That are
all stored in different formats of packed and unpacked ways.
Not all objects have all of the maps.  If an object has color and spec
map i can easy pack it into red,green,blue,spec texture.
If a object has color,lumma,specular,normal map again i can pack it
most effective in 2 textures (rgbl + suvw).

I needed a way to repack them easily.  At first i coded the function
in python and it was pretty slow.  So I rewrote it in c++.
This commit is contained in:
treeform 2008-12-22 23:43:08 +00:00
parent b36dc682a3
commit fcc8ee33b6
2 changed files with 48 additions and 14 deletions

View File

@ -33,7 +33,7 @@ PNMImage(const Filename &filename, PNMFileType *type) {
if (!result) {
pnmimage_cat.error()
<< "Could not read image " << filename << "\n";
}
}
}
////////////////////////////////////////////////////////////////////
@ -110,6 +110,39 @@ copy_from(const PNMImage &copy) {
}
}
////////////////////////////////////////////////////////////////////
// Function: PNMImage::copy_channel
// Access: Published
// Description: Copies a channel from one image into another.
// Images must be the same size
////////////////////////////////////////////////////////////////////
void PNMImage::
copy_channel(const PNMImage &copy, int src_channel, int dest_channel) {
// Make sure the channels are in range
nassertv(src_channel >= 0 && src_channel <= 3);
nassertv(dest_channel >= 0 && dest_channel <= 3);
// Make sure that images are valid
if (!copy.is_valid() || !is_valid()) {
pnmimage_cat.error() << "One of the images is invalid!\n";
return;
}
// Make sure the images are the same size
if (_x_size != copy.get_x_size() || _y_size != copy.get_y_size()){
pnmimage_cat.error() << "Image size doesn't match!\n";
return;
}
// Do the actual copying
for (int x = 0; x < _x_size; x++) {
for (int y = 0; y < _y_size; y++) {
LVecBase4d t = get_xel_a(x, y);
LVecBase4d o = copy.get_xel_a(x, y);
t.set_cell(dest_channel,o.get_cell(src_channel));
set_xel_a(x, y, t);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PNMImage::copy_header_from
// Access: Published
@ -231,7 +264,7 @@ read(const Filename &filename, PNMFileType *type, bool report_unknown_type) {
////////////////////////////////////////////////////////////////////
// Function: PNMImage::read
// Access: Published
// Description: Reads the image data from the indicated stream.
// Description: Reads the image data from the indicated stream.
//
// The filename is advisory only, and may be used
// to suggest a type if it has a known extension.
@ -651,7 +684,7 @@ copy_sub_image(const PNMImage &copy, int xto, int yto,
set_xel_val(x, y, copy.get_xel_val(x - xmin + xfrom, y - ymin + yfrom));
}
}
if (has_alpha() && copy.has_alpha()) {
for (y = ymin; y < ymax; y++) {
for (x = xmin; x < xmax; x++) {
@ -668,7 +701,7 @@ copy_sub_image(const PNMImage &copy, int xto, int yto,
set_xel(x, y, copy.get_xel(x - xmin + xfrom, y - ymin + yfrom));
}
}
if (has_alpha() && copy.has_alpha()) {
for (y = ymin; y < ymax; y++) {
for (x = xmin; x < xmax; x++) {
@ -759,7 +792,7 @@ darken_sub_image(const PNMImage &copy, int xto, int yto,
set_xel_val(x, y, p);
}
}
if (has_alpha() && copy.has_alpha()) {
for (y = ymin; y < ymax; y++) {
for (x = xmin; x < xmax; x++) {
@ -778,13 +811,13 @@ darken_sub_image(const PNMImage &copy, int xto, int yto,
RGBColord c = copy.get_xel(x - xmin + xfrom, y - ymin + yfrom);
RGBColord o = get_xel(x, y);
RGBColord p;
p.set(min(1.0 - ((1.0 - c[0]) * pixel_scale), o[0]),
min(1.0 - ((1.0 - c[1]) * pixel_scale), o[1]),
p.set(min(1.0 - ((1.0 - c[0]) * pixel_scale), o[0]),
min(1.0 - ((1.0 - c[1]) * pixel_scale), o[1]),
min(1.0 - ((1.0 - c[2]) * pixel_scale), o[2]));
set_xel(x, y, p);
}
}
if (has_alpha() && copy.has_alpha()) {
for (y = ymin; y < ymax; y++) {
for (x = xmin; x < xmax; x++) {
@ -829,7 +862,7 @@ lighten_sub_image(const PNMImage &copy, int xto, int yto,
set_xel_val(x, y, p);
}
}
if (has_alpha() && copy.has_alpha()) {
for (y = ymin; y < ymax; y++) {
for (x = xmin; x < xmax; x++) {
@ -848,13 +881,13 @@ lighten_sub_image(const PNMImage &copy, int xto, int yto,
RGBColord c = copy.get_xel(x - xmin + xfrom, y - ymin + yfrom);
RGBColord o = get_xel(x, y);
RGBColord p;
p.set(max(c[0] * pixel_scale, o[0]),
max(c[1] * pixel_scale, o[1]),
p.set(max(c[0] * pixel_scale, o[0]),
max(c[1] * pixel_scale, o[1]),
max(c[2] * pixel_scale, o[2]));
set_xel(x, y, p);
}
}
if (has_alpha() && copy.has_alpha()) {
for (y = ymin; y < ymax; y++) {
for (x = xmin; x < xmax; x++) {

View File

@ -73,6 +73,7 @@ PUBLISHED:
xelval maxval = 255, PNMFileType *type = NULL);
void copy_from(const PNMImage &copy);
void copy_channel(const PNMImage &copy, int src_channel, int dest_channel);
void copy_header_from(const PNMImageHeader &header);
void take_from(PNMImage &orig);
@ -95,7 +96,7 @@ PUBLISHED:
BLOCKING bool read(const Filename &filename, PNMFileType *type = NULL,
bool report_unknown_type = true);
BLOCKING bool read(istream &data, const string &filename = string(),
BLOCKING bool read(istream &data, const string &filename = string(),
PNMFileType *type = NULL,
bool report_unknown_type = true);
BLOCKING bool read(PNMReader *reader);
@ -231,7 +232,7 @@ private:
int &xfrom, int &yfrom, int &x_size, int &y_size,
int &xmin, int &ymin, int &xmax, int &ymax);
INLINE static void compute_spot_pixel(Colord &c, double d2,
INLINE static void compute_spot_pixel(Colord &c, double d2,
double min_radius, double max_radius,
const Colord &fg, const Colord &bg);