Open GL Super Bible
Our rendering code is different now, too. In addition to rotating the figure for better effect, we call glMap2f instead of glMap1f. This specifies control points along two domains (u and v) instead of just one (u). // Sets up the Bzier // This actually only needs to be called once and could go in // the setup function glMap2f(GL_MAP2_VERTEX_3, // Type of data generated 0.0f, // Lower u range 10.0f, // Upper u range 3, // Distance between points in the data 3, // Dimension in u direction (order) 0.0f, // Lower v range 10.0f, // Upper v range 9, // Distance between points in the data 3, // Dimension in v direction (order) &ctrlPoints[0][0][0]); // array of control points We must still specify the lower and upper range for u; and the distance between points in the u domain is still 3. Now, however, we must also specify the lower and upper range in the v domain. The distance between points in the v domain is now 9 values, because we have a threedimensional array of control points, with each span in the u domain being three points of three values each ( 3 ? 3 = 9). Then we tell glMap2f how many points in the v direction are specified for each u division, followed by a pointer to the control points themselves. The twodimensional evaluator is enabled just like the onedimensional one, and we call glMapGrid2f with the number of divisions in the u and v direction. // Enable the evaluator glEnable(GL_MAP2_VERTEX_3); // Use higher level functions to map to a grid, then evaluate the // entire thing. // Map a grid of 10 points from 0 to 10 glMapGrid2f(10,0.0f,10.0f,10,0.0f,10.0f); After the evaluator is set up, we can call the twodimensional (meaning u and v) version of glEvalMesh to evaluate our surface grid. Here we evaluate using lines, and specify the u and v domains values to range from 0 to 10. // Evaluate the grid, using lines glEvalMesh2(GL_LINE,0,10,0,10); The end result is shown in Figure 175.
Lighting and Normal VectorsAnother valuable features of evaluators is the automatic generation of surface normals. By simply changing this code: // Evaluate the grid, using lines glEvalMesh2(GL_LINE,0,10,0,10); to this: // Evaluate the grid, using lines glEvalMesh2(GL_FILL,0,10,0,10); and then calling glEnable(GL_AUTO_NORMAL); in our initialization code, we enable easy lighting of surfaces generated by evaluators. Figure 176 shows the same surface as Figure 175, but with lighting enabled and automatic normalization turned on. The code for this program is found in BEZLIT in the CD subdirectory for this chapter. The program is only slightly modiied from BEZ3D.
NURBSYou can use evaluators to your heart’s content to evaluate Bazier surfaces of any degree, but for more complex curves you will have to assemble your Bazier’s piecewise. As you add more control points, it becomes difficult to create a curve that has good continuity. A higher level of control is available through the glu library’s NURBS functions. NURBS stands for nonuniform rational Bspline. Mathematicians out there might know immediately that this is just a more generalized form of curves and surfaces that can produce Bazier curves and surfaces, as well as some other kinds (mathematically speaking). They allow you to tweak the influence of the control points you specified for the evaluators, to produce smoother curves and surfaces with larger numbers of control points. From Bazier to BSplinesA Bazier curve is defined by two points that act as endpoints, and any number of other control points that influence the shape of the curve. The three Bazier curves in Figure 177 have 3, 4, and 5 control points specified. The curve is tangent to a line that connects the endpoints with their adjacent control points. For quadratic (3 points) and cubic (4 points) curves, the resulting Baziers are quite smooth, usually with a continuity of C3 (curvature). For higher numbers of control points, however, the smoothness begins to break down as the additional control points pull and tug on the curve.
Bsplines (bicubic splines), on the other hand, work much as the Bazier curves do, but the curve is broken down into segments. The shape of any given segment is influenced only by the nearest four control points, producing a piecewise assemblage of a curve with each segment exhibiting characteristics much like a fourthorder Bazier curve. This means a long curve with many control points is inherently smoother, with the junction between each segment exhibiting C3 continuity. It also means that the curve does not necessarily have to pass through any of the control points. KnotsThe real power of NURBS is that you can tweak the influence of the four control points for any given segment of a curve to produce the smoothness needed. This control is done via a sequence of values called knots. Two knot values are defined for every control point. The range of values for the knots matches the u or v parametric domain, and must be nondescending. This is because the knot values determine the influence of the control points that fall within that range in u/v space. Figure 178 shows a curve demonstrating the influence of control points over a curve having four units in the u parametric domain. Points in the middle of the u domain have a greater pull on the curve, and only points between 0 and 3 have any effect on the shape of the curve.
The key here is that one of these influence curves exists at each control point along the u/v parametric domain. The knot sequence then defines the strength of the influence of points within this domain. If a knot value is repeated, then points near this parametric value have even greater influence. The repeating of knot values is called knot multiplicity. Higher knot multiplicity decreases the curvature of the curve or surface within that region.
