home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
RISC DISC 3
/
RISC_DISC_3.iso
/
resources
/
etexts
/
gems
/
gemsv
/
ch7_6
/
zrendv3utils.c
< prev
Wrap
C/C++ Source or Header
|
1995-04-04
|
12KB
|
395 lines
/* 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