experiment with texture filtering

This commit is contained in:
David Rose 2008-05-05 21:02:21 +00:00
parent a88673a24a
commit b226cf6f5d
4 changed files with 71 additions and 25 deletions

View File

@ -35,10 +35,10 @@ void gl_transform_to_viewport(GLContext *c,GLVertex *v)
/* texture */ /* texture */
if (c->texture_2d_enabled) { if (c->texture_2d_enabled) {
v->zp.s=(int)(v->tex_coord.X * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) v->zp.s=(int)(v->tex_coord.X * (ZB_POINT_ST_MAX - ZB_POINT_ST_MIN)
+ ZB_POINT_S_MIN); + ZB_POINT_ST_MIN);
v->zp.t=(int)(v->tex_coord.Y * (ZB_POINT_T_MAX - ZB_POINT_T_MIN) v->zp.t=(int)(v->tex_coord.Y * (ZB_POINT_ST_MAX - ZB_POINT_ST_MIN)
+ ZB_POINT_T_MIN); + ZB_POINT_ST_MIN);
} }
} }

View File

@ -340,3 +340,36 @@ void ZB_clear_viewport(ZBuffer * zb, int clear_z, int z,
} }
} }
} }
#define ZB_ST_FRAC_HIGH (1 << ZB_POINT_ST_FRAC_BITS)
#define ZB_ST_FRAC_MASK (ZB_ST_FRAC_HIGH - 1)
PIXEL lookup_texture_bilinear(PIXEL *texture, int s, int t)
{
PIXEL p1, p2, p3, p4;
int sf, tf;
int r, g, b, a;
p1 = ZB_LOOKUP_TEXTURE_NEAREST(texture, s, t);
p2 = ZB_LOOKUP_TEXTURE_NEAREST(texture, s + ZB_ST_FRAC_HIGH, t);
sf = s & ZB_ST_FRAC_MASK;
p3 = ZB_LOOKUP_TEXTURE_NEAREST(texture, s, t + ZB_ST_FRAC_HIGH);
p4 = ZB_LOOKUP_TEXTURE_NEAREST(texture, s + ZB_ST_FRAC_HIGH, t + ZB_ST_FRAC_HIGH);
tf = t & ZB_ST_FRAC_MASK;
r = (((PIXEL_R(p4) * sf + PIXEL_R(p3) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * tf +
((PIXEL_R(p2) * sf + PIXEL_R(p1) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * (ZB_ST_FRAC_HIGH - tf)) >> ZB_POINT_ST_FRAC_BITS;
g = (((PIXEL_G(p4) * sf + PIXEL_G(p3) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * tf +
((PIXEL_G(p2) * sf + PIXEL_G(p1) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * (ZB_ST_FRAC_HIGH - tf)) >> ZB_POINT_ST_FRAC_BITS;
b = (((PIXEL_B(p4) * sf + PIXEL_B(p3) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * tf +
((PIXEL_B(p2) * sf + PIXEL_B(p1) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * (ZB_ST_FRAC_HIGH - tf)) >> ZB_POINT_ST_FRAC_BITS;
a = (((PIXEL_A(p4) * sf + PIXEL_A(p3) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * tf +
((PIXEL_A(p2) * sf + PIXEL_A(p1) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * (ZB_ST_FRAC_HIGH - tf)) >> ZB_POINT_ST_FRAC_BITS;
return RGBA_TO_PIXEL(r, g, b, a);
}

View File

@ -18,25 +18,36 @@
/* The number of fractional bits below the S and T texture coords. /* The number of fractional bits below the S and T texture coords.
The more we have, the more precise the texel calculation will be The more we have, the more precise the texel calculation will be
when we zoom into small details of a texture; but the greater when we zoom into small details of a texture; but the greater
chance we'll overflow our 32-bit integer if the T texcoord gets chance we might overflow our 32-bit integer. */
large. */ #define ZB_POINT_ST_FRAC_BITS 12
#define ZB_POINT_ST_FRAC_BITS 10
/* Various parameters and accessors based on the above bits. */ /* Various parameters and accessors based on the above bits. */
#define ZB_POINT_S_LOW ZB_POINT_ST_FRAC_BITS #define ZB_POINT_ST_MIN 0
#define ZB_POINT_S_MIN 0 #define ZB_POINT_ST_MAX (1 << (ZB_POINT_ST_BITS + ZB_POINT_ST_FRAC_BITS))
#define ZB_POINT_S_MAX (1 << (ZB_POINT_ST_BITS + ZB_POINT_S_LOW)) #define ZB_POINT_ST_MASK ((1 << (ZB_POINT_ST_BITS + ZB_POINT_ST_FRAC_BITS)) - (1 << ZB_POINT_ST_FRAC_BITS))
#define ZB_POINT_S_MASK ((1 << (ZB_POINT_ST_BITS + ZB_POINT_S_LOW)) - (1 << ZB_POINT_S_LOW))
#define ZB_POINT_T_LOW (ZB_POINT_ST_BITS + ZB_POINT_S_LOW) /* Returns the index within a 256x256 texture for the given (s, t)
#define ZB_POINT_T_MIN 0 texel. */
#define ZB_POINT_T_MAX (1 << (ZB_POINT_ST_BITS + ZB_POINT_T_LOW))
#define ZB_POINT_T_MASK ((1 << (ZB_POINT_ST_BITS + ZB_POINT_T_LOW)) - (1 << ZB_POINT_T_LOW))
// Returns the index within a 256x256 texture for the given (s, t)
// texel.
#define ZB_TEXEL(s, t) \ #define ZB_TEXEL(s, t) \
((((t) & ZB_POINT_T_MASK) | ((s) & ZB_POINT_S_MASK)) >> ZB_POINT_ST_FRAC_BITS) ((((t) & ZB_POINT_ST_MASK) >> (ZB_POINT_ST_FRAC_BITS - ZB_POINT_ST_BITS)) | \
(((s) & ZB_POINT_ST_MASK) >> ZB_POINT_ST_FRAC_BITS))
#define ZB_LOOKUP_TEXTURE_NEAREST(texture, s, t) \
(texture)[ZB_TEXEL(s, t)]
#if 1
/* Use no texture filtering by default. It's faster, even though it
looks terrible. */
#define ZB_LOOKUP_TEXTURE(texture, s, t) \
ZB_LOOKUP_TEXTURE_NEAREST(texture, s, t)
#else
/* Experiment with bilinear filtering. Looks great, but seems to run
about 25% slower. */
#define ZB_LOOKUP_TEXTURE(texture, s, t) \
lookup_texture_bilinear((texture), (s), (t))
#endif
#define ZB_POINT_RED_MIN 0x0000 #define ZB_POINT_RED_MIN 0x0000
#define ZB_POINT_RED_MAX 0xffff #define ZB_POINT_RED_MAX 0xffff
@ -122,6 +133,8 @@ void ZB_clear_viewport(ZBuffer * zb, int clear_z, int z,
int clear_color, int r, int g, int b, int a, int clear_color, int r, int g, int b, int a,
int xmin, int ymin, int xsize, int ysize); int xmin, int ymin, int xsize, int ysize);
PIXEL lookup_texture_bilinear(PIXEL *texture, int s, int t);
/* linesize is in BYTES */ /* linesize is in BYTES */
void ZB_copyFrameBuffer(ZBuffer *zb,void *buf,int linesize); void ZB_copyFrameBuffer(ZBuffer *zb,void *buf,int linesize);

View File

@ -82,7 +82,7 @@ void FNAME(ZB_fillTriangleMapping) (ZBuffer *zb,
{ \ { \
zz=z >> ZB_POINT_Z_FRAC_BITS; \ zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(pz[_a], zz)) { \ if (ZCMP(pz[_a], zz)) { \
tmp = texture[ZB_TEXEL(s, t)]; \ tmp = ZB_LOOKUP_TEXTURE(texture, s, t); \
if (ACMP(zb, PIXEL_A(tmp))) { \ if (ACMP(zb, PIXEL_A(tmp))) { \
STORE_PIX(pp[_a], tmp, PIXEL_R(tmp), PIXEL_G(tmp), PIXEL_B(tmp), PIXEL_A(tmp)); \ STORE_PIX(pp[_a], tmp, PIXEL_R(tmp), PIXEL_G(tmp), PIXEL_B(tmp), PIXEL_A(tmp)); \
STORE_Z(pz[_a], zz); \ STORE_Z(pz[_a], zz); \
@ -118,7 +118,7 @@ void FNAME(ZB_fillTriangleMappingFlat) (ZBuffer *zb,
{ \ { \
zz=z >> ZB_POINT_Z_FRAC_BITS; \ zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(pz[_a], zz)) { \ if (ZCMP(pz[_a], zz)) { \
tmp = texture[ZB_TEXEL(s, t)]; \ tmp = ZB_LOOKUP_TEXTURE(texture, s, t); \
int a = oa * PIXEL_A(tmp) >> 16; \ int a = oa * PIXEL_A(tmp) >> 16; \
if (ACMP(zb, a)) { \ if (ACMP(zb, a)) { \
STORE_PIX(pp[_a], \ STORE_PIX(pp[_a], \
@ -159,7 +159,7 @@ void FNAME(ZB_fillTriangleMappingSmooth) (ZBuffer *zb,
{ \ { \
zz=z >> ZB_POINT_Z_FRAC_BITS; \ zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(pz[_a], zz)) { \ if (ZCMP(pz[_a], zz)) { \
tmp = texture[ZB_TEXEL(s, t)]; \ tmp = ZB_LOOKUP_TEXTURE(texture, s, t); \
int a = oa1 * PIXEL_A(tmp) >> 16; \ int a = oa1 * PIXEL_A(tmp) >> 16; \
if (ACMP(zb, a)) { \ if (ACMP(zb, a)) { \
STORE_PIX(pp[_a], \ STORE_PIX(pp[_a], \
@ -216,7 +216,7 @@ void FNAME(ZB_fillTriangleMappingPerspective) (ZBuffer *zb,
{ \ { \
zz=z >> ZB_POINT_Z_FRAC_BITS; \ zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(pz[_a], zz)) { \ if (ZCMP(pz[_a], zz)) { \
tmp = texture[ZB_TEXEL(s, t)]; \ tmp = ZB_LOOKUP_TEXTURE(texture, s, t); \
if (ACMP(zb, PIXEL_A(tmp))) { \ if (ACMP(zb, PIXEL_A(tmp))) { \
STORE_PIX(pp[_a], tmp, PIXEL_R(tmp), PIXEL_G(tmp), PIXEL_B(tmp), PIXEL_A(tmp)); \ STORE_PIX(pp[_a], tmp, PIXEL_R(tmp), PIXEL_G(tmp), PIXEL_B(tmp), PIXEL_A(tmp)); \
STORE_Z(pz[_a], zz); \ STORE_Z(pz[_a], zz); \
@ -321,7 +321,7 @@ void FNAME(ZB_fillTriangleMappingPerspectiveFlat) (ZBuffer *zb,
{ \ { \
zz=z >> ZB_POINT_Z_FRAC_BITS; \ zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(pz[_a], zz)) { \ if (ZCMP(pz[_a], zz)) { \
tmp = texture[ZB_TEXEL(s, t)]; \ tmp = ZB_LOOKUP_TEXTURE(texture, s, t); \
int a = oa * PIXEL_A(tmp) >> 16; \ int a = oa * PIXEL_A(tmp) >> 16; \
if (ACMP(zb, a)) { \ if (ACMP(zb, a)) { \
STORE_PIX(pp[_a], \ STORE_PIX(pp[_a], \
@ -434,7 +434,7 @@ void FNAME(ZB_fillTriangleMappingPerspectiveSmooth) (ZBuffer *zb,
{ \ { \
zz=z >> ZB_POINT_Z_FRAC_BITS; \ zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(pz[_a], zz)) { \ if (ZCMP(pz[_a], zz)) { \
tmp = texture[ZB_TEXEL(s, t)]; \ tmp = ZB_LOOKUP_TEXTURE(texture, s, t); \
int a = oa1 * PIXEL_A(tmp) >> 16; \ int a = oa1 * PIXEL_A(tmp) >> 16; \
if (ACMP(zb, a)) { \ if (ACMP(zb, a)) { \
STORE_PIX(pp[_a], \ STORE_PIX(pp[_a], \