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

So now we have this group of data that describes the color, distance and angle of a star on the screen. Unfortunately we have more than one star to keep track of. Instead of creating 50 red values, 50 green values, 50 blue values, 50 distance values and 50 angle values, we just create an array called star. Each number in the star array will hold all of the information in our structure called stars. We make the star array in the 8th line below. If we break down the 8th line: stars star[num]. This is what we come up with. The type of array is going to be stars. stars is a structure. So the array is going to hold all of the information in the structure. The name of the array is star. The number of arrays is [num]. So because num=50, we now have an array called star. Our array stores the elements of the structure stars. Alot easier than keeping track of each star with seperate variables. Which would be a very stupid thing to do, and would not allow us to add remove stars by changing the const value of num.

typedef struct // Create A Structure For Star

{

 int r, g, b; // Stars Color

 GLfloat dist; // Stars Distance From Center

 GLfloat angle; // Stars Current Angle

} stars; // Structures Name Is Stars

stars star[num]; // Make 'star' Array Of 'num' Using Info From The Structure 'stars'

Next we set up variables to keep track of how far away from the stars the viewer is (zoom), and what angle we're seeing the stars from (tilt). We make a variable called spin that will spin the twinkling stars on the z axis, which makes them look like they are spinning at their current location.

loop is a variable we'll use in the program to draw all 50 stars, and texture[1] will be used to store the one b&w texture that we load in. If you wanted more textures, you'd increase the value from one to however many textures you decide to use.

GLfloat zoom=-15.0f; // Viewing Distance Away From Stars

GLfloat tilt=90.0f; // Tilt The View

GLfloat spin; // Spin Twinkling Stars

GLuint loop; // General Loop Variable

GLuint texture[1]; // Storage For One Texture

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc

Right after the line above we add code to load in our texture. I shouldn't have to explain the code in great detail. It's the same code we used to load the textures in lesson 6, 7 and 8. The bitmap we load this time is called star.bmp. We generate only one texture using glGenTextures(1, &texture[0]). The texture will use linear filtering.

AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image

{

 FILE *File=NULL; // File Handle

 if (!Filename) // Make Sure A Filename Was Given

 {

  return NULL; // If Not Return NULL

 }

 File=fopen(Filename,"r"); // Check To See If The File Exists

 if (File) // Does The File Exist?

 {

  fclose(File); // Close The Handle

  return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer

 }

 return NULL; // If Load Failed Return NULL

}

This is the section of code that loads the bitmap (calling the code above) and converts it into a textures. Status is used to keep track of whether or not the texture was loaded and created.

int LoadGLTextures() // Load Bitmaps And Convert To Textures

{

 int Status=FALSE; // Status Indicator

 AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture

 memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL

 // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit

 if (TextureImage[0]=LoadBMP("Data/Star.bmp")) {

  Status=TRUE; // Set The Status To TRUE

  glGenTextures(1, &texture[0]); // Create One Texture

  // Create Linear Filtered Texture

  glBindTexture(GL_TEXTURE_2D, texture[0]);

  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

  glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

 }

 if (TextureImage[0]) // If Texture Exists

 {

  if (TextureImage[0]->data) // If Texture Image Exists

  {

   free(TextureImage[0]->data); // Free The Texture Image Memory

  }

  free(TextureImage[0]); // Free The Image Structure

 }

 return Status; // Return The Status

}

Now we set up OpenGL to render the way we want. We're not going to be using Depth Testing in this project, so make sure if you're using the code from lesson one that you remove glDepthFunc(GL_LEQUAL); and glEnable(GL_DEPTH_TEST); otherwise you'll see some very bad results. We're using texture mapping in this code however so you'll want to make sure you add any lines that are not in lesson 1. You'll notice we're enabling texture mapping, along with blending.

int InitGL(GLvoid) // All Setup For OpenGL Goes Here

{

 if (!LoadGLTextures()) // Jump To Texture Loading Routine

 {

  return FALSE; // If Texture Didn't Load Return FALSE

 }

 glEnable(GL_TEXTURE_2D); // Enable Texture Mapping

 glShadeModel(GL_SMOOTH); // Enable Smooth Shading

 glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background

 glClearDepth(1.0f); // Depth Buffer Setup

 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations

 glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Set The Blending Function For Translucency

 glEnable(GL_BLEND); // Enable Blending

The following code is new. It sets up the starting angle, distance, and color of each star. Notice how easy it is to change the information in the structure. The loop will go through all 50 stars. To change the angle of star[1] all we have to do is say star[1].angle = {some number} . It's that simple!

 for (loop=0; loop<num; loop++) // Create A Loop That Goes Through All The Stars

 {

  star[loop].angle=0.0f; // Start All The Stars At Angle Zero

I calculate the distance by taking the current star (which is the value of loop) and dividing it by the maximum amount of stars there can be. Then I multiply the result by 5.0f. Basically what this does is moves each star a little bit farther than the previous star. When loop is 50 (the last star), loop divided by num will be 1.0f. The reason I multiply by 5.0f is because 1.0f*5.0f is 5.0f. 5.0f is the very edge of the screen. I don't want stars going off the screen so 5.0f is perfect. If you set the zoom further into the screen you could use a higher number than 5.0f, but your stars would be alot smaller (because of perspective).