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

The variables r, g and b hold the red intensity, green intensity and blue intensity of our particle. The closer r is to 1.0f, the more red the particle will be. Making all 3 variables 1.0f will create a white particle.

 float r; // Red Value

 float g; // Green Value

 float b; // Blue Value

The variables x, y and z control where the particle will be displayed on the screen. x holds the location of our particle on the x axis. y holds the location of our particle on the y axis, and finally z holds the location of our particle on the z axis.

 float x; // X Position

 float y; // Y Position

 float z; // Z Position

The next three variables are important. These three variables control how fast a particle is moving on specific axis, and what direction to move. If xi is a negative value our particle will move left. Positive it will move right. If yi is negative our particle will move down. Positive it will move up. Finally, if zi is negative the particle will move into the screen, and postive it will move towards the viewer.

 float xi; // X Direction

 float yi; // Y Direction

 float zi; // Z Direction

Lastly, 3 more variables! Each of these variables can be thought of as gravity. If xg is a positive value, our particle will pull to the right. If it's negative our particle will be pulled to the left. So if our particle is moving left (negative) and we apply a positive gravity, the speed will eventually slow so much that our particle will start moving the opposite direction. yg pulls up or down and zg pulls towards or away from the viewer.

 float xg; // X Gravity

 float yg; // Y Gravity

 float zg; // Z Gravity

particles is the name of our structure.

} particles; // Particles Structure

Next we create an array called particle. This array will store MAX_PARTICLES. Translated into english we create storage for 1000 (MAX_PARTICLES) particles. This storage space will store the information for each individual particle.

particles particle[MAX_PARTICLES]; // Particle Array (Room For Particle Info)

We cut back on the amount of code required for this program by storing our 12 different colors in a color array. For each color from 0 to 11 we store the red intensity, the green intensity, and finally the blue intensity. The color table below stores 12 different colors fading from red to violet.

static GLfloat colors[12][3]= // Rainbow Of Colors

{

 {1.0f,0.5f,0.5f}, {1.0f,0.75f,0.5f}, {1.0f,1.0f,0.5f}, {0.75f,1.0f,0.5f},

 {0.5f,1.0f,0.5f}, {0.5f,1.0f,0.75f}, {0.5f,1.0f,1.0f}, {0.5f,0.75f,1.0f},

 {0.5f,0.5f,1.0f}, {0.75f,0.5f,1.0f}, {1.0f,0.5f,1.0f}, {1.0f,0.5f,0.75f}

};

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

Our bitmap loading code hasn't changed.

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

Our texture loading code will load in our particle bitmap and convert it to a linear filtered texture.

 if (TextureImage[0]=LoadBMP("Data/Particle.bmp")) // Load Particle Texture

 {

  Status=TRUE; // Set The Status To TRUE

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

  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

}

The only change I made to the resize code was a deeper viewing distance. Instead of 100.0f, we can now view particles 200.0f units into the screen.

GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window

{

 if (height==0) // Prevent A Divide By Zero By

 {

  height=1; // Making Height Equal One

 }

 glViewport(0, 0, width, height); // Reset The Current Viewport

 glMatrixMode(GL_PROJECTION); // Select The Projection Matrix

 glLoadIdentity(); // Reset The Projection Matrix

 // Calculate The Aspect Ratio Of The Window

 gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,200.0f); ( MODIFIED )

 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix

 glLoadIdentity(); // Reset The Modelview Matrix

}

If you're using the lesson 1 code, replace it with the code below. I've added code to load in our texture and set up blending for our particles.

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

 }

We enable smooth shading, clear our background to black, disable depth testing, blending and texture mapping. After enabling texture mapping we select our particle texture.

 glShadeModel(GL_SMOOTH); // Enables Smooth Shading

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

 glClearDepth(1.0f); // Depth Buffer Setup

 glDisable(GL_DEPTH_TEST); // Disables Depth Testing

 glEnable(GL_BLEND); // Enable Blending

 glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Type Of Blending To Perform

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