home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 505a.lha / GrapicsGems / PolyScan / fancytest.c next >
C/C++ Source or Header  |  1991-05-01  |  3KB  |  107 lines

  1. /*
  2.  * fancytest.c: subroutine illustrating the use of poly_clip and poly_scan
  3.  * for Phong-shading and texture mapping.
  4.  *
  5.  * Note: lines enclosed in angle brackets '<', '>' should be replaced
  6.  * with the code described.
  7.  * Makes calls to hypothetical packages "shade", "image", "texture", "zbuffer".
  8.  *
  9.  * Paul Heckbert    Dec 1989
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <math.h>
  14. #include "poly.h"
  15.  
  16. #define XMAX 1280    /* hypothetical image width */
  17. #define YMAX 1024    /* hypothetical image height */
  18. #define LIGHT_INTEN 255        /* light source intensity */
  19.  
  20. void pixelproc();
  21.  
  22. fancytest()
  23. {
  24.     int i;
  25.     double WS[4][4];    /* world space to screen space transform */
  26.     Poly p;        /* a polygon */
  27.     Poly_vert *v;
  28.  
  29.     static Poly_box box = {0, XMAX, 0, YMAX, -32678, 32767.99};
  30.     /* 3-D screen clipping box, continuous coordinates */
  31.  
  32.     static Window win = {0, 0, XMAX-1, YMAX-1};
  33.     /* 2-D screen clipping window, discrete coordinates */
  34.  
  35.     <initialize world space position (x,y,z), normal (nx,ny,nz), and texture
  36.      position (u,v) at each vertex of p; set p.n>
  37.     <set WS to world-to-screen transform>
  38.  
  39.     /* transform vertices from world space to homogeneous screen space */
  40.     for (i=0; i<p.n; i++) {
  41.     v = &p.vert[i];
  42.     mx4_transform(v->x, v->y, v->z, 1., WS, &v->sx, &v->sy, &v->sz, &v->sw);
  43.     }
  44.  
  45.     /* interpolate sx, sy, sz, sw, nx, ny, nz, u, v in poly_clip */
  46.     p.mask = POLY_MASK(sx) | POLY_MASK(sy) | POLY_MASK(sz) | POLY_MASK(sw) |
  47.     POLY_MASK(nx) | POLY_MASK(ny) | POLY_MASK(nz) |
  48.     POLY_MASK(u) | POLY_MASK(v);
  49.  
  50.     poly_print("before clipping", &p);
  51.     if (poly_clip_to_box(&p, &box) == POLY_CLIP_OUT)    /* clip polygon */
  52.     return;                        /* quit if off-screen */
  53.  
  54.     /* do homogeneous division of screen position and texture position */
  55.     for (i=0; i<p.n; i++) {
  56.     v = &p.vert[i];
  57.     v->sx /= v->sw;
  58.     v->sy /= v->sw;
  59.     v->sz /= v->sw;
  60.     v->u /= v->sw;
  61.     v->v /= v->sw;
  62.     v->q = 1./v->sw;
  63.     }
  64.     /*
  65.      * previously we ignored q (assumed q=1), henceforth ignore sw (assume sw=1)
  66.      * Interpolate sx, sy, sz, nx, ny, nz, u, v, q in poly_scan
  67.      */
  68.     p.mask &= ~POLY_MASK(sw);
  69.     p.mask |= POLY_MASK(q);
  70.  
  71.     poly_print("scan converting the polygon", &p);
  72.     poly_scan(&p, &win, pixelproc);    /* scan convert! */
  73. }
  74.  
  75. static void pixelproc(x, y, pt)        /* called at each pixel by poly_scan */
  76. int x, y;
  77. Poly_vert *pt;
  78. {
  79.     int sz, u, v, inten;
  80.     double len, nor[3], diff, spec;
  81.  
  82.     sz = pt->sz;
  83.     if (sz < zbuffer_read(x, y)) {
  84.     len = sqrt(pt->nx*pt->nx + pt->ny*pt->ny + pt->nz*pt->nz);
  85.     nor[0] = pt->nx/len;        /* unitize the normal vector */
  86.     nor[1] = pt->ny/len;
  87.     nor[2] = pt->nz/len;
  88.     shade(nor, &diff, &spec);    /* compute specular and diffuse coeffs*/
  89.     u = pt->u/pt->q;        /* do homogeneous div. of texture pos */
  90.     v = pt->v/pt->q;
  91.     inten = texture_read(u, v)*diff + LIGHT_INTEN*spec;
  92.     image_write(x, y, inten);
  93.     zbuffer_write(x, y, sz);
  94.     }
  95. }
  96.  
  97. /* mx4_transform: transform 4-vector p by matrix m yielding q: q = p*m */
  98.  
  99. mx4_transform(px, py, pz, pw, m, qxp, qyp, qzp, qwp)
  100. double px, py, pz, pw, m[4][4], *qxp, *qyp, *qzp, *qwp;
  101. {
  102.     *qxp = px*m[0][0] + py*m[1][0] + pz*m[2][0] + pw*m[3][0];
  103.     *qyp = px*m[0][1] + py*m[1][1] + pz*m[2][1] + pw*m[3][1];
  104.     *qzp = px*m[0][2] + py*m[1][2] + pz*m[2][2] + pw*m[3][2];
  105.     *qwp = px*m[0][3] + py*m[1][3] + pz*m[2][3] + pw*m[3][3];
  106. }
  107.