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

First things first… we clear the screen and set up a loop to render all 50 of our butterflies (objects).

void Draw (void) // Draw The Scene

{

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

 for (int loop=0; loop<50; loop++) // Loop Of 50 (Draw 50 Objects)

 {

We call glLoadIdentity( ) to reset the modelview matrix. Then we select the texture that was assigned to our object (obj[loop].tex).

We position the butterfly using glTranslatef() then rotate the buttefly 45 degrees on it's X axis. This tilts the butterfly a little more towards the viewer so it doesn't look like a flat 2D object.

The final rotation spins the butterfly on it's z-axis which makes it spin as it falls down the screen.

  glLoadIdentity (); // Reset The Modelview Matrix

  glBindTexture(GL_TEXTURE_2D, texture[obj[loop].tex]); // Bind Our Texture

  glTranslatef(obj[loop].x, obj[loop].y, obj[loop].z); // Position The Object

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

  glRotatef((obj[loop].spinz), 0.0f, 0.0f, 1.0f); // Spin On The Z-Axis

Texturing a triangle is not all that different from texturing a quad. Just because you only have 3 vertices doesn't mean you can't texture a quad to your triangle. The only difference is that you need to be more aware of your texture coordinates.

In the code below, we draw the first triangle. We start at the top right corner of an invisible quad. We then move left until we get to the top left corner. From there we go to the bottom left corner.

The code below will render the following image: Notice that half the buttefly is rendered on the first triangle. The other half is rendered on the second triangle. The texture coordinates match up with the vertex coordinates and although there are only 3 texture coordinates, it's still enough information to tell OpenGL what portion of the image needs to be mapped to the triangle.

  glBegin(GL_TRIANGLES); // Begin Drawing Triangles

   // First Triangle

   glTexCoord2f(1.0f,1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); // Point 1 (Top Right)

   glTexCoord2f(0.0f,1.0f); glVertex3f(-1.0f, 1.0f, obj[loop].flap); // Point 2 (Top Left)

   glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); // Point 3 (Bottom Left)

The code below renders the second half of the triangle. Same technique as above, but this time we render from the top right to the bottom left, then over to the bottom right. The second point of the first triangle and the third point of the second triangle move back and forth on the z-axis to create the illusion of flapping. What's really happening is that point is moving from –1.0f to 1.0f and then back, which causes the two triangles to bend in the center where the butterflies body is.

If you look at the two pictures you will notice that points 2 and 3 are the tips of the wings. Creates a very nice flapping effect with minimal effort.

   // Second Triangle

   glTexCoord2f(1.0f,1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); // Point 1 (Top Right)

   glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); // Point 2 (Bottom Left)

   glTexCoord2f(1.0f,0.0f); glVertex3f( 1.0f,-1.0f, obj[loop].flap); // Point 3 (Bottom Right)

  glEnd(); // Done Drawing Triangles

The following bit of code moves the butterfly down the screen by subtracting obj[loop].yi from obj[loop].y. The butterfly spinz value is increased by spinzi (which can be a negative or positive value) and the wings are increased by fi. fi can also be a negative or positive direction depending on the direction we want the wings to flap.

  obj[loop].y-=obj[loop].yi; // Move Object Down The Screen

  obj[loop].spinz+=obj[loop].spinzi; // Increase Z Rotation By spinzi

  obj[loop].flap+=obj[loop].fi; // Increase flap Value By fi

After moving the butterfly down the screen, we need to see if it's gone past the bottom of the screen (no longer visible). if it has, we call SetObject(loop) to assign the butterfly a new texture, new fall speed, etc.

  if (obj[loop].y<-18.0f) // Is Object Off The Screen?

  {

   SetObject(loop); // If So, Reassign New Values

  }

To make the wings flap, we check to see if the flap value is greater than or less than 1.0f and –1.0f. If the wing is greater than or less than those values, we change the flap direction by making fi=-fi.

So if the wings were going up, and they hit 1.0f, fi will become a negative value which will make the wings go down.

Sleep(15) has been added to slow the program down by 15 milliseconds. It ran insanely fast on a friends machine, and I was too lazy to modify the code to take advantage of the timer :)

  if ((obj[loop].flap>1.0f) || (obj[loop].flap<-1.0f)) // Time To Change Flap Direction?

  {

   obj[loop].fi=-obj[loop].fi; // Change Direction By Making fi = –fi

  }

 }

 Sleep(15); // Create A Short Delay (15 Milliseconds)

 glFlush (); // Flush The GL Rendering Pipeline

}

I hope you enjoyed the tutorial. Hopefully it makes loading textures from a resource a lot easier to understand, and texturing triangles a snap. I've reread this tutorial about 5 times now, and it seems easy enough, but if you're still having problems, let me know. As always, I want the tutorials to be the best that they can be, so feedback is greatly appreciated!

Thanks to everyone for the great support! This site would be nothing without it's visitors!!!

Jeff Molofee (NeHe)

* DOWNLOAD Visual C++ Code For This Lesson. 

* DOWNLOAD Lesson 38 – Enhanced (Masking, Sorting, Keyboard — NeHe).

* DOWNLOAD Lesson 38 – Screensaver by Brian Hunsucker.