home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsv / ch7_6 / zrendv3utils.c < prev   
C/C++ Source or Header  |  1995-04-04  |  12KB  |  395 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. #ifndef M_PI
  12. #define M_PI    3.14159265358979323846
  13. #endif
  14.  
  15. /*
  16.  *  Parser for the Input -- described in the document on Input
  17.  *  File Format.
  18.  */
  19.  
  20. void readNFFFile (char *filename, InDataSet dataset,
  21.                   Point vrp, MAT3vec  vpn,
  22.                   MAT3vec vupv, Point prp,
  23.                   double *fplanep, double *bplanep,
  24.                   double *uminp, double *umaxp,
  25.                   double *vminp, double *vmaxp,
  26.                   Lights lights,
  27.                   BackGroundColor *backgndcolor,
  28.                   int *datasizep,
  29.                   MtlProp *activeProp,
  30.                   int *currentlight)
  31.  
  32. {
  33.   FILE        *infile;
  34.   char        string[80];
  35.   int         i,
  36.               count,
  37.               state = WAITING,
  38.               currentTriangle=-1;
  39.   double      angle,
  40.               delta[3],
  41.               length,
  42.               lx, ly, lz;
  43.   Point       from;
  44.  
  45.  
  46.   *currentlight = 0;
  47.   infile = fopen (filename,"r");
  48.   if (!infile)
  49.     {
  50.     char fullname[256], *extn;
  51.     int j = 0;
  52.     extn = ".nff";
  53.     while (fullname[j] = filename[j]) j++;
  54.     while (fullname[j] = *extn++);
  55.      infile = fopen (fullname, "r");
  56.     }
  57.   if (!infile)
  58.     {
  59.     fprintf(stderr, "file '%s{.nff}' not found\n");
  60.     exit(1);
  61.     }
  62.  
  63.   while (fgets (&string[0],80,infile) != NULL) 
  64.   {
  65.     if (state == WAITING) 
  66.     {
  67.       switch (string[0])
  68.       {
  69.         case 'v':
  70.           state = VIEWING; /* Read View Specification */
  71.           break;
  72.  
  73.         case 'b':  /* Background Color */
  74.           sscanf (&string[1]," %lf %lf %lf\n", &lx, &ly, &lz);
  75.           backgndcolor->red   = MAX_INTENSITY * lx;
  76.           backgndcolor->green = MAX_INTENSITY * ly;
  77.           backgndcolor->blue  = MAX_INTENSITY * lz;
  78.           break;
  79.  
  80.         case 'l': /* Light Source */
  81.           sscanf (&string[1], " %lf %lf %lf %lf %lf %lf",
  82.                               &lights[*currentlight].location[0], 
  83.                               &lights[*currentlight].location[1],
  84.                               &lights[*currentlight].location[2],
  85.                               &lights[*currentlight].red,
  86.                               &lights[*currentlight].green,
  87.                               &lights[*currentlight].blue);
  88.           (*currentlight)++;
  89.           break;
  90.  
  91.         case 'f':  /* Lighting Constants */
  92.           sscanf (&string[1], " %lf %lf %lf %lf %lf %lf %lf",
  93.                               &(*activeProp).red,
  94.                               &(*activeProp).green,
  95.                               &(*activeProp).blue, 
  96.                               &(*activeProp).diffuseK,
  97.                               &(*activeProp).ambientK,
  98.                               &(*activeProp).c1,
  99.                               &(*activeProp).c2);
  100.           break;
  101.  
  102.         case 'p': /* Triangle to Follow */
  103.           state = TRIDATA;
  104.           count = 0;
  105.           currentTriangle++;
  106.           break;
  107.  
  108.       } /* switch on first char of line */
  109.  
  110.     } /* if in waiting state */
  111.  
  112.     else if (state == VIEWING) 
  113.     {
  114.       switch(string[0])
  115.       {
  116.         case 'f':   /* View point location */
  117.           sscanf (&string[4], " %lf %lf %lf\n",
  118.                               &from[0], &from[1], &from[2]);
  119.           break;
  120.  
  121.         case 'a':
  122.           if (string[1] == 't') /* Look at */
  123.           {
  124.             sscanf(&string[2], " %lf %lf %lf\n",
  125.                                &vrp[0], &vrp[1], &vrp[2]);
  126.           }
  127.           else if (string[1] == 'n')     /* Angle */
  128.           {
  129.             sscanf(&string[5], "%lf\n", &angle);
  130.           }
  131.           break;
  132.  
  133.         case 'u': /* Up Vector */
  134.           sscanf (&string[2], " %lf %lf %lf\n",
  135.                               &vupv[0], &vupv[1], &vupv[2]);
  136.           break;
  137.  
  138.         case 'h':  /* Front or Hither Clipping Plane */
  139.           sscanf (&string[6], " %lf\n", fplanep);
  140.           break;
  141.  
  142.         case 'y': /* Back or Yon Clipping Plane */
  143.           sscanf (&string[3], " %lf\n", bplanep);
  144.           break;
  145.  
  146.         case 'r':  /* resolution is currently ignored */
  147.           for (i=0; i < 3; i++)
  148.           {
  149.             delta[i] = from[i] - vrp[i];
  150.           }
  151.           length = sqrt (delta[0] * delta[0] +
  152.                          delta[1] * delta[1] +
  153.                          delta[2] * delta[2]);
  154.           for (i=0; i < 3; i++)
  155.           {
  156.             vpn[i] = delta[i] / length;
  157.           }
  158.           *fplanep = length - *fplanep;
  159.           *bplanep = length - *bplanep;
  160.           prp[0]   = prp[1] = 0.0;
  161.           prp[2]   = length;
  162.           *uminp   = *vminp = -length * tan(angle*M_PI/360.0);
  163.           *vmaxp   = *umaxp = -*uminp;
  164.           state    = WAITING;
  165.           break;
  166.  
  167.       } /* switch first char in line */
  168.  
  169.     } /* else if in viewing state */
  170.  
  171.     else if (state == TRIDATA)
  172.     {
  173.       sscanf (string,"%lf%lf%lf%lf%lf%lf\n", 
  174.          &(dataset[currentTriangle].vertices[count].vertex[0]), 
  175.          &(dataset[currentTriangle].vertices[count].vertex[1]),
  176.          &(dataset[currentTriangle].vertices[count].vertex[2]), 
  177.          &(dataset[currentTriangle].vertices[count].normal[0]),
  178.          &(dataset[currentTriangle].vertices[count].normal[1]),
  179.          &(dataset[currentTriangle].vertices[count].normal[2]));
  180.  
  181.       if (count == 2)
  182.         state = WAITING;
  183.       else
  184.         count++;
  185.  
  186.     } /* else if just read in triangle data */
  187.  
  188.   } /* while not eof */
  189.  
  190.   fclose(infile);
  191.   *datasizep = currentTriangle + 1;
  192.  
  193. } /* readNFFFile */
  194.  
  195.  
  196. /*
  197.  *  This function is modified from the SPHIGS package of Brown
  198.  *  University. See the book by Foley, vanDam, Feiner, Hughes
  199.  *  and Phillips, Chapter 6, for the algorithm.
  200.  */
  201.  
  202. void evaluateViewOrientationMatrix (Point view_ref_point, 
  203.                                     MAT3vec view_plane_normal,
  204.                                     MAT3vec view_up_vector,
  205.                                     MAT3mat vo_matrix)
  206. {
  207.   MAT3vec       tempvec,
  208.                 up_v,
  209.                 basis[3]; /* basis -- basis vectors for VRC system */
  210.   MAT3mat       trans,
  211.                 rot;
  212.   double        dot,
  213.                 tmp1;
  214.   int           i, j;
  215.  
  216.  
  217.   MAT3_COPY_VEC (up_v, view_up_vector);
  218.   MAT3_NORMALIZE_VEC (up_v, tmp1);
  219.   MAT3_COPY_VEC (basis[2], view_plane_normal);
  220.   MAT3_NORMALIZE_VEC (basis[2], tmp1);
  221.   dot = MAT3_DOT_PRODUCT (up_v, basis[2]);
  222.   MAT3_LINEAR_COMB (basis[1], 1.0, up_v, -dot, basis[2]);
  223.   MAT3_NORMALIZE_VEC (basis[1], tmp1);
  224.   MAT3cross_product (basis[0], basis[2], basis[1]);
  225.   MAT3_SCALE_VEC (basis[0], basis[0], -1);
  226.   MAT3_SCALE_VEC (tempvec, view_ref_point, -1);
  227.   MAT3translate (trans, tempvec);
  228.   MAT3identity (rot);
  229.  
  230.   for (j=0; j < 3; j++)
  231.     for (i=0; i < 3; i++) 
  232.       rot[j][i] = basis[j][i];
  233.  
  234.   MAT3mult (vo_matrix,  rot, trans); 
  235.  
  236. } /* evaluateViewOrientationMatrix */
  237.  
  238.  
  239. /*
  240.  *  This function is modified from the SPHIGS package of Brown
  241.  *  University. See the book by Foley, vanDam, Feiner, Hughes
  242.  *  and Phillips, Chapter 6, for the algorithm.
  243.  */
  244.  
  245. void evaluateViewMappingMatrix (double umin, double umax,
  246.                                 double vmin, double vmax,
  247.                                 Point proj_ref_point, double F,
  248.                                 double B, MAT3mat vm_matrix)
  249. {
  250.   MAT3mat     step3_matrix,
  251.               step4_matrix,
  252.               step3and4_matrix,
  253.               step5_matrix,
  254.               step6_matrix;
  255.   MAT3hvec    vrp,
  256.               vrp_prime;
  257.   MAT3vec     z_axis,
  258.               shear,
  259.               tempvec,
  260.               dop_v,
  261.               scale_vec;
  262.   double      zmin;
  263.  
  264.  
  265.   MAT3_SET_HVEC (vrp, 0.0, 0.0, 0.0, 1.0);
  266.  
  267.   if (proj_ref_point[Z] <= 0.0)
  268.     fprintf (stderr, "Z-coordinate of PRP is zero or negative\n");
  269.   if (F >= proj_ref_point[Z])
  270.     fprintf (stderr, "front clip plane lies behind or on the PRP\n");
  271.   if (B >= F)
  272.     fprintf (stderr, "back clip plane is closer than front to PRP\n");
  273.  
  274.   MAT3_SCALE_VEC (tempvec, proj_ref_point, -1);
  275.   MAT3translate (step3_matrix, tempvec);
  276.   MAT3_ADD_VEC (vrp,  vrp, tempvec);
  277.   dop_v[0] = vrp[0] + (umax+umin)/2;
  278.   dop_v[1] = vrp[1] + (vmax+vmin)/2;
  279.   dop_v[2] = vrp[2];
  280.   MAT3_SET_VEC (z_axis, 0.0, 0.0, 1.0);
  281.   MAT3_SET_VEC (shear, -dop_v[X] / dop_v[Z], -dop_v[Y] / dop_v[Z], 0.0);
  282.   MAT3shear (step4_matrix, z_axis, shear);
  283.   MAT3mult (step3and4_matrix, step4_matrix, step3_matrix);
  284.   MAT3mult_hvec (vrp_prime, vrp, step4_matrix, FALSE);
  285.  
  286.   MAT3_SET_VEC (scale_vec,
  287.                 (2.0)*vrp_prime[Z]/((umax-umin)*(vrp_prime[Z]+B)),
  288.                 (2.0)*vrp_prime[Z]/((vmax-vmin)*(vrp_prime[Z]+B)),
  289.                 -1.0/(vrp_prime[Z]+B));
  290.  
  291.   MAT3scale (step5_matrix, scale_vec);
  292.   zmin = -(vrp_prime[Z]+F)/(vrp_prime[Z]+B);
  293.   MAT3zero (step6_matrix);
  294.   step6_matrix[0][0] = step6_matrix[1][1] = 1.0;
  295.   step6_matrix[3][2] = -1.0;
  296.   step6_matrix[2][2] = 1.0 / (1.0 + zmin);
  297.   step6_matrix[2][3] = -zmin / (1.0 + zmin);
  298.  
  299.   MAT3mult (vm_matrix, step5_matrix, step3and4_matrix);
  300.   MAT3mult (vm_matrix, step6_matrix, vm_matrix);
  301.  
  302. } /* evaluateViewMappingMatrix */
  303.  
  304.  
  305. void evaluateDevMatrix (double viewport_minx,
  306.                         double viewport_maxx, 
  307.                         double viewport_miny,
  308.                         double viewport_maxy,
  309.                         double viewport_minz,
  310.                         double viewport_maxz,
  311.                         MAT3mat dev_matrix)
  312. {
  313.   MAT3mat       scalemat,
  314.                 transmat;
  315.   MAT3vec       scale_vec,
  316.                 trans_vec;
  317.  
  318.  
  319.   MAT3_SET_VEC (scale_vec,
  320.                 (viewport_maxx - viewport_minx)/2,
  321.                 (viewport_maxy - viewport_miny)/2,
  322.                 (viewport_maxz - viewport_minz));
  323.  
  324.   MAT3scale (scalemat, scale_vec);
  325.   MAT3_SET_VEC (trans_vec, 1.0, 1.0, 1.0);
  326.   MAT3translate (transmat, trans_vec);
  327.   MAT3mult (dev_matrix, scalemat, transmat);
  328.   MAT3_SET_VEC (trans_vec, viewport_minx, viewport_miny, viewport_minz);
  329.   MAT3translate (transmat, trans_vec);
  330.   MAT3mult (dev_matrix, transmat, dev_matrix);
  331.  
  332. } /* evaluateDevMatrix */
  333.  
  334.  
  335. /*
  336.  *  This function writes the framebuffer to a TARGA file with
  337.  *  24 bit color.
  338.  */
  339.  
  340. #ifndef NOLUG
  341. void write_tga_buffer (FrameBuffer localBuff, char *filename)
  342. {
  343.   bitmap_hdr    output;
  344.   color         *rptr,
  345.                 *gptr,
  346.                 *bptr;
  347.   int           i, j;
  348.  
  349.  
  350.   allocatebitmap (&output, WINDOW_WIDTH, WINDOW_HEIGHT,
  351.                   COLOR_DEPTH, 1<<COLOR_DEPTH);
  352.   rptr = output.r;
  353.   gptr = output.g;
  354.   bptr = output.b;
  355.  
  356.   /*
  357.    *  Top to bottom row, left to right within a row.
  358.    */
  359.  
  360.   for (j = (WINDOW_HEIGHT - 1); j >= 0; j --) 
  361.   {
  362.     for (i = 0; i < WINDOW_WIDTH; i ++)
  363.     {
  364.       *rptr++ = localBuff[j][i].red;
  365.       *gptr++ = localBuff[j][i].green;
  366.       *bptr++ = localBuff[j][i].blue;
  367.     }
  368.   }
  369.  
  370.   write_tga_file (filename,&output);
  371.  
  372. } /* write_tga_buffer */
  373.  
  374. #else
  375.  
  376. /* NOLUG/RAW mode -- just dump the data IM-style (ASCII header,  , raster) */
  377.  
  378. void write_tga_buffer (FrameBuffer localBuff, char *filename)
  379. {
  380.   FILE *image;
  381.   int i, j;
  382.   image = fopen(filename,"w");
  383.   fprintf(image, "width %d\nheight %d\npixel r%dg%db%d\n%c",
  384.       WINDOW_WIDTH, WINDOW_HEIGHT, BW_DEPTH, BW_DEPTH, BW_DEPTH, '\f');
  385.   for (j = (WINDOW_HEIGHT - 1); j >= 0; j--) 
  386.     for (i = 0; i < WINDOW_WIDTH; i++)
  387.         {
  388.     putc(localBuff[j][i].red, image);
  389.         putc(localBuff[j][i].green, image);
  390.         putc(localBuff[j][i].blue, image);
  391.     }
  392.   fclose(image);
  393. }
  394. #endif
  395.