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.
(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.
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.
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.
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.