**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 #include #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, 320x200 256-color mode */ regset.x.ax = 0x0013; /* AH = 0 selects mode set function, AL = 0x13 selects mode 0x13 when set as parameters for INT 0x10 */ int86(0x10, ®set, ®set); /* 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= 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 = 0x0003; /* AL = 3 selects 80x25 text mode */ int86(0x10, ®set, ®set); } **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 */ };