JMU
Texture Mapping in OpenGL
An Introduction


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Steps in the Initialization Process
Steps in the Rendering Process
Naming a Texture
Naming a Texture (cont.)

An Example

openglexamples/textures/image.c (Fragment: name)
        static GLuint     textureName;

  // Get a name for the texture
  glGenTextures(1, &textureName);
        
Binding a Texture to a Name
Binding a Texture to a Name (cont.)

An Example

openglexamples/textures/image.c (Fragment: bind)
          // Bind the texture object to its name
  glBindTexture(GL_TEXTURE_2D, textureName);
        
Specifying Parameters
Specifying Parameters (cont.)

An Example

openglexamples/textures/image.c (Fragment: parameters)
          // Specify the parameters
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        
Specifying the Application Mode
Specifying the Application Mode (cont.)

An Example

openglexamples/textures/image.c (Fragment: mode)
          // Specify the application mode
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        
Creating the Texture Object
Creating the Texture Object (cont.)

An Example

openglexamples/textures/image.c (Fragment: create)
          // Create the texture object
  glTexImage2D(GL_TEXTURE_2D, 0,                // One resolution (i.e. level 0)
               3,                 // 3 components (i.e., RGB)
               256,               // Width
               256,               // Height
               0,                 // Border width
               GL_RGB,            // Format
               GL_UNSIGNED_BYTE,  // Data type of the texels
               image);
        
Enabling Texture Mapping
Enabling Texture Mapping (cont.)

An Example

openglexamples/textures/image.c (Fragment: enable)
          // Enable textures
  glEnable(GL_TEXTURE_2D);
        
Rendering
Rendering (cont.)

An Example

openglexamples/textures/image.c (Fragment: render)
        /**
 * The display callback
 */
void display() {
  // Clear the screen
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Select the texture object
  glBindTexture(GL_TEXTURE_2D, textureName);

  // Draw the cube
  for (int f = 0; f < 6; f++) {
    glBegin(GL_POLYGON);
    int v;

    v = faces[f][0];
    glTexCoord2f(0.0, 0.0);  // Map to the bottom left texel
    glVertex3fv(vertices[v]);

    v = faces[f][1];
    glTexCoord2f(0.0, 1.0);  // Map to the bottom right texel
    glVertex3fv(vertices[v]);

    v = faces[f][2];
    glTexCoord2f(1.0, 1.0);  // Map to the top right texel
    glVertex3fv(vertices[v]);

    v = faces[f][3];
    glTexCoord2f(1.0, 0.0);  // Map to the top left texel
    glVertex3fv(vertices[v]);

    glEnd();
  }

  // Force the rendering (off-screen)
  glFlush();

  // Handle the double buffering
  glutSwapBuffers();
}
        
Reading Images
Reading Images (cont.)

An Example

openglexamples/textures/image.c (Fragment: image)
        /**
 * Fill the given matrix with a RAW image
 *
 * @param data          The matrix to fill
 */
void readRAWImage(char* filename, GLbyte data[256][256][3]) {
  FILE * file;

  file = fopen(filename, "rb");
  if (file != NULL) {
    fread(data, 256 * 256 * 3, 1, file);
    fclose(file);
  }
}

  // Read the "image"
  GLbyte image[256][256][3];
  readRAWImage("oak.raw", image);

        
Using Multiple Textures
images/brick.gif images/brownpaper.gif images/flagstone.gif
images/frostedglass.gif images/oak.gif images/lake.gif
Using Multiple Textures (cont.)

Initialization

openglexamples/textures/multiple.c (Fragment: init)
        /**
 * Initializations
 */
void init() {
  glClearColor(1.0, 1.0, 1.0, 1.0);
  glShadeModel(GL_FLAT);
  glEnable(GL_DEPTH_TEST);

  // Read the images
  GLbyte image[6][256][256][3];
  readRAWImage("brick.raw", image[0]);
  readRAWImage("brownpaper.raw", image[1]);
  readRAWImage("flagstone.raw", image[2]);
  readRAWImage("frostedglass.raw", image[3]);
  readRAWImage("lake.raw", image[4]);
  readRAWImage("oak.raw", image[5]);

  // Get "names" for the textures
  glGenTextures(6, textureNames);

  for (int i = 0; i < 6; i++) {
    // Select the texture object
    glBindTexture(GL_TEXTURE_2D, textureNames[i]);

    // Set the parameters
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    // Create the texture object
    glTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE,
                 image[i]);
  }

  // Enable textures
  glEnable(GL_TEXTURE_2D);
}
        

Rendering

openglexamples/textures/multiple.c (Fragment: render)
        /**
 * The display callback.
 */
void display() {
  // Clear the screen
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Create the cube
  for (int f = 0; f < 6; f++) {
    // Select a texture object
    glBindTexture(GL_TEXTURE_2D, textureNames[f]);

    // Create the face
    glBegin(GL_QUADS);
    int v;

    v = faces[f][0];
    glTexCoord2f(0.0, 0.0);  // Use bottom left texel
    glVertex3fv(vertices[v]);

    v = faces[f][1];
    glTexCoord2f(0.0, 1.0);  // Use bottom right texel
    glVertex3fv(vertices[v]);

    v = faces[f][2];
    glTexCoord2f(1.0, 1.0);  // Use top right texel
    glVertex3fv(vertices[v]);

    v = faces[f][3];
    glTexCoord2f(1.0, 0.0);  // Use top left texel
    glVertex3fv(vertices[v]);

    glEnd();
  }

  // Force the rendering (off-screen)
  glFlush();

  // Handle the double buffering
  glutSwapBuffers();
}
        
Manipulating Textures
Non-2D Textures
Mipmaps
Texture Mapping onto a Sphere
Texture Mapping onto a Sphere (cont.)

The Display Callback

openglexamples/textures/sphere.c (Fragment: display)
        /**
 * The display callback.
 */
void display() {
  // Clear the screen
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Select the texture object
  glBindTexture(GL_TEXTURE_2D, textureName);

  // Create the sphere
  glPushMatrix();
  glRotatef(90.0, 1.0, 0.0, 0.0);

  GLUquadric *quadric = gluNewQuadric();
  gluQuadricDrawStyle(quadric, GLU_FILL);
  gluQuadricNormals(quadric, GLU_SMOOTH);
  gluQuadricTexture(quadric, GL_TRUE);
  gluSphere(quadric, 1.0, 20, 20);
  gluDeleteQuadric(quadric);
  glPopMatrix();

  // Force the rendering (off-screen)
  glFlush();

  // Handle the double buffering
  glutSwapBuffers();
}
        
Texture Mapping onto other Shapes
Texture Mapping onto other Shapes (cont.)

The Display Callback

openglexamples/textures/teapot.c (Fragment: display)
        /**
 * The display callback
 */
void display() {
  // Clear the screen
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Select the texture object
  glBindTexture(GL_TEXTURE_2D, textureName);

  // Create the teapot
  glutSolidTeapot(1.0);

  // Force the rendering (off-screen)
  glFlush();

  // Handle the double buffering
  glutSwapBuffers();
}