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 */
   /* 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) 
-                  + 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 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
-   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. */
 /* 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) \
 #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);
 
 

+ 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;                                       \
     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],                                               \