| |
|
|
||||
![]() |
||||||
| |
|
|||||
|
Rendering Bézier Patches Generating the vertices for a patch is not too difficult now that we know how to generate them for a curve. Generally what is done is to generate points of constant s at equal steps of t. The symmetrical operation of curves of constant t at equal steps of s could also be done. The same number of steps are taken along s and t. These steps along s and t could be calculated directly or through subdivision. What we end up with is a rectangular grid of points on the patch. We could simply render these points as a quadrilaterals, but a problem arises: there is no guarantee that the quadrilateral is flat. This may be a problem for some renderers. For most purposes, it is easiest to render using triangles, since the slight inaccuracies of not being on the ideal flat surface are negligible and are more than made up for with speed. Listing 3 renders a patch using triangle strips. The decision as to how finely to tessellate the surface is up to the developer. It is usually based on the distance to the model and the available power of the machine doing the rendering. /* * This fragment takes the points returned by a function that subdivides a * Bezier patch and renders them using triangle strips. * * Point is an object that has the x, y, and z coordinates and defines * some mathematical operations for points. See the project accompanying * the article for its definition. * * LevelToWidth[] is a lookup table that calculates the widths of rows given * the depth of recursion. * * cpoints is a 3 x 3 matrix of control points for the quadratic Bezier patch. */ Point* p = QuadraticBezierPatchSubdivide2(cpoints, 3); int width = LevelToWidth[3]; // For all the strips for(int i = 0; i < width - 1; i++) { // Emit the vertices on the strip glBegin(GL_TRIANGLE_STRIP); for(int j = 0; j < width; j++) { glVertex3f(p[i * width + j].x, p[i * width + j].y, p[i * width + j].z); glVertex3f(p[(i + 1) * width + j].x, p[(i + 1) * width + j].y, p[(i + 1) * width + j].z); } glEnd(); } // Free the points delete[] p; |
|
|