home *** CD-ROM | disk | FTP | other *** search
- /* render.c */
- /* written by : Jason R. Wilson 2/23/93 */
-
- /* provides routines for rasterization, hidden surface removal,
- and smooth linear interpolated shading */
-
-
- #include <math.h>
- #include <stdio.h>
- #include "render.h"
-
- /*----------------------------------------------------------------------*/
-
- void RasterizeEdge (EdgeListCell *EdgeList,VisVertexCell *a,
- VisVertexCell *b,int winWidth,int winHeight,
- Window ViewWindow)
-
- /* This routine Rasterizes an Edge and adds the information to the edge */
- /* list. */
-
- {
- int xs,ys,xe,ye; /* the pixel coordinates of the 2 end-points */
- double ViewHeight,ViewWidth;
- double x;
- int y;
- double m;
- double Ri,Ris,Rie,Rinci;
- double Gi,Gis,Gie,Ginci;
- double Bi,Bis,Bie,Binci;
- double zs,ze,z,incz;
- double us,ue,u,incu;
- double vs,ve,v,incv;
- double ns,ne,n,incn;
- VisVertexCell *temp2;
-
- ViewHeight = ViewWindow.Wt - ViewWindow.Wb;
- ViewWidth = ViewWindow.Wr - ViewWindow.Wl;
- if (a->ViewPosition.hom[1] > b->ViewPosition.hom[1])
- {
- temp2 = a; /* swap the pointers */
- a = b;
- b = temp2;
- }
-
-
-
- /* initialization */
-
- xs = rint(((a->ViewPosition.hom[0] - ViewWindow.Wl)/ViewWidth)*winWidth);
- xe = rint(((b->ViewPosition.hom[0] - ViewWindow.Wl)/ViewWidth)*winWidth);
- ys = rint(((a->ViewPosition.hom[1] - ViewWindow.Wb)/ViewHeight)*winHeight);
- ye = rint(((b->ViewPosition.hom[1] - ViewWindow.Wb)/ViewHeight)*winHeight);
-
-
- Ris = a->B.r;
- Rie = b->B.r;
-
- Gis = a->B.g;
- Gie = b->B.g;
-
- Bis = a->B.b;
- Bie = b->B.b;
-
- zs = a->ViewPosition.hom[2];
- ze = b->ViewPosition.hom[2];
-
- us = a->ViewPosition.hom[3]*a->ViewPosition.hom[0];
- ue = b->ViewPosition.hom[3]*b->ViewPosition.hom[0];
- vs = a->ViewPosition.hom[3]*a->ViewPosition.hom[1];
- ve = b->ViewPosition.hom[3]*b->ViewPosition.hom[1];
- ns = a->ViewPosition.hom[3]*a->ViewPosition.hom[2];
- ne = b->ViewPosition.hom[3]*b->ViewPosition.hom[2];
-
-
- if (!((ye - ys - 1) == 0))
- {
- Rinci = (Rie - Ris)/(ye - ys - 1);
- Ginci = (Gie - Gis)/(ye - ys - 1);
- Binci = (Bie - Bis)/(ye - ys - 1);
- incz = (ze - zs)/(ye - ys - 1);
- incu = (ue - us)/(ye - ys - 1);
- incv = (ve - vs)/(ye - ys - 1);
- incn = (ne - ns)/(ye - ys - 1);
- }
-
- Ri = Ris;
- Gi = Gis;
- Bi = Bis;
- z = zs;
- u = us;
- v = vs;
- n = ns;
-
- x = (double)xs;
-
- if (!((ye - ys) == 0))
- m = (double)(xe - xs)/(ye - ys);
- for (y = ys;y < ye;y++)
- {
- /* add info to edge list */
- if (EdgeList[y].OneHere == false)
- {
- EdgeList[y].Xpos1 = rint(x);
- EdgeList[y].RIntensity1 = Ri;
- EdgeList[y].GIntensity1 = Gi;
- EdgeList[y].BIntensity1 = Bi;
- EdgeList[y].Depth1 = z;
- EdgeList[y].uValue1 = u;
- EdgeList[y].vValue1 = v;
- EdgeList[y].nValue1 = n;
- EdgeList[y].OneHere = true;
- }
- else
- {
- if (EdgeList[y].Xpos1 > rint(x))
- {
- EdgeList[y].Xpos2 = EdgeList[y].Xpos1;
- EdgeList[y].RIntensity2 = EdgeList[y].RIntensity1;
- EdgeList[y].GIntensity2 = EdgeList[y].GIntensity1;
- EdgeList[y].BIntensity2 = EdgeList[y].BIntensity1;
- EdgeList[y].Depth2 = EdgeList[y].Depth1;
- EdgeList[y].uValue2 = EdgeList[y].uValue1;
- EdgeList[y].vValue2 = EdgeList[y].vValue1;
- EdgeList[y].nValue2 = EdgeList[y].nValue1;
- EdgeList[y].Xpos1 = rint(x);
- EdgeList[y].RIntensity1 = Ri;
- EdgeList[y].GIntensity1 = Gi;
- EdgeList[y].BIntensity1 = Bi;
- EdgeList[y].Depth1 = z;
- EdgeList[y].uValue1 = u;
- EdgeList[y].vValue1 = v;
- EdgeList[y].nValue1 = n;
- }
- else
- {
- EdgeList[y].Xpos2 = rint(x);
- EdgeList[y].RIntensity2 = Ri;
- EdgeList[y].GIntensity2 = Gi;
- EdgeList[y].BIntensity2 = Bi;
- EdgeList[y].Depth2 = z;
- EdgeList[y].uValue2 = u;
- EdgeList[y].vValue2 = v;
- EdgeList[y].nValue2 = n;
- }
- }
- /* update */
- x = x + m;
- Ri += Rinci;
- Gi += Ginci;
- Bi += Binci;
- z += incz;
- u += incu;
- v += incv;
- n += incn;
- }
-
- }
-
- /***********************************************************************/
-
-
- /*----------------------------------------------------------------------*/
- void renderpoly (PolygonCell *CurrentPoly,ObjectCell *Object,double **Zbuffer,Color **ScreenMap,
- Window ViewWindow,double *MaxIntensity,
- int winWidth,int winHeight,
- Vector uvector,Vector vvector,Vector nvector,Point rpoint)
- /* This function renders the polygon(elements) using Zbuffer hidden surface removal */
- /* and linear interpolation */
- {
-
- EdgeListCell EdgeList[winHeight];
- int loop,loop2;
- VisVertexCell *FirstVertex;
- VisVertexCell *Traverse;
- Color color;
- Color textureColor;
- int ut,vt;
- Homog MapMe;
- double Ri,Riinc;
- double Gi,Giinc;
- double Bi,Biinc;
- double z,zinc;
- double u,uinc;
- double v,vinc;
- double n,ninc;
- Boolean Gone;
-
- /* init. EdgeList */
- for (loop = 0;loop < winHeight;loop++)
- EdgeList[loop].OneHere = false;
-
- /* draw each non-culled polygon */
-
- if (CurrentPoly->Subs[0] == NULL)
- {
- if (!(CurrentPoly->Culled == true))
- {
-
- /* clip polygon */
-
- ClipPolygon (CurrentPoly,ViewWindow,&Gone);
-
- if (!(Gone == true))
- {
- /* rasterize edges of polygon */
-
- Traverse = CurrentPoly->VisVertices;
- FirstVertex = Traverse;
- while (!(Traverse->Next == NULL))
- {
- RasterizeEdge (EdgeList,Traverse,
- Traverse->Next,winWidth,winHeight,ViewWindow);
- Traverse = Traverse->Next;
-
- }
- RasterizeEdge (EdgeList,Traverse,FirstVertex,winWidth,winHeight,
- ViewWindow);
-
- /* draw scan lines of polygon */
-
- for (loop = winHeight;loop > 0;loop--)
- if (EdgeList[loop].OneHere == true)
- {
- Ri = EdgeList[loop].RIntensity1;
- Gi = EdgeList[loop].GIntensity1;
- Bi = EdgeList[loop].BIntensity1;
- z = EdgeList[loop].Depth1;
- u = EdgeList[loop].uValue1;
- v = EdgeList[loop].vValue1;
- n = EdgeList[loop].nValue1;
-
- if (!(EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1 == 0))
- {
- Riinc =
- (EdgeList[loop].RIntensity2 - EdgeList[loop].RIntensity1)/
- (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
- Giinc =
- (EdgeList[loop].GIntensity2 - EdgeList[loop].GIntensity1)/
- (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
- Biinc =
- (EdgeList[loop].BIntensity2 - EdgeList[loop].BIntensity1)/
- (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
- zinc = (EdgeList[loop].Depth2 - EdgeList[loop].Depth1)/
- (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
- uinc = (EdgeList[loop].uValue2 - EdgeList[loop].uValue1)/
- (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
- vinc = (EdgeList[loop].vValue2 - EdgeList[loop].vValue1)/
- (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
- ninc = (EdgeList[loop].nValue2 - EdgeList[loop].nValue1)/
- (EdgeList[loop].Xpos2 - EdgeList[loop].Xpos1 - 1);
- }
-
- for (loop2 = EdgeList[loop].Xpos1;loop2 < EdgeList[loop].Xpos2;
- loop2++)
- {
- if (CurrentPoly->Textured == true)
- /* scale the colors with the texture map stored in obj. */
- {
- MapMe.hom[0] = u;
- MapMe.hom[1] = v;
- MapMe.hom[2] = n;
- MapMe.hom[3] = 1.0;
- MapMe.hom[0] = uvector.dx*u + vvector.dx*v + nvector.dx*n + rpoint.x;
- MapMe.hom[1] = uvector.dy*u + vvector.dy*v + nvector.dy*n + rpoint.y;
- MapMe.hom[2] = uvector.dz*u + vvector.dz*v + nvector.dz*n + rpoint.z;
-
- HomogMultiply (MapMe.hom,Object->InverseTransform.mat);
- MapMe.hom[0] = 1.0 - MapMe.hom[0];
- ut = rint (MapMe.hom[0]*(Object->mapWidth));
- vt = rint (MapMe.hom[1]*(Object->mapHeight));
- if (ut < 0) ut = 0;
- if (vt < 0) vt = 0;
- if (ut >= Object->mapWidth)
- ut = Object->mapWidth - 1;
- if (vt >= Object->mapHeight)
- vt = Object->mapHeight - 1;
-
- textureColor.r = Object->TextureMap[ut][vt].r
- /CurrentPoly->R.r;
- textureColor.g = Object->TextureMap[ut][vt].g
- /CurrentPoly->R.g;
- textureColor.b = Object->TextureMap[ut][vt].b
- /CurrentPoly->R.b;
- color.r = Ri*textureColor.r;
- color.g = Gi*textureColor.g;
- color.b = Bi*textureColor.b;
- }
- else
- {
- color.r = Ri;
- color.g = Gi;
- color.b = Bi;
- }
- if (z < Zbuffer[loop2][winHeight-loop])
- {
- Zbuffer[loop2][winHeight-loop] = z;
- /***********************************************************************/
- if (color.r > *MaxIntensity)
- *MaxIntensity = color.r;
- if (color.g > *MaxIntensity)
- *MaxIntensity = color.g;
- if (color.b > *MaxIntensity)
- *MaxIntensity = color.b;
- ScreenMap[loop2][winHeight-loop].r = color.r;
- ScreenMap[loop2][winHeight-loop].g = color.g;
- ScreenMap[loop2][winHeight-loop].b = color.b;
- /***********************************************************************/
- }
- Ri += Riinc;
- Gi += Giinc;
- Bi += Biinc;
- z += zinc;
- u += uinc;
- v += vinc;
- n += ninc;
- }
- EdgeList[loop].OneHere = false;
- }
- }
- }
- }
- else
- {
- renderpoly (CurrentPoly->Subs[0],Object,Zbuffer,ScreenMap,ViewWindow,MaxIntensity,winWidth,winHeight,uvector,vvector,nvector,rpoint);
- renderpoly (CurrentPoly->Subs[1],Object,Zbuffer,ScreenMap,ViewWindow,MaxIntensity,winWidth,winHeight,uvector,vvector,nvector,rpoint);
- renderpoly (CurrentPoly->Subs[2],Object,Zbuffer,ScreenMap,ViewWindow,MaxIntensity,winWidth,winHeight,uvector,vvector,nvector,rpoint);
- renderpoly (CurrentPoly->Subs[3],Object,Zbuffer,ScreenMap,ViewWindow,MaxIntensity,winWidth,winHeight,uvector,vvector,nvector,rpoint);
- }
- }
-
- /*----------------------------------------------------------------------*/
-
- void RenderObject (ObjectCell *Object,double **Zbuffer,Color **ScreenMap,
- Window ViewWindow,double *MaxIntensity,
- int winWidth,int winHeight,
- Vector uvector,Vector vvector,Vector nvector,Point rpoint)
- {
- PolygonCell *CurrentPoly;
- CurrentPoly = Object->PolygonHead;
- while (!(CurrentPoly == NULL))
- {
- renderpoly (CurrentPoly,Object,Zbuffer,ScreenMap,ViewWindow,MaxIntensity,winWidth,winHeight,uvector,vvector,nvector,rpoint);
- CurrentPoly = CurrentPoly->Next;
- }
-
- }
-
-
-
-
-
-
-
-
-
-
-