⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zrendv10.c

📁 [Game.Programming].Academic - Graphics Gems (6 books source code)
💻 C
📖 第 1 页 / 共 3 页
字号:
/*         Z Buffer Rendering Program Version 10, 02/12/96       Copyright Raghu Karinthi, West Virginia University	*/	       #include "ZRendv10.h"ZBuffer zb;OrigTriangle localSet[NUM_TRIANGLES];FrameBuffer fb;int16 BFCULL;int16 TRIVIAL_REJECT;int16 CLIP;int16 PHONG;MAT3fvec Hvector;SpecLightPoint SpecSource;float out_xmin, out_xmax, out_ymin, out_ymax, out_zmin, out_zmax;/* ---------------------------------------------------------------- */ /*  Generic Utilities */ #define TSWAP(_a_, _b_, _c_) ((_c_) = (_a_), (_a_) = (_b_), (_b_) = (_c_))#define min(_a_, _b_) (((_a_) < (_b_)) ? (_a_) : (_b_))#define max(_a_, _b_) (((_a_) > (_b_)) ? (_a_) : (_b_))#define ZFABS(x) (((x) < 0.0) ? -(x) : (x))/* --------------------------------------------------------------- *//*      Matrix and Vector utilities */#define MAT3_SCALE_VEC(RESULT_V,V,SCALE) \        ((RESULT_V)[0]=(V)[0]*(SCALE), (RESULT_V)[1]=(V)[1]*(SCALE), \	 (RESULT_V)[2]=(V)[2]*(SCALE))#define MAT3_DOT_PRODUCT(V1,V2) \			((V1)[0]*(V2)[0] + (V1)[1]*(V2)[1] + (V1)[2]*(V2)[2])#define MAT3_SUB_VEC(RESULT_V,V1,V2) \        ((RESULT_V)[0] = (V1)[0]-(V2)[0], (RESULT_V)[1] = (V1)[1]-(V2)[1], \         (RESULT_V)[2] = (V1)[2]-(V2)[2])#define MAT3_NORMALIZE_VEC(V,TEMP) \	if ((TEMP = sqrt(MAT3_DOT_PRODUCT(V,V))) > MAT3_EPSILON) { \	   TEMP = 1.0 / TEMP; \	   MAT3_SCALE_VEC(V,V,TEMP); \	} else TEMP = 0.0#define MAT3_CROSS_PRODUCT(RES,V1,V2) \((RES)[0] = (V1)[1] * (V2)[2] - (V1)[2] * (V2)[1], \ (RES)[1] = (V1)[2] * (V2)[0] - (V1)[0] * (V2)[2], \ (RES)[2] = (V1)[0] * (V2)[1] - (V1)[1] * (V2)[0]) void MAT3identity(MAT3mat m){int16 i, j;for (i=0; i < 4; i++)  for (j=0; j < 4; j++)    if (i==j)      m[i][j] = 1.0;    else      m[i][j] = 0.0;}void MAT3mult(MAT3mat result_mat, MAT3mat mat1,	MAT3mat mat2)/* result_mat = mat1 * mat2 */{int16 i, j, k;double tmp;MAT3mat tmp_mat;for (i=0; i < 4; i++)  for (j=0; j < 4; j++) {    tmp = 0.0;    for (k=0; k < 4; k++)      tmp += mat1[i][k]*mat2[k][j];    tmp_mat[i][j] = tmp;  }for (i=0; i < 4; i++)  for (j=0; j < 4; j++)    result_mat[i][j] = tmp_mat[i][j];}#define Det2D(a,b,c,d)((a)*(d)-(b)*(c))/* ------------------------------------------------------------------ *//* Fixed Point Utilities */#define fp_floor(x)  \  (((x) < 0) ? \   (!((x) & LOMASK)) ? ((x) >> LOBITS) : (((x) >> LOBITS)+1) : \   ((x)>> LOBITS) \  )/* *  Works only if x +ve. */#define fp_floor_pos(x) ((x) >> LOBITS)/* *  We use the following approximation. */#define fp_div(x,y) \	  (((x) < 0) ? (((x) / (y) - 1) << LOBITS) : (((x) / (y)) << LOBITS))/* *  Works only if xlo = 0. */#define fp_mult1(x,y) \  (((x)<0) ? \   -(((-(x) & HIMASK)>> LOBITS)*(y)) : \   ((x)>> LOBITS)*(y))/* * Works only if xhi = 0 */#define fp_mult2(x,y) \ (((y)<0)?(-(((((-(y))&HIMASK)>>LOBITS)*(x))+((((-(y))&LOMASK)*(x))>>LOBITS)))\    : ((((y) >> LOBITS) * (x)) + ((((y)&LOMASK)*(x))>>LOBITS)))/* *  Fractional Part if x +ve */#define fp_fraction(x) ((x) & LOMASK)/*  float to fix conversion */#define sh_float_to_fix(x) ( \  (((x) >> FLOATSZM1) ? \  (-( \  ((int32) ((((x) & EXPMASK) >> FFRACSZ) - FEXPOFFSET) > FFRACSZMLOBITS)? \     ((((x) & FFRACMASK) | (0x00800000)) <<  \       ((((x) & EXPMASK) >> FFRACSZ) - FEXPOFFSET - FFRACSZ + LOBITS)) \ : \     ((((x) & FFRACMASK) | (0x00800000)) >>  \       (FFRACSZ - LOBITS -(((x) & EXPMASK) >> FFRACSZ) + FEXPOFFSET )) \)) \ :\  (((int32) (( ((x) & EXPMASK) >> FFRACSZ) - FEXPOFFSET) > FFRACSZMLOBITS)? \     ((((x) & FFRACMASK) | (0x00800000)) <<  \       ((((x) & EXPMASK) >> FFRACSZ) - FEXPOFFSET - FFRACSZ + LOBITS)) \ : \     ((((x) & FFRACMASK) | (0x00800000)) >>  \       (FFRACSZ - LOBITS -(((x) & EXPMASK) >> FFRACSZ) + FEXPOFFSET )) \)) \)/*     float to fix conversion for Z*/#define shzfloat_to_fix(x) ( \  (((x) >> FLOATSZM1) ? \  (-( \  ((int32) ((((x) & EXPMASK) >> FFRACSZ) - FEXPOFFSET) > (FFRACSZ-ZLOBITS))? \     ((((x) & FFRACMASK) | (0x00800000)) <<  \       ((((x) & EXPMASK) >> FFRACSZ) - FEXPOFFSET - FFRACSZ + ZLOBITS)) \ : \     ((((x) & FFRACMASK) | (0x00800000)) >>  \       (FFRACSZ - ZLOBITS -(((x) & EXPMASK) >> FFRACSZ) + FEXPOFFSET )) \)) \ :\  (((int32) (( ((x) & EXPMASK) >> FFRACSZ) - FEXPOFFSET) > (FFRACSZ-ZLOBITS))? \     ((((x) & FFRACMASK) | (0x00800000)) <<  \       ((((x) & EXPMASK) >> FFRACSZ) - FEXPOFFSET - FFRACSZ + ZLOBITS)) \ : \     ((((x) & FFRACMASK) | (0x00800000)) >>  \       (FFRACSZ - ZLOBITS -(((x) & EXPMASK) >> FFRACSZ) + FEXPOFFSET )) \)) \)/* ------------------------------------------------------------------ *//* Output / Display *//*   *  This function writes the framebuffer to a TARGA file with *  24 bit color. */void write_tga_buffer (FrameBuffer fb, char *filename){bitmap_hdr    output;unsigned char *rptr, *gptr, *bptr;int16           i, j;allocatebitmap (&output, WW, WH, 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 = (WH - 1); j >= 0; j --) {  for (i = 0; i < WW; i ++) {    *rptr++ = ((fb[j][i]) & RMASK);    *gptr++ = ((fb[j][i]) & GMASK) >> 8;    *bptr++ = ((fb[j][i]) & BMASK) >> 16;  }}write_tga_file (filename,&output);} /* write_tga_buffer *//* ------------------------------------------------------------------ *//*  Rasterization */	 	/* *  The following : edge data structure, and functions EdgeScan, *  EdgeSetup, and rasterize_sorted_triangle, are modified from the code *  obtained in Graphics Gems III subdirectory accurate_scan due to Kurt *  Fleischer.  Also Refer Lathrop, Kirk, Voorhies, IEEE CG&A 10(5), *  1990 for a discussion */#define EdgeScan(e) \  if ((e).E<0) { \    (e).Ix += (e).AStep; (e).E += (e).DEA; \  } \  else { \   (e).Ix += (e).BStep; (e).E += (e).DEB; \  }#define EdgeSetup(e,xs,ys,dx,dy) \  if ((dy) >= FIX1) { \    si = fp_mult2((FIX1 - (fp_fraction((ys)))),(dx)); \    xi = (xs) + fp_div(si,(dy)); \    si = fp_div((dx), (dy)); \    (e).AStep = fp_floor(si); \    (e).BStep = (e).AStep+1; \    (e).DEA= (dx) - fp_mult1(si, (dy));  \    (e).DEB = (e).DEA - (dy); \    (e).E = fp_mult2(fp_fraction(xi),(dy)) + (e).DEB; \    (e).Ix = fp_floor_pos(xi); \} /* EdgeSetup *//* *  This function does the actual rasterization.  */void rasterize_sorted_triangle (int16       minyv, int16       midyv, 				int16       maxyv, ColorTriangleP   tp){int16         xleft[WH], xright[WH];int16         xmin, xmax, ymin, ymax;fixpoint      x0, y0, x1, y1, x2, y2;edge          left, right;int16         temp; int16         ccw;fixpoint      xi, si, dx, dy;int16         y;float fdx, fdy;float dr_by_dy, dg_by_dy, db_by_dy, dr_by_dx, dg_by_dx, db_by_dx, dz_by_dy,      dz_by_dx; int16         x; float fx0, fy0, z0, r0, g0, b0; /* fx0, fy0 distinguish them from x0 and y0 */float rxy0,gxy0,bxy0,rx0ymin,gx0ymin,bx0ymin,zx0ymin; int32 col, rgboffset[WW]; fixpoint rx0yminf, gx0yminf, bx0yminf, zx0yminf, dr_by_dy_f, dg_by_dy_f,         db_by_dy_f, dz_by_dy_f, dz_by_dx_f, dz_by_dx_x0f, z; float y1y0, y2y0, x1x0, x2x0, det, z1z0, z2z0;float r1r0, r2r0, g1g0, g2g0, b1b0, b2b0;float ndoth, ndothpown;int16 specr, specg, specb;int32 specterm;  x1x0 = (tp->vertices[midyv]).vertex[X] - (tp->vertices[minyv]).vertex[X];x2x0 = (tp->vertices[maxyv]).vertex[X] - (tp->vertices[minyv]).vertex[X];y1y0 = (tp->vertices[midyv]).vertex[Y] - (tp->vertices[minyv]).vertex[Y];y2y0 = (tp->vertices[maxyv]).vertex[Y] - (tp->vertices[minyv]).vertex[Y];  det = x1x0 * y2y0 - x2x0 * y1y0;  /* *  Convert the vertices of the triangle and their color value *  to 'fixpoint' representation. */x0 = sh_float_to_fix (*((fixpoint *)&((tp->vertices[minyv]).vertex[X])));y0 = sh_float_to_fix (*((fixpoint *)&((tp->vertices[minyv]).vertex[Y])));x1 = sh_float_to_fix (*((fixpoint *)&((tp->vertices[midyv]).vertex[X])));y1 = sh_float_to_fix (*((fixpoint *)&((tp->vertices[midyv]).vertex[Y])));x2 = sh_float_to_fix (*((fixpoint *)&((tp->vertices[maxyv]).vertex[X])));y2 = sh_float_to_fix (*((fixpoint *)&((tp->vertices[maxyv]).vertex[Y])));if (((tp->vertices[minyv]).vertex[X]) == 0.0) x0 = 0;if (((tp->vertices[minyv]).vertex[Y]) == 0.0) y0 = 0;if (((tp->vertices[midyv]).vertex[X]) == 0.0) x1 = 0;if (((tp->vertices[midyv]).vertex[Y]) == 0.0) y1 = 0;if (((tp->vertices[maxyv]).vertex[X]) == 0.0) x2 = 0;if (((tp->vertices[maxyv]).vertex[Y]) == 0.0) y2 = 0;xmin = max ((fp_floor_pos(min(min(x0,x1),x2))-1), 0);xmax = min ((fp_floor_pos(max(max(x0,x1),x2))+1), (WW-1));/* *  Find out whether the triangle edges are oriented in clockwise *  or anti-clockwise direction. * */ccw = det > 0.0;/* *  Setup first pair of edges. */if (ccw) {  EdgeSetup (left,  x0, y0, x2-x0, y2-y0)  EdgeSetup (right, x0, y0, x1-x0, y1-y0)} /* if ccw orientation of edges */else {  EdgeSetup (left, x0, y0, x1-x0, y1-y0)  EdgeSetup (right, x0, y0, x2-x0, y2-y0)} /* else clockwise orientation of edges */ymin = fp_floor_pos(y0)+1;temp = fp_floor_pos(y1);for (y = ymin; y <= temp; y++) {  xleft[y] = left.Ix;    EdgeScan (left)  xright[y] = right.Ix;   EdgeScan (right)} /* for every scan line upto the lower 'y' of the two edges *//* *  Setup the third edge. */if (ccw) {  EdgeSetup (right, x1, y1, x2-x1, y2-y1)}else {  EdgeSetup (left, x1, y1, x2-x1, y2-y1)}/* *  Now scan convert the rest of the triangle. */temp = fp_floor_pos(y1) + 1;ymax = fp_floor_pos (y2);for (y = temp; y <= ymax; y++) {  xleft[y] = left.Ix;    EdgeScan (left)  xright[y] = right.Ix;   EdgeScan (right)} /* for every scan line till the uppermost vertex of the triangle */if (PHONG) {  ndoth = tp->normal[X] * Hvector[X] + tp->normal[Y] * Hvector[Y] +    tp->normal[Z] * Hvector[Z];  ndothpown = pow(ndoth,SpecSource.spec_exp);  specr = SpecSource.red * ndothpown;  specg = SpecSource.green * ndothpown;  specb = SpecSource.blue * ndothpown;  specterm = specr + (specg << 8) + (specb << 16);}else  specterm = 0;z1z0 = (tp->vertices[midyv]).vertex[Z] - (tp->vertices[minyv]).vertex[Z];z2z0 = (tp->vertices[maxyv]).vertex[Z] - (tp->vertices[minyv]).vertex[Z];dz_by_dx = (y2y0 * z1z0 - y1y0 * z2z0)/det;dz_by_dy = (x1x0 * z2z0 - x2x0 * z1z0)/det;r1r0 = (tp->vertices[midyv]).red - (tp->vertices[minyv]).red;r2r0 = (tp->vertices[maxyv]).red - (tp->vertices[minyv]).red;dr_by_dx = (y2y0 * r1r0 - y1y0 * r2r0)/det;dr_by_dy = (x1x0 * r2r0 - x2x0 * r1r0)/det;g1g0 = (tp->vertices[midyv]).green - (tp->vertices[minyv]).green;g2g0 = (tp->vertices[maxyv]).green - (tp->vertices[minyv]).green;dg_by_dx = (y2y0 * g1g0 - y1y0 * g2g0)/det;dg_by_dy = (x1x0 * g2g0 - x2x0 * g1g0)/det;b1b0 = (tp->vertices[midyv]).blue - (tp->vertices[minyv]).blue;b2b0 = (tp->vertices[maxyv]).blue - (tp->vertices[minyv]).blue;db_by_dx = (y2y0 * b1b0 - y1y0 * b2b0)/det;db_by_dy = (x1x0 * b2b0 - x2x0 * b1b0)/det;  fx0 = (tp->vertices[minyv]).vertex[X];fy0 = (tp->vertices[minyv]).vertex[Y];z0 = (tp->vertices[minyv]).vertex[Z];r0 = (tp->vertices[minyv]).red;g0 = (tp->vertices[minyv]).green;b0 = (tp->vertices[minyv]).blue; 	fdy = ymin - fy0;rx0ymin = r0 + dr_by_dy * fdy;gx0ymin = g0 + dg_by_dy * fdy;bx0ymin = b0 + db_by_dy * fdy;zx0ymin = z0 + dz_by_dy * fdy;fdx = xmin - fx0;rxy0  = dr_by_dx * fdx;gxy0  = dg_by_dx * fdx;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -