Nehe OpenGL Tutorial Lesson 25th: Morphing

Source: Internet
Author: User

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", &AMP;MORPH1); Load Ball Model
Objload ("Data/torus.txt", &AMP;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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.