24 TexturePeeker(
Texture *tex, Texture::CData *cdata) {
25 if (cdata->_texture_type == Texture::TT_cube_map) {
35 if (tex->do_has_ram_image(cdata) && cdata->_ram_image_compression == Texture::CM_off) {
37 _image = tex->do_get_ram_image(cdata);
38 _x_size = cdata->_x_size;
39 _y_size = cdata->_y_size;
40 _z_size = cdata->_z_size;
41 _component_width = cdata->_component_width;
42 _num_components = cdata->_num_components;
43 _format = cdata->_format;
44 _component_type = cdata->_component_type;
46 }
else if (!cdata->_simple_ram_image._image.empty()) {
48 _image = cdata->_simple_ram_image._image;
49 _x_size = cdata->_simple_x_size;
50 _y_size = cdata->_simple_y_size;
55 _format = Texture::F_rgba;
56 _component_type = Texture::T_unsigned_byte;
60 _image = tex->do_get_uncompressed_ram_image(cdata);
61 _x_size = cdata->_x_size;
62 _y_size = cdata->_y_size;
63 _z_size = cdata->_z_size;
64 _component_width = cdata->_component_width;
65 _num_components = cdata->_num_components;
66 _format = cdata->_format;
67 _component_type = cdata->_component_type;
74 _pixel_width = _component_width * _num_components;
76 switch (_component_type) {
77 case Texture::T_unsigned_byte:
78 _get_component = Texture::get_unsigned_byte;
81 case Texture::T_unsigned_short:
82 _get_component = Texture::get_unsigned_short;
85 case Texture::T_unsigned_int:
86 _get_component = Texture::get_unsigned_int;
89 case Texture::T_float:
90 _get_component = Texture::get_float;
93 case Texture::T_half_float:
94 _get_component = Texture::get_half_float;
97 case Texture::T_unsigned_int_24_8:
98 _get_component = Texture::get_unsigned_int_24;
108 case Texture::F_depth_stencil:
109 case Texture::F_depth_component:
110 case Texture::F_depth_component16:
111 case Texture::F_depth_component24:
112 case Texture::F_depth_component32:
116 case Texture::F_r32i:
117 _get_texel = get_texel_r;
120 case Texture::F_green:
121 _get_texel = get_texel_g;
124 case Texture::F_blue:
125 _get_texel = get_texel_b;
128 case Texture::F_alpha:
129 _get_texel = get_texel_a;
132 case Texture::F_luminance:
133 case Texture::F_sluminance:
134 _get_texel = get_texel_l;
137 case Texture::F_luminance_alpha:
138 case Texture::F_sluminance_alpha:
139 case Texture::F_luminance_alphamask:
140 _get_texel = get_texel_la;
143 case Texture::F_rg16:
144 case Texture::F_rg32:
146 _get_texel = get_texel_rg;
150 case Texture::F_rgb5:
151 case Texture::F_rgb8:
152 case Texture::F_rgb12:
153 case Texture::F_rgb16:
154 case Texture::F_rgb332:
155 case Texture::F_r11_g11_b10:
156 case Texture::F_rgb9_e5:
157 case Texture::F_rgb32:
158 _get_texel = get_texel_rgb;
161 case Texture::F_rgba:
162 case Texture::F_rgbm:
163 case Texture::F_rgba4:
164 case Texture::F_rgba5:
165 case Texture::F_rgba8:
166 case Texture::F_rgba12:
167 case Texture::F_rgba16:
168 case Texture::F_rgba32:
169 case Texture::F_rgb10_a2:
170 _get_texel = get_texel_rgba;
173 case Texture::F_srgb:
174 if (_component_type == Texture::T_unsigned_byte) {
175 _get_texel = get_texel_srgb;
178 <<
"sRGB texture should have component type T_unsigned_byte\n";
182 case Texture::F_srgb_alpha:
183 if (_component_type == Texture::T_unsigned_byte) {
184 _get_texel = get_texel_srgba;
187 <<
"sRGB texture should have component type T_unsigned_byte\n";
193 gobj_cat.error() <<
"Unsupported texture peeker format: " 210 lookup(LColor &color, PN_stdfloat u, PN_stdfloat v)
const {
211 int x = int((u - cfloor(u)) * (PN_stdfloat)_x_size) % _x_size;
212 int y = int((v - cfloor(v)) * (PN_stdfloat)_y_size) % _y_size;
222 nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
223 const unsigned char *p = _image.
p() + (y * _x_size + x) * _pixel_width;
224 (*_get_texel)(color, p, _get_component);
237 color = LColor::zero();
239 u = u * _x_size - 0.5;
240 v = v * _y_size - 0.5;
242 int min_u = int(floor(u));
243 int min_v = int(floor(v));
245 PN_stdfloat frac_u = u - min_u;
246 PN_stdfloat frac_v = v - min_v;
248 LColor p00(LColor::zero()), p01(LColor::zero()), p10(LColor::zero()), p11(LColor::zero());
249 PN_stdfloat w00 = 0.0, w01 = 0.0, w10 = 0.0, w11 = 0.0;
252 w00 = (1.0 - frac_v) * (1.0 - frac_u);
256 w10 = (1.0 - frac_v) * frac_u;
260 w01 = frac_v * (1.0 - frac_u);
264 w11 = frac_v * frac_u;
268 PN_stdfloat net_w = w00 + w01 + w10 + w11;
273 color = (p00 * w00 + p01 * w01 + p10 * w10 + p11 * w11) / net_w;
286 lookup(LColor &color, PN_stdfloat u, PN_stdfloat v, PN_stdfloat w)
const {
287 int x = int((u - cfloor(u)) * (PN_stdfloat)_x_size) % _x_size;
288 int y = int((v - cfloor(v)) * (PN_stdfloat)_y_size) % _y_size;
289 int z = int((w - cfloor(w)) * (PN_stdfloat)_z_size) % _z_size;
291 nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size &&
292 z >= 0 && z < _z_size);
293 const unsigned char *p = _image.
p() + (z * _x_size * _y_size + y * _x_size + x) * _pixel_width;
295 (*_get_texel)(color, p, _get_component);
307 PN_stdfloat min_u, PN_stdfloat min_v, PN_stdfloat max_u, PN_stdfloat max_v)
const {
309 init_rect_minmax(min_x, max_x, min_u, max_u, _x_size);
312 init_rect_minmax(min_y, max_y, min_v, max_v, _y_size);
314 color.set(0.0f, 0.0f, 0.0f, 0.0f);
315 PN_stdfloat net = 0.0f;
316 accum_filter_y(color, net, 0,
317 min_x, max_x, min_u, max_u,
318 min_y, max_y, min_v, max_v,
335 PN_stdfloat min_u, PN_stdfloat min_v, PN_stdfloat min_w,
336 PN_stdfloat max_u, PN_stdfloat max_v, PN_stdfloat max_w)
const {
338 init_rect_minmax(min_x, max_x, min_u, max_u, _x_size);
341 init_rect_minmax(min_y, max_y, min_v, max_v, _y_size);
344 init_rect_minmax(min_z, max_z, min_w, max_w, _z_size);
346 color.set(0.0f, 0.0f, 0.0f, 0.0f);
347 PN_stdfloat net = 0.0f;
348 accum_filter_z(color, net,
349 min_x, max_x, min_u, max_u,
350 min_y, max_y, min_v, max_v,
351 min_z, max_z, min_w, max_w);
363 init_rect_minmax(
int &min_x,
int &max_x, PN_stdfloat &min_u, PN_stdfloat &max_u,
366 PN_stdfloat t = min_u;
370 if (max_u - min_u >= 1.0f) {
374 min_x = (int)cfloor(min_u * (PN_stdfloat)x_size);
375 max_x = (int)cceil(max_u * (PN_stdfloat)x_size);
376 nassertv(min_x <= max_x);
383 accum_filter_z(LColor &color, PN_stdfloat &net,
384 int min_x,
int max_x, PN_stdfloat min_u, PN_stdfloat max_u,
385 int min_y,
int max_y, PN_stdfloat min_v, PN_stdfloat max_v,
386 int min_z,
int max_z, PN_stdfloat min_w, PN_stdfloat max_w)
const {
387 nassertv(min_z >= 0 && min_z <= _z_size &&
388 max_z >= 0 && max_z <= _z_size);
391 if (min_z >= max_z - 1) {
393 accum_filter_y(color, net, zi % _z_size,
394 min_x, max_x, min_u, max_u,
395 min_y, max_y, min_v, max_v,
400 PN_stdfloat w = (min_z + 1) - min_w * _z_size;
401 accum_filter_y(color, net, zi % _z_size,
402 min_x, max_x, min_u, max_u,
403 min_y, max_y, min_v, max_v,
410 accum_filter_y(color, net, zi % _z_size,
411 min_x, max_x, min_u, max_u,
412 min_y, max_y, min_v, max_v,
418 w = max_w * _z_size - (max_z - 1);
419 accum_filter_y(color, net, zi % _z_size,
420 min_x, max_x, min_u, max_u,
421 min_y, max_y, min_v, max_v,
430 accum_filter_y(LColor &color, PN_stdfloat &net,
int zi,
431 int min_x,
int max_x, PN_stdfloat min_u, PN_stdfloat max_u,
432 int min_y,
int max_y, PN_stdfloat min_v, PN_stdfloat max_v,
433 PN_stdfloat weight)
const {
434 nassertv(zi >= 0 && zi < _z_size);
435 nassertv(min_y >= 0 && min_y <= _y_size &&
436 max_y >= 0 && max_y <= _y_size);
439 if (min_y >= max_y - 1) {
441 accum_filter_x(color, net, yi % _y_size, zi, min_x, max_x, min_u, max_u, weight);
445 PN_stdfloat w = (min_y + 1) - min_v * _y_size;
446 accum_filter_x(color, net, yi % _y_size, zi, min_x, max_x, min_u, max_u, weight * w);
452 accum_filter_x(color, net, yi % _y_size, zi, min_x, max_x, min_u, max_u, weight);
457 w = max_v * _y_size - (max_y - 1);
458 accum_filter_x(color, net, yi % _y_size, zi, min_x, max_x, min_u, max_u, weight * w);
466 accum_filter_x(LColor &color, PN_stdfloat &net,
int yi,
int zi,
467 int min_x,
int max_x, PN_stdfloat min_u, PN_stdfloat max_u,
468 PN_stdfloat weight)
const {
469 nassertv(yi >= 0 && yi < _y_size && zi >= 0 && zi < _z_size);
470 nassertv(min_x >= 0 && min_x <= _x_size &&
471 max_x >= 0 && max_x <= _x_size);
474 int xi = min_x % _x_size;
475 const unsigned char *p = _image.
p() + (zi * _x_size * _y_size + yi * _x_size + xi) * _pixel_width;
477 if (min_x >= max_x - 1) {
479 accum_texel(color, net, p, weight);
483 PN_stdfloat w = (min_x + 1) - min_u * _x_size;
484 accum_texel(color, net, p, weight * w);
492 p = _image.
p() + (zi * _x_size * _y_size + yi * _x_size + xi) * _pixel_width;
495 accum_texel(color, net, p, weight);
502 p = _image.
p() + (zi * _x_size * _y_size + yi * _x_size + xi) * _pixel_width;
504 w = max_u * _x_size - (max_x - 1);
505 accum_texel(color, net, p, weight * w);
513 accum_texel(LColor &color, PN_stdfloat &net,
const unsigned char *&p, PN_stdfloat weight)
const {
515 (*_get_texel)(c, p, _get_component);
525 get_texel_r(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
526 color[0] = (*get_component)(p);
537 get_texel_g(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
539 color[1] = (*get_component)(p);
549 get_texel_b(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
552 color[2] = (*get_component)(p);
561 get_texel_a(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
565 color[3] = (*get_component)(p);
573 get_texel_l(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
574 color[0] = (*get_component)(p);
585 get_texel_la(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
586 color[0] = (*get_component)(p);
589 color[3] = (*get_component)(p);
597 get_texel_rg(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
598 color[0] = (*get_component)(p);
599 color[1] = (*get_component)(p);
609 get_texel_rgb(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
610 color[2] = (*get_component)(p);
611 color[1] = (*get_component)(p);
612 color[0] = (*get_component)(p);
621 get_texel_rgba(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
622 color[2] = (*get_component)(p);
623 color[1] = (*get_component)(p);
624 color[0] = (*get_component)(p);
625 color[3] = (*get_component)(p);
633 get_texel_srgb(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
645 get_texel_srgba(LColor &color,
const unsigned char *&p, GetComponentFunc *get_component) {
649 color[3] = (*get_component)(p);
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static std::string format_format(Format f)
Returns the indicated Format converted to a string word.
constexpr bool is_null() const
Returns true if the PointerTo is a NULL pointer, false otherwise.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
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.
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.
bool has_pixel(int x, int y) const
Returns whether a given coordinate is inside of the texture dimensions.
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...
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...
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,...