home *** CD-ROM | disk | FTP | other *** search
/ Cutting-Edge 3D Game Programming with C++ / CE3DC++.ISO / BOOK / CHAP09 / PHONG / DRAWPOLY.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-13  |  3.9 KB  |  128 lines

  1. //
  2. //
  3. //
  4. //
  5. //
  6. //
  7.  
  8. #include <Mem.h>
  9. #include <Dos.h>
  10. #include <Math.h>
  11.  
  12. #include <Conio.h>
  13. #include <IOStream.H>
  14.  
  15. #include "LineType.HPP"
  16.  
  17. LightSource Light = { 0.0F, 0.0F, -10.0F };
  18.  
  19. inline unsigned char CalcColor ( double Nx, double Ny, double Nz )
  20.    {
  21.    unsigned char Color;
  22.    double Mag, CosA;
  23.    Mag = sqrt ( Nx * Nx +
  24.                 Ny * Ny +
  25.                 Nz * Nz );
  26.    CosA = ( Light.X * Nx + Light.Y * Ny + Light.Z * Nz ) / Mag;
  27.    Color = CosA * 120.0F + 125.0F;
  28.  
  29.    return Color;
  30.    }
  31.  
  32. void DrawPoly ( Point2D *SPoint, Point3D *List3D, int SPCount, unsigned char *Dest )
  33.    {
  34.       // Display the panel in the screen buffer "Dest":
  35.    unsigned char RColor, *DPtr;
  36.    CeilLine LeftSeg, RightSeg;
  37.    long Top = 0, N, RightPos, LeftPos, NewRightPos, NewLeftPos, 
  38.         Height, EdgeCount, YIndex, Width, XStart, XEnd;
  39.    double Nx, Ny, Nz, StepNx, StepNy, StepNz;
  40.    EdgeCount = SPCount;
  41.  
  42.    // Search for lowest Y coordinate (top of polygon):
  43.    for ( N = 1; N < SPCount; N++ )
  44.        {
  45.        if ( SPoint [ N ].Y < SPoint [ Top ].Y )
  46.           Top = N;
  47.        }
  48.    RightPos = Top;
  49.    LeftPos = Top;
  50.  
  51.    // Calculate the index to the buffer:
  52.    YIndex = SPoint [ Top ].Y * 320;
  53.  
  54.    // Loop for all polygon edges:
  55.    while ( EdgeCount > 0 )
  56.          {
  57.          // Determine if the right side of the polygon needs 
  58.          // (re)initializing:
  59.          if ( RightSeg.Height () <= 0 )
  60.             {
  61.             NewRightPos = RightPos + 1;
  62.             if ( NewRightPos >= SPCount )
  63.                NewRightPos = 0;
  64.             RightSeg.Init ( SPoint [ RightPos ], List3D [ RightPos ],
  65.                             SPoint [ NewRightPos ], List3D [ NewRightPos ] );
  66.             RightPos = NewRightPos;
  67.             --EdgeCount;
  68.             }
  69.          // Determine if the left side of the polygon needs 
  70.          // (re)initializing:
  71.          if ( LeftSeg.Height () <= 0 )
  72.             {
  73.             NewLeftPos = LeftPos - 1;
  74.             if ( NewLeftPos < 0 )
  75.                NewLeftPos = ( SPCount - 1 );
  76.             LeftSeg.Init ( SPoint [ LeftPos ], List3D [ LeftPos ],
  77.                            SPoint [ NewLeftPos ], List3D [ NewLeftPos ] );
  78.             LeftPos = NewLeftPos;
  79.             --EdgeCount;
  80.             }
  81.          // Subdivide polygon into trapezoid:
  82.          if ( LeftSeg.Height () < RightSeg.Height () )
  83.             {
  84.             Height = LeftSeg.Height ();
  85.             }
  86.          else {
  87.               Height = RightSeg.Height ();
  88.               }
  89.  
  90.          // Loop for the height of the trapezoid:
  91.          while ( Height-- > 0 )
  92.                {
  93.                // Calculate initial values:
  94.                XStart = LeftSeg.GetX ();
  95.                XEnd = RightSeg.GetX ();
  96.                Width = XEnd - XStart;
  97.                if ( Width > 0 )
  98.                   {
  99.                   Nx = LeftSeg.GetNx ();
  100.                   Ny = LeftSeg.GetNy ();
  101.                   Nz = LeftSeg.GetNz ();
  102.  
  103.                   StepNx = ( RightSeg.GetNx () - LeftSeg.GetNx ())  /
  104.                            ( double ) Width;
  105.                   StepNy = ( RightSeg.GetNy () - LeftSeg.GetNy () ) /
  106.                            ( double ) Width;
  107.                   StepNz = ( RightSeg.GetNz () - LeftSeg.GetNz () ) /
  108.                            ( double ) Width;
  109.  
  110.                   DPtr = &Dest [ YIndex + XStart ];
  111.  
  112.                   // Loop for width of scan-line:
  113.                   while ( Width-- > 0 )
  114.                         {
  115.                         RColor = CalcColor ( Nx, Ny, Nz );
  116.                         *DPtr = ( unsigned char ) RColor;
  117.                         ++DPtr;
  118.                         Nx += StepNx;
  119.                         Ny += StepNy;
  120.                         Nz += StepNz;
  121.                         }
  122.                   }
  123.                ++RightSeg;
  124.                ++LeftSeg;
  125.                YIndex += 320;
  126.                }
  127.          }
  128.    }