Use OpenGL to draw typical surfaces in VC
[Text] Abstract: This article mainly discusses general methods of using OpenGL to draw BEZIER, NURBS, etc. in VC . Key words: OpenGL; bezier; NURBS; Surface Draw OpenGL is the most basic method of OpenGL to model OpenGL, but it is difficult to model the modeling of complicated real objects. For these complex objects, the OpenGL base library and function library function (GL library and Glu libraries) are required to extend and complete the method to calculate, curve generation, and surface construction. This extension of this for basic primitives is the extension of point, line and polygon. The point defined in OpenGL can have a size of different sizes, its extended function is: void glpointsize; its parameter size sets the width of points in pixels, and its value must be positive, default 1.0 . For the spread of the line, the width and draw type can be specified by the following function: Void GLLINEWIDTH; Void GLLINESTIPPLE (Glint Factor, Glushort Pattern); GLLINEWIDTH () parameter width specifies line wide in pixels The value must be positive, the default is 1.0. The parameter factor of GLLINESTIPPLE () is a proportional factor stretched with the mode, and the parameter pattern specifies the line mode (e.g., 11001100 will draw a dashed line, drawing 1, 0 when 0 is not drawn). This function can only be used after enabling function glenable (GL_LINE_STIPPLE), and then call GLDISABLE (GL_LINE_STIPPLE) when it is no longer used. The drawing mode of extended polygons includes several full-filled, contour points, contour and pattern filling types. When using, first call GLPOLYGONMODE () Setup mode settings: Void GLPOLYGONMODE (Glenum Face, Glenum Mode); Parameter Face is GL_FRONT, GL_BACK or GL_FRONT_AND BACK; MODE Value can be GL_POINT, GL_LINE or GL_FILL, indicate polygonal type Drawing method of contour point, outline, and fill mode. The default is set to fill mode. After the setting is completed, the pattern fills can be made: void GLPOLYGONSTIPPLE (const glubyte * mask); its parameter Mask must be a pointer to a bitmap of 32 × 32 size, and the value is 1 when drawn, 0 does not draw. The use of this function also needs to start, close setting: glenable (GL_POLYGON-stipple); GLDISABLE (GL_POLYGON_STIPLE); the modeling of complex models is different from simple model modeling, in a simple model, in a plane in a plane The (MORMAL vector) is the same, equal to the normal direction of this plane. For surfaces formed from many small planar polygons in complex models, each of its vertices is different, so the method of each point on the surface is different from the different algorithms taken depending on the different algorithms taken. OpenGL only provides functions given to the current vertex method, without providing a method of calculating the normal vector, and the calculation of the normal vector needs to be done by the developer.
A simple calculation method is given below: Void getNormal (GLFLOAT GX [3], GLFLOAT GY [3], GLFLOAT GZ [3], GLFLOAT * DDNV) {GLFLOAT W0, W1, W2, V0, V1, V2, NR , NX, NY, NZ; W0 = GX [0] -gx [1]; w1 = gy [0] -gy [1]; w2 = gz [0] -gz [1]; v0 = gx [2] - GX [1]; v1 = Gy [2] -gy [1]; v2 = Gz [2] -gz [1]; Nx = (W1 * V2-W2 * V1); NY = (W2 * V0-W0 * V2); NZ = (W0 * V1-W1 * V0); NR = SQRT (Nx * Nx NY * NY NZ * NZ); DDNV [0] = NX / NR; DDNV [1] = NY / NR; DDNV [2] = NZ / NR;} The parameters GX [3], Gy [3] and GZ [3] are three vertices P0, P1, and P2 of approximation of a triangle of the surface. By calculating the vector P0-P1 and the vector P2-P1 for the fork of the vector P2-P1 to obtain its planar pattern, and saved in the array pointed to by the parameter DDNV after normalization. As for the calculation of the vertex method, it is mostly the mean of neighboring plane method. OpenGL provides the method to define the definition function: void glNormal3 {bsifd} (Type Nx, Type NY, TYPE NZ); Void Glnormal3 {BSIFD} V (const type * v); the current method can be set by these two functions. For the definition of non-vector form, the normal three component values are given by parameters nx, NY, and NZ, respectively; for the definition of vector form, the V is set to point to the normal three-component amount. pointer. When applying, normalize the normalization process. Constructing the curve, the surface of the surface is modeled when the complex object is modeled, and the surface is approximated by some line segments and polygons, and will be described by a small number of control points. The definition of the curve is completed by the GLMap1 * () function: Void Glmap1 {fd} (Glenum Target, Type U1, Type U2, Glint Stride, Glint ORDER, Const Type * Points); Parameter Target points out the meaning of the control, and in the Points parameter How much value needs to be provided in it; the Points pointer can point to the control point set, the RGBA color value or the texture coordinate string. The parameters U1 and U2 define the value range of the variable u, which is usually changed from 0 to 1; Stride represents the span (the number of floating point numbers in each storage area, that is, between the two control points) Quantity); the last parameter ORDER is the order, the number of times plus 1, which is consistent with the control points. After the curve is defined, the glenable () function must be explicitly started to work, and its parameters are consistent with the target. Close it through the GLDISABLE () function after use. Curve coordinates can be calculated by glevalcoord1 * () function: void glevalcoord1 {fd} [v] (Type U); this function will generate a curve coordinate value and draw it. The parameter u is any value in the defined domain, and each call will only generate a coordinate, which is also arbitrary. However, more than currently uses uniform interval curve coordinate values, and call GLMAPGRID1 * () and GLMAPGRID1 * () and glevalmesh1 () can obtain equal interval values. These two functions are used to define a one-dimensional grid and calculate the corresponding coordinate value. The structure of the surface can be a mesh line and a fill surface form, and the structure of the curve is similar to the extended expansion into two-dimensional.
The definition function of the surface is given: void Glmap2 {fd} (Glenum Target, Type U1, Type U2, Glint Urget, Glint Uorder, Type V1, Type V2, Glint Vstride, Glint Vorder, Type Points); here's the meaning of Target In GLMAP1 * (), (U1, U2), (V1, V2) are two-dimensional curved coordinates; other parameters such as uORDER, VORDER, USTRIDE, and VSTRIDE, etc. are similar to the definition in the curve; Points To control point coordinates. The calculation of any point of the surface can be done by function void glevalcoord2 {fd} [v] (Type U, TYPE V), by calculating any world coordinate position in the surface by curve coordinate value U, V in the defined domain. For surface, it is also possible to define a uniform spacing coordinate value as a curve: Void GlmapGrid2 {fd} (Glenum Nu, Type U1, Type U2, Glenum NV, Type V1, Type V2); Void Glevation Mode (Glenum Mode, GLINT P1, GLINT P2, GLINT Q1, GLINT Q2); The first function defines a uniform grid of the surface parameter space, from U1 to U2 to the equal interval Nu step, from V1 to V2 to equal interval NV step, then by GlevAlmesh2 () Apply this grid to the already started surface calculation. The MODE parameter of GlevAlmesh2 () may be GL_POINT and GL_LINE, or may be GL_FILL (generated fill space surface).
BEZIER Surface Drawing Drawn a Bezier Surface (Fig. 1) of the Bezier Surface (Fig. 1) by defining a surface and uniform grid (Figure 1): GLFLOAT CTRLPOINTS [4] [4] [3] = {// Control point coordinate {{-2.5, 1.5, 2.0}, {0.5, -1.5, 2.0}, {1.5, -1.5, 2.0}}, {{- 1.5, -0.5, 1.0}, {0.5, 1.5, 2.0}, {0.5, 0.5, 1.0}, {1.5, -0.5, -1.0}}, {{- 1.5, 0.5, 2.0}, {-1.5, 0.5, 1.0}, { 0.5, 0.5, 3.0}, {1.5, -1.5, 1.5, -2.0}, {-0.5, 1.5, -2.0}, {0.5, 0.5, 1.0}, {1.5, 1.5 , -1.0}}}; void init () {GlclearColor (0.0, 0.0, 0.0, 1.0); // clear screen glenable (GL_DEPTH_TEST); // activation depth comparison GLMAP2F (GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0 , 1, 12, 4, & CtrlPoints [0] [0] [0]); // Define the surface glenable (GL_MAP2_VERTEX_3); // Enable surface glenable (GL_AUTO_NORMAL); // Enable surface method to calculate Glenable (GL_NORMALIZE); // Enable method to normalize GlmapGrid2f (20, 0.0, 1.0, 20, 0.0); // Define uniform grid of parameter space GLFLOAT Ambient [4] = {0.4, 0.6, 0.2, 1.0}; // Initializing the light, the process of material GLFLOAT POSITION [4] = {0.0, 1.0, 3.0, 1.0}; GLFLOAT MAT_DIFFUSE [4] = {0.8, 0.6, 0.3, 1.0}; GLFLOAT MAT_SPECULAR [4] = {0.8, 0.6, 0.3 , 1.0}; GLFLOAT MAT_SHININESS [1] = {45.0}; glenable (gl_lighting); glenable (GL_Light0); glLightfv (GL_LIGHT0, GL_AMBIENT, ambient); glLightfv (GL_LIGHT0, GL_POSITION, position); glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess);} FIG. 1 plotted The routine of the Drawing of the BEZier surface NURBS surface can control the shape of the surface by giving a small amount of control points. You can also dynamically generate or adjust the control point through the program during practical applications. In this case, the definition of the surface is to display the GLMAP2f (), GLmapGrid2f (), and the like described above, and the other functions.
In addition to this way, it is also possible to use the OpenGL's function library to draw a function of a non-uniform A-spline curved surface (NURBS surface), which gives some sample code to implement this function: GLFLOAT CTLPoints [4] [4 ] [3]; // Control point storage space Glunurbsobj * twenurb; // pointing to NURBS surface object pointer void INITSURFACE () {INT U, V; for (u = 0; u <4; u ) {for (v = 0; V <4; V ) {CTLPoints [u] [V] [0] = 2.0 * ((GLFLOAT) U - 1.5); CTLPoints [u] [v] [1] = 2.0 * ((GLFLOAT) V - 1.5); if ((u == 1 || U == 2) && (v == 1 || V == 2)) CTLPoints [u] [v] [2] = 6; Else CTLPoints [u] [V] [2] = -6;}}} void init (void) {GLFLOAT MAT_DIFFUSE [] = {0.8, 0.6, 0.3, 1.0}; // Define Surface Material GLFLOAT MAT_SPECULAR [] = {0.8, 0.6, 0.3 , 1.0}; GLfloat mat_shininess [] = {45.0}; glClearColor (0.0, 0.0, 0.0, 1.0); glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess) ; glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); glDepthFunc (GL_LESS); glEnable (GL_DEPTH_TEST); glEnable (GL_AUTO_NORMAL); glEnable (GL_NORMALIZE); InitSurface (); // initialize control point theNurb = gluNewNurbsRenderer (); // Create a NURBS surface object // modify the properties gluNurbsProperty NURBS surface object (theNurb, GLU_SAMPLING_TOLERANCE, 5.0); gluNurbsProperty (theNurb, GLU_DISPLAY_MODE, GLU_FILL);} void CALLBACK Display () {GLfloat knots [8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; // NURBS surface control vector Glclear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Cleans GLPUSHMATRIX (); // Fault Glrotatef (30.0, -1.0, 0.0, 0.0); // Rotation Glscalef (0.5, 0.5, 0.5); // Zoom Transformation Glubeginsurface (THENURB); // Start Surface Draw GlunurbusSurface (Thenurb, 8, Knots, 8, Knots, 4 * 3, 3, & CTLPoints [0] [0] [0] , 4, 4, GL_MAP2_VERTEX_3); // Define the mathematical model of the surface to determine its shape gluendsurface (thenurb); // End the surface to draw GLPopmatrix ();