home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / directx2 / sdk / samples / flip2d / tri.cpp < prev   
Encoding:
C/C++ Source or Header  |  1996-05-28  |  4.2 KB  |  190 lines

  1. /**************************************************************************
  2.  
  3.     TRI.CPP - Simple triangle rasterizer
  4.  
  5.  **************************************************************************/
  6. /**************************************************************************
  7.  
  8.     (C) Copyright 1995-1996 Microsoft Corp.  All rights reserved.
  9.  
  10.     You have a royalty-free right to use, modify, reproduce and 
  11.     distribute the Sample Files (and/or any modified version) in 
  12.     any way you find useful, provided that you agree that 
  13.     Microsoft has no warranty obligations or liability for any 
  14.     Sample Application Files which are modified. 
  15.  
  16.  **************************************************************************/
  17.  
  18. #include <windows.h>
  19. #include "Fixed.h"
  20.  
  21. #define SWAP(x,y)   ((x)^=(y)^=(x)^=(y))
  22. #define SWAPPT(a,b) (SWAP(a.y,b.y), SWAP(a.x,b.x))
  23.  
  24. /**************************************************************************
  25.  
  26.     FillScan8
  27.  
  28.     fill a scan from x0 to x1 (inclusive) with color c
  29.  
  30.     does optimal DWORD writes, making sure to stay aligned so
  31.     it is safe for video memory.
  32.  
  33.  **************************************************************************/
  34. inline void FillScan8(BYTE *p, int x0, int x1, DWORD c)
  35. {
  36.     int dx;
  37.     int z;
  38.  
  39.     dx = x1-x0+1;
  40.     p += x0;
  41.  
  42.     if (dx > 4)
  43.     {
  44.         if (z = (DWORD)p & 0x03)
  45.         {
  46.             while (z++ < 4)
  47.             {
  48.                 *p++ = (BYTE)c;
  49.                 dx--;
  50.             }
  51.         }
  52.  
  53.         while (dx >= 4)
  54.         {
  55.             *((DWORD*)p) = c;
  56.             p += 4;
  57.             dx -= 4;
  58.         }
  59.     }
  60.  
  61.     while (dx-- > 0)
  62.     {
  63.         *p++ = (BYTE)c;
  64.     }
  65. }
  66.  
  67. /**************************************************************************
  68.  
  69.     Triangle8
  70.  
  71.     rasterize a solid color triangle into a 8bpp memory buffer.
  72.  
  73.     NOTE this code does no clipping you better pass
  74.  
  75.     rasterizes a solid color triangle into a memory buffer with any pitch
  76.     also is careful to always write DWORD aligned, so it is safe to be
  77.     used on video memory (and faster too...)
  78.  
  79.  **************************************************************************/
  80.  
  81. void Triangle8(BYTE *p, int next_scan, POINT P0, POINT P1, POINT P2, DWORD c)
  82. {
  83.     Fixed   d,d0;
  84.     Fixed   x,x0;
  85.     int     y;
  86.  
  87.     //
  88.     // expand the color to a DWORD
  89.     //
  90.     c |= c<<8;
  91.     c |= c<<16;
  92.  
  93.     //
  94.     //  sort points so P0.y <= P1.y <= P2.y
  95.     //
  96.     if (P0.y > P1.y) SWAPPT(P0,P1);
  97.     if (P1.y > P2.y) SWAPPT(P1,P2);
  98.     if (P0.y > P1.y) SWAPPT(P0,P1);
  99.  
  100.     //
  101.     //  check for quick out?
  102.     //
  103.     if (P2.y - P0.y == 0)
  104.     {
  105.         return;
  106.     }
  107.  
  108.     //
  109.     //  compute "long" side walk from P0 to P2
  110.     //
  111.     d = (Fixed)(P2.x - P0.x) / (Fixed)(P2.y - P0.y);
  112.  
  113.     x  = P0.x;
  114.     y  = P0.y;
  115.     p += P0.y * next_scan;   // point p to correct scan.
  116.  
  117.     //
  118.     //  do the top
  119.     //
  120.     if (P0.y < P1.y)
  121.     {
  122.         d0 = (Fixed)(P1.x - P0.x) / (Fixed)(P1.y - P0.y);
  123.         x0 = P0.x;
  124.  
  125.         //
  126.         // check for left or right fill
  127.         //
  128.         if (d < d0)
  129.         {
  130.             while (y < P1.y)
  131.             {
  132.                 FillScan8(p, x, x0, c);
  133.                 y++;
  134.                 p  += next_scan;
  135.                 x  += d;
  136.                 x0 += d0;
  137.             }
  138.         }
  139.         else
  140.         {
  141.             while (y < P1.y)
  142.             {
  143.                 FillScan8(p, x0, x, c);
  144.                 y++;
  145.                 p  += next_scan;
  146.                 x  += d;
  147.                 x0 += d0;
  148.             }
  149.         }
  150.     }
  151.  
  152.     //
  153.     // do the bottom.
  154.     //
  155.     
  156.     if (P2.y - P1.y == 0)
  157.     {
  158.         return;
  159.     }
  160.  
  161.     d0 = (Fixed)(P2.x - P1.x) / (Fixed)(P2.y - P1.y);
  162.     x0 = P1.x;
  163.  
  164.     //
  165.     // check for left or right fill
  166.     //
  167.     if (x < x0)
  168.     {
  169.         while (y < P2.y)
  170.         {
  171.             FillScan8(p, x, x0, c);
  172.             y++;
  173.             p  += next_scan;
  174.             x  += d;
  175.             x0 += d0;
  176.         }
  177.     }
  178.     else
  179.     {
  180.         while (y < P2.y)
  181.         {
  182.             FillScan8(p, x0, x, c);
  183.             y++;
  184.             p  += next_scan;
  185.             x  += d;
  186.             x0 += d0;
  187.         }
  188.     }
  189. }
  190.