TRI.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:4k
源码类别:

Windows编程

开发平台:

Visual C++

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