Выбрать главу

The final value points[x][y][2] statement is our sine value. The sin() function requires radians. We take our degree value, which is our float_x multiplied by 40.0f. Once we have that, to convert to radians we take the degree, divide by 360.0f, multiply by pi, or an approximation and then multiply by 2.0f.

I'm going to re-write the DrawGLScene function from scratch so clean it out and it replace with the following code.

int DrawGLScene(GLvoid) // Draw Our GL Scene

{

 int x, y; // Loop Variables

 float float_x, float_y, float_xb, float_yb; // Used To Break The Flag Into Tiny Quads

Different variables used for controlling the loops. See the code below but most of these serve no "specific" purpose other than controlling loops and storing temporary values.

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And Depth Buffer

 glLoadIdentity(); // Reset The Current Matrix

 glTranslatef(0.0f,0.0f,-12.0f); // Translate 17 Units Into The Screen

 glRotatef(xrot,1.0f,0.0f,0.0f); // Rotate On The X Axis

 glRotatef(yrot,0.0f,1.0f,0.0f); // Rotate On The Y Axis

 glRotatef(zrot,0.0f,0.0f,1.0f); // Rotate On The Z Axis

 glBindTexture(GL_TEXTURE_2D, texture[0]); // Select Our Texture

You've seen all of this before as well. Same as in tutorial #6 except I merely push my scene back away from the camera a bit more.

 glBegin(GL_QUADS); // Start Drawing Our Quads

 for(x = 0; x < 44; x++) // Loop Through The X Plane 0-44 (45 Points)

 {

  for( y = 0; y < 44; y++ ) // Loop Through The Y Plane 0-44 (45 Points)

  {

Merely starts the loop to draw our polygons. I use integers here to keep from having to use the int() function as I did earlier to get the array reference returned as an integer.

   float_x = float(x)/44.0f; // Create A Floating Point X Value

   float_y = float(y)/44.0f; // Create A Floating Point Y Value

   float_xb = float(x+1)/44.0f; // Create A Floating Point Y Value+0.0227f

   float_yb = float(y+1)/44.0f; // Create A Floating Point Y Value+0.0227f

We use the four variables above for the texture coordinates. Each of our polygons (square in the grid), has a 1/44 × 1/44 section of the texture mapped on it. The loops will specify the lower left vertex and then we just add to it accordingly to get the other three (i.e. x+1 or y+1).

   glTexCoord2f( float_x, float_y); // First Texture Coordinate (Bottom Left)

   glVertex3f( points[x][y][0], points[x][y][1], points[x][y][2] );

   glTexCoord2f( float_x, float_yb ); // Second Texture Coordinate (Top Left)

   glVertex3f( points[x][y+1][0], points[x][y+1][1], points[x][y+1][2] );

   glTexCoord2f( float_xb, float_yb ); // Third Texture Coordinate (Top Right)

   glVertex3f( points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2] );

   glTexCoord2f( float_xb, float_y ); // Fourth Texture Coordinate (Bottom Right)

   glVertex3f( points[x+1][y][0], points[x+1][y][1], points[x+1][y][2] );

  }

 }

 glEnd(); // Done Drawing Our Quads

The lines above merely make the OpenGL calls to pass all the data we talked about. Four separate calls to each glTexCoord2f() and glVertex3f(). Continue with the following. Notice the quads are drawn clockwise. This means the face you see initially will be the back. The back is filled in. The front is made up of lines.

If you drew in a counter clockwise order the face you'd initially see would be the front face, meaning you would see the grid type texture instead of the filled in face.

 if (wiggle_count == 2) // Used To Slow Down The Wave (Every 2nd Frame Only)

 {

If we've drawn two scenes, then we want to cycle our sine values giving us "motion".

  for (y = 0; y < 45; y++) // Loop Through The Y Plane

  {

   hold=points[0][y][2]; // Store Current Value One Left Side Of Wave

   for( x = 0; x < 44; x++) // Loop Through The X Plane

   {

    // Current Wave Value Equals Value To The Right

    points[x][y][2] = points[x+1][y][2];

   }

   points[44][y][2]=hold; // Last Value Becomes The Far Left Stored Value

  }

  wiggle_count = 0; // Set Counter Back To Zero

 }

 wiggle_count++; // Increase The Counter

What we do here is store the first value of each line, we then move the wave to the left one, causing the image to wave. The value we stored is then added to the end to create a never ending wave across the face of the texture. Then we reset the counter wiggle_count to keep our animation going.

The above code was modified by NeHe (Feb 2000), to fix a flaw in the ripple going across the surface of the texture. The ripple is now smooth.

 xrot+=0.3f; // Increase The X Rotation Variable

 yrot+=0.2f; // Increase The Y Rotation Variable

 zrot+=0.4f; // Increase The Z Rotation Variable

 return TRUE; // Jump Back

}

Standard NeHe rotation values. :) And that's it folks. Compile and you should have a nice rotating bitmapped "wave". I'm not sure what else to say except, whew.. This was LONG! But I hope you guys can follow it/get something out of it. If you have any questions, want me to clear something up or tell me how god awful, lol, I code, then send me a note.

This was a blast, but very energy/time consuming. It makes me appreciate the likes of NeHe ALOT more now. Thanks all.

Jeff Molofee (NeHe)

* DOWNLOAD Visual C++ Code For This Lesson.

* DOWNLOAD Borland C++ Code For This Lesson. (Conversion by Patrick Salmons)

* DOWNLOAD Cygwin Code For This Lesson. (Conversion by Stephan Ferraro)

* DOWNLOAD Delphi Code For This Lesson. (Conversion by Marc Aarts )

* DOWNLOAD Game GLUT Code For This Lesson. (Conversion by Milikas Anastasios)

* DOWNLOAD Irix Code For This Lesson. (Conversion by Rob Fletcher)

* DOWNLOAD Java Code For This Lesson. (Conversion by Jeff Kirby)

* DOWNLOAD Jedi-SDL Code For This Lesson. (Conversion by Dominique Louis)