Syllabus   Blank Homework   Quizzes  
Notes   Labs   Scores   Blank

Lecture Notes
Dr. Tong Lai Yu, 2010
    1. Introduction
    2. OpenGL Shading Language ( GLSL ) I
    3. GLSL II
    4. Curve and Surface Design
    5. Modeling Shapes with Polygonal Meshes
    6. Texture Mapping
    7. Casting Shadows
    8. Tools for Raster Display
    9. Parsing External Objects

    Texture Mapping

    1. Mapping Methods

      Apply discrete data for surface rendering

      Three major techniques:

    2. Two Dimensional Texture Mapping

    3. Assigning Texture Coordinates

      To apply texture maps to an arbitrary surface, it is convenient to define the surface parametrically by a function p(u, v).

      Example: Map a texture onto the side of a cylinder ( excluding the top and bottom sides ) :

      Example:Map texture to sphere

    4. Mipmapping and Antialiasing

    5. Texture Mapping an Image with OpenGL

      Texture mapping -- applying a graphics image, a picutre, or a pattern to a surface.

      Properties of texture maps:

      Steps in Texture Mapping:

      Texture Names:

      To start things off, we first need a texture name. This is essentially a number that OpenGL uses to index all the different textures.

      Now that we have our texture name, we can switch between different textures we want using the function glBindTxeture. This essentially chooses what texture we are working with.

      Texture Parameters:

      Now we can begin to work on our current texture. Before we start, we should set one little texture environment state which tells OpenGL how the texture will act when it is rendered into a scene.

      Next, we have four texture parameters we need to setup. Here is where we can setup such wonderful effects like bilinear and trilinear texture filtering, and mipmapping. We also can setup whether the texture wraps over at the edges or is clamped at the ends. The most common feature used is 'repeating'.

    6. Sample examples

      A Checker board

      //checker.cpp
      #include <GL/gl.h>
      #include <GL/glu.h>
      #include <GL/glut.h>
      #include <stdlib.h>
      #include <stdio.h>
      
      /*  Create checkerboard texture  */
      #define checkImageWidth 64
      #define checkImageHeight 64
      static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
      
      static GLuint texName;
      
      void makeCheckImage(void)
      {
         int i, j, c;
          
         for (i = 0; i < checkImageHeight; i++) {
            for (j = 0; j < checkImageWidth; j++) {
               c = ((((i&0x8)==0)^((j&0x8))==0))*255;
               checkImage[i][j][0] = (GLubyte) c;
               checkImage[i][j][1] = (GLubyte) c;
               checkImage[i][j][2] = (GLubyte) c;
               checkImage[i][j][3] = (GLubyte) 255;
            }
         }
      }
      
      void init(void)
      {    
         glClearColor (0.0, 0.0, 0.0, 0.0);
         glShadeModel(GL_FLAT);
         glEnable(GL_DEPTH_TEST);
      
         makeCheckImage();
         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
      
         glGenTextures(1, &texName);
         glBindTexture(GL_TEXTURE_2D, texName);
      
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
                         GL_NEAREST);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
                         GL_NEAREST);
         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, 
                      checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 
                      checkImage);
      }
      
      void display(void)
      {
         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         glEnable(GL_TEXTURE_2D);
         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
         glBindTexture(GL_TEXTURE_2D, texName);
         glBegin(GL_QUADS);
         glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
         glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
         glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);
         glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);
      
         glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
         glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
         glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);
         glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
         glEnd();
         glFlush();
         glDisable(GL_TEXTURE_2D);
      }
      
      void reshape(int w, int h)
      {
         glViewport(0, 0, (GLsizei) w, (GLsizei) h);
         glMatrixMode(GL_PROJECTION);
         glLoadIdentity();
         gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
         glMatrixMode(GL_MODELVIEW);
         glLoadIdentity();
         glTranslatef(0.0, 0.0, -3.6);
      }
      
      void keyboard(unsigned char key, int x, int y)
      {
         switch (key) {
            case 27:
               exit(0);
               break;
         }
      }
      
      int main(int argc, char** argv)
      {
         glutInit(&argc, argv);
         glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
         glutInitWindowSize(250, 250);
         glutInitWindowPosition(100, 100);
         glutCreateWindow(argv[0]);
         init();
         glutDisplayFunc(display);
         glutReshapeFunc(reshape);
         glutKeyboardFunc(keyboard);
         glutMainLoop();
         return 0; 
      }
        

      Cube with texture images

      /*
       * cubemap.cpp ( Demo for CS 520 ):  Draw a cube with texture images. The cube can be rotated
       * by pressing keys 'x', 'X', 'y', 'Y', 'z', 'Z'.
       * Images are downloaded from Internet.  
       * @Author: T.L. Yu, 2008F
       *
       */
      
      #include <GL/gl.h>
      #include <GL/glu.h>
      #include <GL/glut.h>
      #include <stdlib.h>
      #include <stdio.h>
      #include <string.h>
      #include "imageio.h"
      
      int texImageWidth;
      int texImageHeight;
      int window;
      static GLuint texName[6];			//texture names
      int anglex= 0, angley = 0, anglez = 0;		//rotation angles
      
      //images for texture maps for 6 faces of cube
      char maps[][20] = {"cubemap_fr.png",  "cubemap_bk.png",  "cubemap_rt.png", "cubemap_lf.png",
      		 "cubemap_up.png", "cubemap_dn.png" };
      
      //load texture image
      GLubyte *makeTexImage( char *loadfile )
      {
         int i, j, c, width, height;
         GLubyte *texImage;
        
         /*
           Only works for .png or .tif images.  NULL is returned if errors occurred.
           loadImageRGA() is from imageio library downloaded from Internet.
         */ 
         texImage = loadImageRGBA( (char *) loadfile, &width, &height);	
         texImageWidth = width;
         texImageHeight = height;
      
         return texImage;
      }
      
      void init(void)
      {    
         glClearColor (0.2, 0.2, 0.8, 0.0);
         glShadeModel(GL_FLAT);
      
         glEnable(GL_DEPTH_TEST);
      
         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
         //texName is global
         glGenTextures(6, texName);
        for ( int i = 0; i < 6; ++i ) {	
          GLubyte *texImage = makeTexImage( maps[i] );
          if ( !texImage ) {
            printf("\nError reading %s \n", maps[i] );
            continue;
          }
          glBindTexture(GL_TEXTURE_2D, texName[i]);		//now we work on texName
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texImageWidth, 
                      texImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, texImage);
      
          delete texImage;					//free memory holding texture image
        }
      }
      
      void display(void)
      {
         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         glEnable(GL_TEXTURE_2D);
         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
         float x0 = -1.0, y0 = -1, x1 = 1, y1 = 1, z0 = 1;
         float face[6][4][3] =  { {{x0, y0, z0}, {x1, y0, z0}, {x1, y1, z0}, {x0, y1, z0}},	//front
          		{{x0, y1, -z0}, {x1, y1, -z0}, {x1, y0, -z0}, {x0, y0, -z0}},		//back
      		{{x1, y0, z0}, {x1, y0, -z0}, {x1, y1, -z0}, {x1, y1, z0}},		//right 
      		{{x0, y0, z0}, {x0, y1, z0}, {x0, y1, -z0}, {x0, y0, -z0}},		//left 
      		{{x0, y1, z0}, {x1, y1, z0}, {x1, y1, -z0}, {x0, y1, -z0}},		//top 
      		{{x0, y0, z0}, {x0, y0, -z0}, {x1, y0, -z0}, {x1, y0, z0}}		//bottom 
      		};
         glEnable( GL_CULL_FACE );
         glCullFace ( GL_BACK );
        
         glPushMatrix(); 
         glRotatef( anglex, 1.0, 0.0, 0.0);			//rotate the cube along x-axis
         glRotatef( angley, 0.0, 1.0, 0.0);			//rotate along y-axis	
         glRotatef( anglez, 0.0, 0.0, 1.0);			//rotate along z-axis
      
         for ( int i = 0; i < 6; ++i ) {			//draw cube with texture images
           glBindTexture(GL_TEXTURE_2D, texName[i]);
           glBegin(GL_QUADS);
             glTexCoord2f(0.0, 0.0); glVertex3fv ( face[i][0] ); 	
             glTexCoord2f(1.0, 0.0); glVertex3fv ( face[i][1] );	
             glTexCoord2f(1.0, 1.0); glVertex3fv ( face[i][2] );
             glTexCoord2f(0.0, 1.0); glVertex3fv ( face[i][3] );
           glEnd();
         }
      
         glPopMatrix();
         glFlush();
         glDisable(GL_TEXTURE_2D);
      }
      
      void keyboard(unsigned char key, int x, int y)
      {
        switch(key) {
          case 'x':
            anglex = ( anglex + 3 ) % 360;
            break;
          case 'X':
            anglex = ( anglex - 3 ) % 360;
            break;
          case 'y':
            angley = ( angley + 3 ) % 360;
            break;
          case 'Y':
            angley = ( angley - 3 ) % 360;
            break;
          case 'z':
            anglez = ( anglez + 3 ) % 360;
            break;
          case 'Z':
            anglez = ( anglez - 3 ) % 360;
            break;
          case 27: /* escape */
              glutDestroyWindow(window);
              exit(0);
        }
        glutPostRedisplay();
      }
      
      void reshape(int w, int h)
      {
         glViewport(0, 0, (GLsizei) w, (GLsizei) h);
         glMatrixMode(GL_PROJECTION);
         glLoadIdentity();
         gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
         glMatrixMode(GL_MODELVIEW);
         glLoadIdentity();
         gluLookAt ( 0, 0, 5, 0, 0, 0, 0, 1, 0 );
      }
      
      
      int main(int argc, char** argv)
      {
         glutInit(&argc, argv);
         glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
         glutInitWindowSize(500, 500);
         glutInitWindowPosition(100, 100);
         window = glutCreateWindow(argv[0]);
         init();
         glutDisplayFunc(display);
         glutReshapeFunc(reshape);
         glutKeyboardFunc(keyboard);
         glutMainLoop();
         return 0; 
      }
        

      void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
      Defines a two-dimensional texture. The target parameter is set to either the constant GL_TEXTURE_2D or GL_PROXY_TEXTURE_2D. You use the level parameter if you're supplying multiple resolutions of the texture map; with only one resolution, level should be 0.

      void glCopyTexImage2D(GLenum target, GLint level, GLint internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
      Creates a two-dimensional texture, using framebuffer data to define the texels. The pixels are read from the current GL_READ_BUFFER and are processed exactly as if glCopyPixels() had been called but stopped before final conversion. The settings of glPixelTransfer*() are applied.
      The target parameter must be set to the constant GL_TEXTURE_2D. The level, internalFormat, and border parameters have the same effects that they have for glTexImage2D(). The texture array is taken from a screen-aligned pixel rectangle with the lower-left corner at coordinates specified by the (x, y) parameters. The width and height parameters specify the size of this pixel rectangle. Both width and height must have the form 2m+2b, where m is a nonnegative integer (which can have a different value for width than for height) and b is the value of border.

      Sphere with texture images

      Adopted from http://local.wasp.uwa.edu.au/~pbourke/texture_colour/texturemap/

    7. Environment Mapping

    8. Bump Mapping

    9. More Texture Examples of using OpenGL

      Spherical Map:

      Cube Maps:

      Automatic Texture Coordinates Generation: