Previous | Table of Contents | Next

LISTING 38.3 L38-3.C

     /* Sample program to exercise the polygon-filling routines. This code
        and all polygon-filling code has been tested with Borland and
        Microsoft compilers. */

     #include <conio.h>
     #include <dos.h>
     #include “polygon.h”

     /* Draws the polygon described by the point list PointList in color
        Color with all vertices offset by (X,Y) */
     #define DRAW_POLYGON(PointList,Color,X,Y)                   \
        Polygon.Length = sizeof(PointList)/sizeof(struct Point); \
        Polygon.PointPtr = PointList;                            \
        FillConvexPolygon(&Polygon, Color, X, Y);

     void main(void);
     extern int FillConvexPolygon(struct PointListHeader *, int, int, int);

     void main() {
        int i, j;
        struct PointListHeader Polygon;
        static struct Point ScreenRectangle[] =
              {{0,0},{320,0},{320,200},{0,200}};
        static struct Point ConvexShape[] =
              {{0,0},{121,0},{320,0},{200,51},{301,51},{250,51},{319,143},
              {320,200},{22,200},{0,200},{50,180},{20,160},{50,140},
              {20,120},{50,100},{20,80},{50,60},{20,40},{50,20}};
        static struct Point Hexagon[] =
              {{90,-50},{0,-90},{-90,-50},{-90,50},{0,90},{90,50}};
        static struct Point Triangle1[] = {{30,0},{15,20},{0,0}};
        static struct Point Triangle2[] = {{30,20},{15,0},{0,20}};
        static struct Point Triangle3[] = {{0,20},{20,10},{0,0}};
        static struct Point Triangle4[] = {{20,20},{20,0},{0,10}};
        union REGS regset;

        /* Set the display to VGA mode 13h, 320×200 256-color mode */
        regset.x.ax = 0×0013;   /* AH = 0 selects mode set function,
                                   AL = 0×13 selects mode 0×13
                                   when set as parameters for INT 0×10 */
        int86(0×10, &regset, &regset);

        /* Clear the screen to cyan */
        DRAW_POLYGON(ScreenRectangle, 3, 0, 0);

        /* Draw an irregular shape that meets our definition of convex but
           is not convex by any normal description */
        DRAW_POLYGON(ConvexShape, 6, 0, 0);
        getch();    /* wait for a keypress */

        /* Draw adjacent triangles across the top half of the screen */
        for (j=0; j<=80; j+=20) {
           for (i=0; i<290; i += 30) {
              DRAW_POLYGON(Triangle1, 2, i, j);
              DRAW_POLYGON(Triangle2, 4, i+15, j);
           }
        }

        /* Draw adjacent triangles across the bottom half of the screen */
        for (j=100; j<=170; j+=20) {
           /* Do a row of pointing-right triangles */
           for (i=0; i<290; i += 20) {
              DRAW_POLYGON(Triangle3, 40, i, j);
           }
           /* Do a row of pointing-left triangles halfway between one row
              of pointing-right triangles and the next, to fit between */
           for (i=0; i<290; i += 20) {
              DRAW_POLYGON(Triangle4, 1, i, j+10);
           }
        }
        getch();    /* wait for a keypress */

        /* Finally, draw a series of concentric hexagons of approximately
           the same proportions in the center of the screen */
        for (i=0; i<16; i++) {
           DRAW_POLYGON(Hexagon, i, 160, 100);
           for (j=0; j<sizeof(Hexagon)/sizeof(struct Point); j++) {
              /* Advance each vertex toward the center */
              if (Hexagon[j].X != 0) {
                 Hexagon[j].X -= Hexagon[j].X >= 0 ? 3 : -3;
                 Hexagon[j].Y -= Hexagon[j].Y >= 0 ? 2 : -2;
              } else {
                 Hexagon[j].Y -= Hexagon[j].Y >= 0 ? 3 : -3;
              }
           }
        }
        getch();    /* wait for a keypress */

        /* Return to text mode and exit */
        regset.x.ax = 0×0003;   /* AL = 3 selects 80×25 text mode */
        int86(0×10, &regset, &regset);
     }

LISTING 38.4 POLYGON.H

     /* POLYGON.H: Header file for polygon-filling code */

     /* Describes a single point (used for a single vertex) */
     struct Point {
        int X;   /* X coordinate */
        int Y;   /* Y coordinate */
     };

     /* Describes a series of points (used to store a list of vertices that
        describe a polygon; each vertex is assumed to connect to the two
        adjacent vertices, and the last vertex is assumed to connect to the
        first) */
     struct PointListHeader {
        int Length;                /* # of points */
        struct Point * PointPtr;   /* pointer to list of points */
     };

     /* Describes the beginning and ending X coordinates of a single
        horizontal line */
     struct HLine {
        int XStart; /* X coordinate of leftmost pixel in line */
        int XEnd;   /* X coordinate of rightmost pixel in line */
     };

     /* Describes a Length-long series of horizontal lines, all assumed to
        be on contiguous scan lines starting at YStart and proceeding
        downward (used to describe a scan-converted polygon to the
        low-level hardware-dependent drawing code) */
     struct HLineList {
        int Length;                /* # of horizontal lines */
        int YStart;                /* Y coordinate of topmost line */
        struct HLine * HLinePtr;   /* pointer to list of horz lines */
     };

Previous | Table of Contents | Next

Graphics Programming Black Book © 2001 Michael Abrash