home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / radiance / nextrad.lha / NeXtRad / render.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-22  |  10.2 KB  |  357 lines

  1. /* render.c */
  2. /* written by : Jason R. Wilson    2/23/93 */
  3.  
  4. /* provides routines for rasterization, hidden surface removal,
  5.     and smooth linear interpolated shading */
  6.  
  7.  
  8. #include <math.h>
  9. #include <stdio.h>
  10. #include "render.h"
  11.  
  12. /*----------------------------------------------------------------------*/
  13.  
  14. void RasterizeEdge (EdgeListCell *EdgeList,VisVertexCell *a,
  15.             VisVertexCell *b,int winWidth,int winHeight,
  16.                     Window ViewWindow)
  17.  
  18. /* This routine Rasterizes an Edge and adds the information to the edge */
  19. /* list. */
  20.  
  21. {
  22.    int xs,ys,xe,ye; /* the pixel coordinates of the 2 end-points */
  23.    double ViewHeight,ViewWidth;
  24.    double x;
  25.    int y;
  26.    double m;
  27.    double Ri,Ris,Rie,Rinci;
  28.    double Gi,Gis,Gie,Ginci;
  29.    double Bi,Bis,Bie,Binci;
  30.    double zs,ze,z,incz;
  31.    double us,ue,u,incu;
  32.    double vs,ve,v,incv;
  33.    double ns,ne,n,incn;
  34.    VisVertexCell *temp2;
  35.    
  36.    ViewHeight = ViewWindow.Wt - ViewWindow.Wb;
  37.    ViewWidth  = ViewWindow.Wr - ViewWindow.Wl;
  38.    if (a->ViewPosition.hom[1] > b->ViewPosition.hom[1])
  39.    {
  40.       temp2 = a; /* swap the pointers */
  41.       a = b;
  42.       b = temp2;
  43.    }
  44.    
  45.  
  46.  
  47.    /* initialization */
  48.  
  49.    xs = rint(((a->ViewPosition.hom[0] - ViewWindow.Wl)/ViewWidth)*winWidth);
  50.    xe = rint(((b->ViewPosition.hom[0] - ViewWindow.Wl)/ViewWidth)*winWidth);
  51.    ys = rint(((a->ViewPosition.hom[1] - ViewWindow.Wb)/ViewHeight)*winHeight);
  52.    ye = rint(((b->ViewPosition.hom[1] - ViewWindow.Wb)/ViewHeight)*winHeight);
  53.  
  54.  
  55.    Ris = a->B.r;
  56.    Rie = b->B.r;
  57.  
  58.    Gis = a->B.g;
  59.    Gie = b->B.g;
  60.  
  61.    Bis = a->B.b;
  62.    Bie = b->B.b;
  63.  
  64.    zs = a->ViewPosition.hom[2];
  65.    ze = b->ViewPosition.hom[2];
  66.  
  67.    us = a->ViewPosition.hom[3]*a->ViewPosition.hom[0];
  68.    ue = b->ViewPosition.hom[3]*b->ViewPosition.hom[0];
  69.    vs = a->ViewPosition.hom[3]*a->ViewPosition.hom[1];
  70.    ve = b->ViewPosition.hom[3]*b->ViewPosition.hom[1];
  71.    ns = a->ViewPosition.hom[3]*a->ViewPosition.hom[2];
  72.    ne = b->ViewPosition.hom[3]*b->ViewPosition.hom[2];   
  73.  
  74.    
  75.    if (!((ye - ys - 1) == 0))
  76.    {
  77.       Rinci = (Rie - Ris)/(ye - ys - 1);
  78.       Ginci = (Gie - Gis)/(ye - ys - 1);
  79.       Binci = (Bie - Bis)/(ye - ys - 1);
  80.       incz = (ze - zs)/(ye - ys - 1);
  81.       incu = (ue - us)/(ye - ys - 1);
  82.       incv = (ve - vs)/(ye - ys - 1);
  83.       incn = (ne - ns)/(ye - ys - 1);      
  84.    }
  85.  
  86.    Ri = Ris;
  87.    Gi = Gis;
  88.    Bi = Bis;
  89.    z = zs;
  90.    u = us;
  91.    v = vs;
  92.    n = ns;
  93.    
  94.    x = (double)xs;
  95.  
  96.    if (!((ye - ys) == 0))
  97.       m = (double)(xe - xs)/(ye - ys);
  98.    for (y = ys;y < ye;y++)
  99.    {
  100.       /* add info to edge list */
  101.      if (EdgeList[y].OneHere == false) 
  102.       {
  103.      EdgeList[y].Xpos1 = rint(x);
  104.      EdgeList[y].RIntensity1 = Ri;
  105.      EdgeList[y].GIntensity1 = Gi;
  106.      EdgeList[y].BIntensity1 = Bi;
  107.      EdgeList[y].Depth1 = z;
  108.      EdgeList[y].uValue1 = u;
  109.      EdgeList[y].vValue1 = v;
  110.      EdgeList[y].nValue1 = n;     
  111.      EdgeList[y].OneHere = true;
  112.       }
  113.       else 
  114.       {
  115.      if (EdgeList[y].Xpos1 > rint(x))
  116.      {
  117.         EdgeList[y].Xpos2 = EdgeList[y].Xpos1;
  118.         EdgeList[y].RIntensity2 = EdgeList[y].RIntensity1;
  119.         EdgeList[y].GIntensity2 = EdgeList[y].GIntensity1;
  120.         EdgeList[y].BIntensity2 = EdgeList[y].BIntensity1;
  121.         EdgeList[y].Depth2 = EdgeList[y].Depth1;
  122.         EdgeList[y].uValue2 = EdgeList[y].uValue1;
  123.         EdgeList[y].vValue2 = EdgeList[y].vValue1;
  124.         EdgeList[y].nValue2 = EdgeList[y].nValue1;        
  125.         EdgeList[y].Xpos1 = rint(x);
  126.         EdgeList[y].RIntensity1 = Ri;
  127.         EdgeList[y].GIntensity1 = Gi;
  128.         EdgeList[y].BIntensity1 = Bi;
  129.         EdgeList[y].Depth1 = z;
  130.         EdgeList[y].uValue1 = u;
  131.         EdgeList[y].vValue1 = v;
  132.         EdgeList[y].nValue1 = n;        
  133.      }
  134.      else
  135.      {
  136.         EdgeList[y].Xpos2 = rint(x);
  137.         EdgeList[y].RIntensity2 = Ri;
  138.         EdgeList[y].GIntensity2 = Gi;
  139.         EdgeList[y].BIntensity2 = Bi;
  140.         EdgeList[y].Depth2 = z;
  141.         EdgeList[y].uValue2 = u;
  142.         EdgeList[y].vValue2 = v;
  143.         EdgeList[y].nValue2 = n;        
  144.      }
  145.       }
  146.       /* update */
  147.       x = x + m;
  148.       Ri += Rinci;
  149.       Gi += Ginci;
  150.       Bi += Binci;
  151.       z += incz;
  152.       u += incu;
  153.       v += incv;
  154.       n += incn;     
  155.    }
  156.       
  157. }
  158.  
  159. /***********************************************************************/
  160.  
  161.       
  162. /*----------------------------------------------------------------------*/
  163. void renderpoly (PolygonCell *CurrentPoly,ObjectCell *Object,double **Zbuffer,Color **ScreenMap,
  164.                    Window ViewWindow,double *MaxIntensity,
  165.            int winWidth,int winHeight,
  166.            Vector uvector,Vector vvector,Vector nvector,Point rpoint)
  167. /* This function renders the polygon(elements) using Zbuffer hidden surface removal */
  168. /* and linear interpolation */
  169. {
  170.  
  171.    EdgeListCell EdgeList[winHeight];
  172.    int loop,loop2;
  173.    VisVertexCell *FirstVertex;
  174.    VisVertexCell *Traverse;
  175.    Color color;
  176.    Color textureColor;
  177.    int ut,vt;
  178.    Homog MapMe;
  179.    double Ri,Riinc;
  180.    double Gi,Giinc;
  181.    double Bi,Biinc;
  182.    double z,zinc;
  183.    double u,uinc;
  184.    double v,vinc;
  185.    double n,ninc;
  186.    Boolean Gone;
  187.     
  188.    /* init. EdgeList */
  189.    for (loop = 0;loop < winHeight;loop++)
  190.       EdgeList[loop].OneHere = false;
  191.  
  192.    /* draw each non-culled polygon */
  193.  
  194.    if (CurrentPoly->Subs[0] == NULL)
  195.    {
  196.       if (!(CurrentPoly->Culled == true))
  197.       {
  198.  
  199.      /* clip polygon */
  200.  
  201.      ClipPolygon (CurrentPoly,ViewWindow,&Gone);
  202.  
  203.      if (!(Gone == true))
  204.      {
  205.      /* rasterize edges of polygon */     
  206.  
  207.      Traverse = CurrentPoly->VisVertices;
  208.      FirstVertex = Traverse;
  209.      while (!(Traverse->Next == NULL))
  210.      {
  211.         RasterizeEdge (EdgeList,Traverse,
  212.                Traverse->Next,winWidth,winHeight,ViewWindow);
  213.         Traverse = Traverse->Next;
  214.  
  215.      }
  216.      RasterizeEdge (EdgeList,Traverse,FirstVertex,winWidth,winHeight,
  217.             ViewWindow); 
  218.  
  219.      /* draw scan lines of polygon */
  220.      
  221.      for (loop = winHeight;loop > 0;loop--)
  222.         if (EdgeList[loop].OneHere == true)
  223.         {
  224.            Ri = EdgeList[loop].RIntensity1;
  225.            Gi = EdgeList[loop].GIntensity1;
  226.            Bi = EdgeList[loop].BIntensity1;
  227.            z = EdgeList[loop].Depth1;
  228.            u = EdgeList[loop].uValue1;
  229.            v = EdgeList[loop].vValue1;
  230.            n = EdgeList[loop].nValue1;
  231.  
  232.            if (!(EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1 == 0))
  233.            {
  234.           Riinc =
  235.             (EdgeList[loop].RIntensity2 - EdgeList[loop].RIntensity1)/
  236.              (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
  237.           Giinc =
  238.             (EdgeList[loop].GIntensity2 - EdgeList[loop].GIntensity1)/
  239.              (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
  240.           Biinc =
  241.             (EdgeList[loop].BIntensity2 - EdgeList[loop].BIntensity1)/
  242.              (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
  243.           zinc = (EdgeList[loop].Depth2 - EdgeList[loop].Depth1)/
  244.              (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
  245.           uinc = (EdgeList[loop].uValue2 - EdgeList[loop].uValue1)/
  246.              (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
  247.           vinc = (EdgeList[loop].vValue2 - EdgeList[loop].vValue1)/
  248.              (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
  249.           ninc = (EdgeList[loop].nValue2 - EdgeList[loop].nValue1)/
  250.              (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
  251.              }
  252.              
  253.            for (loop2 = EdgeList[loop].Xpos1;loop2 < EdgeList[loop].Xpos2;
  254.             loop2++)
  255.            {
  256.          if (CurrentPoly->Textured == true)
  257.            /* scale the colors with the texture map stored in obj. */
  258.            {
  259.              MapMe.hom[0] = u;
  260.              MapMe.hom[1] = v;
  261.              MapMe.hom[2] = n;
  262.              MapMe.hom[3] = 1.0;
  263.              MapMe.hom[0] = uvector.dx*u + vvector.dx*v + nvector.dx*n + rpoint.x;
  264.              MapMe.hom[1] = uvector.dy*u + vvector.dy*v + nvector.dy*n + rpoint.y;
  265.              MapMe.hom[2] = uvector.dz*u + vvector.dz*v + nvector.dz*n + rpoint.z;             
  266.              
  267.              HomogMultiply (MapMe.hom,Object->InverseTransform.mat); 
  268.              MapMe.hom[0] = 1.0 - MapMe.hom[0];
  269.              ut = rint (MapMe.hom[0]*(Object->mapWidth)); 
  270.              vt = rint (MapMe.hom[1]*(Object->mapHeight)); 
  271.              if (ut < 0) ut = 0;
  272.              if (vt < 0) vt = 0;
  273.              if (ut >= Object->mapWidth)
  274.                ut = Object->mapWidth - 1; 
  275.              if (vt >= Object->mapHeight)
  276.                vt = Object->mapHeight - 1;
  277.              
  278.              textureColor.r = Object->TextureMap[ut][vt].r
  279.                /CurrentPoly->R.r;
  280.              textureColor.g = Object->TextureMap[ut][vt].g
  281.                /CurrentPoly->R.g;
  282.              textureColor.b = Object->TextureMap[ut][vt].b
  283.                /CurrentPoly->R.b;
  284.              color.r = Ri*textureColor.r;
  285.              color.g = Gi*textureColor.g;
  286.              color.b = Bi*textureColor.b;
  287.            }
  288.          else
  289.            {
  290.              color.r =  Ri;
  291.              color.g =  Gi;
  292.              color.b =  Bi;
  293.            }
  294.            if (z < Zbuffer[loop2][winHeight-loop])
  295.           {
  296.              Zbuffer[loop2][winHeight-loop] = z;
  297. /***********************************************************************/
  298.              if (color.r > *MaxIntensity)
  299.                *MaxIntensity = color.r;
  300.              if (color.g > *MaxIntensity)
  301.                *MaxIntensity = color.g;
  302.              if (color.b > *MaxIntensity)
  303.                *MaxIntensity = color.b;             
  304.              ScreenMap[loop2][winHeight-loop].r = color.r; 
  305.              ScreenMap[loop2][winHeight-loop].g = color.g; 
  306.              ScreenMap[loop2][winHeight-loop].b = color.b; 
  307. /***********************************************************************/
  308.           }
  309.           Ri += Riinc;
  310.           Gi += Giinc;
  311.           Bi += Biinc;
  312.           z += zinc;
  313.           u += uinc;
  314.           v += vinc;
  315.           n += ninc;
  316.            }
  317.            EdgeList[loop].OneHere = false;
  318.          }
  319.        }
  320.        }
  321.     }
  322.    else
  323.      {
  324.       renderpoly (CurrentPoly->Subs[0],Object,Zbuffer,ScreenMap,ViewWindow,MaxIntensity,winWidth,winHeight,uvector,vvector,nvector,rpoint);
  325.       renderpoly (CurrentPoly->Subs[1],Object,Zbuffer,ScreenMap,ViewWindow,MaxIntensity,winWidth,winHeight,uvector,vvector,nvector,rpoint);
  326.       renderpoly (CurrentPoly->Subs[2],Object,Zbuffer,ScreenMap,ViewWindow,MaxIntensity,winWidth,winHeight,uvector,vvector,nvector,rpoint);
  327.       renderpoly (CurrentPoly->Subs[3],Object,Zbuffer,ScreenMap,ViewWindow,MaxIntensity,winWidth,winHeight,uvector,vvector,nvector,rpoint);
  328.     }
  329.  }
  330.  
  331. /*----------------------------------------------------------------------*/
  332.  
  333. void RenderObject (ObjectCell *Object,double **Zbuffer,Color **ScreenMap,
  334.                    Window ViewWindow,double *MaxIntensity,
  335.            int winWidth,int winHeight,
  336.            Vector uvector,Vector vvector,Vector nvector,Point rpoint)
  337. {
  338.   PolygonCell *CurrentPoly;
  339.   CurrentPoly = Object->PolygonHead;
  340.   while (!(CurrentPoly == NULL))
  341.     {
  342.       renderpoly (CurrentPoly,Object,Zbuffer,ScreenMap,ViewWindow,MaxIntensity,winWidth,winHeight,uvector,vvector,nvector,rpoint);
  343.       CurrentPoly = CurrentPoly->Next;
  344.     }
  345.  
  346. }
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.