From fcc8ee33b62a09f24984ef62c34249b034764207 Mon Sep 17 00:00:00 2001 From: treeform Date: Mon, 22 Dec 2008 23:43:08 +0000 Subject: [PATCH] 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++. --- panda/src/pnmimage/pnmImage.cxx | 57 ++++++++++++++++++++++++++------- panda/src/pnmimage/pnmImage.h | 5 +-- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/panda/src/pnmimage/pnmImage.cxx b/panda/src/pnmimage/pnmImage.cxx index 7866b32d48..b4b27a2e02 100644 --- a/panda/src/pnmimage/pnmImage.cxx +++ b/panda/src/pnmimage/pnmImage.cxx @@ -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 ©) { } } +//////////////////////////////////////////////////////////////////// +// 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 ©, 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 ©, 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 ©, 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 ©, 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 ©, 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 ©, 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 ©, 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++) { diff --git a/panda/src/pnmimage/pnmImage.h b/panda/src/pnmimage/pnmImage.h index 988e18b423..ff3b180653 100644 --- a/panda/src/pnmimage/pnmImage.h +++ b/panda/src/pnmimage/pnmImage.h @@ -73,6 +73,7 @@ PUBLISHED: xelval maxval = 255, PNMFileType *type = NULL); void copy_from(const PNMImage ©); + void copy_channel(const PNMImage ©, 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);