Commits

Cliff Biffle committed 1dd892a

At the cost of some memory, made the triangle strip renderer roughly twice as fast, improved accuracy of normal calculations, and fixed a bug in texture application that reduced Y accuracy by 50%. So now it's faster and much better.

Comments (0)

Files changed (2)

KVTriStripRenderer.h

 // into triangle strips.  Computes almost-correct
 // vertex normals for smooth shading.
 @interface KVTriStripRenderer : KVAbstractRenderer {
+  vec3f_t vertices[480][640];
+  vec3f_t normals[480][640];
 }
 
 @end

KVTriStripRenderer.m

   KVAbstractRendererProjector projector =
       (KVAbstractRendererProjector) [self methodForSelector: @selector(projectInto:x:y:z:)];
 
-  vec3f_t normal;
-  // Last two points rendered, for normal calculation.
-  vec3f_t prev[2];
-  vec3f_t coord;
-
   vec3f_t baseColor = [self colorAsRGBVector];
   glColor3fv(&baseColor.x);
   
+  for (int y = 0; y < 480; y++) {
+    for (int x = 0; x < 640; x++) {
+      GLfloat d = zs->z[y][x];
+      projector(self, @selector(projectInto:x:y:z:), &vertices[y][x], x, y, d);
+    }
+  }
+  
+  if (lit) {
+    // The right and bottom edges won't have correct normals.
+    // So be it.
+    for (int y = 0; y < 479; y++) {
+      for (int x = 0; x < 639; x++) {
+        normals[y][x] = compute_normal(vertices[y][x], vertices[y + 1][x], vertices[y + 1][x + 1]);
+      }
+    }
+  }
+  
   for (int y = 0; y < 479; y++) {
     glBegin(GL_TRIANGLE_STRIP);
     
     // Whether we have called glBegin
     BOOL inStrip = YES;
     // Z of last point rendered, for slope test.
-    GLfloat lastDepth = zs->z[y][0];
-    
-    // By not initializing prev here we will calcluate bogus
-    // normals along the leftmost edge.  So be it.
+    GLfloat lastDepth = vertices[y][0].z;
     
     for (int x = 0; x < 640; x++) {
       
       for (int step = 0; step < 2; step++) {
-        GLfloat d = zs->z[(y + step)][x];
+        GLfloat d = vertices[y + step][x].z;
         GLfloat deltaZ = fabsf(d - lastDepth);
         lastDepth = d;
         
           }
         }
         
-        projector(self, @selector(projectInto:x:y:z:), &coord, x, y + step, d);
-        
         if (lit) {
-          normal = compute_normal(prev[0], prev[1], coord);
-          glNormal3fv(&normal.x);
+          glNormal3fv(&normals[y + step][x].x);
         }
 
         if (textured) {
           int colorX = (int) (x * xform.scale.x + xform.offset.x);
-          int colorY = (int) (y * xform.scale.y + xform.offset.y);
+          int colorY = (int) ((y + step) * xform.scale.y + xform.offset.y);
           const rgb_t *pixelColor = &colors->pixels[colorY][colorX];
           
           glColor3ubv(&pixelColor->r);
           vec3f_t falseColor = vector_scale(baseColor, 1.F - d/10.F);
           glColor3fv(&falseColor.x);
         }
-        glVertex3fv(&coord.x);
-        
-        prev[step] = coord;
+        glVertex3fv(&vertices[y + step][x].x);
       }
     }
     if (inStrip) glEnd();