home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsii / interphong.c < prev    next >
C/C++ Source or Header  |  1993-05-26  |  5KB  |  224 lines

  1. /******************************************************
  2. InterPhong shading for Scan-line rendering algorithms 
  3.  
  4. InterPhong shading has been used for rendering the 
  5. synthetic actors Marilyn
  6. Monroe and Humphrey Bogart in the film "Rendez-vous 
  7. a Montreal" directed by Nadia Magnenat Thalmann and 
  8. Daniel Thalmann, 1987
  9.  
  10. *******************************************************/
  11.  
  12. #include <math.h>
  13. #include "GraphicsGems.h"
  14.  
  15. #define RESANTI    3839
  16. #define NBMAXSOURCES    10
  17. #define SQRT3_2    3.464101615
  18. #define NIL     0
  19.  
  20. #define    Trunc(v)    ((int)floor(v))
  21.  
  22. /* normalize vector, return in pn */
  23. #define    unity(v,pn)    { double len ; \
  24.               len = sqrt((v).x*(v).x+(v).y*(v).y+(v).z*(v).z) ; \
  25.               (pn)->x=(v).x/len; (pn)->y=(v).y/len; \
  26.               (pn)->z=(v).z/len; }
  27.  
  28. typedef struct  {
  29.     double r, g, b;
  30. } Colors;
  31.  
  32. typedef struct  {
  33.     Colors coul;
  34.     double w, n;
  35. } RecCoul;
  36.  
  37. /*    Declaration of types used for the datastructures that 
  38. represent the information of a figure for the treatment by 
  39. scanline ( software rendering )
  40.  */
  41.  
  42. typedef struct blocedge { 
  43.     struct blocedge *edsuiv;    /* next edge in the list */
  44.     struct blocpoly *ptpoly1, *ptpoly2;    /* 
  45. polygons sharing this edge */
  46.     double x, dx;    /* Xmin and Xdelta */
  47.     double z, dz;    /* Zmin and Zdelta */
  48.     double ymax;    /* maximum Y of edge */
  49.     double nx, dnx, ny, dny, nz, dnz;
  50.     double px, dpx, py, dpy, pz, dpz;
  51. } BlockEdge;
  52.  
  53. typedef struct blocpoly {
  54.     struct blocpoly *polsuiv;    /* next polygon in the list */
  55.     struct T_ptedge *ptlisttrie;
  56.     RecCoul refl;    /* polygon characteristics color, spec.
  57.              coeff., ... */
  58.     Colors coulpoly;    /* polygon shading */
  59.     Vector3 normalctri;
  60.     double bias, tension;
  61. } BlockPoly;
  62.  
  63. typedef struct T_ptedge {
  64.     BlockEdge *ptedtrie;
  65.     struct T_ptedge *ptedsuiv;
  66. } PtEdge;
  67.  
  68. /*
  69.  * Declaration of types concerning the calculated image for the
  70.  * current scanline ( Z-buffer )
  71.  */
  72.  
  73. typedef struct scanbuf_el {
  74.     Colors c,     /* final color of this pixel */
  75.            polycolor;    /* initial color of 
  76. visible polygon */
  77. } ScanBufType [RESANTI + 1]; 
  78.  
  79. typedef struct depthbuf_el {
  80.     double depth;    /* depth of opaque 
  81. pixel */
  82. } DepthBufType [RESANTI + 1]; 
  83.  
  84. typedef struct    {
  85.     int    xmin, xmax;
  86. } PosBufType;
  87.  
  88. /*
  89.  * Declaration of data structure types to store light source information 
  90.  */
  91.  
  92. static PosBufType    posbuffer;
  93.  
  94. ScanBufType _scanbuffer;        /* Z-buffer */
  95. DepthBufType _depthbuffer;
  96.  
  97. static
  98. void intphong(nestime, noriginal, bias, tension)
  99. Vector3 *nestime, *noriginal;
  100. double bias, tension;
  101.  
  102. /*
  103.     Purpose: interphong interpolation
  104.     Arguments
  105.     nestime     : estimated normal
  106.     noriginal    : original normal
  107.     bias, tension    : bias and tension 
  108. */
  109.  
  110. {
  111.     double fact;
  112.     Vector3    vtemp;
  113.  
  114.     V3Sub (noriginal, nestime, &vtemp);
  115.     fact = fabs(vtemp.x) + fabs(vtemp.y) + fabs(vtemp.z);
  116.     fact = (fact + bias * (SQRT3_2 - fact)) * tension;
  117.     V3Scale (vtemp,fact*V3Length (vtemp));
  118.     V3Add (nestime, &vtemp,nestime); 
  119.     V3Normalize (nestime);
  120. }
  121.  
  122. /*===========================================================*/
  123.  
  124. void shadepoly(ptpoly)
  125. BlockPoly    *ptpoly;
  126.  
  127. /*
  128.     Purpose: shades a polygon on the current scanline
  129.     Arguments
  130.     ptpoly        : polygon to render
  131.     noscline    : current scanline
  132. */
  133.  
  134. {
  135.     BlockEdge    *edge1, *edge2;
  136.     PtEdge    *tripedtrie;
  137.     int        xx;
  138.     double    dxx;
  139.     double    zz, dzz;
  140.     double    diffx;
  141.     double    dnnx, dnny, dnnz;
  142.     Vector3    normal, unitn;
  143.     double    dppx, dppy, dppz;
  144.     Vector3    point;
  145.     Colors    cc;
  146.     RecCoul    ptrefl;
  147.     register struct scanbuf_el    *scanel ;
  148.     register struct depthbuf_el    *depthel ;
  149.  
  150.     tripedtrie = ptpoly->ptlisttrie;
  151.     ptrefl = ptpoly->refl;
  152.     while (tripedtrie != (PtEdge *)NIL) 
  153.     {
  154.         edge1 = tripedtrie->ptedtrie;
  155.         if (tripedtrie->ptedsuiv != (PtEdge *)NIL) 
  156.         {
  157.             tripedtrie = tripedtrie->ptedsuiv;
  158.             edge2 = tripedtrie->ptedtrie;
  159.         } 
  160.         else 
  161.             abort(" Odd number of edges on scanline");
  162.  
  163.         dxx = edge2->x - edge1->x;    /* distance between edges
  164.                            on current scanline */
  165.         if (dxx < 1.0)            /* crossing edges ? */
  166.             dxx = 1.0;
  167.         dxx = 1.0 / dxx;        /* increment per pixel */
  168.         xx = Trunc(edge1->x) + 1;    /* first pixel to be 
  169.                            colored */
  170.         diffx = xx - edge1->x;
  171.  
  172.         dzz = (edge2->z - edge1->z) * dxx;
  173.         zz = edge1->z + dzz * diffx;
  174.  
  175.         if (xx < posbuffer.xmin)
  176.             posbuffer.xmin = xx;
  177.         if (edge2->x > posbuffer.xmax)
  178.             posbuffer.xmax = Trunc(edge2->x);
  179.  
  180.         dnnx = (edge2->nx - edge1->nx) * dxx;
  181.         dnny = (edge2->ny - edge1->ny) * dxx;
  182.         dnnz = (edge2->nz - edge1->nz) * dxx;
  183.         normal.x = (edge1->nx + dnnx * diffx) + dnnx;
  184.         normal.y = (edge1->ny + dnny * diffx) + dnny;
  185.         normal.z = (edge1->nz + dnnz * diffx) + dnnz;
  186.         dppx = (edge2->px - edge1->px) * dxx;
  187.         dppy = (edge2->py - edge1->py) * dxx;
  188.         dppz = (edge2->pz - edge1->pz) * dxx;
  189.         point.x = (edge1->px + dppx * diffx) + dppx;
  190.         point.y = (edge1->py + dppy * diffx) + dppy;
  191.         point.z = (edge1->pz + dppz * diffx) + dppz;
  192.  
  193.         while (xx <= edge2->x) 
  194.         {
  195.             scanel = &_scanbuffer[xx];
  196.             depthel = &_depthbuffer[xx];
  197.  
  198.             if (zz < depthel->depth) 
  199.             {
  200.                 unity(normal, &unitn);
  201.                 intphong(&unitn, &ptpoly->normalctri, 
  202.                     ptpoly->bias, ptpoly->tension);
  203.                 cc = ptpoly->coulpoly;
  204.                 depthel->depth = zz;
  205.                 scanel->polycolor = ptrefl.coul;
  206.                 scanel->c = cc;
  207.             }
  208.             xx = xx + 1;
  209.             zz = zz + dzz;
  210.             normal.x = normal.x + dnnx;
  211.             normal.y = normal.y + dnny;
  212.             normal.z = normal.z + dnnz;
  213.             point.x = point.x + dppx;
  214.             point.y = point.y + dppy;
  215.             point.z = point.z + dppz;
  216.         }
  217.         tripedtrie = tripedtrie->ptedsuiv;
  218.     }
  219. }
  220.  
  221.  
  222.  
  223.  
  224.