An MFC OpenGL Polygon Demo App
Recently, I had some trouble with malformed polygons in one of my OpenGL scientific visualization workbenches. After some research and lots of help from the folks here and comp.graphics.api.opengl, I found the problem—some of my objects were ‘non-simple’ polygons with at least one interior angle greater than 180 degrees (in other words, some part of the polygon is concave vs. convex), and the OpenGL rendering of non-convex polygons is undefined. To correctly render a concave polygon, I needed to tell OpenGL to “tessellate” the polygon (tessellation is the process of breaking a complex polygon into two or more simpler polygons, each of which is entirely convex) and then render the resulting all-convex polygons.
Fortunately, tessellation isn’t that hard to do, and there are lots of general resources such as OpenGL.org, comp.graphics.api.opengl, and “The OpenGL Programming Guide” (aka The Red Book) to draw upon. There are a number of “gluTess…” API calls like glTessBeginPolygon() and glTessEndPolygon that parallel the normal “gl” calls for polygons, and so forth. Setting up rendering with tessellation is pretty much the same as setting it up for non-tessellated polygons except for the CALLBACK functions and memory leak issues. After researching the basics, I started looking for example code, only to discover there really wasn’t much out there dealing with the details of an MFC implementation. There was lots of C code (including Tess.c from the Red Book), but nothing that showed specifically how to implement the required CALLBACK functions in MFC, and how to deal with the potential for memory leaks. So, after getting my application working, I decided to build a sample MFC app called MFCTess to demonstrate at least one technique for making tessellation work in an MFC app.
Starting with a generic MSVC++ V6 MFC Appwizard-generated SDI app, I ported the necessary OpenGL tessellation routines from my other (now working) project and added facilities for generating and displaying a single polygon with one or more contours. I also added the ability to save generated contours in an ASCII .DAT file rather than using MFC’s binary serialization facilities (see the included help file for the .DAT file format).
The purpose of MFCTess is to demonstrate polygon tessellation in MFC. Only one polygon can be displayed at a time, but that one polygon can have any number of contours. The active polygon’s contours are defined by means of a Polygon Definition dialog box (it has its own help topic, accessed by clicking on the Help button in that dialog). Only the X and Y coordinates of the polygon are considered—the Z coordinate information is ignored for purposes of display. The color for each vertex can be defined independently. A right-click context menu is available in the main display window to allow the user to explore the effect of several different OpenGL “Winding” rules.
Polygon contours can be saved to and/or loaded from comma or space-delimited ASCII *.DAT files. It would have been much easier to use the MFC binary serialization facilities but I much prefer ASCII files because you can easily tell whether or not what got saved was actually what you intended to save. The file format and an example are shown in the on-line help topic. Note that the per-contour header string “CONTOUR:” is required. Vertex data is comma or space (either one or both will do) delimited 6-tuples (X,Y,Z, R,G,B). The RGB values are normalized to 255.
A screenshot is shown below, and the VC++ V6 MFC project files (zipped), can be downloaded.