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

  glTexCoord2f(1.5f,roll+0.0f); glVertex3f( 28.0f,+7.0f,-50.0f); // Bottom Right

 glEnd(); // Done Drawing Quads

With the sky out of the way, it's time to draw the ground. We draw the ground starting where the sky texture is the lowest coming towards the viewer. The ground texture rolls at the same speed as the fast moving clouds.

The texture is repeated 7 times from left to right and 4 times from back to front to add a little more detail and to prevent the texture from getting all blocky looking. This is done by increasing the texture coordinates from 0.0f – 1.0f to 0.0f – 7.0f (left to right) and 0.0f – 4.0f (up and down).

 glBindTexture(GL_TEXTURE_2D, textures[6].texID); // Select The Ground Texture

 glBegin(GL_QUADS); // Draw A Quad

  glTexCoord2f(7.0f,4.0f-roll); glVertex3f( 27.0f,-3.0f,-50.0f); // Top Right

  glTexCoord2f(0.0f,4.0f-roll); glVertex3f(-27.0f,-3.0f,-50.0f); // Top Left

  glTexCoord2f(0.0f,0.0f-roll); glVertex3f(-27.0f,-3.0f,0.0f); // Bottom Left

  glTexCoord2f(7.0f,0.0f-roll); glVertex3f( 27.0f,-3.0f,0.0f); // Bottom Right

 glEnd(); // Done Drawing Quad

After drawing the sky and the ground, we jump to the section of code that draws all of our targets (objects) called none other than DrawTargets().

After drawing out targets, we pop the modelview matrix off the stack (restoring it to it's previous state).

 DrawTargets(); // Draw Our Targets

 glPopMatrix(); // Pop The Modelview Matrix

The code below draws the crosshair. We start off by grabbing our current window dimensions. We do this in case the window was resized in windowed mode. GetClientRect grabs the dimensions and stores them in window. We then select our projection matrix and push it onto the stack. We reset the view with glLoadIdentity() and then set the screen up in ortho mode instead of perspective. The window will go from 0 to window.right from left to right, and from 0 to window.bottom from the bottom to the top of the screen.

The third parameter of glOrtho() is supposed to be the bottom value, instead I swapped the bottom and top values. I did this so that the crosshair would be rendered in a counter clockwise direction. With 0 at the top and window.bottom at the bottom, the winding would go the opposite direction and the crosshair and text would not appear.

After setting up the ortho view, we select the modelview matrix, and position the crosshair. Because the screen is upside down, we have to invert the mouse as well. Otherwise our crosshair would move down if we moved the mouse up and up if we moved the mouse down. To do this we subtract the current mouse_y value from the bottom of the window (window.bottom).

After translating to the current mouse position, we draw the crosshair. We do this by calling Object(). Instead of units, we are going to specify the width and height in pixels. The crosshair will be 16x16 pixels wide and tall and the texture used to draw the object is texture 8 (the crosshair texture).

I decided to use a custom cursor for two reasons… first and most important, it looks cool, and it can be modified using any art program that supports the alpha channel. Secondly, some video cards do not display a cursor in fullscreen mode. Playing the game without a cursor in fullscreen mode is not easy :)

 // Crosshair (In Ortho View)

 RECT window; // Storage For Window Dimensions

 GetClientRect (g_window->hWnd,&window); // Get Window Dimensions

 glMatrixMode(GL_PROJECTION); // Select The Projection Matrix

 glPushMatrix(); // Store The Projection Matrix

 glLoadIdentity(); // Reset The Projection Matrix

 glOrtho(0,window.right,0,window.bottom,-1,1); // Set Up An Ortho Screen

 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix

 glTranslated(mouse_x,window.bottom-mouse_y,0.0f); // Move To The Current Mouse Position

 Object(16,16,8); // Draw The Crosshair

This section of code put the title at the top of the screen, and displays the level and score in the bottom left and right corners of the screen. The reason I put this code here is because it's easier to position the text accurately in ortho mode.

 // Game Stats / Title

 glPrint(240,450,"NeHe Productions"); // Print Title

 glPrint(10,10,"Leveclass="underline" %i",level); // Print Level

 glPrint(250,10,"Score: %i",score); // Print Score

This section checks to see if the player has missed more than 10 objects. If so, we set the number of misses (miss) to 9 and we set game to TRUE. Setting the game to TRUE means the game is over!

 if (miss>9) // Have We Missed 10 Objects?

 {

  miss=9; // Limit Misses To 10

  game=TRUE; // Game Over TRUE

 }

In the code below, we check to see if game is TRUE. If game is TRUE, we print the GAME OVER messages. If game is false, we print the players morale (out of 10). The morale is calculated by subtracting the players misses (miss) from 10. The more the player misses, the lower his morale.

 if (game) // Is Game Over?

  glPrint(490,10,"GAME OVER"); // Game Over Message

 else glPrint(490,10,"Morale: %i/10",10-miss); // Print Morale #/10

The last thing we do is select the projection matrix, restore (pop) our matrix back to it's previous state, set the matrix mode to modelview and flush the buffer to make sure all objects have been rendered.

 glMatrixMode(GL_PROJECTION); // Select The Projection Matrix

 glPopMatrix(); // Restore The Old Projection Matrix

 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix

 glFlush(); // Flush The GL Rendering Pipeline

}

This tutorial is the result of many late nights, and many many hours of coding & writing HTML. By the end of this tutorial you should have a good understanding of how picking, sorting, alpha blending and alpha testing works. Picking allows you to create interactive point and click software. Everything from games, to fancy GUI's. The best feature of picking is that you don't have to keep track of where your objects are. You assign a name and check for hits. It's that easy! With alpha blending and alpha testing you can make your objects completely solid, or full of holes. The results are great, and you don't have to worry about objects showing through your textures, unless you want them to! As always, I hope you have enjoyed this tutorial, and hope to see some cool games, or projects based on code from this tutorial. If you have any questions or you find mistakes in the tutorial please let me know… I'm only human :)

I could have spent alot more time adding things like physics, more graphics, more sound, etc. This is just a tutorial though! I didn't write it to impress you with bells and whistles. I wrote it to teach you OpenGL with as little confusion as possible. I hope to see some cool modifications to the code. If you add something cool the the tutorial send me the demo. If it's a cool modification I'll post it to the downloads page. If I get enough modifications I may set up a page dedicated to modified versions of this tutorial! I am here to give you a starting point. The rest is up to you :)

Jeff Molofee (NeHe)

* DOWNLOAD Visual C++ Code For This Lesson.

* DOWNLOAD Delphi Code For This Lesson. (Conversion by Hugh Waite