home *** CD-ROM | disk | FTP | other *** search
- /* Accurate Rendering Algorithm Based on the Z-Buffer Algorithm
- Developed by Raghu Karinthi
- West Virginia University
- Department of Computer Science
- P.O.Box 6330
- Morgantown WV 26506-6330
- raghu@cs.wvu.edu
- Version 3 01/20/95 */
-
- #include "ZRendv3.h"
- #ifndef M_PI
- #define M_PI 3.14159265358979323846
- #endif
-
- /*
- * Parser for the Input -- described in the document on Input
- * File Format.
- */
-
- void readNFFFile (char *filename, InDataSet dataset,
- Point vrp, MAT3vec vpn,
- MAT3vec vupv, Point prp,
- double *fplanep, double *bplanep,
- double *uminp, double *umaxp,
- double *vminp, double *vmaxp,
- Lights lights,
- BackGroundColor *backgndcolor,
- int *datasizep,
- MtlProp *activeProp,
- int *currentlight)
-
- {
- FILE *infile;
- char string[80];
- int i,
- count,
- state = WAITING,
- currentTriangle=-1;
- double angle,
- delta[3],
- length,
- lx, ly, lz;
- Point from;
-
-
- *currentlight = 0;
- infile = fopen (filename,"r");
- if (!infile)
- {
- char fullname[256], *extn;
- int j = 0;
- extn = ".nff";
- while (fullname[j] = filename[j]) j++;
- while (fullname[j] = *extn++);
- infile = fopen (fullname, "r");
- }
- if (!infile)
- {
- fprintf(stderr, "file '%s{.nff}' not found\n");
- exit(1);
- }
-
- while (fgets (&string[0],80,infile) != NULL)
- {
- if (state == WAITING)
- {
- switch (string[0])
- {
- case 'v':
- state = VIEWING; /* Read View Specification */
- break;
-
- case 'b': /* Background Color */
- sscanf (&string[1]," %lf %lf %lf\n", &lx, &ly, &lz);
- backgndcolor->red = MAX_INTENSITY * lx;
- backgndcolor->green = MAX_INTENSITY * ly;
- backgndcolor->blue = MAX_INTENSITY * lz;
- break;
-
- case 'l': /* Light Source */
- sscanf (&string[1], " %lf %lf %lf %lf %lf %lf",
- &lights[*currentlight].location[0],
- &lights[*currentlight].location[1],
- &lights[*currentlight].location[2],
- &lights[*currentlight].red,
- &lights[*currentlight].green,
- &lights[*currentlight].blue);
- (*currentlight)++;
- break;
-
- case 'f': /* Lighting Constants */
- sscanf (&string[1], " %lf %lf %lf %lf %lf %lf %lf",
- &(*activeProp).red,
- &(*activeProp).green,
- &(*activeProp).blue,
- &(*activeProp).diffuseK,
- &(*activeProp).ambientK,
- &(*activeProp).c1,
- &(*activeProp).c2);
- break;
-
- case 'p': /* Triangle to Follow */
- state = TRIDATA;
- count = 0;
- currentTriangle++;
- break;
-
- } /* switch on first char of line */
-
- } /* if in waiting state */
-
- else if (state == VIEWING)
- {
- switch(string[0])
- {
- case 'f': /* View point location */
- sscanf (&string[4], " %lf %lf %lf\n",
- &from[0], &from[1], &from[2]);
- break;
-
- case 'a':
- if (string[1] == 't') /* Look at */
- {
- sscanf(&string[2], " %lf %lf %lf\n",
- &vrp[0], &vrp[1], &vrp[2]);
- }
- else if (string[1] == 'n') /* Angle */
- {
- sscanf(&string[5], "%lf\n", &angle);
- }
- break;
-
- case 'u': /* Up Vector */
- sscanf (&string[2], " %lf %lf %lf\n",
- &vupv[0], &vupv[1], &vupv[2]);
- break;
-
- case 'h': /* Front or Hither Clipping Plane */
- sscanf (&string[6], " %lf\n", fplanep);
- break;
-
- case 'y': /* Back or Yon Clipping Plane */
- sscanf (&string[3], " %lf\n", bplanep);
- break;
-
- case 'r': /* resolution is currently ignored */
- for (i=0; i < 3; i++)
- {
- delta[i] = from[i] - vrp[i];
- }
- length = sqrt (delta[0] * delta[0] +
- delta[1] * delta[1] +
- delta[2] * delta[2]);
- for (i=0; i < 3; i++)
- {
- vpn[i] = delta[i] / length;
- }
- *fplanep = length - *fplanep;
- *bplanep = length - *bplanep;
- prp[0] = prp[1] = 0.0;
- prp[2] = length;
- *uminp = *vminp = -length * tan(angle*M_PI/360.0);
- *vmaxp = *umaxp = -*uminp;
- state = WAITING;
- break;
-
- } /* switch first char in line */
-
- } /* else if in viewing state */
-
- else if (state == TRIDATA)
- {
- sscanf (string,"%lf%lf%lf%lf%lf%lf\n",
- &(dataset[currentTriangle].vertices[count].vertex[0]),
- &(dataset[currentTriangle].vertices[count].vertex[1]),
- &(dataset[currentTriangle].vertices[count].vertex[2]),
- &(dataset[currentTriangle].vertices[count].normal[0]),
- &(dataset[currentTriangle].vertices[count].normal[1]),
- &(dataset[currentTriangle].vertices[count].normal[2]));
-
- if (count == 2)
- state = WAITING;
- else
- count++;
-
- } /* else if just read in triangle data */
-
- } /* while not eof */
-
- fclose(infile);
- *datasizep = currentTriangle + 1;
-
- } /* readNFFFile */
-
-
- /*
- * This function is modified from the SPHIGS package of Brown
- * University. See the book by Foley, vanDam, Feiner, Hughes
- * and Phillips, Chapter 6, for the algorithm.
- */
-
- void evaluateViewOrientationMatrix (Point view_ref_point,
- MAT3vec view_plane_normal,
- MAT3vec view_up_vector,
- MAT3mat vo_matrix)
- {
- MAT3vec tempvec,
- up_v,
- basis[3]; /* basis -- basis vectors for VRC system */
- MAT3mat trans,
- rot;
- double dot,
- tmp1;
- int i, j;
-
-
- MAT3_COPY_VEC (up_v, view_up_vector);
- MAT3_NORMALIZE_VEC (up_v, tmp1);
- MAT3_COPY_VEC (basis[2], view_plane_normal);
- MAT3_NORMALIZE_VEC (basis[2], tmp1);
- dot = MAT3_DOT_PRODUCT (up_v, basis[2]);
- MAT3_LINEAR_COMB (basis[1], 1.0, up_v, -dot, basis[2]);
- MAT3_NORMALIZE_VEC (basis[1], tmp1);
- MAT3cross_product (basis[0], basis[2], basis[1]);
- MAT3_SCALE_VEC (basis[0], basis[0], -1);
- MAT3_SCALE_VEC (tempvec, view_ref_point, -1);
- MAT3translate (trans, tempvec);
- MAT3identity (rot);
-
- for (j=0; j < 3; j++)
- for (i=0; i < 3; i++)
- rot[j][i] = basis[j][i];
-
- MAT3mult (vo_matrix, rot, trans);
-
- } /* evaluateViewOrientationMatrix */
-
-
- /*
- * This function is modified from the SPHIGS package of Brown
- * University. See the book by Foley, vanDam, Feiner, Hughes
- * and Phillips, Chapter 6, for the algorithm.
- */
-
- void evaluateViewMappingMatrix (double umin, double umax,
- double vmin, double vmax,
- Point proj_ref_point, double F,
- double B, MAT3mat vm_matrix)
- {
- MAT3mat step3_matrix,
- step4_matrix,
- step3and4_matrix,
- step5_matrix,
- step6_matrix;
- MAT3hvec vrp,
- vrp_prime;
- MAT3vec z_axis,
- shear,
- tempvec,
- dop_v,
- scale_vec;
- double zmin;
-
-
- MAT3_SET_HVEC (vrp, 0.0, 0.0, 0.0, 1.0);
-
- if (proj_ref_point[Z] <= 0.0)
- fprintf (stderr, "Z-coordinate of PRP is zero or negative\n");
- if (F >= proj_ref_point[Z])
- fprintf (stderr, "front clip plane lies behind or on the PRP\n");
- if (B >= F)
- fprintf (stderr, "back clip plane is closer than front to PRP\n");
-
- MAT3_SCALE_VEC (tempvec, proj_ref_point, -1);
- MAT3translate (step3_matrix, tempvec);
- MAT3_ADD_VEC (vrp, vrp, tempvec);
- dop_v[0] = vrp[0] + (umax+umin)/2;
- dop_v[1] = vrp[1] + (vmax+vmin)/2;
- dop_v[2] = vrp[2];
- MAT3_SET_VEC (z_axis, 0.0, 0.0, 1.0);
- MAT3_SET_VEC (shear, -dop_v[X] / dop_v[Z], -dop_v[Y] / dop_v[Z], 0.0);
- MAT3shear (step4_matrix, z_axis, shear);
- MAT3mult (step3and4_matrix, step4_matrix, step3_matrix);
- MAT3mult_hvec (vrp_prime, vrp, step4_matrix, FALSE);
-
- MAT3_SET_VEC (scale_vec,
- (2.0)*vrp_prime[Z]/((umax-umin)*(vrp_prime[Z]+B)),
- (2.0)*vrp_prime[Z]/((vmax-vmin)*(vrp_prime[Z]+B)),
- -1.0/(vrp_prime[Z]+B));
-
- MAT3scale (step5_matrix, scale_vec);
- zmin = -(vrp_prime[Z]+F)/(vrp_prime[Z]+B);
- MAT3zero (step6_matrix);
- step6_matrix[0][0] = step6_matrix[1][1] = 1.0;
- step6_matrix[3][2] = -1.0;
- step6_matrix[2][2] = 1.0 / (1.0 + zmin);
- step6_matrix[2][3] = -zmin / (1.0 + zmin);
-
- MAT3mult (vm_matrix, step5_matrix, step3and4_matrix);
- MAT3mult (vm_matrix, step6_matrix, vm_matrix);
-
- } /* evaluateViewMappingMatrix */
-
-
- void evaluateDevMatrix (double viewport_minx,
- double viewport_maxx,
- double viewport_miny,
- double viewport_maxy,
- double viewport_minz,
- double viewport_maxz,
- MAT3mat dev_matrix)
- {
- MAT3mat scalemat,
- transmat;
- MAT3vec scale_vec,
- trans_vec;
-
-
- MAT3_SET_VEC (scale_vec,
- (viewport_maxx - viewport_minx)/2,
- (viewport_maxy - viewport_miny)/2,
- (viewport_maxz - viewport_minz));
-
- MAT3scale (scalemat, scale_vec);
- MAT3_SET_VEC (trans_vec, 1.0, 1.0, 1.0);
- MAT3translate (transmat, trans_vec);
- MAT3mult (dev_matrix, scalemat, transmat);
- MAT3_SET_VEC (trans_vec, viewport_minx, viewport_miny, viewport_minz);
- MAT3translate (transmat, trans_vec);
- MAT3mult (dev_matrix, transmat, dev_matrix);
-
- } /* evaluateDevMatrix */
-
-
- /*
- * This function writes the framebuffer to a TARGA file with
- * 24 bit color.
- */
-
- #ifndef NOLUG
- void write_tga_buffer (FrameBuffer localBuff, char *filename)
- {
- bitmap_hdr output;
- color *rptr,
- *gptr,
- *bptr;
- int i, j;
-
-
- allocatebitmap (&output, WINDOW_WIDTH, WINDOW_HEIGHT,
- COLOR_DEPTH, 1<<COLOR_DEPTH);
- rptr = output.r;
- gptr = output.g;
- bptr = output.b;
-
- /*
- * Top to bottom row, left to right within a row.
- */
-
- for (j = (WINDOW_HEIGHT - 1); j >= 0; j --)
- {
- for (i = 0; i < WINDOW_WIDTH; i ++)
- {
- *rptr++ = localBuff[j][i].red;
- *gptr++ = localBuff[j][i].green;
- *bptr++ = localBuff[j][i].blue;
- }
- }
-
- write_tga_file (filename,&output);
-
- } /* write_tga_buffer */
-
- #else
-
- /* NOLUG/RAW mode -- just dump the data IM-style (ASCII header, , raster) */
-
- void write_tga_buffer (FrameBuffer localBuff, char *filename)
- {
- FILE *image;
- int i, j;
- image = fopen(filename,"w");
- fprintf(image, "width %d\nheight %d\npixel r%dg%db%d\n%c",
- WINDOW_WIDTH, WINDOW_HEIGHT, BW_DEPTH, BW_DEPTH, BW_DEPTH, '\f');
- for (j = (WINDOW_HEIGHT - 1); j >= 0; j--)
- for (i = 0; i < WINDOW_WIDTH; i++)
- {
- putc(localBuff[j][i].red, image);
- putc(localBuff[j][i].green, image);
- putc(localBuff[j][i].blue, image);
- }
- fclose(image);
- }
- #endif
-