Syllabus   Blank Homework   Quizzes  
Notes   Labs   Scores   Blank


Lecture Notes
Dr. Tong Yu, Sept. 2013
All the materials presented here are adopted from the textbook and the listed references.
    1. Introduction
    2. Line Drawing
    3. Drawing Objects
    4. More Drawing Tools
    5. Vertex Array
    6. Normal Vectors and Polygonal Models of Surfaces
    7. Viewing I -- Affine Transformations
    8. Viewing II -- Projections
    9. Color
    10. Lighting
    11. Blending, antialiasing, fog ..
    12. Display Lists, Bitmaps and Images
    Appendix. Games and SDL

    Lighting

    1. Importance of Lighting

    2. lighting and shading are important tools for making graphics images appear more realistic and more understandable

    3. provides crucial visual cues about the curvature and orientation of surfaces

    4. makes three-dimensionality apparent in a graphics image

      Figure A lit and an unlit sphere

    5. teapot example

      (a) Wireframe teapot
      (b) Teapot drawn with solid color but no lighting or shading

      (c) flat shading with only ambient and diffuse lighting
      (d) Gouraud interpolation with only ambient and diffuse reflection

      (e) flat shading with ambient, diffuse, and specular lighting
      (f) Gouraud shading with ambient, diffuse, and specular lighting

    6. A Hidden-Surface Removal Survival Kit

    7. With shaded polygons, it becomes very important to draw the objects that are closer to our viewing position and to eliminate objects obscured by others nearer to the eye.

    8. Consider:
        while (1) { 
           get_viewing_point_from_mouse_position(); 
           glClear(GL_COLOR_BUFFER_BIT); 
           draw_3d_object_A(); 
           draw_3d_object_B(); 
        }

    9. One object may obscure the other.

    10. hidden-surface removal -- the elimination of parts of solid objects that are obscured by others, easiest to be done by using depth buffer ( also called z-buffer )

    11. A depth buffer works by associating a depth from the view plane with each pixel

    12. glClear( GL_DEPTH_BUFFER_BIT ) sets all pixels depths to the largest possible distance

      Before each pixel is drawn, a comparison is done with the depth value already stored at the pixel. If the new pixel is closer ( smaller value ), the new pixel's color and depth values replace those that are currently written into the pixel.

    13. Example:
        glutInitDisplayMode (GLUT_DEPTH | .... );
        glEnable(GL_DEPTH_TEST); 
        ... 
        while (1) { 
           glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
           get_viewing_point_from_mouse_position(); 
           draw_3d_object_A(); 
           draw_3d_object_B(); 
        }

    14. Global and Local Lighting Models
    15. Global: take into account properties of the whole scene ( expensive to compute )
      • Ray Tracing
      • Radiosity
    16. Local: take into account only:
      • material
      • surface geometry
      • lights (location, kind and color )
    17. The Phong Lighting Model ( local )

      Simplest and by far the most popular, lighting and shading model
      An empirical model, not based exactly on physical laws

    18. All light sources are modeled as point light sources

    19. Light is modeled as consisting of Red, Green, Blue

    20. Apply superposition principle to calculate light reflection intensities independently for each light source and for each of the 3 color components ( R, G, B ), e.g. R = R1 + R2

    21. Treats light or illumination as being of three distinct kinds:

      • Ambient Light -- light that arrives equally from all directions, i.e. light that has been scattered so much by its environment that it is impossible to determine its direction ( so it is a global light )

      • Diffuse Light -- light from a point source that will be reflected diffusely ( i.e. refelected evenly in all directions away from the surface )

      • Specular Light -- light from a point source that will be reflected specularly ( i.e. reflected in a mirror-like fashion, as from a shinny surface )

        These light components interact with the corresponding material properties.
        i.e. the diffuse light interacts with the diffuse material property and the
        specular light interacts with the specular material property

    22. Gives material properties to each surface:

      • Ambient Reflection Properties

      • Diffuse Reflection Properties

      • Specular Reflection Properties

      • Emissive Properties -- The emissivity of a surface controls how much light the surface emits in the absence of any incident light. Light emitted from a surface does not act as light source that illuminates other surfaces; instead, it only affects the color seen by the observer

    23. Ambient Reflection and Emissivity

        Iain = total intensity of incoming ambient light

        ca = reflectivity coefficient

        The intensity of outgoing light is

          Ia = ca Iain

        In addition, a surface can also be given an emissive intensity constant Ie which is equal to the light emitted by the surface


          Sphere with only ambient light

    24. Diffuse Reflection

        The intensity of outgoing light is

          Id = cd Idin cos θ

        where cos θ = |L.N|


          Diffuse light distribution


          Sphere with only diffuse light

    25. Specular Reflection

        The intensity of outgoing light is

          Is = cs Isin (cos α) f

        where α = angle between perfect reflection and the observing reflection
                  f = experimentally adjusted positive constant


          Specular light distribution


          Sphere with only specular light

      • Multiple Lights and Colors

          I = Ia + Id + Is + Ie


            Phong Distribution


              Sphere with Phong lighting
    26. Summary of Lighting in OpenGL

    27. To enable Phong lighting calculation:
        glEnable ( GL_LIGHTING );

    28. OpenGL includes eight point sources ( radiating in all directions ), they could be "turned on" by
        glEnable ( GL_LIGHTi );     //i = 0, 1, 2, .. 7

    29. Gourand shading can be turned on ( default ) or off by
        glShadeModel ( GL_FLAT );     //off

        glShadeModel ( GL_SMOOTH );     //on

        ( see smooth.cpp example in previous chapter. Gouraud interpolation is named after H. Gourand, who proposed linear interpolation in 1971 as a method of blending coloars across polygons. )

    30. Can rednder both faces ( front and back ) or one face ( default ) of polygons.
        glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE );

    31. Specifies normal at a vertex and material properties by
        	glNormal3f( x, y, z );	//(x, y, z) is the normal
        	glMaterial*(...);	//multiple glMaterial command O.K.
        	glVertex*(...);		//vertex position
        	

    32. Setting light properties by, for example,
        	float color[4] = { r, g, b, a };
        	glLightModelfv ( GL_LIGHT_MODEL_AMBIENT, color );
        	
        The alpha component is for blending ( see next chapter ), which is usually set to 1.

    33. Setting light position by
        	float pos[4] = { x, y, z, w };
        	glLightfv ( GL_LIGHTi, GL_POSITION, pos );
        	
        if w ≠ 0, => positional light at position ( x/w, y/w, z/w )

        if w = 0, => directional light ( light source at infinity ), (x, y, z ) is the direction of the source

    34. Setting light intensity values ( colors ) by, for example,
        	float color[4] = { r, g, b, a };
        	glLightfv( GL_LIGHTi, GL_AMBIENT, color );
        	

    35. Setting material properties by, for example,
        	float color[4] = {r, g, b, a};
        	glMaterialfv ( GL_FRONT, GL_AMBIENT, color };
        or
        	glEnable( GL_COLOR_MATERIAL );
        
        then the glColor*() will affect material properties. You then code as
        
        	glNormal3f( x, y, z );
        	glColor3f( r, g, b );	//change reflectivity parameters
        	glVertex* ( .... );	
        	
    36. Simple Example: Rendering a Lit Sphere

      1. Define normal vectors for each vertex of all the objects. These normals determine the orientation of the object relative to the light sources. ( In our example, the normals are defined as part of the glutSolidSphere() )

      2. Create, select, and position one or more light sources.

      3. Create and select a lighting model, which defines the level of global ambient light and the effective location of the viewpoint (for the purposes of lighting calculations).

      4. Define material properties for the objects in the scene.

      //light.cpp
      #include <GL/glut.h>
      #include <stdlib.h>
      
      /*  Initialize material property, light source, lighting model,
       *  and depth buffer.
       */
      void init(void) 
      {
         GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
         GLfloat mat_shininess[] = { 50.0 };
         GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
         GLfloat light[] = { 1.0, 0.2, 0.2 };
         GLfloat lmodel_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
         glClearColor (0.0, 0.0, 0.0, 0.0);
         glShadeModel (GL_SMOOTH);
      
         glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
         glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
         glLightfv(GL_LIGHT0, GL_POSITION, light_position);
      
         glLightfv(GL_LIGHT0, GL_DIFFUSE, light );
         glLightfv(GL_LIGHT0, GL_SPECULAR, light );
         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
      
         glEnable(GL_LIGHTING);
         glEnable(GL_LIGHT0);
         glEnable(GL_DEPTH_TEST);
      }
      
      void display(void)
      {
         glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         glutSolidSphere (1.0, 20, 16);
         glFlush ();
      }
      
      void reshape (int w, int h)
      {
         glViewport (0, 0, (GLsizei) w, (GLsizei) h);
         glMatrixMode (GL_PROJECTION);
         glLoadIdentity();
         if (w <= h)
            glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,
               1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
         else
            glOrtho (-1.5*(GLfloat)w/(GLfloat)h,
               1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
         glMatrixMode(GL_MODELVIEW);
         glLoadIdentity();
      }
      
      int main(int argc, char** argv)
      {
         glutInit(&argc, argv);
         glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
         glutInitWindowSize (500, 500); 
         glutInitWindowPosition (100, 100);
         glutCreateWindow (argv[0]);
         init ();
         glutDisplayFunc(display); 
         glutReshapeFunc(reshape);
         glutMainLoop();
         return 0;
      }
        

      void glLight{if}(GLenum light, GLenum pname, TYPE param);
      void glLight{if}v(GLenum light, GLenum pname, TYPE *param);

      Creates the light specified by light, which can be GL_LIGHT0, GL_LIGHT1, ... , or GL_LIGHT7. The characteristic of the light being set is defined by pname, which specifies a named parameter (see Table below). param indicates the values to which the pname characteristic is set; it's a pointer to a group of values if the vector version is used, or the value itself if the nonvector version is used. The nonvector version can be used to set only single-valued light characteristics.

      Parameter Name Default Value Meaning
      GL_AMBIENT (0.0, 0.0, 0.0, 1.0) ambient RGBA intensity of light
      GL_DIFFUSE (1.0, 1.0, 1.0, 1.0) diffuse RGBA intensity of light
      GL_SPECULAR (1.0, 1.0, 1.0, 1.0)     specular RGBA intensity of light
      GL_POSITION (0.0, 0.0, 1.0, 0.0) (x, y, z, w) position of light
      GL_SPOT_DIRECTION (0.0, 0.0, -1.0) (x, y, z) direction of spotlight
      GL_SPOT_EXPONENT     0.0 spotlight exponent
      (how concentrated is the light)
      GL_SPOT_CUTOFF 180.0 spotlight cutoff angle
      GL_CONSTANT_ATTENUATION 1.0 constant attenuation factor
      GL_LINEAR_ATTENUATION 0.0 linear attenuation factor
      GL_QUADRATIC_ATTENUATION   0.0 quadratic attenuation factor

      Position

      Spotlights

      A spotlight is just a point source limited by a cone of angle θ
      Intensity is greatest in the direction that the spotlight is pointing and
      trailing off towards the sides, but dropping to zero outside the cutoff angle θ:

        I = I0cose ( α )   if α < θ
          = 0   if α ≥ θ
        glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);
        GLfloat spot_direction[] = { -1.0, -1.0, 0.0 };
        glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
        int exp = 2; //( default is 0, exp can be 0 → 128 )
        glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, exp);

      Attenuation

      OpenGL attenuates a light source by multiplying the contribution of that source by an attenuation factor:

        attenuation factor =           1          
          kc + kld + kqd2
      where
      d = distance between the light's position and the vertex
      
      kc = GL_CONSTANT_ATTENUATION
      
      kl = GL_LINEAR_ATTENUATION
      
      kq = GL_QUADRATIC_ATTENUATION
      

      By default, kc = 1.0, kl = kq = 0.0.
      You can give these parameters different values:

      glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.0);
      glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 1.0);
      glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.5);
      

      Multiple lights

      Can have up to 8 light sources.

      Example: Second light source
      GLfloat light1_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
      GLfloat light1_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
      GLfloat light1_specular[] = { 1.0, 1.0, 1.0, 1.0 };
      GLfloat light1_position[] = { -2.0, 2.0, 1.0, 1.0 };
      GLfloat spot_direction[] = { -1.0, -1.0, 0.0 };
      
      glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
      glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
      glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular);
      glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
      glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.5);
      glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.5);
      glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.2);
      
      glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 45.0);
      glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction);
      glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.0);
      
      glEnable(GL_LIGHT1);
      

    37. Defining Material Properties

      glMaterial*()

      Example:Different Material Properties

         //material.cpp
         GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
         GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
         GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 };
         GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 };
         GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
         GLfloat no_shininess[] = { 0.0 };
         GLfloat low_shininess[] = { 5.0 };
         GLfloat high_shininess[] = { 100.0 };
         GLfloat mat_emission[] = {0.3, 0.2, 0.2, 0.0};
      
         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      
      /*  draw sphere in first row, first column
       *  diffuse reflection only; no ambient or specular  
       */
         glPushMatrix();
         glTranslatef (-3.75, 3.0, 0.0);
         glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
         glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
         glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
         glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
         glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
         glutSolidSphere(1.0, 16, 16);
         glPopMatrix();
      
      /*  draw sphere in first row, second column
       *  diffuse and specular reflection; low shininess; no ambient
       */
         glPushMatrix();
         glTranslatef (-1.25, 3.0, 0.0);
         glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
         glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
         glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
         glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
         glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
         glutSolidSphere(1.0, 16, 16);
         glPopMatrix();
      
      /*  draw sphere in first row, third column
       *  diffuse and specular reflection; high shininess; no ambient
       */
         glPushMatrix();
         glTranslatef (1.25, 3.0, 0.0);
         glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
         glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
         glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
         glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
         glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
         glutSolidSphere(1.0, 16, 16);
         glPopMatrix();
      
      /*  draw sphere in first row, fourth column
       *  diffuse reflection; emission; no ambient or specular refl.
       */
         glPushMatrix();
         glTranslatef (3.75, 3.0, 0.0);
         glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
         glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
         glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
         glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
         glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
         glutSolidSphere(1.0, 16, 16);
         glPopMatrix();
      

       
       
       
      No ambient reflection
       

       

      Grey ambient reflection
       

       

      Blue ambient reflection
       

      Figure column:

      1. blue diffuse material color with no specular properties
      2. adds white specular reflection with a low shininess exponent
      3. uses a high shininess exponent and thus a more concentrated light
      4. uses blue diffuse color and, instead of specular reflection, adds an emissive component

      Example: A reddish object bathed in greenish light

      Suppose a sphere has ambient and diffuse reflection coefficients
        (0.8, 0.2, 0.1)
      It appears mostly red when bathed in white light.
      If we illuminate it with a greenish light
        Iin = (0.15, 0.7, 0.15)
      the reflected light is then given by
        I = (0.12, 0.14, 0.015)
      which is a fairly even mix of red and green, and would appear yellowish.

    38. Controlling a Light's Position and Direction

      A light source is subject to the same matrix transformations as a geometric primitive.

    39. Keeping the Light stationary

      Set the light position after whatever viewing and/or modeling transformations

      ....
      ....
      glViewport (0, 0, (GLsizei) w, (GLsizei) h);
      glMatrixMode (GL_PROJECTION);
      glLoadIdentity();
      if (w <= h) 
          glOrtho (-1.5, 1.5, -1.5*h/w, 1.5*h/w, -10.0, 10.0);
      else 
          glOrtho (-1.5*w/h, 1.5*w/h, -1.5, 1.5, -10.0, 10.0);
      glMatrixMode (GL_MODELVIEW);
      
      glLoadIdentity();
      GLfloat light_position[] = { 1.0, 1.0, 1.0, 1.0 };
      glLightfv(GL_LIGHT0, GL_POSITION, position);
      

      You may put the code in init() or reshape().

    40. Independently Moving the Light

      Set the position after the model transformations

      static GLdouble spin;
      
      void display(void)
      {
          GLfloat light_position[] = { 0.0, 0.0, 1.5, 1.0 };
          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      
          glPushMatrix();
              gluLookAt (0.0, 0.0, 6.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
              glPushMatrix();
                  glRotated(spin, 1.0, 0.0, 0.0);
                  glLightfv(GL_LIGHT0, GL_POSITION, light_position);
              glPopMatrix();
              glutSolidTorus (0.275, 0.85, 8, 15);
          glPopMatrix();
          glFlush();
      }
      

      //movelight.cpp
      #include <GL/gl.h>
      #include <GL/glu.h>
      
      static int spin = 0;
      
      void init(void) 
      {
         glClearColor (0.0, 0.0, 0.0, 0.0);
         glShadeModel (GL_SMOOTH);
         glEnable(GL_LIGHTING);
         glEnable(GL_LIGHT0);
         glEnable(GL_DEPTH_TEST);
      }
      
      /*  Here is where the light position is reset after the modeling
       *  transformation (glRotated) is called.  This places the
       *  light at a new position in world coordinates.  The cube
       *  represents the position of the light.
       */
      void display(void)
      {
         GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };
      
         glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         glPushMatrix ();
         glTranslatef (0.0, 0.0, -5.0);
      
         glPushMatrix ();
         glRotated ((GLdouble) spin, 1.0, 0.0, 0.0);
         glLightfv (GL_LIGHT0, GL_POSITION, position);
      
         glTranslated (0.0, 0.0, 1.5);
         glDisable (GL_LIGHTING);
         glColor3f (0.0, 1.0, 1.0);
         glutWireCube (0.5);
         glEnable (GL_LIGHTING);
         glPopMatrix ();
      
         glutSolidTorus (0.275, 0.85, 8, 15);
         glPopMatrix ();
         glFlush ();
      }
      
      void reshape (int w, int h)
      {
         glViewport (0, 0, (GLsizei) w, (GLsizei) h);
         glMatrixMode (GL_PROJECTION);
         glLoadIdentity();
         gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
         glMatrixMode(GL_MODELVIEW);
         glLoadIdentity();
      }
      
      void mouse(int button, int state, int x, int y)
      {
         switch (button) {
            case GLUT_LEFT_BUTTON:
               if (state == GLUT_DOWN) {
                  spin = (spin + 30) % 360;
                  glutPostRedisplay();
               }
               break;
            default:
               break;
         }
      }
      int main(int argc, char** argv)
      {
         glutInit(&argc, argv);
         glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
         glutInitWindowSize (500, 500); 
         glutInitWindowPosition (100, 100);
         glutCreateWindow (argv[0]);
         init ();
         glutDisplayFunc(display); 
         glutReshapeFunc(reshape);
         glutMouseFunc(mouse);
         glutMainLoop();
         return 0;
      }
      

    41. Moving the Light Source together with the Viewpoint

      Set the light position before the viewing transformation. Then the viewing transformation affects both the light source and the viewpoint in the same way.

      GLfloat light_position() = { 0.0, 0.0, 0.0, 1.0 };
      
      glViewport(0, 0, (GLint) w, (GLint) h);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      glLightfv(GL_LIGHT0, GL_POSITION, light_position);
      

      If the viewpoint is now moved, the light will move along with it, maintaining (0, 0, 0) distance, relative to the eye. Suppose the global variables (ex, ey, ez) and (upx, upy, upz) control the position of the viewpoint and up vector. The display() routine that's called from the event loop to redraw the scene might be this:

      static GLdouble ex, ey, ez, upx, upy, upz;
      
      void display(void)
      {
          glClear(GL_COLOR_BUFFER_MASK | GL_DEPTH_BUFFER_MASK);
          glPushMatrix();
              gluLookAt (ex, ey, ez, 0.0, 0.0, 0.0, upx, upy, upz);
              glutSolidTorus (0.275, 0.85, 8, 15);	//inner radious, outer radius, nsides, rings
          glPopMatrix();
          glFlush();
      }