Browse Source

experiment with texture filtering

David Rose 17 years ago
parent
commit
b226cf6f5d

+ 4 - 4
panda/src/tinydisplay/clip.c

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

+ 33 - 0
panda/src/tinydisplay/zbuffer.c

@@ -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);
+}
+

+ 29 - 16
panda/src/tinydisplay/zbuffer.h

@@ -18,25 +18,36 @@
 /* The number of fractional bits below the S and T texture coords.
    The more we have, the more precise the texel calculation will be
    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
-   large. */
-#define ZB_POINT_ST_FRAC_BITS 10
+   chance we might overflow our 32-bit integer. */
+#define ZB_POINT_ST_FRAC_BITS 12
 
 /* Various parameters and accessors based on the above bits. */
-#define ZB_POINT_S_LOW ZB_POINT_ST_FRAC_BITS
-#define ZB_POINT_S_MIN 0
-#define ZB_POINT_S_MAX (1 << (ZB_POINT_ST_BITS + ZB_POINT_S_LOW))
-#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)
-#define ZB_POINT_T_MIN 0
-#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_POINT_ST_MIN 0
+#define ZB_POINT_ST_MAX (1 << (ZB_POINT_ST_BITS + ZB_POINT_ST_FRAC_BITS))
+#define ZB_POINT_ST_MASK ((1 << (ZB_POINT_ST_BITS + ZB_POINT_ST_FRAC_BITS)) - (1 << ZB_POINT_ST_FRAC_BITS))
+
+/* Returns the index within a 256x256 texture for the given (s, t)
+   texel. */
 #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_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 xmin, int ymin, int xsize, int ysize);
 
+PIXEL lookup_texture_bilinear(PIXEL *texture, int s, int t);
+
 /* linesize is in BYTES */
 void ZB_copyFrameBuffer(ZBuffer *zb,void *buf,int linesize);
 

+ 6 - 6
panda/src/tinydisplay/ztriangle_two.h

@@ -82,7 +82,7 @@ void FNAME(ZB_fillTriangleMapping) (ZBuffer *zb,
   {                                                                     \
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     if (ZCMP(pz[_a], zz)) {                                             \
-      tmp = texture[ZB_TEXEL(s, t)];                              \
+      tmp = ZB_LOOKUP_TEXTURE(texture, s, t);                              \
       if (ACMP(zb, 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);                                            \
@@ -118,7 +118,7 @@ void FNAME(ZB_fillTriangleMappingFlat) (ZBuffer *zb,
   {                                                                     \
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     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;                                  \
       if (ACMP(zb, a)) {                                                \
         STORE_PIX(pp[_a],                                               \
@@ -159,7 +159,7 @@ void FNAME(ZB_fillTriangleMappingSmooth) (ZBuffer *zb,
   {                                                                     \
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     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;                                 \
       if (ACMP(zb, a)) {                                                \
         STORE_PIX(pp[_a],                                               \
@@ -216,7 +216,7 @@ void FNAME(ZB_fillTriangleMappingPerspective) (ZBuffer *zb,
   {                                                                     \
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     if (ZCMP(pz[_a], zz)) {                                             \
-      tmp = texture[ZB_TEXEL(s, t)];                                    \
+      tmp = ZB_LOOKUP_TEXTURE(texture, s, t);                                    \
       if (ACMP(zb, 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);                                            \
@@ -321,7 +321,7 @@ void FNAME(ZB_fillTriangleMappingPerspectiveFlat) (ZBuffer *zb,
   {                                                                     \
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     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;                                  \
       if (ACMP(zb, a)) {                                                \
         STORE_PIX(pp[_a],                                               \
@@ -434,7 +434,7 @@ void FNAME(ZB_fillTriangleMappingPerspectiveSmooth) (ZBuffer *zb,
   {                                                                     \
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     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;                                 \
       if (ACMP(zb, a)) {                                                \
         STORE_PIX(pp[_a],                                               \