mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
Add bilinear filtering to TexturePeeker
This commit is contained in:
parent
862f0e4db2
commit
1c9985d2f7
@ -48,3 +48,11 @@ INLINE int TexturePeeker::
|
|||||||
get_z_size() const {
|
get_z_size() const {
|
||||||
return _z_size;
|
return _z_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a given coordinate is inside of the texture dimensions.
|
||||||
|
*/
|
||||||
|
INLINE bool TexturePeeker::
|
||||||
|
has_pixel(size_t x, size_t y) const {
|
||||||
|
return x >= 0 && y >= 0 && x < _x_size && y < _y_size;
|
||||||
|
}
|
||||||
|
@ -168,13 +168,70 @@ void TexturePeeker::
|
|||||||
lookup(LColor &color, PN_stdfloat u, PN_stdfloat v) const {
|
lookup(LColor &color, PN_stdfloat u, PN_stdfloat v) const {
|
||||||
int x = int((u - cfloor(u)) * (PN_stdfloat)_x_size) % _x_size;
|
int x = int((u - cfloor(u)) * (PN_stdfloat)_x_size) % _x_size;
|
||||||
int y = int((v - cfloor(v)) * (PN_stdfloat)_y_size) % _y_size;
|
int y = int((v - cfloor(v)) * (PN_stdfloat)_y_size) % _y_size;
|
||||||
|
fetch_pixel(color, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Works like TexturePeeker::lookup(), but instead uv-coordinates integer
|
||||||
|
* coordinates are used.
|
||||||
|
*/
|
||||||
|
void TexturePeeker::
|
||||||
|
fetch_pixel(LColor& color, size_t x, size_t y) const {
|
||||||
nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
|
nassertv(x >= 0 && x < _x_size && y >= 0 && y < _y_size);
|
||||||
const unsigned char *p = _image.p() + (y * _x_size + x) * _pixel_width;
|
const unsigned char *p = _image.p() + (y * _x_size + x) * _pixel_width;
|
||||||
|
|
||||||
(*_get_texel)(color, p, _get_component);
|
(*_get_texel)(color, p, _get_component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a bilinear lookup to retrieve the color value stored at the uv
|
||||||
|
* coordinate (u, v).
|
||||||
|
*
|
||||||
|
* In case the point is outside of the uv range, color is set to zero,
|
||||||
|
* and false is returned. Otherwise true is returned.
|
||||||
|
*/
|
||||||
|
bool TexturePeeker::
|
||||||
|
lookup_bilinear(LColor &color, PN_stdfloat u, PN_stdfloat v) const {
|
||||||
|
color = LColor::zero();
|
||||||
|
|
||||||
|
u = u * _x_size - 0.5;
|
||||||
|
v = v * _y_size - 0.5;
|
||||||
|
|
||||||
|
int min_u = int(floor(u));
|
||||||
|
int min_v = int(floor(v));
|
||||||
|
|
||||||
|
PN_stdfloat frac_u = u - min_u;
|
||||||
|
PN_stdfloat frac_v = v - min_v;
|
||||||
|
|
||||||
|
LColor p00(LColor::zero()), p01(LColor::zero()), p10(LColor::zero()), p11(LColor::zero());
|
||||||
|
PN_stdfloat w00 = 0.0, w01 = 0.0, w10 = 0.0, w11 = 0.0;
|
||||||
|
|
||||||
|
if (has_pixel(min_u, min_v)) {
|
||||||
|
w00 = (1.0 - frac_v) * (1.0 - frac_u);
|
||||||
|
fetch_pixel(p00, min_u, min_v);
|
||||||
|
}
|
||||||
|
if (has_pixel(min_u + 1, min_v)) {
|
||||||
|
w10 = (1.0 - frac_v) * frac_u;
|
||||||
|
fetch_pixel(p10, min_u + 1, min_v);
|
||||||
|
}
|
||||||
|
if (has_pixel(min_u, min_v + 1)) {
|
||||||
|
w01 = frac_v * (1.0 - frac_u);
|
||||||
|
fetch_pixel(p01, min_u, min_v + 1);
|
||||||
|
}
|
||||||
|
if (has_pixel(min_u + 1, min_v + 1)) {
|
||||||
|
w11 = frac_v * frac_u;
|
||||||
|
fetch_pixel(p11, min_u + 1, min_v + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
PN_stdfloat net_w = w00 + w01 + w10 + w11;
|
||||||
|
if (net_w == 0.0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
color = (p00 * w00 + p01 * w01 + p10 * w10 + p11 * w11) / net_w;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills "color" with the RGBA color of the texel at point (u, v, w).
|
* Fills "color" with the RGBA color of the texel at point (u, v, w).
|
||||||
*
|
*
|
||||||
|
@ -36,8 +36,11 @@ PUBLISHED:
|
|||||||
INLINE int get_y_size() const;
|
INLINE int get_y_size() const;
|
||||||
INLINE int get_z_size() const;
|
INLINE int get_z_size() const;
|
||||||
|
|
||||||
|
INLINE bool has_pixel(size_t x, size_t y) const;
|
||||||
void lookup(LColor &color, PN_stdfloat u, PN_stdfloat v) const;
|
void lookup(LColor &color, PN_stdfloat u, PN_stdfloat v) const;
|
||||||
void lookup(LColor &color, PN_stdfloat u, PN_stdfloat v, PN_stdfloat w) const;
|
void lookup(LColor &color, PN_stdfloat u, PN_stdfloat v, PN_stdfloat w) const;
|
||||||
|
void fetch_pixel(LColor &color, size_t x, size_t y) const;
|
||||||
|
bool lookup_bilinear(LColor &color, PN_stdfloat u, PN_stdfloat v) const;
|
||||||
void filter_rect(LColor &color,
|
void filter_rect(LColor &color,
|
||||||
PN_stdfloat min_u, PN_stdfloat min_v,
|
PN_stdfloat min_u, PN_stdfloat min_v,
|
||||||
PN_stdfloat max_u, PN_stdfloat max_v) const;
|
PN_stdfloat max_u, PN_stdfloat max_v) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user