home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / FLIP2D / TRI.CPP < prev   
C/C++ Source or Header  |  1996-08-28  |  4KB  |  191 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. //SWAP has a compiler generated problem on alpha.... do it the old fashioned way:
  23. #define SWAPPT(a,b) {POINT p; p=a;a=b;b=p;} //(SWAP(a.y,b.y), SWAP(a.x,b.x))
  24.  
  25. /**************************************************************************
  26.  
  27.     FillScan8
  28.  
  29.     fill a scan from x0 to x1 (inclusive) with color c
  30.  
  31.     does optimal DWORD writes, making sure to stay aligned so
  32.     it is safe for video memory.
  33.  
  34.  **************************************************************************/
  35. inline void FillScan8(BYTE *p, int x0, int x1, DWORD c)
  36. {
  37.     int dx;
  38.     int z;
  39.  
  40.     dx = x1-x0+1;
  41.     p += x0;
  42.  
  43.     if (dx > 4)
  44.     {
  45.         if (z = (DWORD)p & 0x03)
  46.         {
  47.             while (z++ < 4)
  48.             {
  49.                 *p++ = (BYTE)c;
  50.                 dx--;
  51.             }
  52.         }
  53.  
  54.         while (dx >= 4)
  55.         {
  56.             *((DWORD*)p) = c;
  57.             p += 4;
  58.             dx -= 4;
  59.         }
  60.     }
  61.  
  62.     while (dx-- > 0)
  63.     {
  64.         *p++ = (BYTE)c;
  65.     }
  66. }
  67.  
  68. /**************************************************************************
  69.  
  70.     Triangle8
  71.  
  72.     rasterize a solid color triangle into a 8bpp memory buffer.
  73.  
  74.     NOTE this code does no clipping you better pass
  75.  
  76.     rasterizes a solid color triangle into a memory buffer with any pitch
  77.     also is careful to always write DWORD aligned, so it is safe to be
  78.     used on video memory (and faster too...)
  79.  
  80.  **************************************************************************/
  81.  
  82. void Triangle8(BYTE *p, int next_scan, POINT P0, POINT P1, POINT P2, DWORD c)
  83. {
  84.     Fixed   d,d0;
  85.     Fixed   x,x0;
  86.     int     y;
  87.  
  88.     //
  89.     // expand the color to a DWORD
  90.     //
  91.     c |= c<<8;
  92.     c |= c<<16;
  93.  
  94.     //
  95.     //  sort points so P0.y <= P1.y <= P2.y
  96.     //
  97.     if (P0.y > P1.y) SWAPPT(P0,P1);
  98.     if (P1.y > P2.y) SWAPPT(P1,P2);
  99.     if (P0.y > P1.y) SWAPPT(P0,P1);
  100.  
  101.     //
  102.     //  check for quick out?
  103.     //
  104.     if (P2.y - P0.y == 0)
  105.     {
  106.         return;
  107.     }
  108.  
  109.     //
  110.     //  compute "long" side walk from P0 to P2
  111.     //
  112.     d = (Fixed)(P2.x - P0.x) / (Fixed)(P2.y - P0.y);
  113.  
  114.     x  = P0.x;
  115.     y  = P0.y;
  116.     p += P0.y * next_scan;   // point p to correct scan.
  117.  
  118.     //
  119.     //  do the top
  120.     //
  121.     if (P0.y < P1.y)
  122.     {
  123.         d0 = (Fixed)(P1.x - P0.x) / (Fixed)(P1.y - P0.y);
  124.         x0 = P0.x;
  125.  
  126.         //
  127.         // check for left or right fill
  128.         //
  129.         if (d < d0)
  130.         {
  131.             while (y < P1.y)
  132.             {
  133.                 FillScan8(p, x, x0, c);
  134.                 y++;
  135.                 p  += next_scan;
  136.                 x  += d;
  137.                 x0 += d0;
  138.             }
  139.         }
  140.         else
  141.         {
  142.             while (y < P1.y)
  143.             {
  144.                 FillScan8(p, x0, x, c);
  145.                 y++;
  146.                 p  += next_scan;
  147.                 x  += d;
  148.                 x0 += d0;
  149.             }
  150.         }
  151.     }
  152.  
  153.     //
  154.     // do the bottom.
  155.     //
  156.     
  157.     if (P2.y - P1.y == 0)
  158.     {
  159.         return;
  160.     }
  161.  
  162.     d0 = (Fixed)(P2.x - P1.x) / (Fixed)(P2.y - P1.y);
  163.     x0 = P1.x;
  164.  
  165.     //
  166.     // check for left or right fill
  167.     //
  168.     if (x < x0)
  169.     {
  170.         while (y < P2.y)
  171.         {
  172.             FillScan8(p, x, x0, c);
  173.             y++;
  174.             p  += next_scan;
  175.             x  += d;
  176.             x0 += d0;
  177.         }
  178.     }
  179.     else
  180.     {
  181.         while (y < P2.y)
  182.         {
  183.             FillScan8(p, x0, x, c);
  184.             y++;
  185.             p  += next_scan;
  186.             x  += d;
  187.             x0 += d0;
  188.         }
  189.     }
  190. }
  191.