home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsv / ch7_6 / zrendv3.c < prev    next >
C/C++ Source or Header  |  1995-04-04  |  18KB  |  661 lines

  1. /* Accurate Rendering Algorithm Based on the Z-Buffer Algorithm
  2.    Developed by Raghu Karinthi
  3.                 West Virginia University
  4.         Department of Computer Science
  5.         P.O.Box 6330
  6.         Morgantown WV 26506-6330
  7.         raghu@cs.wvu.edu
  8.                 Version 3  01/20/95  */
  9.  
  10. #include "ZRendv3.h"
  11.  
  12. #define ZFABS(x) (((x) < 0.0) ? -(x) : (x))
  13.  
  14. #define sub_vec(res,V1,V2) \
  15. { \
  16.   (res)[0] = (V1)[0] - (V2)[0]; \
  17.   (res)[1] = (V1)[1] - (V2)[1]; \
  18.   (res)[2] = (V1)[2] - (V2)[2]; \
  19. }
  20.  
  21.  
  22. #define dot_product(V1,V2) \
  23.   ((V1)[0] * (V2)[0]  +  (V1)[1] * (V2)[1]  +  (V1)[2] * (V2)[2])
  24.  
  25.  
  26. #define mathpointmult(x,y,z,w,vec,mat) \
  27. { \
  28.   (x) = (vec)[0] * (mat)[0][0] + \
  29.                     (vec)[1] * (mat)[0][1] + \
  30.                     (vec)[2] * (mat)[0][2] + \
  31.                     (mat)[0][3]; \
  32.                                  \
  33.   (y) = (vec)[0] * (mat)[1][0] + \
  34.                     (vec)[1] * (mat)[1][1] + \
  35.                     (vec)[2] * (mat)[1][2] + \
  36.                     (mat)[1][3]; \
  37.                                  \
  38.   (z) = (vec)[0] * (mat)[2][0] + \
  39.                     (vec)[1] * (mat)[2][1] + \
  40.                     (vec)[2] * (mat)[2][2] + \
  41.                     (mat)[2][3]; \
  42.                                  \
  43.   (w) = (vec)[0] * (mat)[3][0] + \
  44.                     (vec)[1] * (mat)[3][1] + \
  45.                     (vec)[2] * (mat)[3][2] + \
  46.                     (mat)[3][3]; \
  47. } /* mathpointmult */
  48.  
  49. #define TSWAP(_a_, _b_, _c_) \
  50. { \
  51.   (_c_) = (_a_); (_a_) = (_b_); (_b_) = (_c_); \
  52. }
  53.  
  54.  
  55. #define min(_a_, _b_) (((_a_) < (_b_)) ? (_a_) : (_b_))
  56. #define max(_a_, _b_) (((_a_) > (_b_)) ? (_a_) : (_b_))
  57.  
  58.  
  59. #define fp_int(x)  \
  60.   (((x) < 0) ? \
  61.    (!((x) & LOMASK)) ? ((x) >> LOBITS) : (((x) >> LOBITS)+1) : \
  62.    ((x) >> LOBITS) \
  63.   )
  64.  
  65.  
  66. /* 
  67.  *  Works only if x +ve.
  68.  */
  69.  
  70. #define fp_int_flr(x) ((x) >> LOBITS)
  71.  
  72.  
  73. /*
  74.  *  We use the following approximation.
  75.  */
  76.  
  77. #define fp_div(x,y) \
  78.           (((x) < 0) ? ((x) / (y) - 1) << LOBITS : ((x) / (y)) << LOBITS)
  79.  
  80. /*
  81.  *  Works only if xlo = 0.
  82.  */
  83.  
  84. #define fp_mult1(x,y) \
  85.   (((x)<0) ? \
  86.    -(((-(x) & HIMASK)>> LOBITS)*(y)) : \
  87.    ((x)>> LOBITS)*(y))
  88. /* 
  89.  * Works only if xhi = 0  
  90.  */
  91.  
  92. #define fp_mult2(x,y) \
  93.   (((y)<0)?(-((((-(y))&HIMASK)>>LOBITS)*(x)+((((-(y))&LOMASK)*x)>>LOBITS)))\
  94.     : (((y) >> LOBITS) * (x) + ((((y)&LOMASK)*x)>>LOBITS)))
  95.  
  96. /* 
  97.  *  Fractional Part if x +ve 
  98.  */
  99.  
  100. #define fp_fraction(x) ((x) & LOMASK)
  101.   
  102. /* Turn a double into a fixpoint number int two's complement. 
  103.     Negative numbers become:  ~a + 1
  104.  */
  105. fixpoint fp_fix(double x)
  106. {
  107.   int negative = (x < 0);
  108.   double i;                /* integer part */
  109.   /* not used: double fraction;    /* fraction part, positive only */
  110.   fixpoint p;            /* fixpoint version of abs(x) */
  111.  
  112.   x = fabs(x);
  113.   i = floor(x);
  114.   /* not used: fraction = x - i; */
  115.  
  116.   p = (((int) i) << LOBITS) | ((int) ((x-i)*(1<<LOBITS)));
  117.  
  118.   if (negative) return (-p);
  119.   else return (p);
  120. }
  121.  
  122.  
  123.  
  124. /*
  125.  *  The following : edge data structure, and functions EdgeScan,
  126.  *  EdgeSetup, and rasterize_sorted_triangle, are modified from the code
  127.  *  obtained in Graphics Gems III subdirectory accurate_scan due to Kurt
  128.  *  Fleischer.  Also Refer Lathrop, Kirk, Voorhies, IEEE CG&A 10(5),
  129.  *  1990 for a discussion
  130.  */
  131.  
  132. /*
  133.  *  Array has the fields called E, Imin, Astep, Bstep, DEA and DEB
  134.  *  in the paper by Lathrop, Kirk and Voorhies.
  135.  */
  136.  
  137. typedef int edge[6];
  138.  
  139.  
  140. #define EdgeScan(e) \
  141.   if ((e)[0] < 0 ) \
  142.   { \
  143.     (e)[1] += (e)[2]; (e)[0] += (e)[4]; \
  144.   } \
  145.   else \
  146.   { \
  147.    (e)[1] += (e)[3]; (e)[0] += (e)[5]; \
  148.   }
  149.  
  150. #define EdgeSetup(e,x0,y0,x1,y1) \
  151. { \
  152.   dx = (x1)-(x0); \
  153.   dy = (y1)-(y0); \
  154.   if (dy >= FIX1) \
  155.   { \
  156.     si = fp_div(dx, dy); \
  157.     sf = dx - fp_mult1(si, dy);  \
  158.     xi = (x0) + fp_mult2((FIX1 - fp_fraction((y0))),si) ; \
  159.     e[2] = fp_int(si); \
  160.     e[3] = e[2]+1; \
  161.     e[4]= sf; \
  162.     e[5] = sf - dy; \
  163.     e[0] = fp_mult2(fp_fraction(xi),dy) + e[5]; \
  164.     e[1] = fp_int(xi); \
  165.   } \
  166.   else e[1] = fp_int(x0); \
  167. } /* EdgeSetup */
  168.  
  169. /*
  170.  *  This function applies the view Transform to set of triangles.
  171.  */
  172.  
  173. void viewTrans_DivByW_DevTrans (InDataSet localSet, register int count,
  174.                                 MAT3mat transform)
  175. {
  176.   int           i, j;
  177.  
  178.   double x,y,z,w;
  179.  
  180.   /* For every triangle do... */
  181.  
  182.   for( i = 0; i < count; i++)
  183.   {
  184.     for( j = 0; j < 3; j++)
  185.     {
  186.       mathpointmult (x,y,z,w,localSet[i].vertices[j].vertex,transform)
  187.  
  188.     x /= w; 
  189.         y /= w;
  190.         z /= w;
  191.  
  192.       localSet[i].vertices[j].vertex[X] = x * (double) WINDOW_WIDTH/2
  193.     + (double) WINDOW_WIDTH/2;
  194.       localSet[i].vertices[j].vertex[Y] = y * (double) WINDOW_WIDTH/2
  195.     + (double) WINDOW_HEIGHT/2;
  196.       localSet[i].vertices[j].vertex[Z] = z * (double) WINDOW_WIDTH
  197.     + (double) WINDOW_WIDTH;
  198.     } /* for j */
  199.  
  200.   } /* for i */
  201.  
  202. } /* viewTrans_DivByW_DevTrans */
  203.  
  204.  
  205. /*
  206.  *  This function does the actual rasterization.
  207.  *  Like integer version, but uses EdgeSetup.
  208.  */
  209.  
  210. void rasterize_sorted_triangle (int         minv,
  211.                                 int         midv, 
  212.                                 int         maxv,
  213.                                 InDataSet   tp,
  214.                                 FrameBuffer localBuff)
  215. {
  216.   edge          left, right,
  217.                 zleft, zright, zspan, 
  218.                 rleft, rright, rspan,
  219.                 gleft, gright, gspan,
  220.                 bleft, bright, bspan;
  221.   int           x, yi,
  222.                 xmin, xmax;
  223.   int           temp;
  224.   int           temp1;
  225.   int           cw;
  226.   fixpoint      sf, xi, si, dx, dy;
  227.   fixpoint      fxmin, fxmax,
  228.                 fzmin, fzmax, z,
  229.                 frmin, frmax, r,
  230.                 fgmin, fgmax, g,
  231.                 fbmin, fbmax, b;
  232.   fixpoint      x0, y0, z0, r0, g0, b0;
  233.   fixpoint      x1, y1, z1, r1, g1, b1;
  234.   fixpoint      x2, y2, z2, r2, g2, b2;
  235.   
  236.   /*
  237.    *  Convert the vertices of the triangle and their color value
  238.    *  to 'fixpoint' representation.
  239.    */
  240.  
  241.   x0 = fp_fix ((tp->vertices[minv]).vertex[X]);
  242.   y0 = fp_fix ((tp->vertices[minv]).vertex[Y]);
  243.   z0 = fp_fix ((tp->vertices[minv]).vertex[Z]);
  244.  
  245.   x1 = fp_fix ((tp->vertices[midv]).vertex[X]);
  246.   y1 = fp_fix ((tp->vertices[midv]).vertex[Y]);
  247.   z1 = fp_fix ((tp->vertices[midv]).vertex[Z]);
  248.  
  249.   x2 = fp_fix ((tp->vertices[maxv]).vertex[X]);
  250.   y2 = fp_fix ((tp->vertices[maxv]).vertex[Y]);
  251.   z2 = fp_fix ((tp->vertices[maxv]).vertex[Z]);
  252.  
  253.   r0 = (tp->vertices[minv]).red;
  254.   g0 = (tp->vertices[minv]).green;
  255.   b0 = (tp->vertices[minv]).blue;
  256.  
  257.   r1 = (tp->vertices[midv]).red;
  258.   g1 = (tp->vertices[midv]).green;
  259.   b1 = (tp->vertices[midv]).blue;
  260.  
  261.   r2 = (tp->vertices[maxv]).red;
  262.   g2 = (tp->vertices[maxv]).green;
  263.   b2 = (tp->vertices[maxv]).blue;
  264.  
  265.   /*
  266.    *  Find out whether the triangle edges are oriented in clockwise
  267.    *  or anti-clockwise direction.
  268.    *
  269.    */
  270.  
  271.   cw = (  ((tp->vertices[midv]).vertex[1] -
  272.            (tp->vertices[minv]).vertex[1]) *
  273.  
  274.           ((tp->vertices[maxv]).vertex[0] -
  275.            (tp->vertices[minv]).vertex[0])
  276.  
  277.         < ((tp->vertices[midv]).vertex[0] -
  278.            (tp->vertices[minv]).vertex[0]) *
  279.  
  280.           ((tp->vertices[maxv]).vertex[1] -
  281.            (tp->vertices[minv]).vertex[1])
  282.        );
  283.  
  284.   /*
  285.    *  Setup first pair of edges.
  286.    */
  287.  
  288.   if (cw)
  289.   {
  290.     EdgeSetup (left, x0, y0, x2, y2);
  291.     EdgeSetup (zleft, z0, y0, z2, y2);
  292.     EdgeSetup (rleft, r0, y0, r2, y2);
  293.     EdgeSetup (gleft, g0, y0, g2, y2);
  294.     EdgeSetup (bleft, b0, y0, b2, y2);
  295.  
  296.     EdgeSetup (right, x0, y0, x1, y1);
  297.     EdgeSetup (zright, z0, y0, z1, y1);
  298.     EdgeSetup (rright, r0, y0, r1, y1);
  299.     EdgeSetup (gright, g0, y0, g1, y1);
  300.     EdgeSetup (bright, b0, y0, b1, y1);
  301.  
  302.   } /* if cw orientation of edges */
  303.  
  304.   else
  305.   {
  306.     EdgeSetup (left, x0, y0, x1, y1);
  307.     EdgeSetup (zleft, z0, y0, z1, y1);
  308.     EdgeSetup (rleft, r0, y0, r1, y1);
  309.     EdgeSetup (gleft, g0, y0, g1, y1);
  310.     EdgeSetup (bleft, b0, y0, b1, y1);
  311.  
  312.     EdgeSetup (right, x0, y0, x2, y2);
  313.     EdgeSetup (zright, z0, y0, z2, y2);
  314.     EdgeSetup (rright, r0, y0, r2, y2);
  315.     EdgeSetup (gright, g0, y0, g2, y2);
  316.     EdgeSetup (bright, b0, y0, b2, y2);
  317.  
  318.   } /* else anti-clockwise orientation of edges */
  319.  
  320.     
  321.   temp = min (fp_int_flr ((cw) ? y2 : y1), fp_int_flr ((cw) ? y1 : y2));
  322.   for (yi = fp_int_flr (y0) + 1; yi <= temp; yi ++)
  323.   {
  324.     fxmin = left[1];    EdgeScan (left)
  325.     fxmax = right[1];   EdgeScan (right)
  326.     fzmin = zleft[1];   EdgeScan (zleft)
  327.     fzmax = zright[1];  EdgeScan (zright)
  328.     frmin = rleft[1];   EdgeScan (rleft)
  329.     frmax = rright[1];  EdgeScan (rright)
  330.     fgmin = gleft[1];   EdgeScan (gleft)
  331.     fgmax = gright[1];  EdgeScan (gright)
  332.     fbmin = bleft[1];   EdgeScan (bleft)
  333.     fbmax = bright[1];  EdgeScan (bright)
  334.  
  335.     xmin = fxmin;
  336.     xmax = fxmax;
  337.    
  338.     fxmin = fxmin << LOBITS;
  339.     fxmax = fxmax << LOBITS;
  340.     fzmin = fzmin << LOBITS;
  341.     fzmax = fzmax << LOBITS;
  342.     frmin = frmin << LOBITS;
  343.     frmax = frmax << LOBITS;
  344.     fgmin = fgmin << LOBITS;
  345.     fgmax = fgmax << LOBITS;
  346.     fbmin = fbmin << LOBITS;
  347.     fbmax = fbmax << LOBITS;  
  348.  
  349.     EdgeSetup (zspan, fzmin, fxmin, fzmax, fxmax);
  350.     EdgeSetup (rspan, frmin, fxmin, frmax, fxmax);
  351.     EdgeSetup (gspan, fgmin, fxmin, fgmax, fxmax);
  352.     EdgeSetup (bspan, fbmin, fxmin, fbmax, fxmax);
  353.  
  354.     for (x = xmin + 1; x <= xmax; x ++)
  355.     {
  356.       z = zspan[1]; EdgeScan (zspan)
  357.       r = rspan[1]; EdgeScan (rspan)
  358.       g = gspan[1]; EdgeScan (gspan)
  359.       b = bspan[1]; EdgeScan (bspan)
  360.  
  361.       if (localBuff[yi][x].z < z)
  362.       {
  363.         localBuff[yi][x].z      = z;
  364.         localBuff[yi][x].red    = r;
  365.         localBuff[yi][x].green  = g;
  366.         localBuff[yi][x].blue   = b;
  367.       }
  368.  
  369.     } /* for all pixels on the scan line between the edges */
  370.  
  371.   } /* for every scan line upto the lower 'y' of the two edges */
  372.  
  373.   /*
  374.    *  Setup the third edge.
  375.    */
  376.  
  377.   if (!cw)
  378.   {
  379.     EdgeSetup (left, x1, y1, x2, y2);
  380.     EdgeSetup (zleft, z1, y1, z2, y2);
  381.     EdgeSetup (rleft, r1, y1, r2, y2);
  382.     EdgeSetup (gleft, g1, y1, g2, y2);
  383.     EdgeSetup (bleft, b1, y1, b2, y2);
  384.   }
  385.   else
  386.   {
  387.     EdgeSetup (right, x1, y1, x2, y2);
  388.     EdgeSetup (zright, z1, y1, z2, y2);
  389.     EdgeSetup (rright, r1, y1, r2, y2);
  390.     EdgeSetup (gright, g1, y1, g2, y2);
  391.     EdgeSetup (bright, b1, y1, b2, y2);
  392.   }
  393.  
  394.   /*
  395.    *  Now scan convert the rest of the triangle.
  396.    */
  397.  
  398.   temp = max (fp_int_flr ((cw) ? y0 : y1), fp_int_flr ((cw) ? y1 : y0)) + 1; 
  399.   temp1 = fp_int_flr (y2);
  400.   for (yi = temp; yi <= temp1; yi ++)
  401.   {
  402.     fxmin = left[1];    EdgeScan (left)
  403.     fxmax = right[1];   EdgeScan (right)
  404.     fzmin = zleft[1];   EdgeScan (zleft)
  405.     fzmax = zright[1];  EdgeScan (zright)
  406.     frmin = rleft[1];   EdgeScan (rleft)
  407.     frmax = rright[1];  EdgeScan (rright)
  408.     fgmin = gleft[1];   EdgeScan (gleft)
  409.     fgmax = gright[1];  EdgeScan (gright)
  410.     fbmin = bleft[1];   EdgeScan (bleft)
  411.     fbmax = bright[1];  EdgeScan (bright)
  412.  
  413.     xmin = fxmin;
  414.     xmax = fxmax;
  415.    
  416.     fxmin = fxmin << LOBITS;
  417.     fxmax = fxmax << LOBITS;
  418.     fzmin = fzmin << LOBITS;
  419.     fzmax = fzmax << LOBITS;
  420.     frmin = frmin << LOBITS;
  421.     frmax = frmax << LOBITS;
  422.     fgmin = fgmin << LOBITS;
  423.     fgmax = fgmax << LOBITS;
  424.     fbmin = fbmin << LOBITS;
  425.     fbmax = fbmax << LOBITS;  
  426.  
  427.     EdgeSetup (zspan, fzmin, fxmin, fzmax, fxmax);
  428.     EdgeSetup (rspan, frmin, fxmin, frmax, fxmax);
  429.     EdgeSetup (gspan, fgmin, fxmin, fgmax, fxmax);
  430.     EdgeSetup (bspan, fbmin, fxmin, fbmax, fxmax);
  431.  
  432.     for (x = xmin + 1; x <= xmax; x ++)
  433.     {
  434.       z = zspan[1]; EdgeScan (zspan)
  435.       r = rspan[1]; EdgeScan (rspan)
  436.       g = gspan[1]; EdgeScan (gspan)
  437.       b = bspan[1]; EdgeScan (bspan)
  438.  
  439.       if (localBuff[yi][x].z < z)
  440.       {
  441.         localBuff[yi][x].z     = z;
  442.         localBuff[yi][x].red   = r;
  443.         localBuff[yi][x].green = g;
  444.         localBuff[yi][x].blue  = b;
  445.       }
  446.  
  447.     } /* for every pixel on scan line b/w the left and right edges */
  448.  
  449.   } /* for every scan line till the uppermost vertex of the triangle */
  450.  
  451. } /* rasterize_sorted_triangle */
  452.  
  453.  
  454. /*
  455.  *  Rasterizes a triangle. It first orients the triangle edges so that
  456.  *  vertex 0 is lower that vertex 1 which in turn is lower than vertex 2.
  457.  */
  458.  
  459. void rasterizeTriangle (FrameBuffer localBuff, InDataSet tp)
  460. {
  461.   int       minv = 0, midv = 1, maxv = 2, tmp = 0;
  462.  
  463.  
  464.   if ((tp->vertices[minv]).vertex[Y] >
  465.       (tp->vertices[midv]).vertex[Y])
  466.   {
  467.     TSWAP (minv, midv, tmp); 
  468.   }
  469.  
  470.   if ((tp->vertices[minv]).vertex[Y] >
  471.       (tp->vertices[maxv]).vertex[Y])
  472.   {
  473.     TSWAP (minv, maxv, tmp);
  474.   }
  475.  
  476.   if ((tp->vertices[midv]).vertex[Y] >
  477.       (tp->vertices[maxv]).vertex[Y])
  478.   {
  479.     TSWAP (midv, maxv, tmp);
  480.   }
  481.  
  482.   rasterize_sorted_triangle (minv, midv, maxv, tp, localBuff);
  483.  
  484. } /* rasterizeTriangle */
  485.  
  486.  
  487. /*
  488.  *  The function rasterizes a set of triangles one at a time.
  489.  */
  490.  
  491. void Rasterize (InDataSet localSet, int count, FrameBuffer localBuff)
  492. {
  493.   int i;
  494.  
  495.  
  496.   for (i = 0; i < count; i ++) 
  497.   {
  498.     rasterizeTriangle (localBuff, &localSet[i]);
  499.   }
  500.  
  501. } /* Rasterize */
  502.  
  503.  
  504. /*
  505.  *  Function to Shade the Triangle Vertices.
  506.  */
  507.  
  508. void Lighting (InDataSet localSet,int *datasizep,
  509.                double Iar, double Iag, double Iab,
  510.                double Kar, double Kdr, double Kag,
  511.                double Kdg, double Kab, double Kdb,
  512.                double c1, double c2,
  513.                int num_lights, Lights lights)
  514. {
  515.   int       i = 0, j = 0, k = 0;
  516.   MAT3vec   temp1;
  517.   double    dist, r = 0.0, g = 0.0, b = 0.0;
  518.   double    tmp2r, tmp2g, tmp2b ;
  519.  
  520.   tmp2r = Iar * Kar * MAX_INTENSITY / (num_lights + 1);
  521.   tmp2g = Iag * Kag * MAX_INTENSITY / (num_lights + 1);
  522.   tmp2b = Iab * Kab * MAX_INTENSITY / (num_lights + 1);
  523.  
  524.   for (k=0; k < num_lights; k++) {
  525.     lights[k].red *= Kdr * MAX_INTENSITY / (num_lights+1);
  526.     lights[k].green *= Kdg * MAX_INTENSITY / (num_lights+1);
  527.     lights[k].blue *= Kdb * MAX_INTENSITY / (num_lights+1);
  528.   }
  529.   for(i = 0; i < (*datasizep); i++)
  530.   {
  531.     for (j = 0; j < 3; j++)
  532.     {
  533.       r = tmp2r; g = tmp2g; b = tmp2b;
  534.       for (k = 0; k < num_lights; k++)
  535.       {
  536.         sub_vec (temp1, lights[k].location,
  537.                         localSet[i].vertices[j].vertex)
  538.  
  539.         dist = sqrt (temp1[X]*temp1[X] +
  540.                      temp1[Y]*temp1[Y] +
  541.                      temp1[Z]*temp1[Z]);
  542.  
  543.         dist = 1 / dist * (1 + c1*dist + c2*dist*dist);
  544.  
  545.         r += ZFABS (lights[k].red * dist *
  546.                   dot_product (temp1, localSet[i].vertices[j].normal));
  547.  
  548.         g += ZFABS (lights[k].green * dist *
  549.                   dot_product (temp1, localSet[i].vertices[j].normal));
  550.  
  551.         b += ZFABS (lights[k].blue * dist *
  552.                   dot_product (temp1, localSet[i].vertices[j].normal));
  553.  
  554.       } /* for k */
  555.  
  556.       localSet[i].vertices[j].red   = fp_fix(r);
  557.       localSet[i].vertices[j].green = fp_fix(g);
  558.       localSet[i].vertices[j].blue  = fp_fix(b);
  559.  
  560.     } /* for j */
  561.  
  562.   } /* for i */
  563.  
  564. } /* Lighting */
  565.  
  566.  
  567.  
  568. void main(int argc, char **argv)
  569. {
  570.   int               i, j, datasize, num_lights;
  571.   InDataSet         localSet;
  572.   Point             vrp, prp;
  573.   MAT3vec           vpn, vupv;
  574.   double            fplane, bplane,
  575.                     umin, umax, vmin, vmax;
  576.   MAT3mat           vo_matrix, vm_matrix, transform;
  577.   MtlProp           activeProp;
  578.   FrameBuffer       localBuff;
  579.   Lights            lights;
  580.   BackGroundColor   backgndcolor;
  581.   clock_t           tm1, tm2;
  582.  
  583.  
  584.   localSet = (InDataSet) calloc (1, NUM_TRIANGLES * sizeof (Triangle));
  585.   lights = (Lights) calloc (1, NUM_LIGHT_SOURCES * sizeof (LightPoint));
  586.  
  587.   readNFFFile (argv[1], localSet,
  588.                vrp, vpn, vupv,
  589.                prp, &fplane, &bplane,
  590.                &umin, &umax, &vmin, &vmax,
  591.                lights, &backgndcolor,
  592.                &datasize, &activeProp, &num_lights);
  593.  
  594. #ifdef PRINTVIEWINGVALS
  595.  
  596.   fprintf (stderr, "Number of triangles: %d\n", datasize);
  597.   fprintf (stderr, "Vrp                : %lf %lf %lf\n",
  598.                          vrp[0], vrp[1], vrp[2]);
  599.   fprintf (stderr, "Vpn                : %lf %lf %lf\n",
  600.                          vpn[0], vpn[1], vpn[2]);
  601.   fprintf (stderr, "Vupv               : %lf %lf %lf\n",
  602.                          vupv[0], vupv[1], vupv[2]);
  603.   fprintf (stderr, "prp                : %lf %lf %lf\n",
  604.                          prp[0], prp[1], prp[2]);
  605.   fprintf (stderr, "fplane             : %lf\n", fplane);
  606.   fprintf (stderr, "bplane             : %lf\n", bplane);
  607.   fprintf (stderr, "umin, umax         : %lf %lf\n",
  608.                                  umin, umax);
  609.   fprintf (stderr, "vmin, vmax         : %lf %lf\n",
  610.                                  vmin, vmax);
  611.  
  612. #endif /* PRINTVIEWINGVALS */
  613.  
  614.  
  615.   for (i=0; i < WINDOW_HEIGHT; i++)
  616.   {
  617.     for (j=0; j < WINDOW_WIDTH; j++)
  618.     {
  619.       localBuff[i][j].red = backgndcolor.red;
  620.       localBuff[i][j].green = backgndcolor.green;
  621.       localBuff[i][j].blue = backgndcolor.blue;
  622.     }
  623.   }
  624.  
  625.   evaluateViewOrientationMatrix (vrp, vpn, vupv, vo_matrix);
  626.   evaluateViewMappingMatrix (umin, umax, vmin, vmax,
  627.                              prp, fplane, bplane, vm_matrix);
  628.   MAT3mult (transform, vm_matrix, vo_matrix);
  629.  
  630.   tm1 = clock ();
  631.   Lighting (localSet, &datasize,
  632.             activeProp.red, activeProp.green, activeProp.blue,
  633.             activeProp.ambientK, activeProp.diffuseK, 
  634.             activeProp.ambientK, activeProp.diffuseK, 
  635.             activeProp.ambientK, activeProp.diffuseK, 
  636.             activeProp.c1, activeProp.c2, num_lights, lights);
  637.   tm2 = clock ();
  638.   printf ("Lighting took %f secs.\n",
  639.                           (double) (tm2-tm1)/CLOCKS_PER_SEC);
  640.  
  641.   tm1 = clock ();
  642.   viewTrans_DivByW_DevTrans (localSet, datasize, transform);
  643.   tm2 = clock (); 
  644.   printf ("Transformation took %f secs.\n",
  645.                           (double)(tm2-tm1)/CLOCKS_PER_SEC);
  646.  
  647.   tm1 = clock ();
  648.   Rasterize (localSet, datasize, localBuff);
  649.   tm2 = clock ();
  650.   printf ("Rasterize took %f secs\n",(double) (tm2-tm1)/CLOCKS_PER_SEC);
  651.  
  652.   write_tga_buffer (localBuff, (argc > 2) ? argv[2] : DEFAULTOUT); 
  653.  
  654.   free ((char *) localSet);
  655.   free ((char *) lights);
  656.  
  657. } /* main */
  658.  
  659.  
  660.  
  661.