17 static double get_unsigned_byte_i(
const unsigned char *&p) {
21 static double get_signed_byte_i(
const unsigned char *&p) {
22 return *(
signed char *)p++;
25 static double get_unsigned_short_i(
const unsigned char *&p) {
35 static double get_signed_short_i(
const unsigned char *&p) {
45 static double get_unsigned_int_i(
const unsigned char *&p) {
57 static double get_signed_int_i(
const unsigned char *&p) {
76 TexturePeeker(
Texture *tex, Texture::CData *cdata) {
78 if (tex->do_has_ram_image(cdata) && cdata->_ram_image_compression == Texture::CM_off) {
80 _image = tex->do_get_ram_image(cdata);
81 _x_size = cdata->_x_size;
82 _y_size = cdata->_y_size;
83 _z_size = cdata->_z_size;
84 _pixel_width = cdata->_component_width * cdata->_num_components;
85 _format = cdata->_format;
86 _component_type = cdata->_component_type;
88 else if (!cdata->_simple_ram_image._image.empty()) {
90 _image = cdata->_simple_ram_image._image;
91 _x_size = cdata->_simple_x_size;
92 _y_size = cdata->_simple_y_size;
96 _format = Texture::F_rgba;
97 _component_type = Texture::T_unsigned_byte;
101 _image = tex->do_get_uncompressed_ram_image(cdata);
102 _x_size = cdata->_x_size;
103 _y_size = cdata->_y_size;
104 _z_size = cdata->_z_size;
105 _pixel_width = cdata->_component_width * cdata->_num_components;
106 _format = cdata->_format;
107 _component_type = cdata->_component_type;
115 switch (_component_type) {
116 case Texture::T_unsigned_byte:
117 _get_component = get_unsigned_byte_i;
120 case Texture::T_unsigned_short:
121 _get_component = get_unsigned_short_i;
124 case Texture::T_unsigned_int:
125 _get_component = get_unsigned_int_i;
128 case Texture::T_byte:
129 _get_component = get_signed_byte_i;
132 case Texture::T_short:
133 _get_component = get_signed_short_i;
137 _get_component = get_signed_int_i;
147 switch (_component_type) {
148 case Texture::T_unsigned_byte:
149 _get_component = Texture::get_unsigned_byte;
152 case Texture::T_unsigned_short:
153 _get_component = Texture::get_unsigned_short;
156 case Texture::T_unsigned_int:
157 _get_component = Texture::get_unsigned_int;
160 case Texture::T_float:
161 _get_component = Texture::get_float;
164 case Texture::T_half_float:
165 _get_component = Texture::get_half_float;
168 case Texture::T_unsigned_int_24_8:
169 _get_component = Texture::get_unsigned_int_24;
180 case Texture::F_depth_stencil:
181 case Texture::F_depth_component:
182 case Texture::F_depth_component16:
183 case Texture::F_depth_component24:
184 case Texture::F_depth_component32:
188 case Texture::F_r32i:
189 case Texture::F_r16i:
190 _get_texel = get_texel_r;
193 case Texture::F_green:
194 _get_texel = get_texel_g;
197 case Texture::F_blue:
198 _get_texel = get_texel_b;
201 case Texture::F_alpha:
202 _get_texel = get_texel_a;
205 case Texture::F_luminance:
206 case Texture::F_sluminance:
207 _get_texel = get_texel_l;
210 case Texture::F_luminance_alpha:
211 case Texture::F_sluminance_alpha:
212 case Texture::F_luminance_alphamask:
213 _get_texel = get_texel_la;
217 case Texture::F_rg8i:
218 case Texture::F_rg16:
219 case Texture::F_rg16i:
220 case Texture::F_rg32:
221 case Texture::F_rg32i:
222 _get_texel = get_texel_rg;
226 case Texture::F_rgb5:
227 case Texture::F_rgb8:
228 case Texture::F_rgb8i:
229 case Texture::F_rgb12:
230 case Texture::F_rgb16:
231 case Texture::F_rgb16i:
232 case Texture::F_rgb332:
233 case Texture::F_r11_g11_b10:
234 case Texture::F_rgb9_e5:
235 case Texture::F_rgb32:
236 case Texture::F_rgb32i:
237 _get_texel = get_texel_rgb;
240 case Texture::F_rgba:
241 case Texture::F_rgbm:
242 case Texture::F_rgba4:
243 case Texture::F_rgba5:
244 case Texture::F_rgba8:
245 case Texture::F_rgba8i:
246 case Texture::F_rgba12:
247 case Texture::F_rgba16:
248 case Texture::F_rgba16i:
249 case Texture::F_rgba32:
250 case Texture::F_rgba32i:
251 case Texture::F_rgb10_a2:
252 _get_texel = get_texel_rgba;
255 case Texture::F_srgb:
256 if (_component_type == Texture::T_unsigned_byte) {
257 _get_texel = get_texel_srgb;
260 <<
"sRGB texture should have component type T_unsigned_byte\n";
264 case Texture::F_srgb_alpha:
265 if (_component_type == Texture::T_unsigned_byte) {
266 _get_texel = get_texel_srgba;
269 <<
"sRGB texture should have component type T_unsigned_byte\n";
275 gobj_cat.error() <<
"Unsupported texture peeker format: "
281 _is_cube = (cdata->_texture_type == Texture::TT_cube_map ||
282 cdata->_texture_type == Texture::TT_cube_map_array);
294 lookup(LColor &color, PN_stdfloat u, PN_stdfloat v)
const {
296 int x = int((u - cfloor(u)) * (PN_stdfloat)_x_size) % _x_size;
297 int y = int((v - cfloor(v)) * (PN_stdfloat)_y_size) % _y_size;
314 lookup(LColor &color, PN_stdfloat u, PN_stdfloat v, PN_stdfloat w)
const {
316 int x = int((u - cfloor(u)) * (PN_stdfloat)_x_size) % _x_size;
317 int y = int((v - cfloor(v)) * (PN_stdfloat)_y_size) % _y_size;
318 int z = int((w - cfloor(w)) * (PN_stdfloat)_z_size) % _z_size;
320 nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size &&
321 z >= 0 && z < _z_size);
322 const unsigned char *p = _image.
p() + (z * _x_size * _y_size + y * _x_size + x) * _pixel_width;
324 (*_get_texel)(color, p, _get_component);
327 PN_stdfloat absu = fabs(u),
330 PN_stdfloat magnitude;
331 PN_stdfloat u2d, v2d;
336 if (absw >= absu && absw >= absv) {
338 magnitude = 0.5 / absw;
339 u2d = w < 0.0 ? -u : u;
342 else if (absv >= absu) {
344 magnitude = 0.5 / absv;
346 v2d = v < 0.0 ? -w : w;
350 magnitude = 0.5 / absu;
351 u2d = u < 0.0 ? w : -w;
354 u2d = u2d * magnitude + 0.5;
355 v2d = v2d * magnitude + 0.5;
357 int x = int((u2d - cfloor(u2d)) * (PN_stdfloat)_x_size) % _x_size;
358 int y = int((v2d - cfloor(v2d)) * (PN_stdfloat)_y_size) % _y_size;
369 nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
370 const unsigned char *p = _image.
p() + (y * _x_size + x) * _pixel_width;
371 (*_get_texel)(color, p, _get_component);
379 fetch_pixel(LColor &color,
int x,
int y,
int z)
const {
380 nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size && z >= 0 && z < _z_size);
381 const unsigned char *p = _image.
p() + ((z * _y_size + y) * _x_size + x) * _pixel_width;
382 (*_get_texel)(color, p, _get_component);
394 color = LColor::zero();
396 u = u * _x_size - 0.5;
397 v = v * _y_size - 0.5;
399 int min_u = int(floor(u));
400 int min_v = int(floor(v));
402 PN_stdfloat frac_u = u - min_u;
403 PN_stdfloat frac_v = v - min_v;
405 LColor p00(LColor::zero()), p01(LColor::zero()), p10(LColor::zero()), p11(LColor::zero());
406 PN_stdfloat w00 = 0.0, w01 = 0.0, w10 = 0.0, w11 = 0.0;
409 w00 = (1.0 - frac_v) * (1.0 - frac_u);
413 w10 = (1.0 - frac_v) * frac_u;
417 w01 = frac_v * (1.0 - frac_u);
421 w11 = frac_v * frac_u;
425 PN_stdfloat net_w = w00 + w01 + w10 + w11;
430 color = (p00 * w00 + p01 * w01 + p10 * w10 + p11 * w11) / net_w;
443 PN_stdfloat min_u, PN_stdfloat min_v, PN_stdfloat max_u, PN_stdfloat max_v)
const {
445 init_rect_minmax(min_x, max_x, min_u, max_u, _x_size);
448 init_rect_minmax(min_y, max_y, min_v, max_v, _y_size);
450 color.set(0.0f, 0.0f, 0.0f, 0.0f);
451 PN_stdfloat net = 0.0f;
452 accum_filter_y(color, net, 0,
453 min_x, max_x, min_u, max_u,
454 min_y, max_y, min_v, max_v,
471 PN_stdfloat min_u, PN_stdfloat min_v, PN_stdfloat min_w,
472 PN_stdfloat max_u, PN_stdfloat max_v, PN_stdfloat max_w)
const {
474 init_rect_minmax(min_x, max_x, min_u, max_u, _x_size);
477 init_rect_minmax(min_y, max_y, min_v, max_v, _y_size);
480 init_rect_minmax(min_z, max_z, min_w, max_w, _z_size);
482 color.set(0.0f, 0.0f, 0.0f, 0.0f);
483 PN_stdfloat net = 0.0f;
484 accum_filter_z(color, net,
485 min_x, max_x, min_u, max_u,
486 min_y, max_y, min_v, max_v,
487 min_z, max_z, min_w, max_w);
499 init_rect_minmax(
int &min_x,
int &max_x, PN_stdfloat &min_u, PN_stdfloat &max_u,
502 PN_stdfloat t = min_u;
506 if (max_u - min_u >= 1.0f) {
510 min_x = (int)cfloor(min_u * (PN_stdfloat)x_size);
511 max_x = (int)cceil(max_u * (PN_stdfloat)x_size);
512 nassertv(min_x <= max_x);
519 accum_filter_z(LColor &color, PN_stdfloat &net,
520 int min_x,
int max_x, PN_stdfloat min_u, PN_stdfloat max_u,
521 int min_y,
int max_y, PN_stdfloat min_v, PN_stdfloat max_v,
522 int min_z,
int max_z, PN_stdfloat min_w, PN_stdfloat max_w)
const {
523 nassertv(min_z >= 0 && min_z <= _z_size &&
524 max_z >= 0 && max_z <= _z_size);
527 if (min_z >= max_z - 1) {
529 accum_filter_y(color, net, zi % _z_size,
530 min_x, max_x, min_u, max_u,
531 min_y, max_y, min_v, max_v,
536 PN_stdfloat w = (min_z + 1) - min_w * _z_size;
537 accum_filter_y(color, net, zi % _z_size,
538 min_x, max_x, min_u, max_u,
539 min_y, max_y, min_v, max_v,
546 accum_filter_y(color, net, zi % _z_size,
547 min_x, max_x, min_u, max_u,
548 min_y, max_y, min_v, max_v,
554 w = max_w * _z_size - (max_z - 1);
555 accum_filter_y(color, net, zi % _z_size,
556 min_x, max_x, min_u, max_u,
557 min_y, max_y, min_v, max_v,
566 accum_filter_y(LColor &color, PN_stdfloat &net,
int zi,
567 int min_x,
int max_x, PN_stdfloat min_u, PN_stdfloat max_u,
568 int min_y,
int max_y, PN_stdfloat min_v, PN_stdfloat max_v,
569 PN_stdfloat weight)
const {
570 nassertv(zi >= 0 && zi < _z_size);
571 nassertv(min_y >= 0 && min_y <= _y_size &&
572 max_y >= 0 && max_y <= _y_size);
575 if (min_y >= max_y - 1) {
577 accum_filter_x(color, net, yi % _y_size, zi, min_x, max_x, min_u, max_u, weight);
581 PN_stdfloat w = (min_y + 1) - min_v * _y_size;
582 accum_filter_x(color, net, yi % _y_size, zi, min_x, max_x, min_u, max_u, weight * w);
588 accum_filter_x(color, net, yi % _y_size, zi, min_x, max_x, min_u, max_u, weight);
593 w = max_v * _y_size - (max_y - 1);
594 accum_filter_x(color, net, yi % _y_size, zi, min_x, max_x, min_u, max_u, weight * w);
602 accum_filter_x(LColor &color, PN_stdfloat &net,
int yi,
int zi,
603 int min_x,
int max_x, PN_stdfloat min_u, PN_stdfloat max_u,
604 PN_stdfloat weight)
const {
605 nassertv(yi >= 0 && yi < _y_size && zi >= 0 && zi < _z_size);
606 nassertv(min_x >= 0 && min_x <= _x_size &&
607 max_x >= 0 && max_x <= _x_size);
610 int xi = min_x % _x_size;
611 const unsigned char *p = _image.
p() + (zi * _x_size * _y_size + yi * _x_size + xi) * _pixel_width;
613 if (min_x >= max_x - 1) {
615 accum_texel(color, net, p, weight);
619 PN_stdfloat w = (min_x + 1) - min_u * _x_size;
620 accum_texel(color, net, p, weight * w);
628 p = _image.
p() + (zi * _x_size * _y_size + yi * _x_size + xi) * _pixel_width;
631 accum_texel(color, net, p, weight);
638 p = _image.
p() + (zi * _x_size * _y_size + yi * _x_size + xi) * _pixel_width;
640 w = max_u * _x_size - (max_x - 1);
641 accum_texel(color, net, p, weight * w);
649 accum_texel(LColor &color, PN_stdfloat &net,
const unsigned char *&p, PN_stdfloat weight)
const {
651 (*_get_texel)(c, p, _get_component);
661 get_texel_r(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
662 color[0] = (*get_component)(p);
673 get_texel_g(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
675 color[1] = (*get_component)(p);
685 get_texel_b(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
688 color[2] = (*get_component)(p);
697 get_texel_a(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
701 color[3] = (*get_component)(p);
709 get_texel_l(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
710 color[0] = (*get_component)(p);
721 get_texel_la(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
722 color[0] = (*get_component)(p);
725 color[3] = (*get_component)(p);
733 get_texel_rg(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
734 color[0] = (*get_component)(p);
735 color[1] = (*get_component)(p);
745 get_texel_rgb(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
746 color[2] = (*get_component)(p);
747 color[1] = (*get_component)(p);
748 color[0] = (*get_component)(p);
757 get_texel_rgba(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
758 color[2] = (*get_component)(p);
759 color[1] = (*get_component)(p);
760 color[0] = (*get_component)(p);
761 color[3] = (*get_component)(p);
769 get_texel_srgb(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
781 get_texel_srgba(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
785 color[3] = (*get_component)(p);
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
void clear()
To empty the PTA, use the clear() method, since assignment to NULL is problematic (given the ambiguit...
constexpr bool is_null() const
Returns true if the PointerTo is a NULL pointer, false otherwise.
void lookup(LColor &color, PN_stdfloat u, PN_stdfloat v) const
Fills "color" with the RGBA color of the texel at point (u, v).
void fetch_pixel(LColor &color, int x, int y) const
Works like TexturePeeker::lookup(), but instead uv-coordinates integer coordinates are used.
bool has_pixel(int x, int y) const
Returns whether a given coordinate is inside of the texture dimensions.
bool lookup_bilinear(LColor &color, PN_stdfloat u, PN_stdfloat v) const
Performs a bilinear lookup to retrieve the color value stored at the uv coordinate (u,...
void filter_rect(LColor &color, PN_stdfloat min_u, PN_stdfloat min_v, PN_stdfloat max_u, PN_stdfloat max_v) const
Fills "color" with the average RGBA color of the texels within the rectangle defined by the specified...
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
static bool is_integer(Format format)
Returns true if the indicated format is an integer format, false otherwise.
static std::string format_format(Format f)
Returns the indicated Format converted to a string word.
BEGIN_PUBLISH EXPCL_PANDA_PNMIMAGE float decode_sRGB_float(unsigned char val)
Decodes the sRGB-encoded unsigned char value to a linearized float in the range 0-1.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.