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

   // Create MipMapped Texture

   glBindTexture(GL_TEXTURE_2D, texture[loop+4]); // Gen Tex 4 and 5

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);

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

  }

  for (loop=0; loop<=1; loop++) {

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

   {

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

    {

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

    }

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

   }

  }

 }

 return Status; // Return The Status

}

We'll modify the cube drawing code a little. Instead of using 1.0 and –1.0 for the normal values, we'll use 0.5 and –0.5. By changing the value of the normal, you can zoom the reflection map in and out. If the normal value is high, the image being reflected will be bigger, and may appear blocky. By reducing the normal value to 0.5 and –0.5 the reflected image is zoomed out a bit so that the image reflecting off the cube isn't all blocky looking. Setting the normal value too low will create undesirable results.

GLvoid glDrawCube() {

 glBegin(GL_QUADS);

  // Front Face

  glNormal3f( 0.0f, 0.0f, 0.5f);

  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, –1.0f, 1.0f);

  glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, –1.0f, 1.0f);

  glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);

  glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);

  // Back Face

  glNormal3f( 0.0f, 0.0f,-0.5f);

  glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, –1.0f, –1.0f);

  glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, –1.0f);

  glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, –1.0f);

  glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, –1.0f, –1.0f);

  // Top Face

  glNormal3f( 0.0f, 0.5f, 0.0f);

  glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, –1.0f);

  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);

  glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);

  glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, –1.0f);

  // Bottom Face

  glNormal3f( 0.0f,-0.5f, 0.0f);

  glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, –1.0f, –1.0f);

  glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, –1.0f, –1.0f);

  glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, –1.0f, 1.0f);

  glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, –1.0f, 1.0f);

  // Right Face

  glNormal3f( 0.5f, 0.0f, 0.0f);

  glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, –1.0f, –1.0f);

  glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, –1.0f);

  glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);

  glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, –1.0f, 1.0f);

  // Left Face

  glNormal3f(-0.5f, 0.0f, 0.0f);

  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, –1.0f, –1.0f);

  glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, –1.0f, 1.0f);

  glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);

  glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, –1.0f);

 glEnd();

}

Now in InitGL we add two new function calls, these two calls set the texture generation mode for S and T to Sphere Mapping. The texture coordinates S, T, R & Q relate in a way to object coordinates x, y, z and w. If you are using a one-dimensional texture (1D) you will use the S coordinate. If your texture is two dimensional, you will use the S & T coordinates.

So what the following code does is tells OpenGL how to automatically generate the S and T coordinates for us based on the sphere-mapping formula. The R and Q coordinates are usually ignored. The Q coordinate can be used for advanced texture mapping extensions, and the R coordinate may become useful once 3D texture mapping has been added to OpenGL, but for now we will ignore the R & Q Coords. The S coordinate runs horizontally across the face of our polygon, the T coordinate runs vertically across the face of our polygon.

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); // Set The Texture Generation Mode For S To Sphere Mapping ( NEW )

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); // Set The Texture Generation Mode For T To Sphere Mapping ( NEW )

We're almost done! All we have to do is set up the rendering, I took out a few of the quadratic objects because they didn't work well with environment mapping. The first thing we need to do is enable texture generation. Then we select the reflective texture (sphere map) and draw our object. After all of the objects you want sphere-mapped have been drawn, you will want to disable texture generation, otherwise everything will be sphere mapped. We disable sphere-mapping before we draw the background scene (we don't want the background sphere mapped). You will notice that the bind texture commands may look fairly complex. All we're doing is selecting the filter to use when drawing our sphere map or the background image.

int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing

{

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

 glLoadIdentity(); // Reset The View

 glTranslatef(0.0f,0.0f,z);

 glEnable(GL_TEXTURE_GEN_S); // Enable Texture Coord Generation For S ( NEW )

 glEnable(GL_TEXTURE_GEN_T); // Enable Texture Coord Generation For T ( NEW )

 glBindTexture(GL_TEXTURE_2D, texture[filter+(filter+1)]); // This Will Select A Sphere Map

 glPushMatrix();

 glRotatef(xrot,1.0f,0.0f,0.0f);

 glRotatef(yrot,0.0f,1.0f,0.0f);

 switch(object) {

 case 0:

  glDrawCube();

  break;

 case 1:

  glTranslatef(0.0f,0.0f,-1.5f); // Center The Cylinder

  gluCylinder(quadratic,1.0f,1.0f,3.0f,32,32); // A Cylinder With A Radius Of 0.5 And A Height Of 2

  break;

 case 2:

  gluSphere(quadratic,1.3f,32,32); // Sphere With A Radius Of 1 And 16 Longitude/Latitude Segments

  break;

 case 3:

  glTranslatef(0.0f,0.0f,-1.5f); // Center The Cone

  gluCylinder(quadratic,1.0f,0.0f,3.0f,32,32); // Cone With A Bottom Radius Of .5 And Height Of 2

  break;

 };

 glPopMatrix();

 glDisable(GL_TEXTURE_GEN_S); // Disable Texture Coord Generation ( NEW )

 glDisable(GL_TEXTURE_GEN_T); // Disable Texture Coord Generation ( NEW )