mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -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 {
|
||||
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 {
|
||||
int x = int((u - cfloor(u)) * (PN_stdfloat)_x_size) % _x_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);
|
||||
const unsigned char *p = _image.p() + (y * _x_size + x) * _pixel_width;
|
||||
|
||||
(*_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).
|
||||
*
|
||||
|
@ -36,8 +36,11 @@ PUBLISHED:
|
||||
INLINE int get_y_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, 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,
|
||||
PN_stdfloat min_u, PN_stdfloat min_v,
|
||||
PN_stdfloat max_u, PN_stdfloat max_v) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user