fix sampling issue

This commit is contained in:
Bigfoot71 2025-09-29 03:41:12 +02:00
parent a5dd7e3ce7
commit fdb6334d5e

61
src/external/rlsw.h vendored
View File

@ -2109,36 +2109,50 @@ static inline void sw_get_pixel(float* color, const void* pixels, uint32_t offse
/* === Texture Sampling Part === */ /* === Texture Sampling Part === */
static inline void sw_texture_map(int* out, float in, int max, SWwrap mode)
{
switch (mode) {
case SW_REPEAT:
*out = (int)(sw_fract(in) * max + 0.5f);
break;
case SW_CLAMP:
*out = (int)(sw_saturate(in) * max + 0.5f);
break;
}
}
static inline void sw_texture_sample_nearest(float* color, const sw_texture_t* tex, float u, float v) static inline void sw_texture_sample_nearest(float* color, const sw_texture_t* tex, float u, float v)
{ {
int x, y; u = (tex->sWrap == SW_REPEAT) ? sw_fract(u) : sw_saturate(u);
sw_texture_map(&x, u, tex->wMinus1, tex->sWrap); v = (tex->tWrap == SW_REPEAT) ? sw_fract(v) : sw_saturate(v);
sw_texture_map(&y, v, tex->hMinus1, tex->tWrap);
int x = u * tex->width, y = v * tex->height;
sw_get_pixel(color, tex->pixels.cptr, y * tex->width + x, tex->format); sw_get_pixel(color, tex->pixels.cptr, y * tex->width + x, tex->format);
} }
static inline void sw_texture_sample_linear(float* color, const sw_texture_t* tex, float u, float v) static inline void sw_texture_sample_linear(float* color, const sw_texture_t* tex, float u, float v)
{ {
float uScaled = u * tex->wMinus1; // REVIEW: With a bit more cleverness we could clearly reduce the
float vScaled = v * tex->hMinus1; // number of operations here, but for now it works fine.
int x0, y0, x1, y1; float xf = u * tex->width - 0.5f;
sw_texture_map(&x0, u, tex->wMinus1, tex->sWrap); float yf = v * tex->height - 0.5f;
sw_texture_map(&y0, v, tex->hMinus1, tex->tWrap);
sw_texture_map(&x1, u + tex->tx, tex->wMinus1, tex->sWrap); int x0 = (int)floorf(xf);
sw_texture_map(&y1, v + tex->ty, tex->hMinus1, tex->tWrap); int y0 = (int)floorf(yf);
float fx = xf - x0;
float fy = yf - y0;
int x1 = x0 + 1;
int y1 = y0 + 1;
if (tex->sWrap == SW_CLAMP) {
x0 = x0 > tex->wMinus1 ? tex->wMinus1 : x0;
x1 = x1 > tex->wMinus1 ? tex->wMinus1 : x1;
}
else {
x0 = (x0 % tex->width + tex->width) % tex->width;
x1 = (x1 % tex->width + tex->width) % tex->width;
}
if (tex->tWrap == SW_CLAMP) {
y0 = y0 > tex->hMinus1 ? tex->hMinus1 : y0;
y1 = y1 > tex->hMinus1 ? tex->hMinus1 : y1;
}
else {
y0 = (y0 % tex->height + tex->height) % tex->height;
y1 = (y1 % tex->height + tex->height) % tex->height;
}
float c00[4], c10[4], c01[4], c11[4]; float c00[4], c10[4], c01[4], c11[4];
sw_get_pixel(c00, tex->pixels.cptr, y0 * tex->width + x0, tex->format); sw_get_pixel(c00, tex->pixels.cptr, y0 * tex->width + x0, tex->format);
@ -2146,9 +2160,6 @@ static inline void sw_texture_sample_linear(float* color, const sw_texture_t* te
sw_get_pixel(c01, tex->pixels.cptr, y1 * tex->width + x0, tex->format); sw_get_pixel(c01, tex->pixels.cptr, y1 * tex->width + x0, tex->format);
sw_get_pixel(c11, tex->pixels.cptr, y1 * tex->width + x1, tex->format); sw_get_pixel(c11, tex->pixels.cptr, y1 * tex->width + x1, tex->format);
float fx = uScaled - floorf(uScaled);
float fy = vScaled - floorf(vScaled);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
float t = c00[i] + fx * (c10[i] - c00[i]); float t = c00[i] + fx * (c10[i] - c00[i]);
float b = c01[i] + fx * (c11[i] - c01[i]); float b = c01[i] + fx * (c11[i] - c01[i]);