Go from "translation" Nehe OpenGL tutorial
Objective
Statement, this Nehe OpenGL tutorial series of articles by 51 blog yarin Translation (2010-08-19), this blog for reprint and a little collation and modification. Thank you for compiling Nehe's OpenGL pipeline tutorial, as well as yarn translation finishing.
Nehe OpenGL Lesson 25th: Morphing
Deform and load 3D objects from a file:
Welcome to this exciting lesson, in this lesson, we will introduce the deformation of the model. It is important to note that each model must have the same vertex to correspond to one by one and apply the warp.
In this lesson, we also teach you how to read model data from a file. The
file starts with the same section as before, without any changes.
We'll add a few rotation variables to record the rotated information. and use Cx,cy,cz to set the position of the object on the screen. The
variable key is used to record the current model, and step is used to set intermediate steps between adjacent deformations. If step is 200, it takes 200 times to turn one object into another.
Finally we use a variable to set whether or not to use transformations.
glfloat xrot,yrot,zrot, // X, Y & Z axis rotation angle
xspeed,yspeed,zspeed, //X, Y & Z Rotation speed of the axis
cx,cy,cz=-15; //object's position
int Key=1; identifier of the object
int step=0,steps=200; Number of steps to transform
BOOL Morph=false; Whether to use deform
The following structure defines a three-dimensional vertex
typedef struct
{
float x, y, Z;
} VERTEX;
The following structure uses vertices to describe a three-dimensional object
typedef struct//object structure
{
int Verts; The number of vertices in an object
VERTEX *points; Pointer that contains vertex data
} OBJECT;
The MaxVer is used to record the maximum number of vertices in each object, such as when an object uses 5 vertices and the other object uses 20 vertices, then the number of vertices of the object is 20.
The knot defines four of the model objects we use, and saves the middle state of the adjacent model deformation in the helper, sour the original model object, and dest the model object that will be deformed.
int maxver; Maximum number of vertices
Object Morph1,morph2,morph3,morph4,//Our four objects
Helper,*sour,*dest; Help object, original object, target object
wndproc () function does not change
The following function is used to allocate memory space for the model to save vertex data
void objallocate (OBJECT *k,int N)
{
k->points= (vertex*) malloc (sizeof (VERTEX) *n); // Allocate memory space for n vertices
}
The following function is used to release the memory space allocated for the model
void Objfree (OBJECT *k)
{
free (k-> points);
}
We use a loop to read characters, read up to 255 characters, and when we encounter a ' \ n ' carriage return, stop reading and return immediately.
void Readstr (FILE *f,char *string) //reads a line of characters
{
do
{
fgets ( String, 255, f); //reads up to 255 characters
} while ((string[0] = = '/') | | (string[0] = = ' \ n ')); //encounters a carriage return stops reading
return; //returns
}
void Objload (char *name,object *k) //load a model from a file
{
int ver; //save vertex number
float rx,ry , rz; //save model location
FILE *filein; //Open File Handle
char oneline[255]; //Save 255 characters
filein = fopen (name, "RT"); //open a text file for reading
readstr ( Filein,oneline); //reads a line of text
sscanf (oneline, "Vertices:%d\n", &ver); //search string "Vertices:" and save the number of vertices in the ver variable
k->verts=ver; //set the number of vertices of the model
objallocate (k,ver); //allocating memory for model data
The following loop reads the data for each row (that is, each vertex) and saves it in memory?/td>
for (int i=0;i<ver;i++)//loop all vertices
{
Readstr (Filein,oneline); Reading a row of data
SSCANF (Oneline, "%f%f%f", &rx, &ry, &rz); Save vertex data in Rx,ry,rz
k->points[i].x = Rx; Saves the x-coordinate of the current vertex
K->points[i].y = ry; Save the y-coordinate of the current vertex
K->points[i].z = RZ; Saves the z-coordinate of the current vertex
}
Fclose (Filein); Close File
if (ver>maxver) maxver=ver; //record the maximum number of vertices
}
The following function calculates the displacement of each transformation of the I vertex based on the set interval
VERTEX Calculate (int i) //calculates the displacement of the first vertex of each transformation
{
vertex a;
a.x= (sour->points[i].x-dest->points[i].x)/steps;
a.y= ( SOUR->POINTS[I].Y-DEST->POINTS[I].Y)/steps;
a.z= (Sour->points[i]. Z-DEST->POINTS[I].Z)/steps;
return a;
}
Resizeglscene () function does not change
glvoid resizeglscene (glsizei width, glsizei height)
The following function completes the initialization function, which sets the blending mode to semitransparent
int INITGL (glvoid)
{
Glblendfunc (Gl_src_alpha,gl_one); Set semitransparent blending mode
Glclearcolor (0.0f, 0.0f, 0.0f, 0.0f); Set the clear color to black
Glcleardepth (1.0); Set a value of 1 in the depth cache
Gldepthfunc (gl_less); Setting the depth test function
Glenable (gl_depth_test); Enable depth Testing
Glshademodel (Gl_smooth); Set shading mode to smooth shading
Glhint (Gl_perspective_correction_hint, gl_nicest);
The following code is used to load our model object
maxver=0; The maximum number of vertices initialized is 0
Objload ("Data/sphere.txt", &MORPH1); Load Ball Model
Objload ("Data/torus.txt", &MORPH2); Load Ring Model
Objload ("Data/tube.txt", &morph3); Load Cube model
The fourth model is not read from the file, we randomly generate a model point between ( -7,-7,-7)-(7,7,7), which has 486 vertices as we do with the model we're carrying.
Objallocate (&morph4,486); Allocating memory resources for a fourth model
for (int i=0;i<486;i++)//random set of 486 vertices
{
morph4.points[i].x= (float) (rand ()%14000)/1000)-7;
Morph4.points[i].y= (float) (rand ()%14000)/1000)-7;
morph4.points[i].z= (float) (rand ()%14000)/1000)-7;
}
Initialize the intermediate model as a sphere and set both the original and the target model to the ball
Objload ("Data/sphere.txt", &helper);
sour=dest=&morph1;
return TRUE; Initialization complete, successful return
}
Here is the specific drawing code, as usual we set the model changes first, so that we can better observe.
void Drawglscene (Glvoid)
{
Glclear (Gl_color_buffer_bit | Gl_depth_buffer_bit); Empty cache
Glloadidentity (); Resetting the Model transformation matrix
Gltranslatef (CX,CY,CZ); Panning and rotating
Glrotatef (xrot,1,0,0);
Glrotatef (yrot,0,1,0);
Glrotatef (zrot,0,0,1);
Xrot+=xspeed; Yrot+=yspeed; Zrot+=zspeed; Increase the angle of rotation depending on the rotational speed
Glfloat Tx,ty,tz; Vertex TEMP variable
VERTEX Q; Save temporary vertices for intermediate calculations
Next we draw the points in the model, and if you enable deformation, the intermediate process points of the deformation are computed.
Glbegin (gl_points); Point Draw Start
for (int i=0;i<morph1.verts;i++)//loop draws each vertex in model 1
{
if (morph) q=calculate (i); else q.x=q.y=q.z=0; If Deform is enabled, the intermediate model is computed
helper.points[i].x-=q.x;
HELPER.POINTS[I].Y-=Q.Y;
Helper.points[i].z-=q.z;
tx=helper.points[i].x; Save calculations to X, y, z variables
TY=HELPER.POINTS[I].Y;
Tz=helper.points[i].z;
To make the animation run smoothly, we plotted three points in the middle state. Let the deformation process change from bluish green to blue next state.
glcolor3f (0,1,1); Set color
glvertex3f (Tx,ty,tz); Draw vertices
glcolor3f (0,0.5f,1); Turn the color blue some
tx-=2*q.x; TY-=2*Q.Y; TY-=2*Q.Y; If Warp is enabled, the vertices after 2 steps are drawn
glvertex3f (Tx,ty,tz);
glcolor3f (0,0,1); Turn the color blue some
tx-=2*q.x; TY-=2*Q.Y; TY-=2*Q.Y; If Warp is enabled, the vertices after 2 steps are drawn
glvertex3f (Tx,ty,tz);
}
Glend (); Draw End
Finally, if deform is enabled, increment the step parameter and then draw the next point.
Increase the number of warp steps if Deform is enabled
if (morph && step<=steps) step++; else {morph=false; sour=dest; step=0;}
return TRUE; Everything OK
}
The Killglwindow () function basically doesn't change, just add code that frees 5 of the model's memory
Objfree (&MORPH1); Release Model 1 Memory
Objfree (&MORPH2); Release Model 2 Memory
Objfree (&MORPH3); Release Model 3 Memory
Objfree (&MORPH4); Release Model 4 Memory
Objfree (&helper); Release Model 5 Memory
Createglwindow () function does not change
BOOL Createglwindow ()
LRESULT CALLBACK WndProc ()
In the WinMain () function, we have added some keyboard-controlled functions
if (Keys[vk_prior])//pageup key is pressed
zspeed+=0.01f; Press to increase the speed of rotation around the z-axis
if (Keys[vk_next])//PageDown key is pressed
zspeed-=0.01f; Press to decrease the speed of rotation around the z-axis
if (Keys[vk_down])//DOWN ARROW key is pressed
xspeed+=0.01f; Press to increase the speed of rotation around the x-axis
if (keys[vk_up])//The UP ARROW key is pressed
xspeed-=0.01f; Press to reduce the speed of rotation around the x-axis
if (Keys[vk_right])//RIGHT ARROW key is pressed
yspeed+=0.01f; Press to increase the speed of rotation along the Y axis
if (Keys[vk_left])//LEFT ARROW key is pressed
yspeed-=0.01f; Press to decrease the speed of rotation along the y-axis
if (keys[' Q '))//q key is pressed
cz-=0.01f; Yes, move it to the screen.
if (keys[' z '])//z key is pressed
cz+=0.01f; Yes, move it out of the screen.
if (keys[' W '))//W key is pressed
cy+=0.01f; Yes then move up
if (keys[' s '))//S key is pressed
cy-=0.01f; Yes then move Down
if (keys[' d '))//d key is pressed
cx+=0.01f; Yes then move right
if (keys[' a '))//a key is pressed
cx-=0.01f; Yes then move left
1,2,3,4 key to set the target model for deformation
if (keys[' 1 ') && (key!=1) &&!morph)//If 1 is pressed, then deform to model 1
{
Key=1;
Morph=true;
dest=&morph1;
}
if (keys[' 2 ') && (key!=2) &&!morph)//If 2 is pressed, then deform to model 1
{
key=2;
Morph=true;
dest=&morph2;
}
if (keys[' 3 ') && (key!=3) &&!morph)//If 3 is pressed, then deform to model 1
{
key=3;
Morph=true;
dest=&morph3;
}
if (keys[' 4 ') && (key!=4) &&!morph)//If 4 is pressed, then deform to model 1
{
key=4;
Morph=true;
dest=&morph4;
}
Original source code and version of the download:
Http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=25
Nehe OpenGL Tutorial Lesson 25th: Morphing