Tricks of the Windows Game Programming Gurus:Windows GDI, Controls, and Last-Minute Gift Ideas

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

Notice the slickness here! I defined the `RECT` on-the-fly as well as the brush. The brush doesn’t need to be deleted because it was never selected into context; hence, it’s transient.

> Warning: I’m being fairly loose about the HDC and other details in these examples, so I hope you’re awake! Obviously, for any of these examples to work you must have a window, an HDC, and perform the appropriate prolog and epilog code to each segment. As the book continues, I will assume that you know this already.

As an example of using the `Rectangle()` function, take a look at `DEMO4_3.CPP`; it draws a slew of random rectangles in different sizes and colors on the window surface. However, as a change, I retrieved the handle to the entire window rather than just the client area, so the window looks like it’s getting destroyed—cool, huh? Take a look at Figure 4.6 to see the output the program creates.

Figure 4.6 Rectangle program `DEMO4_3.EXE`.

#### Round and Round She Goes—Circles

Back in the ’80s if you could make your computer draw a circle, you were a mastermind. There were a number of ways to do it—with the explicit formula:

    (x-x0)2 + (y-y0)2 = r2

Or maybe with the sine and cosine functions:

    x=r*cos(angle)

    y=r*sin(angle)

Or maybe with lookup tables! The point is that circles aren’t the fastest things in the world to draw. This dilemma is no longer important with 500MHz Pentium II’s, but it used to be. In any case, GDI has a circle drawing function—well, sort of… GDI likes ellipses rather than circles.

If you recall from geometry, an ellipse is like a squished circle on either axis. An ellipse has both a major axis and a minor axis, as shown in the figure. The equation of an ellipse centered at (x0,y0) is shown in Figure 4.7.

Figure 4.7 The mathematics of circles and ellipses.

You would think that GDI would use some of the same concepts—the major axis and minor axis to define an ellipse—but GDI took a slightly different approach to defining an ellipse. With GDI, you simply give a bounding rectangle and GDI draws the ellipse that’s bounded by it. In essence, you’re defining the origin of the ellipse while at the same time the major and minor axes—whatever!

The function that draws an ellipse is called `Ellipse()` and it draws with the current pen and brush. Here’s the prototype:

    BOOL Ellipse( HDC hdc,// handle to device context

         int nLeftRect,   // x-coord. of bounding

                          // rectangle’s upper-left corner

         int nTopRect,    // y-coord. of bounding

                          // rectangle’s upper-left corner

         int nRightRect,  // x-coord. of bounding

                          // rectangle’s lower-right corner

         int nBottomRect ); // y-coord. bounding

                            // rectangle’s f lower-right corner

So to draw a circle you would make sure that the bounding rectangle was square. For example, to draw a circle that had center (20,20) with a radius of 10, you would do this:

    Ellipse(hdc,10,10,30,30);

Get it? And if you wanted to draw a real-life ellipse with major axis 100, minor axis 50, with an origin of (300,200), you would do this:

    Ellipse(hdc,250,175,350,225);

For a working example of drawing ellipses, take a look at `DEMO4_4.CPP` on the CD and the associated executable. The program draws a moving ellipse in a simple animation loop of erase, move, draw. This type of animation loop is very similar to the technique we’ll use later called double buffering or page flipping, but with those techniques we won’t be able to see the update as shown in the demo, and hence there won’t be a flicker! For fun, try messing with the demo and changing things around. See if you can figure out how to add more ellipses.

#### Polygon, Polygon, Wherefore Art Thou, Polygon?

The last little primitive I want to show you is the polygon primitive. Its purpose is to draw open or closed polygonal objects very quickly. The function that draws a polygon is called `Polygon()` and is shown here:

    BOOL Polygon(HDC hdc,       // handle to device context

         CONST POINT *lpPoints, // pointer to polygon’s vertices

         int nCount );          // count of polygon’s vertices

You simply send `Polygon()` a list of `POINT`s along with the number of them and it will draw a closed polygon with the current pen and brush. Take a look at Figure 4.8 to see this graphically.

Figure 4.8 Using the `Polygon()` function.

Here’s an example:

    // create the polygon shown in the figure

    POINT poly[7] = {p0x, p0y, p1x, p1y, p2x, p2y,

    p3x, p3y, p4x, p4y, p5x, p5y, p6x, p6y,  };

    // assume hdc is valid, and pen and brush are selected into

    // graphics device context

    Polygon(hdc, poly,7);

That was easy! Of course, if you send points that make a degenerate polygon, or a polygon that closes on itself, GDI will do its best to draw it, but no promises!

As an example of drawing filled polygons, `DEMO4_5.CPP` draws a collection of random 3–10 point polygons all over the screen with a little delay between each, so you can see the weird results that occur with degenerate polygon vertex lists. Figure 4.9 shows the output of the program in action. Notice that because the points are random, the polygons are almost always degenerate due to overlapping geometry. Can you find a way to make sure that all the points exist within a convex hull?

Figure 4.9 Output of polygon program `DEMO4_5.EXE`.

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.