home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / source / chapterg / lg-5.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-18  |  6.4 KB  |  137 lines

  1. /* Demonstrates unweighted antialiased drawing in 640x480 Hicolor (32K color) 
  2. mode. 
  3.   Tested with Borland C++ 4.02 in small model by Jim Mischel 12/16/94.
  4.   Requires: L26-6.C, L26-1.C, L26-3.C, FILCNVX.C, and L22-4.ASM.
  5. */
  6. #include <conio.h>
  7. #include <dos.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "polygon.h"
  11. /* Draws the polygon described by the point list PointList in the
  12.    color specified by RED, GREEN, AND BLUE, with all vertices
  13.    offset by (x,y), to ScanLineBuffer, at ResMul multiple of
  14.    horizontal and vertical resolution. The address of ColorTemp is
  15.    cast to an int to satisfy the prototype for FillCnvxPolyDrvr; this
  16.    trick will work only in a small data model */
  17. #define DRAW_POLYGON_HIGH_RES(PointList,RED,GREEN,BLUE,x,y,ResMul) { \
  18.    Polygon.Length = sizeof(PointList)/sizeof(struct Point);          \
  19.    Polygon.PointPtr = PointTemp;                                     \
  20.    /* Multiply all vertical & horizontal coordinates */              \
  21.    for (k=0; k<sizeof(PointList)/sizeof(struct Point); k++) {        \
  22.       PointTemp[k].X = PointList[k].X * ResMul;                      \
  23.       PointTemp[k].Y = PointList[k].Y * ResMul;                      \
  24.    }                                                                 \
  25.    ColorTemp.Red=RED; ColorTemp.Green=GREEN; ColorTemp.Blue=BLUE;    \
  26.    FillCnvxPolyDrvr(&Polygon, (int)&ColorTemp, x, y, DrawBandedList);}
  27. #define SCREEN_WIDTH 640
  28. #define SCREEN_SEGMENT 0xA000
  29.  
  30. void main(void);
  31. extern void DrawPixel(int, int, char);
  32. extern void DrawBandedList(struct HLineList *, struct RGB *);
  33. extern int SetHCMode(int);
  34.  
  35. /* Table of gamma corrected mappings of linear color intensities in
  36.    the range 0-255 to the nearest pixel values in the range 0-31,
  37.    assuming a gamma of 2.3 */
  38. static unsigned char ColorMappings[] = {
  39.     0, 3, 4, 4, 5, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9,10,10,10,
  40.    10,10,11,11,11,11,11,12,12,12,12,12,13,13,13,13,13,13,14,14,
  41.    14,14,14,14,14,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,
  42.    17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,
  43.    19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,21,
  44.    21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,
  45.    22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,
  46.    24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,
  47.    25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,
  48.    27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,
  49.    28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,
  50.    29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,
  51.    30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31};
  52. /* Pointer to buffer in which high-res scanned data will reside */
  53. struct RGB *ScanLineBuffer;
  54. int ScanBandStart, ScanBandEnd;  /* top & bottom of each high-res
  55.                                   band we'll draw to ScanLineBuffer */
  56. int ScanBandWidth;      /* # subpixels across each scan band */
  57. int BitmapWidthInBytes = 640*2;  /* # of bytes per raster line in
  58.                                     Hicolor VGA display memory */
  59. void main()
  60. {
  61.    int i, j, k, m, Red, Green, Blue, jXRes, kXWidth;
  62.    int SubpixelsPerMegapixel;
  63.    unsigned int Megapixel, ResolutionMultiplier;
  64.    long BufferSize;
  65.    struct RGB ColorTemp;
  66.    struct PointListHeader Polygon;
  67.    struct Point PointTemp[4];
  68.    static struct Point Face0[] =
  69.          {{396,276},{422,178},{338,88},{288,178}};
  70.    static struct Point Face1[] =
  71.          {{306,300},{396,276},{288,178},{210,226}};
  72.    static struct Point Face2[] =
  73.          {{338,88},{266,146},{210,226},{288,178}};
  74.    int LeftBound=210, RightBound=422, TopBound=88, BottomBound=300;
  75.    union REGS regset;
  76.  
  77.    printf("Subpixel resolution multiplier:");
  78.    scanf("%d", &ResolutionMultiplier);
  79.    SubpixelsPerMegapixel = ResolutionMultiplier*ResolutionMultiplier;
  80.    ScanBandWidth = SCREEN_WIDTH*ResolutionMultiplier;
  81.  
  82.    /* Get enough space for one scan line scanned out at high
  83.       resolution horz and vert (each pixel is 4 bytes) */
  84.    if ((BufferSize = (long)ScanBandWidth*4*ResolutionMultiplier) >
  85.          0xFFFF) {
  86.       printf("Band won't fit in one segment\n"); exit(0); }
  87.    if ((ScanLineBuffer = malloc((int)BufferSize)) == NULL) {
  88.       printf("Couldn't get memory\n"); exit(0); }
  89.  
  90.    /* Attempt to enable 640x480 Hicolor mode */
  91.    if (SetHCMode(0x2E) == 0)
  92.       { printf("No Hicolor DAC detected\n"); exit(0); };
  93.  
  94.    /* Scan out the polygons at high resolution one screen scan line at
  95.       a time (ResolutionMultiplier high-res scan lines at a time) */
  96.    for (i=TopBound; i<=BottomBound; i++) {
  97.       /* Set the band dimensions for this pass */
  98.       ScanBandEnd = (ScanBandStart = i*ResolutionMultiplier) +
  99.             ResolutionMultiplier - 1;
  100.       /* Clear the drawing buffer */
  101.       memset(ScanLineBuffer, 0, BufferSize);
  102.       /* Draw the current band of the cube to the scan line buffer */
  103.       DRAW_POLYGON_HIGH_RES(Face0,0xFF,0,0,0,0,ResolutionMultiplier);
  104.       DRAW_POLYGON_HIGH_RES(Face1,0,0xFF,0,0,0,ResolutionMultiplier);
  105.       DRAW_POLYGON_HIGH_RES(Face2,0,0,0xFF,0,0,ResolutionMultiplier);
  106.  
  107.   /* Coalesce subpixels into normal screen pixels (megapixels) and draw them */
  108.       for (j=LeftBound; j<=RightBound; j++) {
  109.          jXRes = j*ResolutionMultiplier;
  110.          /* For each screen pixel, sum all the corresponding
  111.             subpixels, for each color component */
  112.          for (k=Red=Green=Blue=0; k<ResolutionMultiplier; k++) {
  113.             kXWidth = k*ScanBandWidth;
  114.             for (m=0; m<ResolutionMultiplier; m++) {
  115.                Red += ScanLineBuffer[jXRes+kXWidth+m].Red;
  116.                Green += ScanLineBuffer[jXRes+kXWidth+m].Green;
  117.                Blue += ScanLineBuffer[jXRes+kXWidth+m].Blue;
  118.             }
  119.          }
  120.          /* Calc each color component's average brightness; convert
  121.             that into a gamma corrected portion of a Hicolor pixel,
  122.             then combine the colors into one Hicolor pixel */
  123.          Red = ColorMappings[Red/SubpixelsPerMegapixel];
  124.          Green = ColorMappings[Green/SubpixelsPerMegapixel];
  125.          Blue = ColorMappings[Blue/SubpixelsPerMegapixel];
  126.          Megapixel = (Red << 10) + (Green << 5) + Blue;
  127.          DrawPixel(j, i, Megapixel);
  128.       }
  129.    }
  130.    getch();    /* wait for a keypress */
  131.  
  132.    /* Return to text mode and exit */
  133.    regset.x.ax = 0x0003;   /* AL = 3 selects 80x25 text mode */
  134.    int86(0x10, ®set, ®set);
  135. }
  136.  
  137.