Exercise 5: Special Effects

This exercise covers more advanced effects used to render scenes such as transparent surfaces,
fog and texture maps.

Copy the directory /vol/www/ee/Teaching/Courses/CGI/exercise5 to obtain the examples.



1. Transparent Teapot

(i) In Exercise 4 you developed a program teapot.c which used lighting and surface reflectance properties. An example final program is given in exercise5/teapot.c. Compile and run
this program or use your final program from exercise4.

(ii) Blending is used to combine (overlay) images of a rendered object with the contents of the
frame buffer. This can be used to create effects such as transparency or overlay a rendered model
on an existing image.

Alpha blending is used to weight between the new rendered image pixel-by-pixel with the existing
contents of the framebuffer. Where the alpha component is the 'A' in the RGBA colour specified
using glColorf();

To make a transparent teapot you need the following steps:
   a) Use glEnable(GL_BLEND) in initgl() to enable blending

   b) Render the inside of the teapot only:
        glColor4f(0.2,0.5,0.75,0.3);
        glCullFace(GL_FRONT );
        glEnable(GL_CULL_FACE);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glutSolidTeapot(0.5);

        The alpha value for the back surface is set to 0.3  and the blending is specified
        by glBlendFunc() such that the pixel value for each colour component is
            C = A*Rendered object colour + (1-A) * framebuffer pixel colour

         Different combinations of forground/background blending factors are used to produce
         various special effects such as transparency of 3D objects, keying with a background image
         or to represent non-rectangular objects as images.

   c) Now render the outside of the teapot as above but with glCullFace(GL_BACK)

You should now obtain a rendering of a transparent teapot where you can see the inside
of parts of the model.

(iii) Add further transparent objects of different colours  infront and behind the teapot setting the blending factors to be able to see the effects of each layer.

    To combine transparent and opaque objects you can use the depth buffer to first render
    the opaque object and then make the depth buffer read-only using glDepthMask(GL_FALSE)
    before rendering the transparent object.



2. Fog

OpenGL supports fog which makes objects fade with increase in distance from the viewer.
Fog is implemented using the depth buffer. Polygons colour is then blended with the fog colour
according to distance.

To use fog:
(a) Enable the depth buffer glEnable(GL_DEPTH_TEST)
    making sure you have initialised glut with  a depth buffer
(b) Enable fog glEnable(GL_FOG)
(c) Set the fog parameters
    glFogi(GL_FOG_MODE, mode)  - rate of fade mode = GL_EXP, GL_EXP2 or GL_LINEAR
    glFogfv(GL_FOG_DENSITY,rgba);   RGBA colour of fog
    glFogf(GL_FOG_DENSITY,d);    Density of fog
    glFogf(GL_FOG_START, dist); - start depth for fog
    glFogf(GL_FOG_END,dist);  - further rendered polygon (fades to fog colour)

(i) Compile and run the program fog.c which shows 5 sphere at increasing depth which are
    faded according to the fog model. The 'f' key controls the fog mode used.

    Try each of the fog models which determine the rate of fade with depth.

(ii) Add an additional sphere which can be interactively controlled to increase/decrease depth.

(iii) Experiment with chaning the fog parameters such as colour and density.



3. Texture Maps

Texture maps  (1D or 2D images) can be applied to 3D objects to represent surface detail.
The colour values in all or part of the image are applied to the surface to either replace or combine
with the other surface properties such as colour, reflectance etc. This can be an effient way to create models with realistic appearance.

The steps required to use texture mapping in OpenGL are:

a) Create a texture map object either read from file or synthesised.
    using glTexImage1D/2D()
c) Specify texture map parameters glTexParameter()
b) Indicate how the texture maps onto the surface by specifying texture coordinates   for each vertex
    using glTexCoord()
c) Enable texuter mapping for either 1D or 2D
    glEnable(GL_TEXTURE_1D/2D)
    (if both are enabled the 2D will be used ie two texture coordinates (u,v))
d) Draw the scene

(i) Compile and run the program checker.c which shows a synthesised checkerboard texture image
    mapped onto two polygons.

    Look at the source code to see how the texture map/properties are specified in init(),
    the texture coordinates are specified in display() and the 2D checker board imageis synthesised
    in makeCheckImage()

    glPixelStorei() specifies the format of the pixels in the checker board image
                        (no space between values)
    glGenTextures() and glBindTexture() name and create an OpenGL texture object.
                             Binding assigns the current active texture image from which is
                             read between images. Loading multiple images and switching between
                             them by binding and rebinding is an efficient mechanism for multiple texture maps.
    glTexImage2D() specifies the texture map image and mapping properties.
    glTexEnv() sets the drawing mode to GL_DECAL which colours the surface
                      with the values in the texture map.

(ii) Modify the program to map the checker board image onto the sides of a cube
    (ie 6 quadrilateral faces)

(iii) Try setting a material colour using glColor3f(); and set the texture mode to GL_MODULATE in      glTexEnvf() to use the texture map to modulate the surface colour.

(iii) Make the cube transparent using alpha blending as in exercise 1 and rotate it about the
     its center.   To use blending you will have to setup the display with an alpha buffer
    using GLUT_ALPHA and enable blending. Then set the surface transparanceis appropriatly.
    Render the front and back facing sides of the cube separatly.



4. Automatic Texture Generation

OpenGL can automatically generated texture coordinates using glTexGen().

(i) Compile and run texgen.c

    The 1D synthetic stripe texture map is  automatically mapped onto the teapot with texture
    coordinate in the s direction orthogonal  to the plane  specified using GL_OBJECT_PLANE
    specified in glTexGen()

(ii) Modify the program to automatically generate a texture maps with stripes in the x and y directions.
     Use a 2D synthetic stripe image.

(iii) Now make the texture move dynamically across the surface.