![]() ![]() |
Two sample shapes that are easily modeled "by hand" with triangle strips (above) and a wall shape that is not (below). |
![]() |
![]() |
OpenGL requires that all geometry to be rendered must consist of some combination of points, straight line segments, and triangles. To a certain extent, more complex shapes can be fairly easily constructed by clever use of the various triangle primitive types we have seen. (See the two sample shapes at the top on the right.)
If the holes and/or concavities are much more complex, however (e.g., the wall models at the bottom on the right), it becomes much more difficult – for all practical purposes, impossible – to create the model geometry without the help of some sort of sophisticated algorithm. This is where OpenGL's polygon tessellation functionality comes into play. You simply use the OpenGL glu tessellation sub-API to define all the contours (i.e., connected sets of edges that comprise the outer and inner boundaries of a desired object), and then OpenGL will use callback functions you have registered to tell you the sequence of triangle primitives that can be used to render the shape.
To use the facility, the geometry (and, optionally, the additional per-vertex attributes) of the object's contours are specified once, typically during execution of a ModelView subclass constructor. After you have done so, the basic tessellation algorithm runs, and your code captures and stores in data structures specifications for the triangle primitives that are to be rendered. Then during display callbacks (specifically when your render method is called), you simply bind the vertex array as usual and use those data structures to issue a series of glDrawArrays calls.
Minor note: The most common spelling of "tessellation" is with two "l"s, however the OpenGL API uses one "l" in its data types and function prototypes.
Extra Header File | Extra Link Library | |
Linux | #include <GL/glu.h> | -lGLU |
Macintosh | #include <OpenGL/glu.h> |
This is the easy part. When the render method of your ModelView subclass is called, bind the appropriate vertex array and then simply loop through the "glDrawArrays buffer" you created:
for (int i=0 ; i<bufSize ; i++) glDrawArrays(buf[i].mode, buf[i].start, buf[i].num);
You may well find your way via google to what looks like a much simpler way to incorporate polygon tessellation into your code. There will be no need for buffering of anything, and all the routines you pass to gluTessCallback are OpenGL calls like glBegin, glVertex3dv, and glEnd. You would be right in thinking that this is a much simpler approach, however you would never get it to work because those calls are all deprecated and will not work with shader-based OpenGL programs. Trust me: the way I have described it here and in class is the only way it will work!
This polygon tessellation facility is a holdover from the early days of OpenGL. It is still available, although it is not well advertised. There are many more options supported in this sub-API than what we have covered here. If you find an early version of the Addison-Wesley book "OpenGL Programming Guide" (a.k.a "The Red Book"), you will find that it has an entire chapter devoted to the facility. As of 2019 November 15, an online version of this chapter is available.