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;
71 if (_image.is_null()) {
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);