Get t ing St art ed wit h OpenGL

Course Notes for COMP 471 and COMP 676
Peter Grogono
grogono@cs.concordia.ca
January 1998
(Updat ed by Kim Lanziner, J une 1998)
c ( Pet er Grogono, 1998.
These not es may be phot ocopied for st udent s t aking courses
in graphics programming at Concordia University.
Depart ment of Comput er Science
Concordia University
1455 de Maisonneuve Blvd. West
Mont r´eal, Qu´ebec, H3G 1M8
CONT ENT S i
Cont ent s
1 Int roduct ion 1
1.1 Compiling and Execut ing an OpenGL Program . . . . . . . . . . . . . . . . . . 1
1.2 A Simple OpenGL Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Drawing Object s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 OpenGL Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2 Callbacks 8
2.1 The Idle Funct ion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2 Keyboard Callback Funct ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3 Mouse Event Callback Funct ions . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.4 Reshaping t he Graphics Window . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3 Primit ive Object s 17
3.1 The Coordinat e Syst em . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.2 Point s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3 Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.4 Polygons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.5 Hidden Surface Eliminat ion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.6 Animat ion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4 Transformat ions 23
4.1 Model View Transformat ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.2 Project ion Transformat ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.3 Perspect ive Transformat ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.4 Combining Viewpoint and Perspect ive . . . . . . . . . . . . . . . . . . . . . . . 29
5 Light ing 32
5.1 A Simple Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.2 Normal Vect ors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.3 Defining Mat erial Propert ies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.4 Defining t he Light s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.5 Defining a Light ing Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.6 Put t ing It All Toget her . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
LIST OF FIGURES ii
6 Odds and Ends 41
6.1 Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.2 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.2.1 Bit mapped Charact ers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
6.2.2 St roked Charact ers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.3 Special Object s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
6.4 Programming Hint s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
A Spaces and Transformat ions 49
A.1 Scalar, Vect or, Affi ne, and Euclidean Spaces . . . . . . . . . . . . . . . . . . . . 49
A.2 Mat rix Transformat ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
A.3 Sequences of Transformat ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
A.4 Viewing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
B Theory of Illuminat ion 55
B.1 St eps t o Realist ic Illuminat ion . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
B.2 Mult iple Light Sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
B.3 Polygon Shading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
C Funct ion Reference 60
List of Figures
1 Make file for SGI machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2 Make file for Solaris machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
3 The basic OpenGL program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
4 Displaying a bright red line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
5 Drawing vert ical yellow lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
6 Rot at ing a wire cube . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
7 A callback funct ion t hat spins t he cube . . . . . . . . . . . . . . . . . . . . . . 10
8 A keyboard callback funct ion t hat select s an axis . . . . . . . . . . . . . . . . . 11
9 Quit t ing wit h t he escape key . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
10 A callback funct ion t hat responds t o mouse but t ons . . . . . . . . . . . . . . . 13
11 A callback funct ion t hat responds t o dragging t he mouse . . . . . . . . . . . . . 13
12 A callback funct ion t hat responds t o window reshaping . . . . . . . . . . . . . . 14
13 Maint aining scaling invariant s . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
LIST OF TABLES iii
14 Drawing primit ives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
15 Default viewing volume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
16 Labelling t he corners of a cube . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
17 Drawing a cube . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
18 A balancing act . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
19 Pushing and popping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
20 Perspect ive project ion wit h gl Fr us t um( ) . . . . . . . . . . . . . . . . . . . . . 27
21 Perspect ive project ion using gl uPer s pect i ve( ) . . . . . . . . . . . . . . . . . . 28
22 Reshaping wit h gl uPer s pect i ve( ) . . . . . . . . . . . . . . . . . . . . . . . . . 28
23 gl uPer s pect i ve( ) wit h a small value of α . . . . . . . . . . . . . . . . . . . . 28
24 gl uPer s pect i ve( ) wit h a large value of α . . . . . . . . . . . . . . . . . . . . . 29
25 Using gl uLookAt ( ) and gl uPer s pect i ve( ) . . . . . . . . . . . . . . . . . . . . 31
26 A simple object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
27 Comput ing normals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
28 Using gl Mat er i al ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
29 Illuminat ing t he sun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
30 Code for a simple menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
31 Displaying a st ring of t ext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
32 Obt aining and report ing OpenGL errors . . . . . . . . . . . . . . . . . . . . . . 47
33 Basic t ransformat ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
34 Perspect ive t ransformat ion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
35 Illuminat ing an object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
List of Tables
1 OpenGL Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2 Const ant s for special keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3 Primit ive Specifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4 Opt ions for drawing polygons . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5 Common t ransformat ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
6 Paramet ers for gl Mat er i al f v( ) . . . . . . . . . . . . . . . . . . . . . . . . . . 36
7 Paramet ers for gl Li ght f v( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
8 Paramet ers for gl Li ght Model ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . 39
9 Font s for gl ut Bi t mapChar act er ( ) . . . . . . . . . . . . . . . . . . . . . . . . . 62
10 Mask bit s for clearing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
11 Display mode bit s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
12 Cursor codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
1 INT RODUCT ION 1
Get t ing St art ed wit h OpenGL
Peter Grogono
J anuary 1998
1 Int roduct ion
OpenGL consist s of t hree libraries: t he Graphics Library (GL); t he Graphics Library Ut ilit ies
(GLU); and t he Graphics Library Ut ilit ies Toolkit (GLUT). Funct ion names begin wit h gl ,
gl u, or gl ut , depending on which library t hey belong t o.
Several versions of t hese libraries have been implement ed. The explanat ions and programs
in t hese not es are based on t he Silicon Graphics implement at ion. Anot her implement at ion,
called Mesa, has been inst alled on t he “greek” machines. Implement at ions are also available
for PCs running linux, Windows 95, or Widows NT.
The main sources for t hese not es are list ed below.
1. OpenGL Programming Guide. Mason Woo, J ackie Neider, and Tom Davis. Second
Edit ion, Addison-Wesley, 1997. The “offi cial guide t o learning OpenGL”.
2. The OpenGL Utility Toolkit (GLUT) Programming Interface. Mark J . Kilgard. Silicon
Graphics, 1997. ht t p: / / r eal i t y. s gi . com/ mj k/ s pec3/ s pec3. ht ml .
3. The OpenGL Graphics System: a Specification (Version 1.1). Mark Segal and Kurt
Akeley. Silicon Graphics, 1997.
ht t p: / / www. s gi . com/ Technol ogy/ OpenGL/ gl s pec1. 1/ gl s pec. ht ml .
Since people are const ant ly changing t heir web pages and links, you may find t hat t he URLs
above do not work. If so, t ry going t o Silicon Graphics’ web sit e (www. s gi . com) and exploring.
You could also t ry links from my web pages for COMP 471:
www. cs . concor di a. ca/ ~f acul t y/ gr ogono/ comp471. ht ml .
Appendix C cont ains specificat ions of all of t he funct ions ment ioned in t hese not es, and a few
ot hers as well. To use OpenGL eff ect ively, however, you must know not only t he specificat ions
of individual funct ions but also t he way in which t hese funct ions work t oget her in programs.
Sect ions 2 t hrough 6 provide examples of ways in which t he funct ions can be used.
I have t ried t o make t his manual as accurat e as possible. If you find errors, omissions, or
misprint s, please send an e-mail message t o me at grogono@cs.concordia.ca.
1.1 Compiling and Execut ing an OpenGL Program
In order t o run an OpenGL program, you must t ell t he compiler where t o find t he header files
and t he linker where t o find t he libraries. The easiest way t o do t his is t o use a “makefile”.
Figure 1 shows a makefile suit able for SGI machines and Figure 2 shows a makefile suit able for
Solaris machines on greeknet (it does not work for l ambda or ot her machines running Sun).
To compile a program using eit her of t hese makefiles, writ e
1 INT RODUCT ION 2
CC = cc
LDLI BS = - l gl ut - l GL - l GLU - l Xmu - l X11 - l m
I NCLUDE =
execut abl e:
$( CC) - g $( I NCLUDE) $( PROG) . c \
$( LDFLAGS) $( LDLI BS) - o $( PROG)
Figure 1: Make file for SGI machines
execut abl e:
gcc - I / pkg/ gl ut / i ncl ude - I / pkg/ mes a/ i ncl ude \
- I / pkg/ X11/ i ncl ude - c $( PROG) . c
gcc - o $( PROG) $( PROG) . o - L/ pkg/ gl ut / l i b - R/ pkg/ gl ut / l i b \
- l gl ut - L/ pkg/ mes a/ l i b - R/ pkg/ mes a/ l i b - l Mes aGLU - l Mes aGL \
- L/ pkg/ X11/ l i b - R/ pkg/ X11/ l i b - l Xmu - l Xt - l Xext - l X11 \
- l s ocket - l ns l - l m
Figure 2: Make file for Solaris machines
make PROG=name
where “name” is t he name of a C program without an extension. The program must cont ain
t he direct ive #i ncl ude <GL/ gl ut . h>. It may also cont ain direct ives t o include header files
from ot her libraries.
To execut e t he program, ent er t he following command:
name
where “name” is t he name of your program, again wit hout any ext ension.
These st eps apply t o a program t hat consist s of a single C source file. If you writ e a program
wit h several source files, you will have t o writ e a suit able make file for it .
Alt hough OpenGL provides a st andard API (applicat ion programmers’ int erface), many im-
plement at ions do not provide all of t he specified feat ures. Current ly (J anuary 1998), t he
greeknet machines are running Version 1.1 in t he Mesa implement at ion and t he SGI machines
in VA–03 are running Version 1.0 in t he SGI implement at ion. Consequent ly, t here are a few
feat ures, including int erleaved arrays, t hat work on t he Suns but do not work on t he O2s.
1.2 A Simple OpenGL Program
Figure 3 shows a simple OpenGL program. Alt hough t his program does not hing useful, it
defines a pat t ern t hat is used by most OpenGL programs. The line numbers are not part of
t he program, but are used in t he explanat ion below.
Line 1. Every OpenGL program should include GL/ gl ut . h. The file gl ut . h includes gl u. h,
gl . h and ot her header files required by GLUT.
1 INT RODUCT ION 3
1 #i ncl ude <GL/ gl ut . h>
2
3 voi d di s pl ay ( voi d)
4 {
5 gl Cl ear ( GL_COLOR_BUFFER_BI T) ;
6 }
7
8 voi d i ni t ( voi d)
9 {
10 }
11
12 i nt mai n ( i nt ar gc, char *ar gv[ ] )
13 {
14 gl ut I ni t ( &ar gc, ar gv) ;
15 gl ut I ni t Di s pl ayMode( GLUT_SI NGLE | GLUT_RGBA) ;
16 gl ut I ni t Wi ndowSi ze( 800, 600) ;
17 gl ut I ni t Wi ndowPos i t i on( 100, 50) ;
18 gl ut Cr eat eWi ndow( "My f i r s t openGL pr ogr am") ;
19 i ni t ( ) ;
20 gl ut Di s pl ayFunc( di s pl ay) ;
21 gl ut Mai nLoop( ) ;
22 r et ur n 0;
23 }
Figure 3: The basic OpenGL program
Line 3. You must writ e a funct ion t hat displays t he graphical object s in your model. The
funct ion shown here clears t he screen but does not display anyt hing. Your program does
not call t his funct ion explicit ly, but it will be called at appropriat e t imes by OpenGL.
Line 5. It is usually a good idea t o clear various buff ers before st art ing t o draw new object s.
The colour buff er, cleared by t his call, is where t he image of your model is act ually
st ored.
Line 8. It is convent ional t o put “st andard init ializat ion” (t he gl ut . . . calls) in t he mai n
program and applicat ion dependent init ializat ion in a funct ion wit h a name like i ni t ( )
or myi ni t ( ) . In t his program, t he funct ion i ni t ( ) is defined in lines 8 t hrough 10, does
not hing, and is invoked at line 19.
Line 14. The funct ion gl ut I ni t ( ) init ializes t he OpenGL library. It is convent ional t o pass
t he command line argument s t o t his funct ion because it may use some of t hem. You
will probably not need t his feat ure.
Line 15. The funct ion gl ut I ni t Di s pl ayMode( ) init ializes t he display. It s argument is a bit
st ring.
Delet ing t his line would not aff ect t he execut ion of t he program, because t he argument s
shown are t he default values.
Line 16. This call request s a graphics window 800 pixels wide and 600 pixels high.
1 INT RODUCT ION 4
voi d di s pl ay ( voi d)
{
gl Cl ear ( GL_COLOR_BUFFER_BI T) ;
gl Col or 3f ( 1. 0, 0. 0, 0. 0) ;
gl Begi n( GL_LI NES) ;
gl Ver t ex2f ( - 1. 0, 0. 0) ;
gl Ver t ex2f ( 1. 0, 0. 0) ;
gl End( ) ;
gl Fl us h( ) ;
}
Figure 4: Displaying a bright red line
Line 17. This call says t hat t he left side of t he graphics window should be 100 pixels from
t he left of t he screen and t he t op of t he graphics window should be 50 pixels below t he
t op of t he screen. Not e t hat t he Y value is measured from t he t op of t he screen.
Line 18. This call creat es t he window using t he set t ings given previously. The t ext in t he
argument becomes t he t it le of t he window. The window does not act ually appear on
t he screen unt il gl ut Mai nLoop( ) has been called.
Line 19. This is a good place t o perform any addit ional init ializat ion t hat is needed. Some
init ializat ion, such as calls t o gl Enabl e( ) , must come aft er gl ut Cr eat eWi ndow( ) .
Line 20. This call regist ers t he callback funct ion di s pl ay( ) . Aft er execut ing t he call,
OpenGL knows what funct ion t o call t o display your model in t he window. Sect ion 2
describes callback funct ions.
Line 21. The last st at ement of an OpenGL program calls gl ut Mai nLoop( ) . This funct ion
processes event s unt il t he program is t erminat ed. Well-writ t en programs should provide
t he user wit h an easy way of st opping t he program, for example by select ing Quit from
a menu or by pressing t he esc key.
1.3 Drawing Object s
All t hat remains is t o describe addit ions t o Figure 3. The first one t hat we will consider is
an improved di s pl ay( ) funct ion. Figure 4 shows a funct ion t hat displays a line. The call
gl Col or 3f ( 1. 0, 0. 0, 0. 0) specifies t he colour of t he line as “maximum red, no green, and no
blue”.
The const ruct ion gl Begi n( mode) ; . . . ; gl End( ) ; is used t o display groups of primit ive
object s. The value of mode det ermines t he kind of object : in t his case, GL_LI NES t ells OpenGL
t o expect one or more lines given as pairs of vert ices.
In t his case, t he line goes from (−1, 0) t o (1, 0), as specified by t he two calls t o gl Ver t ex2f ( ) .
If we use t he default viewing region, as in Figure 3, t his line runs horizont ally across t he
cent re of t he window.
The call gl Fl us h( ) forces previously execut ed OpenGL commands t o begin execut ion. If
OpenGL is running on a workst at ion t hat communicat es direct ly wit h it s graphics subsyst em,
1 INT RODUCT ION 5
voi d di s pl ay ( voi d)
{
i nt i ;
gl Cl ear ( GL_COLOR_BUFFER_BI T) ;
gl Col or 3f ( 1. 0, 1. 0, 0. 0) ;
gl Begi n( GL_LI NES) ;
f or ( i = - 25; i <= 25; i ++)
{
f l oat x = i / 25. 0;
gl Ver t ex2f ( x, - 1. 0) ;
gl Ver t ex2f ( x, 1. 0) ;
}
gl End( ) ;
}
Figure 5: Drawing vert ical yellow lines
gl Fl us h( ) will probably have no eff ect on t he behaviour of t he program. It is import ant
t o use it if your program is running, or might be run, in a client / server cont ext , however,
because ot herwise at t empt s by t he syst em t o opt imize packet t ransfers may prevent good
graphics performance.
The suffi x “3f ” indicat es t hat gl Col or 3f ( ) requires t hree argument s of type GLf l oat . Sim-
ilarly, gl Ver t ex2f ( ) requires two argument s of type GLf l oat . Appendix C provides more
det ails of t his not at ional convent ion and explains why it is used.
The code between gl Begi n( ) and gl End( ) is not rest rict ed t o gl calls. Figure 5 shows a
display funct ion t hat uses a loop t o draw 51 vert ical yellow (red + green) lines across t he
window. Sect ion 3 describes some of t he ot her primit ive object s available in OpenGL.
The call gl Cl ear ( GL_COLOR_BUFFER_BI T) clears t he colour buff er t o t he background colour.
You can set t he background colour by execut ing
gl Cl ear Col or ( r , g, b, a) ;
wit h appropriat e values of r , g, b, and a during init ializat ion. Each argument is a float ing-
point number in t he range [0, 1] specifying t he amount of a colour (r ed, green, blue) or blending
(alpha). The default values are all zero, giving a black background. To make t he background
blue, you could call
gl Cl ear Col or ( 0. 0, 0. 0, 1. 0, 0. 0) ;
Blending is an advanced feat ure; unless you know how t o use it , set t he fourt h argument of
gl Cl ear Col or t o zero.
OpenGL allows you t o define a viewing volume; only object s t hat are inside t he viewing
volume will appear on t he screen. The following code est ablishes a viewing volume wit h
ort hogonal project ion.
1 INT RODUCT ION 6
gl Mat r i xMode( GL_PROJ ECTI ON) ;
gl LoadI dent i t y( ) ;
gl Or t ho( l ef t , r i ght , bot t om, t op, near , f ar ) ;
An object at (x, y, z ) will be displayed only if x, y, and z sat isfy t he following inequalit ies:
l ef t ≤ x ≤ r i ght ,
bot t om ≤ y ≤ t op,
near ≤ z ≤ f ar .
The default project ion is ort hogonal wit h boundaries l ef t = bot t om = near = −1 and
r i ght = t op = f ar = 1. The following version of i ni t ( ) set s t he background colour t o whit e
and defines a viewing volume in which 0 < x < 5, 0 < y < 5, and −2 < z < 2. Sect ion 3.1
describes coordinat e syst ems.
voi d i ni t ( voi d)
{
gl Cl ear Col or ( 1. 0, 1. 0, 1. 0, 0. 0) ;
gl Mat r i xMode( GL_PROJ ECTI ON) ;
gl LoadI dent i t y( ) ;
gl Or t ho( 0. 0, 5. 0, 0. 0, 5. 0, - 2. 0, 2. 0) ;
}
The last t hree lines of t his funct ion illust rat e t he select ion, init ializat ion, and t ransformat ion
of t he project ion mat rix. Sect ion 4 describes mat rix t ransformat ions in det ail. To obt ain a
realist ic view of a t hree-dimensional model, you will need a perspect ive project ion rat her t han
an ort hogonal project ion, as described in Sect ion 4.3.
1.4 OpenGL Types
OpenGL defines a number of types t hat are usually equivalent t o C types. You can use C
types but , if you want t o writ e port able OpenGL programs, it is bet t er t o use t he OpenGL
types: see Table 1. The suffi x column cont ains t he let t er t hat is used in funct ion names; for
example, t he “f ” in gl Ver t ex3f .
1 INT RODUCT ION 7
Suffi x Dat a type C Type OpenGL Type
b 8-bit int eger s i gned char GLbyt e
s 16-bit int eger s hor t GLs hor t
i 32-bit int eger i nt or l ong GLi nt , GLs i zei
f 32-bit float ing point f l oat GLf l oat , GLcl ampf
d 64-bit float ing point doubl e GLdoubl e, GLcl ampd
ub 8-bit unsigned int eger uns i gned char GLubyt e, GLbool ean
us 16-bit unsigned int eger uns i gned s hor t GLus hor t
ui 32-bit unsigned int eger uns i gned i nt GLui nt , GLenum, GLbi t f i el d
Table 1: OpenGL Types
2 CALLBACKS 8
2 Callbacks
GLUT handles event s wit h callback funct ions. If you want t o handle an event , such as a
keyst roke or mouse movement , you writ e a funct ion t hat performs t he desired act ion. Then
you regist er your funct ion by passing it s name as an argument t o a funct ion wit h a name of
t he form gl ut . . . Func( ) , in which “. . . ” indicat es which callback you are regist ering.
Since OpenGL defines t he argument list s of callback funct ions, you usually cannot pass infor-
mat ion in funct ion argument s. Inst ead, you have t o violat e t he programming pract ices you
have been t aught and use global variables. Typical OpenGL programs usually cont ain t he
following component s:
• declarat ions of global variables whose values aff ect t he scene;
• a di s pl ay( ) funct ion t hat uses t he global variables t o draw t he scene; and
• one or more callback funct ions t hat respond t o event s by changing t he values of t he
global variables.
The program in Figure 6 illust rat es t hese convent ions. It displays a wire-frame cube which is
rot at ed about t he X , Y , and Z axes by t he angles x_angl e, y_angl e, and z_angl e, which
are st ored as global variables wit h init ial values zero. We will add callback funct ions t o t his
program t o rot at e t he cube. The comment “Cal l back r egi s t r at i on her e” in t he main
program shows where t he callbacks should be regist ered.
There is one callback funct ion t hat must be declared in all OpenGL programs: it is t he
display callback, and it is regist ered by calling gl ut Di s pl ayFunc( ) wit h t he name of t he
display funct ion as it s argument .
2.1 The Idle Funct ion
OpenGL calls t he idle funct ion when it has not hing else t o do. The most common applicat ion
of t he idle funct ion is t o provide cont inuous animat ion. We will use t he idle funct ion t o make
t he cube in Figure 6 rot at e. The axis of rot at ion is det ermined by t he global variable axi s ,
and is t he X -axis init ially.
1. The main program must regist er t he idle funct ion. The following call regist ers an idle
funct ion called s pi n( ) :
gl ut I dl eFunc( s pi n) ;
2. The idle funct ion must be declared. It has no argument s and ret urns no result s. Figure 7
shows an idle funct ion t hat increment s one of t he angles by 1

(one degree) and request s
t hat t he model be redisplayed. The global variable axi s det ermines which angle is
increment ed.
Not ice t hat , aft er changing t he angle, s pi n( ) does not call di s pl ay( ) direct ly. Inst ead, it
calls gl ut Pos t Redi s pl ay( ) , which informs gl ut Mai nLoop( ) t o redisplay t he model at t he
next convenient opport unity.
2 CALLBACKS 9
#i ncl ude <GL/ gl ut . h>
#def i ne SI ZE 500
f l oat x_angl e = 0. 0;
f l oat y_angl e = 0. 0;
f l oat z_angl e = 0. 0;
enum { X, Y, Z } axi s = X;
voi d di s pl ay ( voi d)
{
gl Cl ear ( GL_COLOR_BUFFER_BI T) ;
gl Mat r i xMode( GL_MODELVI EW) ;
gl LoadI dent i t y( ) ;
gl Rot at ef ( x_angl e, 1. 0, 0. 0, 0. 0) ;
gl Rot at ef ( y_angl e, 0. 0, 1. 0, 0. 0) ;
gl Rot at ef ( z_angl e, 0. 0, 0. 0, 1. 0) ;
gl ut Wi r eCube( 1. 0) ;
gl ut SwapBuf f er s ( ) ;
}
voi d i ni t ( voi d)
{
gl Mat r i xMode( GL_PROJ ECTI ON) ;
gl LoadI dent i t y( ) ;
gl Or t ho( - 5. 0, 5. 0, - 5. 0, 5. 0, - 5. 0, 5. 0) ;
}
i nt mai n ( i nt ar gc, char *ar gv[ ] )
{
gl ut I ni t ( &ar gc, ar gv) ;
gl ut I ni t Di s pl ayMode( GLUT_DOUBLE | GLUT_RGB) ;
gl ut I ni t Wi ndowSi ze( SI ZE, SI ZE) ;
gl ut I ni t Wi ndowPos i t i on( 100, 50) ;
gl ut Cr eat eWi ndow( "Rot at i ng a wi r e cube") ;
i ni t ( ) ;
/ * Cal l back r egi s t r at i on her e */
gl ut Di s pl ayFunc( di s pl ay) ;
gl ut Mai nLoop( ) ;
}
Figure 6: Rot at ing a wire cube
2 CALLBACKS 10
voi d s pi n ( voi d)
{
s wi t ch ( axi s )
{
cas e X:
x_angl e += 1. 0;
br eak;
cas e Y:
y_angl e += 1. 0;
br eak;
cas e Z:
z_angl e += 1. 0;
br eak;
def aul t :
br eak;
}
gl ut Pos t Redi s pl ay( ) ;
}
Figure 7: A callback funct ion t hat spins t he cube
2.2 Keyboard Callback Funct ions
If t he program has regist ered a keyboard callback funct ion, t his funct ion is called whenever
t he user presses a key. The following st eps modify t he cube program so t hat it responds t o
t he keys ‘x’, ‘y’, and ‘z’ by changing t he axis of rot at ion of t he cube.
1. Regist er a keyboard callback funct ion.
gl ut Keyboar dFunc( keyboar d) ;
2. The keyboard funct ion is declared as in Figure 8. It receives t hree argument s: t he key
t hat was pressed, and t he current X and Y coordinat es of t he mouse.
It would be possible t o rewrit e keyboar d( ) so t hat it called gl ut Pos t Redi s pl ay( ) once only,
aft er t he s wi t ch st at ement . The advant age of t he code shown is t hat t he scene is redisplayed
only when one of t he keys x, y, or z has been pressed; ot her keys are ignored.
The callback funct ion regist ered by gl ut Keyboar dFunc( ) recognizes only keys corresponding
t o ASCII graphic charact ers and esc, sc backspace, and delete. To make your program
respond t o ot her keys, such as t he arrow keys and “F” keys:
1. Regist er a special key callback funct ion.
gl ut Speci al Func( s peci al ) ;
2 CALLBACKS 11
voi d keyboar d ( uns i gned char key, i nt x, i nt y)
{
s wi t ch ( key)
{
cas e ’ x’ :
axi s = X;
gl ut Pos t Redi s pl ay( ) ;
br eak;
cas e ’ y’ :
axi s = Y;
gl ut Pos t Redi s pl ay( ) ;
br eak;
cas e ’ z’ :
axi s = Z;
gl ut Pos t Redi s pl ay( ) ;
br eak;
def aul t :
br eak;
}
}
Figure 8: A keyboard callback funct ion t hat select s an axis
2. Declare t he special key funct ion as follows:
voi d s peci al ( i nt key, i nt x, i nt y)
{
s wi t ch ( key)
{
/ * Code t o handl e s peci al keys */
}
}
The argument s t hat OpenGL passes t o s peci al ( ) are: t he key code, as defined in
Table 2; t he X coordinat e of t he mouse; and t he Y coordinat e of t he mouse.
The keyboard callback funct ion in Figure 9 is a useful default : it allows t he user t o quit t he
program by pressing t he escape key.
2.3 Mouse Event Callback Funct ions
There are several ways of using t he mouse and two ways of responding t o mouse act ivity. The
first callback funct ion responds t o pressing or releasing one of t he mouse but t ons.
1. Regist er a mouse callback funct ion.
2 CALLBACKS 12
GLUT_KEY_F1 GLUT_KEY_F8 GLUT_KEY_UP
GLUT_KEY_F2 GLUT_KEY_F9 GLUT_KEY_DOWN
GLUT_KEY_F3 GLUT_KEY_F10 GLUT_KEY_PAGE_UP
GLUT_KEY_F4 GLUT_KEY_F11 GLUT_KEY_PAGE_DOWN
GLUT_KEY_F5 GLUT_KEY_F12 GLUT_KEY_HOME
GLUT_KEY_F6 GLUT_KEY_LEFT GLUT_KEY_END
GLUT_KEY_F7 GLUT_KEY_RI GHT GLUT_KEY_I NSERT
Table 2: Const ant s for special keys
#def i ne ESCAPE 27
voi d keyboar d ( uns i gned char key, i nt x, i nt y)
{
i f ( key == ESCAPE)
exi t ( 0) ;
}
Figure 9: Quit t ing wit h t he escape key
gl ut Mous eFunc( mous e_but t on) ;
2. The mouse callback funct ion is passed four argument s.
• The first argument specifies t he but t on. It s value is one of GLUT_LEFT_BUTTON,
GLUT_MI DDLE_BUTTON, or GLUT_RI GHT_BUTTON.
• The second argument specifies t he but t on st at e. It s value is one of GLUT_DOWN(t he
but t on has been pressed) or GLUT_UP (t he but t on has been released).
• The remaining two argument s are t he X and Y coordinat es of t he mouse.
Figure 10 shows a mouse funct ion t hat uses t he mouse but t ons t o select t he axis of
rot at ion and t he X posit ion of t he mouse t o set t he value of t he corresponding angle.
The value of new_angl e will be 0 if t he mouse cursor is at t he left of t he OpenGL window
and 360 if t he mouse cursor is at t he right of t he window. If t he user has changed t he
widt h of t he window, t he value of SI ZE will be wrong, and t he result s will be diff erent ;
Sect ion 2.4 shows how you can avoid t his problem.
An OpenGL program can also respond t o “dragging” event s in which t he user holds a mouse
but t on down and moves t he mouse.
1. Regist er a callback funct ion for mouse dragging event s:
gl ut Mot i onFunc( dr ag) ;
2 CALLBACKS 13
voi d mous e_but t on ( i nt but t on, i nt s t at e, i nt x, i nt y)
{
doubl e new_angl e = x * 360. 0 / SI ZE;
i f ( but t on == GLUT_LEFT_BUTTON && s t at e == GLUT_DOWN)
{
x_angl e = new_angl e;
gl ut Pos t Redi s pl ay( ) ;
}
el s e i f ( but t on == GLUT_MI DDLE_BUTTON && s t at e == GLUT_DOWN)
{
y_angl e = new_angl e;
gl ut Pos t Redi s pl ay( ) ;
}
el s e i f ( but t on == GLUT_RI GHT_BUTTON && s t at e == GLUT_DOWN)
{
z_angl e = new_angl e;
gl ut Pos t Redi s pl ay( ) ;
}
}
Figure 10: A callback funct ion t hat responds t o mouse but t ons
voi d dr ag ( i nt x, i nt y)
{
z_angl e = 360. 0 * x / SI ZE;
x_angl e = 360. 0 * y / SI ZE;
gl ut Pos t Redi s pl ay( ) ;
}
Figure 11: A callback funct ion t hat responds t o dragging t he mouse
2. The mot ion funct ion is given t he X and Y coordinat es of t he mouse. Figure 11 shows
a mot ion funct ion t hat uses t he posit ion of t he mouse t o set z_angl e and x_angl e.
The funct ion gl ut Pas s i veMot i onFunc( ) regist ers a callback funct ion t hat responds t o mouse
movement when no but t ons have been pressed.
2.4 Reshaping t he Graphics Window
Whenever t he user moves or resizes t he graphics window, OpenGL informs your program,
provided t hat you have regist ered t he appropriat e callback funct ion. The main problem wit h
reshaping is t hat t he user is likely t o change t he shape of t he window as well as it s size; you
do not want t he change t o dist ort your image.
1. Regist er a callback funct ion t hat will respond t o window reshaping:
2 CALLBACKS 14
voi d r es hape ( i nt wi dt h, i nt hei ght )
{
GLf l oat w, h;
gl Vi ewpor t ( 0, 0, wi dt h, hei ght ) ;
gl Mat r i xMode( GL_PROJ ECTI ON) ;
gl LoadI dent i t y( ) ;
i f ( wi dt h > hei ght )
{
w = ( 5. 0 * wi dt h) / hei ght ;
h = 5. 0;
}
el s e
{
w = 5. 0;
h = ( 5. 0 * hei ght ) / wi dt h;
}
gl Or t ho( - w, w, - h, h, - 5. 0, 5. 0) ;
gl ut Pos t Redi s pl ay( ) ;
}
Figure 12: A callback funct ion t hat responds t o window reshaping
gl ut Res hapeFunc( r es hape) ;
2. Figure 12 shows a callback funct ion t hat responds t o a reshape request . The argu-
ment s are t he widt h and height of t he new window, in pixels. The funct ion first calls
gl Vi ewpor t ( ) t o updat e t he viewport so t hat it includes t he ent ire window. Then, it
changes t he view t o mat ch t he shape of t he new window in such a way t hat none of t he
scene is lost . The code ensures t hat :
• The rat io w/ h is t he same as t he rat io wi dt h/ hei ght ; and
• The smaller of wand h is 5.0, ensuring t hat none of t he model will be cut out of
t he scene.
If your program uses t he mouse posit ion as a source of input , it is a good idea t o mat ch t he
mouse coordinat es t o t he borders of t he graphics window. Figure 13 out lines a program t hat
uses t he mouse t o set t he global variables xpos and ypos . The callback funct ions r es hape( )
and dr ag( ) work t oget her t o maint ain t he following invariant s:
xpos = 0 at t he left
xpos = 1 at t he right
ypos = 0 at t he bot t om
ypos = 1 at t he t op
Not e:
2 CALLBACKS 15
• The Y = 0 is t he t op of t he screen in mouse coordinat es but t he bot t om of t he screen
in graphics coordinat es.
• The code does not ensure t hat 0 ≤ xpos ≤ 1 or 0 ≤ ypos ≤ 1 because of an oddity in
t he X window syst em t hat allows t he user t o drag t he mouse out side an applicat ion’s
window wit hout t he applicat ion giving up cont rol.
• The funct ion r es hape( ) comput es t he aspect rat io of t he new window and passes it t o
gl uPer s pect i ve( ) t o set up a perspect ive project ion.
2 CALLBACKS 16
#i ncl ude <GL/ gl ut . h>
i nt s cr een_wi dt h = 600;
i nt s cr een_hei ght = 400;
GLf l oat xpos = 0. 0;
GLf l oat ypos = 0. 0;
voi d di s pl ay ( voi d)
{
/ * di s pl ay t he model us i ng xpos and ypos */
}
voi d dr ag ( i nt mx, i nt my)
{
xpos = ( GLf l oat ) mx / s cr een_wi dt h;
ypos = 1. 0 - ( GLf l oat ) my / s cr een_hei ght ;
gl ut Pos t Redi s pl ay( ) ;
}
voi d r es hape ( i nt wi dt h, i nt hei ght )
{
s cr een_wi dt h = wi dt h;
s cr een_hei ght = hei ght ;
gl Vi ewpor t ( 0, 0, wi dt h, hei ght ) ;
gl Mat r i xMode( GL_PROJ ECTI ON) ;
gl LoadI dent i t y( ) ;
gl uPer s pect i ve( 30. 0, ( GLf l oat ) wi dt h / ( GLf l oat ) hei ght , 1. 0, 20. 0) ;
gl ut Pos t Redi s pl ay( ) ;
}
i nt mai n ( i nt ar gc, char *ar gv[ ] )
{
gl ut I ni t ( &ar gc, ar gv) ;
gl ut I ni t Di s pl ayMode( GLUT_RGB) ;
gl ut I ni t Wi ndowSi ze( s cr een_wi dt h, s cr een_hei ght ) ;
gl ut Cr eat eWi ndow( "Demons t r at i on of r es hapi ng") ;
gl ut Di s pl ayFunc( di s pl ay) ;
gl ut Mot i onFunc( dr ag) ;
gl ut Res hapeFunc( r es hape) ;
gl ut Mai nLoop( ) ;
}
Figure 13: Maint aining scaling invariant s
3 PRIMIT IVE OBJECT S 17
3 Primit ive Object s
The di s pl ay( ) callback funct ion usually cont ains code t o render your model int o graphical
images. All models are built from primit ive part s. There are a few funct ions for familiar
object s, such as spheres, cones, cylinders, t oruses, and t eapot s, but you have t o build ot her
shapes yourself. OpenGL provides funct ions for drawing primit ive object s, including point s,
lines, and polygons. There are also various short -cut s for drawing t he set s of relat ed polygons
(usually t riangles) t hat approximat e t hree-dimensional surfaces.
The code for drawing primit ives has t he general form
gl Begi n( mode) ;
. . . . .
gl End( ) ;
Table 3 explains what OpenGL expect s for each value of t he paramet er mode. Assume, in
each case, t hat t he code specifies n vert ices v
0
, v
1
, v
2
, . . . , v
n−1
. For some modes, n should be
a mult iple of somet hing: e.g., for GL_TRI ANGLES, n will normally be a mult iple of 3. It is not
an error t o provide ext ra vert ices, but OpenGL will ignore t hem. The polygon drawn in mode
GL_POLYGONmust be convex.
Figure 14 shows how t he vert ices of t riangle and quadrilat eral collect ions are labelled. The
label numbers are import ant , t o ensure bot h t hat t he t opology of t he object is correct and
t hat t he vert ices appear in count er-clockwise order (see Sect ion 3.4).
Separat e t riangles are oft en easier t o code t han t riangle st rips or fans. The t rade-off is t hat
your program will run slight ly more slowly, because you will have mult iple calls for each vert ex.
Mode Value Eff ect
GL_POI NTS Draw a point at each of t he n vert ices.
GL_LI NES Draw t he unconnect ed line segment s v
0
v
1
, v
2
v
3
, . . . v
n−2
v
n−1
.
GL_LI NE_STRI P Draw t he connect ed line segment s v
0
v
1
, v
1
v
2
, . . . , v
n−2
v
n−1
.
GL_LI NE_LOOP Draw a closed loop of lines v
0
v
1
, v
1
, v
2
, . . . , v
n−2
v
n−1
, v
n−1
v
0
.
GL_TRI ANGLES Draw t he t riangle v
0
v
1
v
2
, t hen t he t riangle v
3
v
4
v
5
, and so on.
GL_TRI ANGLE_STRI P Draw t he t riangle v
0
v
1
v
2
, t hen use v
3
t o draw a second t riangle,
and so on (see Figure 14 (a)).
GL_TRI ANGLE_FAN Draw t he t riangle v
0
v
1
v
2
, t hen use v
3
t o draw a second t riangle,
and so on (see Figure 14 (b)).
GL_QUADS Draw t he quadrilat eral v
0
v
1
v
2
v
3
, t hen t he quadrilat eral v
4
v
5
v
6
v
7
,
and so on.
GL_QUAD_STRI P Draw t he quadrilat eral v
0
v
1
v
3
v
2
, t hen t he quadrilat eral v
2
v
3
v
5
v
4
,
and so on (see Figure 14 (c)).
GL_POLYGON Draw a single polygon using v
0
, v
1
, . . . , v
n−1
as vert ices (n ≥ 3).
Table 3: Primit ive Specifiers
3 PRIMIT IVE OBJECT S 18
r
v
0
r
v
1
r
v
2
r
v
3
r
v
4
r
v
5
¡
¡
¡
¡e
e
e
e
¨
¨
¨
¨
¢
¢
¢
¢
¢
¢¢
¨
¨
¨
¨
e
e
e
e
r
r
r
r

r
v
0
r
v
1
r
v
2
r
v
3
r
v
4

d
d
r
r
r
r

r
v
0
r
v
1
r
v
2
r
v
3
r
v
4
r
v
5
r
v
6
r
v
7
r
r
r
r

¨
¨
¨
¨
¢
¢
¢
¢
¢
¢¢
r
r
r
r
(a) GL TRI ANGLE STRI P (b) GL TRI ANGLE FAN (c) GL QUADSTRI P
Figure 14: Drawing primit ives
window border
c
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
−1
x
1
−1
y
1
1
z
−1
E
X
T
Y
¨
¨
¨
¨%
Z
Figure 15: Default viewing volume
3.1 The Coordinat e Syst em
When we draw an object , where will it be? OpenGL object s have four coordinat es: x, y, z ,
and w. The first two, x and y must always be specified. The z coordinat e default s t o 0. The
w coordinat e default s t o 1. (Appendix A.1 explains t he use of w.) Consequent ly, a call t o
gl Ver t ex( ) may have 2, 3, or (occasionally) 4 argument s.
Object s are visible only if t hey are inside t he viewing volume. By default , t he viewing
volume is t he 2 2 cube bounded by −1 ≤ x ≤ 1, −1 ≤ y ≤ 1, and −1 ≤ z ≤ 1, wit h t he
screen in t he plane z = 0: see Figure 15. The project ion is ort hographic (no perspect ive),
as if we were viewing t he window from infinit ely far away.
The following code changes t he boundaries of t he viewing volume but maint ains an ort ho-
graphic project ion:
gl Mat r i xMode( GL_PROJ ECTI ON) ;
3 PRIMIT IVE OBJECT S 19
f ace mode
GL_FRONT_AND_BACK(default ) GL_FI LL (default )
GL_FRONT GL_LI NE
GL_BACK GL_POI NT
Table 4: Opt ions for drawing polygons
gl LoadI dent i t y( ) ;
gl Or t ho( l ef t , r i ght , bot t om, t op, near , f ar ) ;
An object at (x, y, z ) will be visible if l ef t ≤ x ≤ r i ght , bot t om≤ y ≤ t op, and −near ≤
z ≤ −f ar . Not e t he sign reversal in t he Z -axis: t his convent ion ensures t hat t he coordinat e
syst em is right -handed.
3.2 Point s
The size of a point is set by gl Poi nt Si ze( s i ze) . The default value of s i ze is 1.0.
3.3 Lines
The widt h of a line is set by gl Li neWi dt h( s i ze) . The default value of s i ze is 1.0.
To draw st ippled (or dashed) lines, use t he following code:
gl Enabl e( GL_LI NE_STI PPLE) ;
gl Li neSt i ppl e( f act or , pat t er n) ;
The pat t er n is a 16-bit number in which a 0-bit means “don’t draw” and a 1-bit means “do
draw”. The f act or indicat es how much t he pat t ern should be “st ret ched”.
Example: Aft er t he following code has been execut ed, lines will be drawn as 10 10 pixel
squares separat ed by 10 pixels (not e t hat A
16
= 1010
2
).
gl Enabl e( GL_LI NE_STI PPLE) ;
gl Li neWi dt h( 10. 0) ;
gl Li neSt i ppl e( 10, 0xAAAA) ;
3.4 Polygons
The modes GL_POI NTS, GL_LI NES, GL_LI NE_STRI P, and GL_LI NE_LOOP are st raight forward.
The ot her modes all describe polygons of one sort or anot her.
The way in which polygons are drawn is det ermined by calling gl Pol ygonMode( f ace, mode) ; .
Table 4 shows t he possible values of f ace and mode.
3 PRIMIT IVE OBJECT S 20
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
¨
0
1
2
3
4
5
6
7
Figure 16: Labelling t he corners of a cube
How do we decide which is t he front of a polygon? The rule t hat GL uses is: if t he vert ices
appear in a count er-clockwise order in t he viewing window, we are looking at t he front of t he
polygon. If we draw a solid object , such as a cube, t he “front ” of each face should be t he
“out side”. The dist inct ion between front and back does not mat t er in t he default mode, in
which t he front and back sides of a polygon are t reat ed in t he same way.
Example: Suppose t hat we want t o draw a unit cube cent ered at t he origin, wit h vert ices
numbered as in Figure 16. Figure 17 shows t he code required.
We begin by declaring an array pt giving t he coordinat es of each vert ex. Next , we declare a
funct ion f ace( ) t hat draws one face of t he cube. Finally, we declare a funct ion cube( ) t hat
draws six faces, providing t he vert ices in count er-clockwise order when viewed from out side
t he cube.
Polygons must be convex. The eff ect of drawing a concave or re-ent rant (self-int ersect ing)
polygon is undefined. If necessary, convert a concave polygon t o two or more convex polygons
by adding int ernal edges.
Colouring The funct ion call gl ShadeModel ( mode) det ermines t he colouring of polygons.
By default , mode is GL_SMOOTH, which means t hat GL will use t he colours provided at each
vert ex and int erpolat ed colours for all ot her point s. For example, if you draw a rect angle wit h
red corners at t he left and blue corners at t he right , t he left edge will be red, t he right edge
will be blue, and t he ot her point s will be shades of purple.
If mode is GL_FLAT, t he ent ire polygon has t he same colour as it s first vert ex.
A set of t hree point s defines a plane. If t here are more t han t hree point s in a set , t here may be
no plane t hat cont ains t hem. GL will draw non-planar “polygons”, but light ing and shading
eff ect s may be a bit st range.
St ippling To draw st ippled polygons, execut e t he following code:
3 PRIMIT IVE OBJECT S 21
t ypedef GLf l oat Poi nt [ 3] ;
Poi nt pt [ ] = {
{ - 0. 5, - 0. 5, 0. 5 },
{ - 0. 5, 0. 5, 0. 5 },
{ 0. 5, 0. 5, 0. 5 },
{ 0. 5, - 0. 5, 0. 5 },
{ - 0. 5, - 0. 5, - 0. 5 },
{ - 0. 5, 0. 5, - 0. 5 },
{ 0. 5, 0. 5, - 0. 5 },
{ 0. 5, - 0. 5, - 0. 5 } };
voi d f ace ( i nt v0, i nt v1, i nt v2, i nt v3)
{
gl Begi n( GL_POLYGON) ;
gl Ver t ex3f v( pt [ v0] ) ;
gl Ver t ex3f v( pt [ v1] ) ;
gl Ver t ex3f v( pt [ v2] ) ;
gl Ver t ex3f v( pt [ v3] ) ;
gl End( ) ;
}
voi d cube ( voi d)
{
f ace( 0, 3, 2, 1) ;
f ace( 2, 3, 7, 6) ;
f ace( 0, 4, 7, 3) ;
f ace( 1, 2, 6, 5) ;
f ace( 4, 5, 6, 7) ;
f ace( 0, 1, 5, 4) ;
}
Figure 17: Drawing a cube
gl Enabl e( GL_POLYGON_STI PPLE) ;
gl Pol ygonSt i ppl e( pat t er n) ;
The argument pat t er n is a point er t o a 32 32 pixel bit map (32
2
= 1024 bit s = 128 byt es =
256 hex charact ers).
Rect angles Since rect angles are used oft en, GL provides a special funct ion, gl Rect ( ) for
drawing rect angles in t he z = 0 plane. This funct ion is defined in Appendix C.
3.5 Hidden Surface Eliminat ion
To obt ain a realist ic view of a collect ion of primit ive object s, t he graphics syst em must display
only t he object s t hat t he viewer can see. Since t he component s of t he model are typically
3 PRIMIT IVE OBJECT S 22
surfaces (t riangles, polygons, et c.), t he st ep t hat ensures t hat invisible surfaces are not ren-
dered is called hidden surface eliminat ion. There are various ways of eliminat ing hidden
surfaces; OpenGL uses a dept h buff er.
The dept h buff er is a two-dimensional array of numbers; each component of t he array corre-
sponds t o a pixel in t he viewing window. In general, several point s in t he model will map t o
a single pixel. The dept h-buff er is used t o ensure t hat only t he point closest t o t he viewer is
act ually displayed.
To enable hidden surface eliminat ion, modify your graphics program as follows:
• When you init ialize t he display mode, include t he dept h buff er bit :
gl ut I ni t Di s pl ayMode( GLUT_RGBA | GLUT_DEPTH) ;
• During init ializat ion and aft er creat ing t he graphics window, execut e t he following st at e-
ment t o enable t he dept h-buff er t est :
gl Enabl e( GL_DEPTH_TEST) ;
• In t he di s pl ay( ) funct ion, modify t he call t o gl Cl ear ( ) so t hat it clears t he dept h-
buff er as well as t he colour buff er:
gl Cl ear ( GL_COLOR_BUFFER_BI T | GL_DEPTH_BUFFER_BI T) ;
3.6 Animat ion
If your program has an idle callback funct ion t hat changes t he values of some global variables,
OpenGL will display your model repeat edly, giving t he eff ect of animat ion. The display will
probably flicker, however, because images will be alt ernat ely drawn and erased. To avoid
flicker, modify your program t o use double buff ering. In t his mode, OpenGL renders t he
image int o one buff er while displaying t he cont ent s of t he ot her buff er.
• When you init ialize t he display mode, include t he double buff er bit :
gl ut I ni t Di s pl ayMode( GLUT_RGBA | GLUT_DOUBLE) ;
• At t he end of t he di s pl ay( ) funct ion include t he call
gl ut SwapBuf f er s ( ) ;
4 T RANSFORMAT IONS 23
4 Transformat ions
The eff ect of a t ransformat ion is t o move an object , or set of object s, wit h respect t o a
coordinat e syst em. Table 5 describes some common t ransformat ions. The least import ant
t ransformat ion is shearing; OpenGL does not provide primit ive funct ions for it .
We can apply t ransformat ions t o: t he model; part s of t he model; t he camera (or eye) posit ion;
and t he camera “lens”.
In OpenGL, t he first t hree of t hese are called “model view” t ransformat ions and t he last is
called t he “project ion” t ransformat ion. Not e t hat model t ransformat ions and camera t rans-
format ions are complement ary: for every t ransformat ion t hat changes t he model, t here is a
corresponding inverse t ransformat ion t hat changes t he camera and has t he same eff ect on t he
screen.
The OpenGL funct ions t hat are used t o eff ect t ransformat ions include gl Mat r i xMode( ) ,
gl LoadI dent i t y( ) , gl Tr ans l at ef ( ) , gl Rot at ef ( ) , and gl Scal ef ( ) .
4.1 Model View Transformat ions
A t ransformat ion is represent ed by a mat rix. (Appendix A provides an overview of t he
t heory of represent ing t ransformat ions as mat rices.) OpenGL maint ains two current mat rices:
t he model view mat rix and t he project ion mat rix. gl Mat r i xMode( ) select s t he current
mat rix; gl LoadI dent i t y( ) init ializes it ; and t he ot her funct ions change it . In t he example
below, t he left column shows typical code and t he right column shows t he eff ect in pseudocode.
M is t he current mat rix, I is t he ident ity mat rix, T is a t ranslat ion mat rix, R is a rot at ion
mat rix, and denot es mat rix mult iplicat ion. The final value of M is I T R = T R.
gl Mat r i xMode( GL MODELVI EW) ;
gl LoadI dent i t y( ) ; M := I
gl Tr ans l at ef ( x, y, z) ; M := M T
gl Rot at ef ( a, x, y, z) ; M := M R
You might t hink it nat ural t o draw somet hing and t hen t ransform it . OpenGL, however, works
t he ot her way round: you define t he t ransformat ions first and t hen you draw t he object s. This
seems backwards, but act ually provides great er flexibility in t he drawing process, because we
can int erleave drawing and t ransformat ion operat ions. Consider t he following pseudocode:
Name Eff ect
Translat e Move or slide along a st raight line
Rot at e Rot at e, spin, or twist , about an axis t hrough t he origin
Scale Make an object larger or smaller
Shear Turn rect angles int o parallelograms
Perspect ive Give illusion of dept h for 3D object s
Table 5: Common t ransformat ions
4 T RANSFORMAT IONS 24
1 voi d di s pl ay ( voi d)
2 {
3 gl Cl ear ( GL_COLOR_BUFFER_BI T) ;
4 gl Mat r i xMode( GL_MODELVI EW) ;
5 gl LoadI dent i t y( ) ;
6 gl ut Wi r eCube( 1. 0) ;
7 gl Tr ans l at ef ( 0. 0, 0. 5, 0. 0) ;
8 gl Rot at ef ( - 90. 0, 1. 0, 0. 0, 0. 0) ;
9 gl ut Wi r eCone( 0. 5, 2. 0, 15, 15) ;
10 gl Rot at ef ( 90. 0, 1. 0, 0. 0, 0. 0) ;
11 gl Tr ans l at ef ( 0. 0, 2. 5, 0. 0) ;
12 gl ut Wi r eSpher e( 0. 5, 15, 15) ;
13 }
Figure 18: A balancing act
i ni t i al i ze model vi ew mat r i x
dr aw obj ect P1
do t r ans f or mat i on T1
dr aw obj ect P2
do t r ans f or mat i on T2
dr aw obj ect P3
. . . . .
The object P1 is drawn wit hout any t ransformat ions: it will appear exact ly as defined in t he
original coordinat e syst em. When t he object P2 is drawn, t ransformat ion T1 is in eff ect ; if
T1 is a t ranslat ion, for example, P2 will be displaced from t he origin. Then P3 is drawn wit h
t ransformat ions T1 and T2 (t hat is, t he t ransformat ion T1 T2) in eff ect .
In pract ice, we usually define a camera t ransformat ion first , before drawing any object s. This
makes sense, because changing t he posit ion of t he camera should change t he ent ire scene. By
default , t he camera is posit ioned at t he origin and is looking in t he negat ive Z direct ion.
Alt hough we can t hink of a t ransformat ion as moving eit her t he object s or t he coordinat e sys-
t em, it is oft en simpler t o t hink of t he coordinat es moving. The following example illust rat es
t his way of t hinking.
The program bal ance. c draws a sphere on t he t op of a cone which is st anding on a cube.
Figure 18 shows t he display callback funct ion t hat const ruct s t his model (t he line numbers
are not part of t he program).
Line 3 clears t he buff er, line 4 select s t he model view mat rix, and line 5 init ialize t he mat rix.
The first object drawn is a unit cube (line 6); since no t ransformat ions are in eff ect , t he cube
is at t he origin. Since t he cone must sit on t op of t he cube, line 7 t ranslat es t he coordinat e
syst em up by 0.5 unit s.
The axis of t he cone provided by GLUT is t he Z axis, but we need a cone wit h it s axis in t he
Y direct ion. Consequent ly, we rot at e t he coordinat e syst em (line 8), draw t he cone (line 9),
and rot at e t he coordinat e syst em back again (line 10). Not e t hat t he rot at ion in line 10:
1. does not aff ect t he cone, which has already been drawn; and
4 T RANSFORMAT IONS 25
2. avoids confusion: if it it was not t here, we would have a coordinat e syst em wit h a
horizont al Y axis and a vert ical Z axis.
Line 11 moves t he origin t o t he cent re of t he sphere, which is 2.0+ 0.5 unit s (t he height of t he
cone plus t he radius of t he sphere) above t he t op face of t he cube. Line 12 draws t he sphere.
The example demonst rat es t hat we can st art at t he origin (t he “cent re” of t he model) and
move around drawing part s of t he model. Somet imes, however, we have t o get back t o a
previous coordinat e syst em. Consider drawing a person, for inst ance: we could draw t he
body, move t o t he left shoulder, draw t he upper arm, move t o t he elbow joint , draw t he lower
arm, move t o t he wrist , and draw t he hand. Then what ? How do we get back t o t he body t o
draw t he right arm?
The solut ion t hat OpenGL provides for t his problem is a mat rix st ack. There is not just one
model view mat rix, but a st ack t hat can cont ain 32 model view mat rices. (The specificat ion of
t he API requires a st ack dept h of at least 32 mat rices; implement at ions may provide more.)
The funct ion gl Pus hMat r i x( ) pushes t he current mat rix ont o t he st ack, and t he funct ion
gl PopMat r i x( ) pops t he current mat rix off t he st ack (and loses it ). Using t hese funct ions,
we could rewrit e lines 8–10 of t he example as:
gl Pus hMat r i x( ) ;
gl Rot at ef ( - 90. 0, 1. 0, 0. 0, 0. 0) ;
gl ut Wi r eCone( 0. 5, 2. 0, 15, 15) ;
gl PopMat r i x( ) ;
The st ack version is more effi cient because it is fast er t o copy a mat rix t han it is t o const ruct
a new mat rix and perform a mat rix mult iplicat ion. It is always bet t er t o push and pop t han
t o apply inverse t ransformat ions.
When pushing and popping mat rices, it is import ant t o realize t hat t he sequence
gl PopMat r i x( ) ;
gl Pus hMat r i x( ) ;
does have an eff ect : t he two calls do not cancel each ot her out . To see t his, look at Figure 19.
The left column cont ains line numbers for ident ificat ion, t he second column cont ains code,
t he t hird column shows t he mat rix at t he t op of t he st ack aft er each funct ion has execut ed,
and t he ot her columns show t he mat rices lower in t he st ack. The mat rices are shown as I
(t he ident ity), T (t he t ranslat ion), and R (t he rot at ion). At line 4, t here are t hree mat rices
on t he st ack, wit h T occupying t he t op two places. Line 5 post -mult iplies t he t op mat rix by
R. Line 6 pops t he product T R off t he st ack, rest oring t he st ack t o it s value at line 3. Line 7
pushes t he st ack and copies t he t op mat rix. Not e t he diff erence between t he st ack ent ries at
line 5 and line 7.
4.2 Project ion Transformat ions
The usual pract ice in OpenGL coding is t o define a project ion mat rix once and not t o apply
any t ransformat ions t o it . The project ion mat rix can be defined during init ializat ion, but a
bet t er place t o define it is t he reshape funct ion. If t he user changes t he shape of t he viewing
4 T RANSFORMAT IONS 26
# Code St ack
1 gl LoadI dent i t y( ) ; I
2 gl Pus hMat r i x( ) ; I I
3 gl Tr ans l at ef ( 1. 0, 0. 0, 0. 0) ; T I
4 gl Pus hMat r i x( ) ; T T I
5 gl Rot at ef ( 10. 0, 0. 0, 1. 0, 0. 0) ; T R T I
6 gl PopMat r i x( ) ; T I
7 gl Pus hMat r i x( ) ; T T I
Figure 19: Pushing and popping
window, t he program should respond by changing t he project ion t ransformat ion so t hat t he
view is not dist ort ed. The callback funct ion r es hape( ) in Figure 12 on page 14 shows how
t o do t his.
The following code illust rat es t he default set t ings:
gl Mat r i xMode( GL_PROJ ECTI ON) ;
gl LoadI dent i t y( ) ;
gl Or t ho( - 1. 0, 1. 0, - 1. 0, 1. 0, - 1. 0, 1. 0) ;
This code defines an ort hographic project ion (no perspect ive) and defines t he viewing vol-
ume t o be a 2 2 2 unit cube cent ered at t he origin. The six argument s are, respect ively:
minimum X , maximum X , minimum Y , maximum Y , minimum Z , and maximum Z .
4.3 Perspect ive Transformat ions
It is not surprising t hat dist ant object s appear t o be smaller t han close object s: if an object
is furt her from our eyes, it will subt end a smaller angle at t he eye and hence creat e a smaller
image on t he ret ina. A project ion t hat capt ures t his phenomenon in a two-dimensional view
is called a perspect ive project ion.
The diff erence between an ort hographic project ion and a perspect ive project ion lies in t he
shape of t he viewing volume. As we have seen, t he viewing volume for an ort hographic
project ion is a cuboid (rect angular box). The viewing volume for a perspect ive project ion
is a frust um, or t runcat ed pyramid. The apex of t he pyramid is at t he eye; and t he t op
and bot t om of t he frust um det ermine t he dist ances of t he nearest and furt hest point s t hat
are visible. The sides of t he pyramid det ermine t he visibility of object s in t he ot her two
dimensions.
OpenGL provides t he funct ion gl Fr us t um( ) t o define t he frust um direct ly, as shown in Fig-
ure 20. The eye and t he apex of t he pyramid are at t he point labelled O at t he left of t he
diagram. We can t hink of t he closer vert ical plane as t he screen: t he closest object s lie in t he
plane of t he screen and ot her object s lie behind it . The first four argument s det ermine t he
range of X and Y values as follows: l ef t corresponds t o minimum X ; r i ght corresponds t o
maximum X ; bot t omcorresponds t o minimum Y ; and t op corresponds t o maximum Y .
4 T RANSFORMAT IONS 27
r
r
r
r
r
r
r
r
O
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3

r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
near
' E
far
' E
top
right
left
bottom
&
&
&b
Figure 20: Perspect ive project ion wit h gl Fr us t um( )
Not e t hat near and f ar do not correspond direct ly t o Z values. Bot h near and f ar must be
posit ive, and visible Z values lie in t he range −f ar ≤ Z ≤ −near .
The funct ion gl uPer s pect i ve( ) provides anot her way of defining t he frust um t hat is more
int uit ive and oft en convenient . The first argument defines t he vert ical angle t hat t he viewport
subt ends at t he eye in degrees. This angle is called α in Figure 21; it s value must sat isfy
0

< α < 180

. The height of t he window is h = 2 near t an(α / 2). The second argument , ar
in Figure 21, is t he aspect rat io, which is t he widt h of t he viewport divided by it s height .
Thus w = ar h = 2 ar near t an(α / 2). The last two argument s, near and f ar , det ermine
t he nearest and furt hest point s visible.
The presence of t he aspect -rat io argument makes it easy t o use gl uPer s pect i ve( ) in a
window reshaping callback funct ion: Figure 22 shows a typical example.
The model view t ransformat ion and t he project ion t ransformat ion must work t oget her in such
a way t hat at least part of t he model lies in t he viewing volume. If it doesn’t , we won’t see
anyt hing.
Bot h project ion t ransformat ions assume t hat our camera (or eye) is sit uat ed at t he origin
and is looking in t he negat ive Z direct ion. (Why negat ive Z , rat her t han posit ive Z ? By
convent ion, t he screen coordinat es have X point ing right and Y point ing up. If we want a
right -handed coordinat e syst em, Z must point t owards t he viewer.) Consequent ly, we should
posit ion our model somewhere on t he negat ive Z axis.
The value of al pha det ermines t he vert ical angle subt ended by t he viewport at t he user’s eye.
Figure 23 shows t he eff ect of a small value of al pha. The model is a wire cube whose image
4 T RANSFORMAT IONS 28
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
O
α
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
r
r
r
r
r
near
' E
far
' E
w
r
r
r

r
r
r
rj
h
T
c
Figure 21: Perspect ive project ion using gl uPer s pect i ve( )
voi d r es hape ( i nt wi dt h, i nt hei ght )
{
gl Vi ewpor t ( 0, 0, wi dht , hei ght ) ;
gl Mat r i xMode( GL_PROJ ECTI ON) ;
gl Loadi dent i t y( ) ;
gl uPer s pect i ve( 30. 0, ( GLf l oat ) wi dt h / ( GLf l oat ) hei ght , 1, 20) ;
}
Figure 22: Reshaping wit h gl uPer s pect i ve( )
occupies half of t he viewport . The eff ect is t hat of viewing t he cube from a large dist ance:
t he back of t he cube is only slight ly smaller t han t he front .
view on screen
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@
@@
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
h
hh
α
Figure 23: gl uPer s pect i ve( ) wit h a small value of α
4 T RANSFORMAT IONS 29

d
d

d
d
view on screen
¡
¡
¡
¡
¡
¡
¡
¡
¡
¡
¡
¡
¡
α
e
e
e
e
e
e
e
e
e
e
e
e
e
Figure 24: gl uPer s pect i ve( ) wit h a large value of α
Figure 24 shows t he eff ect of a large value of al pha. The model is again a wire cube whose
image occupies half of t he viewport . The eff ect is of viewing t he cube from a small dist ance:
t he back of t he cube is much smaller t han t he front .
Making al pha smaller wit hout moving t he model simulat es “zooming in”: t he image get s
larger in t he viewport . Making al pha larger simulat es “zooming out ”: t he image get s smaller.
Alt hough we can use al pha t o manipulat e t he image in any way we please, t here is a correct
value for it . Suppose t hat t he user is sit t ing at a dist ance d from a screen of height h: t he
appropriat e value of al pha is given by
α = 2 t an
−1

h
2 d

.
For example, if h = 12 in and d = 24 in, t hen
α = 2 t an
−1

12
2 24

≈ 28

.
If you have used a 35 mm camera, you may find t he following comparisons helpful. The
vert ical height of a 35 mm film frame is h = 24 mm, so h/ 2 = 12 mm. When t he camera is
used wit h a lens wit h focal lengt h f mm, t he vert ical angle subt ended by t he field of view is
2 t an
−1
(12/ f ). The angle for a 24 mm wide-angle lens is about 53

; t he angle for a regular
50 mm lens is about 27

; and t he angle for a 100 mm t elephot o lens is about 14

.
4.4 Combining Viewpoint and Perspect ive
The funct ion gl uLookAt ( ) defines a model-view t ransformat ion t hat simulat es viewing (“look-
ing at ”) t he scene from a part icular viewpoint . It t akes nine argument s of type GLf l oat . The
4 T RANSFORMAT IONS 30
first t hree argument s define t he camera (or eye) posit ion wit h respect t o t he origin; t he next
t hree argument s are t he coordinat es of a point in t he model t owards which t he camera is
direct ed; and t he last t hree argument s are t he component s of a vect or point ing upwards. In
t he call
gl uLookAt ( 0. 0, 0. 0, 10. 0,
0. 0, 0. 0, 0. 0,
0. 0, 1. 0, 0. 0 ) ;
t he point of int erest in t he model is at (0, 0, 0), t he posit ion of t he camera relat ive t o t his
point is (0, 0, 10), and t he vect or (0, 1, 0) (t hat is, t he Y -axis) is point ing upwards.
Alt hough t he idea of gl uLookAt ( ) seems simple, t he funct ion is t ricky t o use in pract ice.
Oft en, int roducing a call t o gl uLookAt ( ) has t he undesirable eff ect of making t he image
disappear alt oget her! In t he following code, t he eff ect of t he call t o gl uLookAt ( ) is t o move
t he origin t o (0, 0, −10); but t he near and far planes defined by gl uPer s pect i ve( ) are at
z = −1 and z = −5, respect ively. Consequent ly, t he cube is beyond t he far plane and is
invisible.
gl Mat r i xMode( GL_PROJ ECTI ON) ;
gl LoadI dent i t y( ) ;
gl uPer s pect i ve( 30, 1, 1, 5) ;
gl Mat r i xMode( GL_MODELVI EW) ;
gl LoadI dent i t y( ) ;
gl uLookAt ( 0, 0, 10, 0, 0, 0, 0, 1, 0 ) ;
gl ut Wi r eCube( 1. 0) ;
Figure 25 demonst rat es how t o use gl uLookAt ( ) and gl uPer s pect i ve( ) t oget her. The two
import ant variables are al pha and di s t . The idea is t hat t he ext ension of t he object in t he Z -
direct ion is less t han 2; consequent ly, it can be enclosed complet ely by planes at z = di s t −1
and z = di s t + 1. To ensure t hat t he object is visible, gl uLookAt ( ) set s t he camera posit ion
t o (0, 0, di s t ).
Changing t he value of al pha in Figure 25 changes t he size of t he object , as explained above.
The height of t he viewing window is 2 (di s t −1) t an (al pha/ 2); increasing al pha makes t he
viewing window larger and t he object smaller.
Changing t he value of di s t also changes t he size of t he image in t he viewport , but in a
diff erent way. The perspect ive changes, giving t he eff ect of approaching (if di s t get s smaller
and t he object get s larger) or going away (if di s t get s larger and t he object get s smaller).
It is possible t o change al pha and di s t t oget her in such a way t hat t he size of a key object
in t he model st ays t he same while t he perspect ive changes. (For example, consider a series
of diagrams t hat st art s wit h Figure 23 and ends wit h Figure 24.) This is a rat her simple
t echnique in OpenGL, but it is an expensive eff ect in movies or t elevision because t he zoom
cont rol of t he lens must be coupled t o t he t racking mot ion of t he camera. Hit chcock used t his
t rick t o good eff ect in his movies Vertigo and Marnie.
4 T RANSFORMAT IONS 31
#i ncl ude <GL/ gl ut . h>
cons t i nt SI ZE = 500;
f l oat al pha = 60. 0;
f l oat di s t = 5. 0;
voi d di s pl ay ( voi d)
{
gl Cl ear ( GL_COLOR_BUFFER_BI T) ;
gl Mat r i xMode( GL_MODELVI EW) ;
gl LoadI dent i t y( ) ;
gl uLookAt ( 0. 0, 0. 0, di s t ,
0. 0, 0. 0, 0. 0,
0. 0, 1. 0, 0. 0 ) ;
gl ut Wi r eCube( 1. 0) ;
}
voi d i ni t ( voi d)
{
gl Mat r i xMode( GL_PROJ ECTI ON) ;
gl LoadI dent i t y( ) ;
gl uPer s pect i ve( al pha, 1. 0, di s t - 1. 0, di s t + 1. 0) ;
}
i nt mai n ( i nt ar gc, char *ar gv[ ] )
{
gl ut I ni t ( &ar gc, ar gv) ;
gl ut I ni t Wi ndowSi ze( SI ZE, SI ZE) ;
gl ut I ni t Wi ndowPos i t i on( 100, 50) ;
gl ut Cr eat eWi ndow( "A Per s pect i ve Vi ew") ;
i ni t ( ) ;
gl ut Di s pl ayFunc( di s pl ay) ;
gl ut Mai nLoop( ) ;
}
Figure 25: Using gl uLookAt ( ) and gl uPer s pect i ve( )
5 LIGHT ING 32
5 Light ing
We t alk about “t hree dimensional” graphics but , wit h current t echnology, t he best we can do
is t o creat e t he illusion of t hree-dimensional object s on a two-dimensional screen. Perspect ive
is one kind of illusion, but it is not enough. A perspect ive project ion of a uniformly-coloured
cube, for example, looks like an irregular hexagon. We can paint t he faces of t he cube in
diff erent colours, but t his does not help us t o display a realist ic image of a cube of one colour.
We can improve t he illusion of dept h by simulat ing t he light ing of a scene. If a cube is
illuminat ed by a single light source, it s faces have diff erent bright nesses, and t his st rengt hens
t he illusion t hat it is t hree dimensional. Appendix B out lines t he t heory of illuminat ion; t his
sect ion describes some of t he feat ures t hat OpenGL provides for light ing a scene.
To light a model, we must provide OpenGL wit h informat ion about t he object s in t he scene
and t he light s t hat illuminat e t hem. To obt ain realist ic light ing eff ect s, we must define:
1. normal vect ors for each vert ex of each object ;
2. mat erial propert ies for each object ;
3. t he posit ions and ot her propert ies of t he light sources; and
4. a light ing model.
Since OpenGL provides reasonable default s for many propert ies, we have t o add only a few
funct ion calls t o a program t o obt ain simple light ing eff ect s. For full realism, however, t here
is quit e a lot of work t o do.
5.1 A Simple Example
Suppose t hat we have a program t hat displays a sphere. We must eliminat e hidden surfaces
by passing GLUT_DEPTHt o gl ut I ni t Di s pl ayMode( ) and by clearing GL_DEPTH_BUFFER_BI T
in t he display funct ion. The following st eps would be necessary t o illuminat e a sphere.
1. Define normal vect ors. If we use t he GLUT funct ion gl ut Sol i dSpher e( ) , t his st ep is
unnecessary, because normals are already defined for t he sphere and ot her GLUT solid
object s.
2. Define mat erial propert ies. We can use t he default propert ies.
3. Define light sources. The following code should be execut ed during init ializat ion:
gl Enabl e( GL_LI GHTI NG) ;
gl Enabl e( GL_LI GHT0) ;
4. Define a light ing model. We can use t he default model.
This is t he simplest case, in which we add just two lines of code. The following sect ions
describe more of t he det ails.
5 LIGHT ING 33

€
€
€
€
€
€
f
f
f
f
f
ff
€
€
€
€
€
€

0
1
2
3
Figure 26: A simple object
5.2 Normal Vect ors
For any plane surface, t here is a normal vector at right angles t o it . A pencil st anding
vert ically on a horizont al deskt op provides an appropriat e ment al image.
OpenGL associat es normals wit h vert ices rat her t han surfaces. This seems surprising at first ,
but it has an import ant advant age. Oft en, we are using flat polygons as approximat ions t o
curved surfaces. For example, a sphere is const ruct ed of many small rect angles whose edges
are lines of lat it ude and longit ude. If we provide a single normal for each rect angle, OpenGL
will illuminat e each rect angle as a flat surface. If, inst ead, we provide a normal at each vert ex,
OpenGL will illuminat e t he rect angles as if t hey were curved surfaces, and provide a bet t er
illusion of a sphere.
Consequent ly, t here are two ways of specifying normals. Consider t he very simple object
shown in Figure 26 consist ing of two t riangles. We could provide a single normal for each
t riangle using t he following code:
gl Begi n( GL_TRI ANGLES) ;
gl Nor mal 3f ( u0, v0, w0) ; / * Nor mal f or t r i angl e 012. */
gl Ver t ex3f ( x0, y0, z0) ;
gl Ver t ex3f ( x1, y1, z1) ;
gl Ver t ex3f ( x2, y2, z2) ;
gl Nor mal 3f ( u1, v1, w1) ; / * Nor mal f or t r i angl e 132. */
gl Ver t ex3f ( x1, y1, z1) ;
gl Ver t ex3f ( x3, y3, z3) ;
gl Ver t ex3f ( x2, y2, z2) ;
gl End( ) ;
The funct ion gl Nor mal ( ) defines a normal vect or for any vert ex definit ions t hat follow it .
Not e t hat it is possible for two normals t o be associat ed wit h t he same vert ex: in t he code
above, vert ices 1 and 2 each have two normals. As far as OpenGL is concerned, t he code
defines six vert ices, each wit h it s own normal.
The ot her way of describing t his object requires a normal for each vert ex. The normals at
vert ices 0 and 3 are perpendicular t o t he corresponding t riangles. The normals at vert ices 1
and 2 are comput ed by averaging t he normals for t he t riangles. In t he following code, each
vert ex definit ion is preceded by t he definit ion of t he corresponding normal.
5 LIGHT ING 34
gl Begi n( GL_TRI ANGLES) ;
gl Nor mal 3f ( u0, v0, w0) ; / * Nor mal t o t r i angl e 012 */
gl Ver t ex3f ( x0, y0, z0) ;
gl Nor mal 3f ( ua, va, wa) ; / * Aver age */
gl Ver t ex3f ( x1, y1, z1) ;
gl Nor mal 3f ( ua, va, wa) ; / * Aver age */
gl Ver t ex3f ( x2, y2, z2) ;
gl Nor mal 3f ( ua, va, wa) ; / * Aver age */
gl Ver t ex3f ( x1, y1, z1) ;
gl Nor mal 3f ( u3, v3, w3) ; / * Nor mal t o t r i angl e 132 */
gl Ver t ex3f ( x3, y3, z3) ;
gl Nor mal 3f ( ua, va, wa) ; / * Aver age */
gl Ver t ex3f ( x2, y2, z2) ;
gl End( ) ;
We do not usually see code like t his in OpenGL programs, because it is usually more convenient
t o st ore t he dat a in arrays. The following example is more typical; each component of t he
arrays nor mand ver t is an array of t hree f l oat s.
gl Begi n{GL_TRI ANGLES}
f or ( i = 0; i < MAX; i ++)
{
gl Nor mal 3f v( nor m[ i ] ) ;
gl Ver t ex3f v( ver t [ i ] ) ;
}
gl End( ) ;
Each normal vect or should be normalized (!) in t he sense t hat it s lengt h should be 1. Nor-
malizing t he vect or (x, y, z ) gives t he vect or (x/ s, y/ s, z / s), where s =

x
2
+ y
2
+ z
2
.
If you include t he st at ement gl Enabl e( GL_NORMALI ZE) in your init ializat ion code, OpenGL
will normalize vect ors for you. However, it is usually more effi cient t o normalize vect ors
yourself.
Comput ing Normal Vect ors The vect or normal t o a t riangle wit h vert ices (x
1
, y
1
, z
1
),
(x
2
, y
2
, z
2
), and (x
3
, y
3
, z
3
) is (a, b, c), where
a = +

y
2
−y
1
z
2
−z
1
y
3
−y
1
z
3
−z
1

b = −

x
2
−x
1
z
2
−z
1
x
3
−x
1
z
3
−z
1

c = +

x
2
−x
1
y
2
−y
1
x
3
−x
1
y
3
−y
1

To comput e t he average of n vect ors, simply add t hem up and divide by n. In pract ice, t he
division by n is not usually necessary, because we can simply add t he normal vect ors at a
vert ex and t hen normalize t he result ing vect or.
5 LIGHT ING 35
enum { X, Y, Z };
t ypedef f l oat Poi nt [ 3] ;
t ypedef f l oat Vect or [ 3] ;
Poi nt poi nt s [ MAX_POI NTS] ;
voi d f i nd_nor mal ( i nt p, i nt q, i nt r , Vect or v) {
f l oat x1 = poi nt s [ p] [ X] ;
f l oat y1 = poi nt s [ p] [ Y] ;
f l oat z1 = poi nt s [ p] [ Z] ;
f l oat x2 = poi nt s [ q] [ X] ;
f l oat y2 = poi nt s [ q] [ Y] ;
f l oat z2 = poi nt s [ q] [ Z] ;
f l oat x3 = poi nt s [ r ] [ X] ;
f l oat y3 = poi nt s [ r ] [ Y] ;
f l oat z3 = poi nt s [ r ] [ Z] ;
v[ X] = + ( y2- y1) *( z3- z1) - ( z2- z1) *( y3- y1) ;
v[ Y] = - ( x2- x1) *( z3- z1) + ( z2- z1) *( x3- x1) ;
v[ Z] = + ( x2- x1) *( y3- y1) - ( y2- y1) *( x3- x1) ;
}
Figure 27: Comput ing normals
Formally, t he normalized average vect or of a set of vect ors ¦ (x
i
, y
i
, z
i
) [ i = 1, 2, . . . , n ¦ is

X
S
,
Y
S
,
Z
S

, where X =
i=n
¸
i=1
x
i
, Y =
i=n
¸
i=1
y
i
, Z =
i=n
¸
i=1
z
i
, and S =

X
2
+ Y
2
+ Z
2
.
Figure 27 shows a simple funct ion t hat comput es vect or normal for a plane defined by t hree
point s p, q, and r , chosen from an array of point s.
5.3 Defining Mat erial Propert ies
When light ing is enabled, OpenGL ignores gl Col or ( ) calls. Inst ead, it comput es t he colour
of each point using informat ion about t he light s, t he object s, and t heir relat ive posit ions. The
funct ion t hat defines t he eff ect of light ing an object is gl Mat er i al f v( ) and it requires t hree
argument s.
1. The first argument det ermines which face we are defining. The possible values are
GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK.
It is usually best t o use GL_FRONTbecause, in most sit uat ions, only front faces should be
visible. (Recall t hat a face is at t he “front ” if it s vert ices are given in count erclockwise
order as seen by t he viewer.) You can specify diff erent propert ies for front and back
faces by calling gl Mat er i al f v( ) twice, once wit h GL_FRONT and again wit h GL_BACK.
2. The second argument is a paramet er name. Table 6 shows it s possible values.
3. The t hird argument provides t he value of t he corresponding paramet er: it is a point er
t o an array.
5 LIGHT ING 36
Paramet er Meaning Default
GL_DI FFUSE diff use colour of mat erial (0.8, 0.8, 0.8, 1.0)
GL_AMBI ENT ambient colour of mat erial (0.2, 0.2, 0.2, 1.0)
GL_AMBI ENT_AND_DI FFUSE ambient and diff use
GL_SPECULAR specular colour of mat erial (0.0, 0.0, 0.0, 1.0)
GL_SHI NI NESS specular exponent 0.0
GL_EMI SSI ON emissive colour of mat erial (0.0.0, 0.0, 1.0)
Table 6: Paramet ers for gl Mat er i al f v( )
The first column of Table 6 shows t he paramet er names accept ed by gl Mat er i al f v( ) ; t he
second column describes t he meaning of t he paramet er; and t he t hird column shows t he value
t hat will be provided if you do not call gl Mat er i al f v( ) .
The diff use colour of an object is it s colour when it is direct ly illuminat ed; it is what we
normally mean when we say, for example, “t he book is blue”. The ambient colour of an
object is it s colour when it is illuminat ed by t he ambient (or “background”) light in t he scene.
For most object s, t he diff use and ambient colours are almost t he same. For t his reason,
OpenGL provides t he paramet er name GL_AMBI ENT_AND_DI FFUSEwhich set s t he ambient and
diff use colours t o t he same value.
The specular colour of an object produces highlight s when t he object is direct ly illuminat ed.
Smoot h, polished surfaces give specular reflect ions but dull, mat t e object s do not . Specular
highlight s usually have t he colour of t he light source, rat her t han t he object ; consequent ly, if
a specular colour is defined, it is usually whit e.
The specular exponent det ermines t he smoot hness of a specular surface. It s value must be
between 0.0 and 128.0. A low value gives a large, dull highlight , and a high value gives a
small, bright highlight .
Define an emissive colour for an object if it is emit t ing light . For example, a light bulb in your
model would have an emissive colour of whit e or almost whit e. Defining an emissive colour
does not make t he object a source of light : you must put a light source at t he same posit ion
in t he scene t o provide t he light .
Figure 28 shows some examples of t he use of gl Mat er i al f v( ) . Propert ies do not aut omat i-
cally revert t o t heir default s: if you want t o rest ore a default value, you must do so explicit ly.
For example, t he shininess of t he dark blue sphere must be t urned off before drawing t he dull
red cube.
5.4 Defining t he Light s
To use light ing, you must first enable it by calling gl Enabl e( GL_LI GHTI NG) . You must also
enable each light t hat you want t o use. OpenGL provides eight light s, named GL_LI GHT0
t hrough GL_LI GHT7. To enable light n, call gl Enabl e( GL_LI GHTn) .
The funct ion gl Li ght f v( ) specifies t he propert ies of a light and is used in t he same way
as gl Mat er i al f v( ) . There are t hree argument s: t he first specifies a light , t he second is a
5 LIGHT ING 37
/ * Dat a decl ar at i ons */
GLf l oat of f [ ] = { 0. 0, 0. 0, 0. 0, 0. 0 };
GLf l oat whi t e[ ] = { 1. 0, 1. 0, 1. 0, 1. 0 };
GLf l oat r ed[ ] = { 1. 0, 0. 0, 0. 0, 1. 0 };
GLf l oat deep_bl ue[ ] = { 0. 1, 0. 5, 0. 8, 1. 0 };
GLf l oat s hi ny[ ] = { 50. 0 };
GLf l oat dul l [ ] = { 0. 0; }
/ * Dr aw a s mal l , dar k bl ue s pher e wi t h s hi ny hi ghl i ght s */
gl Mat er i al f v( GL_FRONT, GL_AMBI ENT_AND_DI FFUSE, deep_bl ue) ;
gl Mat er i al f v( GL_FRONT, GL_SPECULAR, whi t e) ;
gl Mat er i al f v( GL_FRONT, GL_SHI NI NESS, s hi ny) ;
gl ut Sol i dSpher e( 0. 2, 10, 10) ;
/ * Dr aw a l ar ge, r ed cube made of non- r ef l ect i ve mat er i al */
gl Mat er i al f v( GL_FRONT, GL_AMBI ENT_AND_DI FFUSE, r ed) ;
gl Mat er i al f v( GL_FRONT, GL_SPECULAR, of f ) ;
gl Mat er i al f v( GL_FRONT, GL_SHI NI NESS, dul l ) ;
gl ut Sol i dCube( 10. 0) ;
/ * Dr aw a whi t e, gl owi ng s pher e */
gl Mat er i al f v( GL_FRONT, GL_AMBI ENT_AND_DI FFUSE, of f ) ;
gl Mat er i al f v( GL_FRONT, GL_SPECULAR, of f ) ;
gl Mat er i al f v( GL_FRONT, GL_SHI NI NESS, dul l ) ;
gl Mat er i al f v{GL_FRONT, GL_EMI SSI ON, whi t e) ;
gl ut Sol i dSpher e( 10. 0, 20, 20) ;
Figure 28: Using gl Mat er i al ( )
paramet er name, and t he t hird is a value for t hat paramet er. Table 7 shows t he paramet er
names and t heir default values.
The diff use colour is t he colour of t he direct ional light t hat appears t o come from t he light
it self. It is t he colour t hat we normally associat e wit h t he light . The default is bright whit e.
The ambient colour is t he cont ribut ion t hat t he light makes t o t he ambient colour of t he
scene. Since ambient light pervades t he scene, wit hout appearing t o come from any part icular
direct ion, t he default value is black.
The specular colour is t he colour given t o highlight s in specular object s t hat are illuminat ed by
t his light . It is usually t he same as t he diff use colour. For example, a brown bot t le illuminat ed
by a whit e light has whit e highlight s.
The posit ion of t he light can be specified in two ways: if t he fourt h component of t he vect or
is 0, t he light is called directional and t he eff ect is t hat of a light source infinit ely far way. If
t he fourt h component is 1, t he light source is called positional and t he eff ect is t hat of a light
at t he corresponding point .
For example: t he vect or (−1, 1, 0, 0) is a light source at t he left of t he scene (x = −1); above
it (y = 1); infinit ely far away and hence direct ional (w = 0). This vect or would be suit able
5 LIGHT ING 38
Paramet er Meaning Default
GL_DI FFUSE diff use colour (1.0, 1.0, 1.0, 1.0)
GL_AMBI ENT ambient colour (0.0, 0.0, 0.0, 1.0)
GL_SPECULAR specular colour (1.0, 1.0, 1.0, 1.0)
GL_POSI TI ON posit ion (0.0, 0.0, 1.0, 0.0)
GL_CONSTANT ATTENUATI ON const ant at t enuat ion 1.0
GL_LI NEAR_ATTENUATI ON linear at t enuat ion 0.0
GL_QUADRATI C_ATTENUATI ON quadrat ic at t enuat ion 0.0
GL_SPOT_DI RECTI ON direct ion of spot light (0.0, 0.0, −1.0)
GL_SPOT_CUTOFF cut off angle of spot light 180.0
GL_SPOT_EXPONENT exponent of spot light 0.0
Table 7: Paramet ers for gl Li ght f v( )
for sunlight .
The vect or (0, 1, −5, 1) is a light source at t he t op cent re (x = 0, y = 1) of t he scene; behind
it (z = −5); and at a finit e dist ance (w = 1). This vect or would be suit able for an overhead
light in a room.
Direct ional light ing requires less comput at ion t han posit ional light ing because t here are fewer
angles t o calculat e.
In t he real world, t he int ensity of a light decreases wit h dist ance. OpenGL calls t his decrease
“at t enuat ion”. There is no at t enuat ion for a direct ional light because it is infinit ely far away.
OpenGL at t enuat es a posit ional light source by mult iplying t he int ensity of t he light by
1
C + L d + Q d
2
where C is t he const ant at t enuat ion fact or, L is t he linear at t enuat ion fact or, Q is t he
quadrat ic at t enuat ion fact or, and d is t he dist ance between t he light and t he object . The
default values are C = 1 and L = Q = 0. Including linear and/ or quadrat ic at t enuat ion
fact ors increases t he realism of t he scene at t he expense of ext ra comput at ion.
By default , a light radiat es in all direct ions. A spotlight radiat es a cone of light in a part icular
direct ion. Obviously, a direct ional light cannot be a spot light . To t urn a posit ional light int o
a spot light , provide t he following values:
• GL_SPOT_DI RECTI ONdet ermines t he direct ion in which t he spot light is point ing.
• GL_SPOT_CUTOFF det ermines t he “spread” of t he light . It is t he angle between t he axis
of t he cone and t he edge of t he light beam. The default value, 180

, corresponds t o
an omni-direct ional light (i.e. not a spot light ). If t he angle is not 180

, it must be
between 0

and 90

. The angle 5

gives a highly-focused searchlight eff ect ; t he angle
90

illuminat es anyt hing in front of t he light but not hing behind it .
• GL_SPOT_EXPONENT det ermines how t he light varies from t he axis t o t he edges of t he
cone. The default value, 0.0, gives uniform light across t he cone; a higher value focuses
t he light t owards t he cent re of t he cone.
5 LIGHT ING 39
Paramet er Meaning Default
GL_LI GHT_MODEL_AMBI ENT ambient light int ensity (0.2, 0.2, 0.2, 1.0)
GL_LI GHT_MODEL_LOCAL_VI EWER simulat e a close viewpoint GL_FALSE
GL_LI GHT_MODEL_TWO_SI DE select two-sided light ing GL_FALSE
Table 8: Paramet ers for gl Li ght Model ( )
5.5 Defining a Light ing Model
The funct ion gl Li ght Model ( ) defines a light ing model. The first argument is a paramet er
name and t he second argument is a value for t hat paramet er. Table 8 shows t he possible
paramet er names, t heir meanings, and t heir default values.
The ambient light int ensity det ermines t he colour of t he light t hat pervades t he scene, inde-
pendent ly of any act ual light s. It s default value, dark grey, ensures t hat you will see somet hing
even if your light s are not swit ched on or are point ing in t he wrong direct ion. In reality, most
scenes do have a cert ain amount of ambient light . For example, a sunlit scene is illuminat ed
not only by t he sun (direct ional and bright yellow) but also by t he sky (ambient and light
blue). Dark greenish-blue ambient light would be suit able for an underwat er scene. For special
applicat ions, such as deep space scenes, set t he ambient light t o black.
By default , OpenGL calculat es specular reflect ions wit h t he assumpt ion t hat t he scene is
being viewed from infinit ely far away. Specifying a local viewer by giving t he value GL_TRUE
provides more realist ic result s but requires a considerable amount of addit ional comput at ion.
By default , OpenGL illuminat es only t he front sides of polygons. (This is t rue even if you
have defined mat erial propert ies for bot h sides of your polygons.) In many cases, t he back
sides of polygons are invisible anyway. For example, t he back sides of t he polygons of a sphere
face t he inside of t he sphere. Specifying two-sided illuminat ion by giving t he value GL_TRUE
t ells OpenGL t o illuminat e any face of a polygon t hat is visible, at t he expense of addit ional
comput at ion.
5.6 Put t ing It All Toget her
It is usually best t o build a lit scene increment ally. St art by enabling light ing and t urning on
a light :
gl Enabl e( GL_LI GHTI NG) ;
gl Enabl e( GL_LI GHT0) ;
At t his point , you are using default values for t he propert ies of t he object s in your model
and t he light s. Next , add st at ement s t hat provide explicit values when t he default s are not
suit able. You will probably want t o st art by posit ioning your light (or light s) and t hen defining
t he surface propert ies of your object s. Some int eract ions may be surprising, alt hough t hey
are realist ic. For example, a green object will appear black (and t herefore invisible) in red
light .
Point s t o not e:
5 LIGHT ING 40
1 GLf l oat di r [ ] = { 0. 0, 0. 0, 1. 0, 0. 0 };
2 GLf l oat pos [ ] = { 0. 0, 0. 0, 0. 0, 1. 0 };
3 GLf l oat s un_col [ ] = { 1. 0, 1. 0, 0. 6, 0. 0 };
4
5 voi d di s pl ay ( voi d)
6 {
7 gl Cl ear ( GL_COLOR_BUFFER_BI T | GL_DEPTH_BUFFER_BI T) ;
8 gl Mat r i xMode( GL_MODELVI EW) ;
9 gl LoadI dent i t y( ) ;
10 gl Li ght f v( GL_LI GHT0, GL_POSI TI ON, di r ) ;
11 gl Tr ans l at ef ( 0. 0, 0. 0, - di s t ) ;
12 gl Mat er i al f v( GL_FRONT, GL_AMBI ENT_AND_DI FFUSE, s un_col ) ;
13 gl ut Sol i dSpher e( 0. 4, 40, 40) ;
14 gl Li ght f v( GL_LI GHT0, GL_POSI TI ON, pos ) ;
15 . . . . .
16 }
Figure 29: Illuminat ing t he sun
• Remember t hat OpenGL is a st at e machine. Once a call has been execut ed, it s eff ect s
remain unt il undone. For example, if you have a number of object s and you make t he
first one red, all t he ot hers will be red unless you explicit ly say ot herwise.
• If your light s do not move, you can set t hem up during init ializat ion. If you want moving
light s, t he calls t hat set posit ion must be in your di s pl ay( ) callback funct ion. Usually,
you will set light posit ions aft er choosing t he viewpoint (e.g. wit h gl uLookAt ( ) ) and
before making any ot her t ransformat ions.
• OpenGL has a rat her simple view of illuminat ion. It does not comput e shadows and it
does not recognize object s as obst acles in t he light pat hs. If you const ruct a “solar sys-
t em” consist ing of a sun, a planet , and a moon, t he planet and it s moon are illuminat ed
by t he sun, but t he moon does not disappear when t he planet is between it and t he sun
(lunar eclipse) and it does not t hrow a shadow on t he planet (solar eclipse).
• An object which is a light source must be lit twice: once t o make it visible and once t o
make it act as a light source. The code in Figure 29 demonst rat es how t o do t his. Line
10 int roduces a direct ional light source on t he Z axis t o illuminat e t he sun. Line 11 is
a t ranslat ion t hat moves t he sun int o t he viewing volume. Lines 12 and 13 define t he
propert ies of t he sun and display it as a solid sphere. Line 14 moves t he light source t o
t he cent re of t he sun so t hat it will illuminat e t he planet s and sat ellit es drawn in lines
15ff .
6 ODDS AND ENDS 41
6 Odds and Ends
6.1 Menus
GLUT provides menus. The format of menus is rest rict ed but t he funct ions are easy t o use.
Follow t he st eps below t o define a menu wit hout submenus.
1. Call gl ut Cr eat eMenu( f unc) t o creat e t he menu. f unc is t he name of a funct ion t hat
will handle menu-select ion event s (see it em 4 below).
2. Call gl ut AddMenuEnt r y( s t r i ng, num) for each menu it em. s t r i ng is t he st ring t hat
will be displayed in t he menu. numis a const ant t hat will be ret urned by t he callback
funct ion when t he user select s t his it em. You must ensure t hat all select ions have
diff erent values.
3. Call gl ut At t achMenu( but t on) t o “at t ach” t he menu t o a mouse but t on. but t on should
be one of GLUT_LEFT_BUTTON, GLUT_MI DDLE_BUTTON, or GLUT_RI GHT_BUTTON.
4. Writ e t he callback funct ion for t he menu. This funct ion has one int eger argument and
ret urns not hing. The value passed t o it will be one of t he const ant s t hat you chose in
st ep 2.
Figure 30 shows an example of t he code required for a simple menu. The init ializat ion func-
t ion i ni t i al i ze menu( ) must be called explicit ly by t he applicat ion program. The callback
funct ion choos e col our ( ) is not called by t he program but will be called by GLUT when t he
user has invked t he menu by pressing t he right mouse but t on and has made a select ion from
t he menu.
Follow t he st eps below t o obt ain menus wit h submenus.
1. To creat e a submenu, call gl ut Cr eat eMenu( ) as before. This t ime, however, you should
keep a copy of t he int eger t hat it ret urns. Suppose, for example, t hat you writ e
i nt s ub1 = gl ut Cr eat eMenu( get _key) ;
2. Complet e t he submenu wit h calls t o gl ut AddMenuEnt r y( ) , but do not at t ach it t o a
but t on.
3. Writ e code for t he main menu aft er t he submenus. (That is, build t he menu “t ree”
bot t om-up.) To add a submenu t o t he main menu, call gl ut AddSubMenu( s t r i ng, num) .
s t r i ng is t he t ext t hat appears in t he main menu t o ident ify t he submenu and numis
t he value ret urned by gl ut Cr eat eMenu( ) in t he first st ep.
Not e t hat t he main menu can cont ain bot h simple ent ries (added wit h gl ut AddMenuEnt r y( ) )
and submenus (added wit h gl ut AddSubMenu( ) ).
6.2 Text
OpenGL provides two kinds of charact ers: bit -mapped charact ers and st roked charact ers.
6 ODDS AND ENDS 42
#def i ne M_RED 20
#def i ne M_GREEN 21
#def i ne M_BLUE 22
voi d choos e_col our ( i nt s el )
{
s wi t ch ( s el )
{
cas e M_RED:
/ * Act i on f or r ed s el ect i on. */
br eak;
cas e M_GREEN:
/ * Act i on f or gr een s el ect i on. */
br eak;
cas e M_BLUE:
/ * Act i on f or bl ue s el ect i on. */
br eak;
def aul t :
br eak;
}
}
voi d i ni t i al i ze_menu ( voi d)
{
gl ut Cr eat eMenu( choos e_col our ) ;
gl ut AddMenuEnt r y( "Red", M_RED) ;
gl ut AddMenuEnt r y( "Gr een", M_GREEN) ;
gl ut AddMenuEnt r y( "Bl ue", M_BLUE) ;
gl ut AddMenuEnt r y( "Qui t ", M_QUI T) ;
gl ut At t achMenu( GLUT_RI GHT_BUTTON) ;
}
Figure 30: Code for a simple menu
6.2.1 Bit mapped Charact ers
Bit mapped charact ers, as t heir name implies, are bit maps t hat are displayed on t he screen
wit hout scaling or rot at ion. The size of each charact er is det ermined by t he size of pixels on
t he screen, and is fixed. Two st eps are necessary t o display a bit mapped charact er: first , set
t he rast er posit ion for t he charact er; t hen display t he charact er.
The call
gl Ras t er Pos 2f }( x, y)
set s t he rast er posit ion t o t he point (x, y). Any t ransformat ions current ly in eff ect are applied
t o t he coordinat es x and y. Aft er execut ing t he following code, for example, t he rast er posit ion
is (4, 6):
6 ODDS AND ENDS 43
voi d di s pl ay_s t r i ng ( i nt x, i nt y, char *s t r i ng)
{
i nt l en, i ;
gl Ras t er Pos 2f ( x, y) ;
l en = s t r l en( s t r i ng) ;
f or ( i = 0; i < l en; i ++)
{
gl ut Bi t mapChar act er ( GLUT_BI TMAP_TI MES_ROMAN_24, s t r i ng[ i ] ) ;
}
}
Figure 31: Displaying a st ring of t ext
gl Mat r i xMode( GL_MODEL_VI EW) ;
gl LoadI dent i t y( ) ;
gl Tr ans l at ef ( 3. 0, 5. 0) ;
gl Ras t er Pos 2f ( 1. 0, 1. 0) ;
The call
gl ut Bi t mapChar act er ( GLUT_BI TMAP_9_BY_15, ’ z’ ) ;
displays t he charact er ‘z’ in a 9 15 pixel, fixed-widt h font at t he current rast er posit ion,
and t hen moves t he rast er posit ion right one charact er-widt h. Thus we can display a st ring
wit hout having t o change t he rast er posit ion aft er each charact er. Figure 31 shows a simple
funct ion t hat you can use t o display a st ring of t ext at a given posit ion. Table 9 on page 62
shows t he available bit mapped font s.
If t he t ext does not appear on t he screen, it is probably not in t he viewing volume. If t here
are no t ranslat ions in t he Z direct ion, t he t ext lies in t he plane Z = 0, which is not in
t he viewing volume of a perspect ive t ransformat ion. One way t o fix t his problem is t o call
gl Ras t er Pos 3f ( x, y, z) .
Bit mapped t ext can be t ricky t o use because t here is no obvious relat ion between model
coordinat es and screen coordinat es. It is somet imes a good idea t o display t ext before applying
any model view t ransformat ions (t hat is, immediat ely aft er gl LoadI dent i t y( ) in t he display
funct ion). If you have several lines of t ext , you will have t o comput e t he line separat ion
using t he window height (in pixels) and t he range of Y values defined by your project ion
t ransformat ion.
6.2.2 St roked Charact ers
St roked charact ers are t rue object s t hat can be scaled, t ranslat ed, and rot at ed. The call
gl ut St r okeChar act er ( f ont , c) ;
displays t he charact er wit h ASCII code c in t he given font at t he current posit ion (t hat
is, aft er applying t he t ransformat ions current ly in eff ect t o t he point (0, 0, 0)). The font s
6 ODDS AND ENDS 44
available are GLUT_MONO_ROMAN(fixed widt h) and GLUT_STROKE_ROMAN(proport ional widt h).
Since charact ers are about 120 unit s high, you will usually want t o scale t hem.
The following program illust rat es t he use of st roked font s. It reads charact ers from t he
keyboard, st ores t hem in a st ring, and cont inuously rot at es t he st ring in t he viewing window.
#i ncl ude <GL/ gl ut . h>
#def i ne LEN 50
#def i ne HEI GHT 600
#def i ne WI DTH 800
f l oat angl e = 0. 0;
char buf f er [ LEN] ;
i nt l en;
voi d di s pl ay ( voi d)
{
char *p;
gl Cl ear ( GL_COLOR_BUFFER_BI T) ;
gl Mat r i xMode( GL_MODELVI EW) ;
gl LoadI dent i t y( ) ;
gl Rot at ef ( angl e, 0. 0, 1. 0, 0. 0) ;
gl Tr ans l at ef ( - 400. 0, 0. 0, 0. 0) ;
gl Col or 3f ( 1. 0, 1. 0, 0. 0) ;
f or ( p = buf f er ; *p; p++)
gl ut St r okeChar act er ( GLUT_STROKE_ROMAN, *p) ;
gl ut SwapBuf f er s ( ) ;
}
voi d keys ( uns i gned char key, i nt x, i nt y)
{
i f ( key == 27)
exi t ( 0) ;
el s e i f ( l en < LEN - 1)
{
buf f er [ l en++] = key;
gl ut Pos t Redi s pl ay( ) ;
}
}
voi d s pi n ( voi d)
{
angl e += 2. 0;
gl ut Pos t Redi s pl ay( ) ;
}
i nt mai n( i nt ar gc, char **ar gv)
{
6 ODDS AND ENDS 45
gl ut I ni t ( &ar gc, ar gv) ;
gl ut I ni t Di s pl ayMode( GLUT_DOUBLE | GLUT_RGB) ;
gl ut I ni t Wi ndowSi ze( WI DTH, HEI GHT) ;
gl ut Cr eat eWi ndow( "Ent er your name. ESC t o qui t . ") ;
gl Li neWi dt h( 3. 0) ;
gl ut Di s pl ayFunc( di s pl ay) ;
gl ut Keyboar dFunc( keys ) ;
gl ut I dl eFunc( s pi n) ;
f or ( l en = 0; l en < LEN; l en++)
buf f er [ l en] = ’ \ 0’ ;
l en = 0;
gl ut Mai nLoop( ) ;
}
6.3 Special Object s
The GLUT library provides several object s t hat are rat her t edious t o build. These object s
are fully defined, wit h normals, and t hey are useful for experiment ing wit h light ing. Their
prot otypes are list ed below.
A “wire” object displays as a wire frame; t his is not very pret ty but may be useful during
debugging. A “solid” object looks like a solid, but you should define it s mat erial propert ies
yourself, as described in Figure 5.3.
For a sphere, “slices” are lines of longit ude and “st acks” are lines of lat it ude. Cones are
analogous. For a t orus, “sides” run around t he t orus and “rings” run around t he “t ube”.
voi d gl ut Wi r eSpher e ( doubl e r adi us , i nt s l i ces , i nt s t acks ) ;
voi d gl ut Sol i dSpher e ( doubl e r adi us , i nt s l i ces , i nt s t acks ) ;
voi d gl ut Wi r eCube ( doubl e s i ze) ;
voi d gl ut Sol i dCube ( doubl e s i ze) ;
voi d gl ut Wi r eTor us ( doubl e i nner , doubl e out er , i nt s i des , i nt r i ngs ) ;
voi d gl ut Sol i dTor us ( doubl e i nner , doubl e out er , i nt s i des , i nt r i ngs ) ;
voi d gl ut Wi r eI cos ahedr on ( voi d) ;
voi d gl ut Sol i dI cos ahedr on ( voi d) ;
voi d gl ut Wi r eOct ahedr on ( voi d) ;
voi d gl ut Sol i dOct ahedr on ( voi d) ;
voi d gl ut Wi r eTet r ahedr on ( voi d) ;
voi d gl ut Sol i dTet r ahedr on ( voi d) ;
voi d gl ut Wi r eDodecahedr on ( voi d) ;
voi d gl ut Sol i dDodecahedr on ( voi d) ;
voi d gl ut Wi r eCone ( doubl e r adi us , doubl e hei ght , i nt s l i ces , i nt s t acks ) ;
voi d gl ut Sol i dCone ( doubl e r adi us , doubl e hei ght , i nt s l i ces , i nt s t acks ) ;
voi d gl ut Wi r eTeapot ( doubl e s i ze) ;
voi d gl ut Sol i dTeapot ( doubl e s i ze) ;
6.4 Programming Hint s
Program Development . The recommended way of developing a program is writ e a spec-
ificat ion and a design before st art ing t o code. This works well if you know exact ly what you
6 ODDS AND ENDS 46
want t o do and have accurat e knowledge about t he capabilit ies and limit at ions of t he syst ems
on which your program is going t o run. When you are writ ing your first graphics programs,
you may not know precisely what you want t o do or whet her you will be able t o do it . In t his
sit uat ion, increment al development may be t he best st rat egy.
The idea is t o develop t he program in small st eps, ensuring t hat you have somet hing working
at each st ep. In choosing t he next st ep, ask yourself what is most likely t o go wrong. This
st rat egy makes it less likely t hat you will complet e 90% of your graphics project , only t o
discover t he fat al flaw t hat makes it unworkable.
The following examples illust rat e t he increment al development of some hypot het ical programs.
• Your applicat ion is supposed t o show an aircraft performing aerobat ics. There are two
problems here: modelling t he aircraft and displaying complex mot ions. Since t he second
is harder, t he first st ep might be t o make a very simple object , such as a wire cube,
perform aerobat ics. When t he mot ions are sat isfact ory, replace t he cube by a plane.
• Your applicat ion supposed t o show a number of moving object s, such as pool balls in a
simulat ed game of pool. The following increment s might be used: display a st at ionary
ball; display a moving ball; display a moving ball t hat bounces off t he rails at t he sides
of a t able; display two moving balls t hat collide realist ically; display fift een (or as many
as required) moving, colliding balls.
• Your applicat ion is supposed t o show an aquarium full of fish wit h various sizes and
colours swimming around. Check first of all t hat you can model a single, grey fish and
make it swim convincingly. Then design ot her fish wit h diff erent shapes and colours. It
may be possible t o obt ain some shapes simply by scaling t he original fish.
Team Project s. Working on a graphics project wit h a t eam can be a rewarding experience
because a t eam can achieve significant ly more t han an individual in a given amount of t ime.
The problem t hat is most likely t o arise wit h a t eam project is int egrat ion failure: t eam
members build component s of t he project t hat work well individually, but fail when put
t oget her.
OpenGL is a “st at e machine” wit h a very large number of possible st at es: almost every
funct ion changes it s st at e in one way or anot her. Consequent ly, OpenGL programs are prone
t o int egrat ion failure because one component of t he program will put OpenGL int o a st at e
t hat ot her component s do not expect .
The best way t o avoid int egrat ion failure is t o build a simplified version of t he complet e syst em
at a very early st age. The first version will cont ain each component in a minimal form. As
each component is developed, enhanced versions are incorporat ed int o t he syst em and t he
syst em is t est ed. It may be wort hwhile t o give one of t he members of t he t eam t he job of
maint aining t he syst em while it s component s are being const ruct ed.
Debugging Debugging a graphics program is quit e diff erent from debugging ot her kinds of
program. Convent ional debugging t ools may not be very helpful, but t he mere appearance of
t he image may provide import ant informat ion t hat is not usually available.
6 ODDS AND ENDS 47
voi d check_er r or ( )
{
GLenum er r or _code = gl Get Er r or ( ) ;
i f ( er r or _code ! = GL_NO_ERROR)
pr i nt f ( "GL er r or : %s . \ n", gl uEr r or St r i ng( er r or _code) ) ;
}
Figure 32: Obt aining and report ing OpenGL errors
• A common and frust rat ing problem is a blank screen. The usual cause is t hat your model
is out side t he viewing volume. Try removing t ransformat ions (especially gl uLookAt ( ) )
or changing t hem; add an idle callback funct ion, if you haven’t already got one, so t hat
you can make t he image change cont inuously in various ways; t ry running t he program
wit h and wit hout light ing.
• Check t hat you have included everyt hing needed t o obt ain t he eff ect you want . For
example, for hidden surface eliminat ion, you must init ialize correct ly, and enable t he
dept h t est , and clear t he dept h buff er bit (Sect ion 3.5).
• If illuminat ed surfaces look st range, you may have comput ed t he normals incorrect ly
(Sect ion 5.2). One way t o check t his is t o plot t he normals by drawing a line from each
grid-point of t he surface in t he direct ion of t he normal at t hat point .
• In most development environment s, t he OpenGL program will have access t o a t ext
window (s t dout ) and t he graphics window. You can find out what is going on by using
pr i nt f ( ) st at ement s t o writ e in t he t ext window.
• OpenGL may det ect errors, but it does not report t hem unless you ask it t o do so. If an
error is det ect ed in a part icular command, t hat command has no eff ect . Figure 32 shows
a funct ion t hat checks for errors and displays t hem in your command-line window. By
calling t his funct ion from various places in your code you can discover what OpenGL is
doing or failing t o do.
Effi ciency Don’t invest a lot of t ime and eff ort int o making your program effi cient unt il you
know you have t o do so. If effi ciency is import ant for your applicat ion, put your eff ort int o
t he display callback funct ion, because t his funct ion usually has t he most significant eff ect on
t he performance of your program.
The performance of OpenGL programs depends on t he plat form t hey are running on. Perfor-
mance is aff ect ed by many fact ors, but is st rongly dependent on processor speed and graphics
cont roller capabilit ies. OpenGL programs usually run well on SGI machines, because t hese
machines use hardware t o implement low-level operat ions such as dept h-buff er comparison
and polygon shading. But it is nevert heless a mist ake t o ignore performance issues when
using anot her plat form on t he grounds t hat “it will be fast enough on SGI”.
Graphics programming oft en involves a t rade-off between det ail in t he image and speed of
t he animat ion. Roughly speaking, you can have a very det ailed image or fast animat ion, but
not bot h. Consider t his when using increment al development as described above: a cube t hat
performs elegant aerobat ics is small consolat ion if your airplane flies like a snail.
6 ODDS AND ENDS 48
Every feat ures t hat you add t o an OpenGL program will probably slow it down slight ly.
Normals, illuminat ion, t ext ures, reflect ions, shadows, and fog all cont ribut e t o t he appearance
of t he finished pict ure, but t hey all t ake t ime t o comput e. If you want fast movement , you
may have t o simplify appearance.
Advanced Feat ures This int roduct ory manual does not discuss many of t he most int er-
est ing feat ures of OpenGL. Once you have mast ered t he basic principles of OpenGL pro-
gramming, however, you should not find it hard t o learn ot her feat ures from a book such as
OpenGL Programming Guide.
Some feat ures, such as display list s, do not int roduce new capabilit ies, but provide improved
performance. Ot hers, such as clipping planes and st encils, may be used bot h t o enhance
bot h capability and performance. Alt hough OpenGL does not provide direct support for
shadows and reflect ions, it provides facilit ies t hat simplify t heir implement at ion. You can
build models by providing set s of point s, or by using t esselat ors and evaluat ors. You can use
t he accumulat ion buff er for ant ialiasing, blurring, dept h of field simulat ion, and jit t ering.
All you need is t ime and imaginat ion.
A SPACES AND T RANSFORMAT IONS 49
A Spaces and Transformat ions
We could build build graphical models and view t hem in a single coordinat e frame, but t his
would be very t edious. Inst ead, we work wit h many coordinat e frames (or “reference syst ems”)
and move between t hem by using t ransformat ions. In t he following examples, we move from
a frame (x, y, z ) t o a new frame (x

, y

, z

).
• Move t he origin t o (a, b, c).
x

= x −a
y

= y −b
z

= z −c
• Rot at e t he frame about t he z axis t hrough an angle θ .
x

= x cos θ −y sin θ
y

= x sin θ + y cos θ
z

= z
• Scale t he axes by fact ors r, s, and t .
x

= r x
y

= s y
z

= t z
If M = m
ij
is a 3 3 mat rix, we have

m
11
m
12
m
13
m
21
m
22
m
23
m
31
m
32
m
33
¸
¸
¸
¸

x
y
z
¸
¸
¸
¸
=

m
11
x + m
12
y + m
13
z
m
21
x + m
22
y + m
23
z
m
31
x + m
32
y + m
33
z
¸
¸
¸
¸
which shows t hat we can represent a scaling or rot at ion, but not a t ranslat ion, using a 3 3
mat rix.
The solut ion is t o use 4 4 mat rices. We can view t his as an algebraic t rick, but t here is
a mat hemat ical just ificat ion t hat we present briefly in Sect ion A.1. For det ails, consult t he
Appendix of Computer Graphics: Principles and Practice, by Foley and van Dam.
A.1 Scalar, Vect or, Affi ne, and Euclidean Spaces
Scalar Space An element of a scalar space is just a real number. The familiar operat ions
(add, subt ract , mult iply, and divide) are defined for real numbers and t hey obey familiar laws
such as commut at ion, associat ion, dist ribut ion, et c. (In t he following, we will use lower-case
Greek let t ers (α , β , γ , . . .) t o denot e scalars.)
A SPACES AND T RANSFORMAT IONS 50
Vect or Space A vect or space is a collect ion of vect ors t hat obey cert ain laws. (We will use
bold lower-case Roman let t ers (u, v, w, . . .) t o denot e vect ors.)
We can add vect ors (not at ion: u + v); vect or addit ion is commut at ive and associat ive. Vect or
subt ract ion (not at ion: u −v) is t he inverse of addit ion. For any vect or v, we have v −v = 0,
t he unique zero vector.
We can also mult iply a vect or by a scalar (not at ion: α v). The result is a vect or and we have
laws such as α (β v) = (α β ) v, α (u + v) = α u + α v, . . ..
We say t hat a set , U, of vect ors spans a vect or space V if every vect or in V can be writ t en as
in t he form α
1
u
1
+ α
2
u
2
+ + α
n
u
n
wit h u
1
∈ U, . . . , u
n
∈ U. The dimension of a vect or
space is t he number of vect ors in it s smallest spanning set . We can represent every vect or in
a n-dimensional vect or space as a t uple of n real numbers. For example, in a 3-dimensional
vect or space, every vect or can be writ t en as (x, y, z ) where x, y, and z are real numbers.
The zero vect or plays a special role in a vect or space: it defines an origin. We cannot move
t he origin, and we cannot t ranslat e a vect or. The only operat ions we can perform on vect ors
are scaling and rot at ion. This is just t he limit at ion we found wit h 3 3 mat rices above.
Affi ne Space An affi ne space, like a vect or space, cont ains scalars and vect ors wit h t he
same operat ions and laws. An affi ne space also cont ains point s (not at ion: P, Q, . . .). Point s
appear in two operat ions:
1. The difference between two point s P and Q is a vect or (not at ion: P −Q).
2. The sum of a point P and a vect or v is a point (not at ion: P + v).
Given a scalar α and point s P, Q, t he expression P + α (Q−P) is called t he affine combination
of the points P and Q by α . To underst and t his expression, not e t hat : P and Q are point s;
Q − P is t he diff erence between two point s, and hence a vect or; α (Q − P) is a scalar t imes
a vect or, and hence a vect or; P + α (Q −P) is t he sum of a point and a vect or, and hence a
point .
If α = 0, t hen P + α (Q−P) simplifies t o P + 0 = P. If α = 1, t hen P + α (Q−P) simplifies t o
P + (Q −P) = Q. (This reduct ion can be derived from t he axioms of an affi ne space, which
we have not given here. Int uit ively, Q −P is an arrow (vect or) represent ing a t rip from Q t o
P; by adding t his vect or t o P, we get back t o Q.)
The set of point s ¦ P + α (Q−P) [ α ∈ {¦ is defined t o be a line in affi ne space. If 0 < α < 1,
t hen P + α (Q −P) is between P and Q.
Cont inuing in t his way, we can express many geomet rical propert ies in t erms of t he axioms of
an affi ne space. There is no absolut e scale (like inches or cent imet res) but we can represent
rat ios. An affine transformation is a t ransformat ion t hat preserves cert ain rat ios.
Represent at ion of an Affi ne Space We define a point t o be a t uple (x, y, z , 1) and a vect or
t o be a t uple (x, y, z , 0), wit h x, y, z ∈ {. Using component -wise addit ion and subt ract ion:
• (x, y, z , 1) −(x

, y

, z

, 1) = (x −x

, y −y

, z −z

, 0): t he diff erence between two point s is
a vect or;
A SPACES AND T RANSFORMAT IONS 51
• (x, y, z , 1) + (x

, y

, z

, 0) = (x + x

, y + y

, z + z

, 1): t he sum of a point and a vect or is a
point ; and
• (x, y, z , 0) ±(x

, y

, z

, 0) = (x ±x

, y ±y

, z ±z

, 0): t he sum or diff erence of vect ors is a
vect or.
It is possible t o show formally t hat t his represent at ion sat isfies t he axioms of an affi ne space.
The space represent ed is act ually a t hree-dimensional affine subspace of a four-dimensional
vect or space.
The advant age of t his represent at ion is t hat all of t he t ransformat ions t hat we need for graphics
can be expressed as 4 4 mat rices. In part icular, t he t ranslat ion t hat we could not do wit h
3 3 mat rices is now possible.

1 0 0 a
0 1 0 b
0 0 1 c
0 0 0 1
¸
¸
¸
¸
¸
¸
¸

x
y
z
1
¸
¸
¸
¸
¸
¸
¸
=

x + a
y + b
z + c
1
¸
¸
¸
¸
¸
¸
¸
In t his example and below, we writ e point s in t he affi ne space as 4 1 mat rices (column
mat rices), and a point is always t he second (or final) t erm in a product . In running t ext , we
writ e [x, y, z , 1]
T
(t ranspose of a 1 4 mat rix) for a 4 1 mat rix.
Euclidean Space We cannot make measurement s in an affi ne space. We int roduce dist ance
via inner product s. The inner product of vect ors u = [u
x
, u
y
, u
z
, 0]
T
and v = [v
x
, v
y
, v
z
, 0]
T
is
u v = u
x
v
x
+ u
y
v
y
+ u
z
v
z
The length of a vect or v is
|v| =

v v =

v
2
x
+ v
2
y
+ v
2
z
We define:
• The distance between two point s P and Q is |P −Q|.
• The angle α between two vect ors u and v is α where
cos α =
u v
|u| |v|
If u v = 0, t hen cos α = 0 and α = 90

and t he vect ors u and v are ort hogonal.
A space in which we can measure dist ances and angles in t his way is called a Euclidean space.
Defining measurement in ot her ways yields non-Euclidean spaces of various kinds.
A.2 Mat rix Transformat ions
We now have t he machinery required t o define t ransformat ions in t hree-dimensional Euclidean
space as 4 4 mat rices. The import ant t ransformat ions are summarized in Figure 33. The
ident ity t ransformat ion doesn’t change anyt hing; t ranslat ion moves t he origin t o t he point
[−t
x
, −t
y
, −t
z
, 1]
T
; scaling mult iplies x values by s
x
, et c; and t he rot at ions rot at e t he frame
count erclockwise t hrough an angle θ about t he given axis.
A SPACES AND T RANSFORMAT IONS 52

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
¸
¸
¸
¸
¸
¸
¸

1 0 0 t
x
0 1 0 t
y
0 0 1 t
z
0 0 0 1
¸
¸
¸
¸
¸
¸
¸

s
x
0 0 0
0 s
y
0 0
0 0 s
z
0
0 0 0 1
¸
¸
¸
¸
¸
¸
¸
Ident ity Translat ion Scale

1 0 0 0
0 cos θ −sin θ 0
0 sin θ cos θ 0
0 0 0 1
¸
¸
¸
¸
¸
¸
¸

cos θ 0 sin θ 0
0 1 0 0
−sin θ 0 cos θ 0
0 0 0 1
¸
¸
¸
¸
¸
¸
¸

cos θ −sin θ 0 0
sin θ cos θ 0 0
0 0 1 0
0 0 0 1
¸
¸
¸
¸
¸
¸
¸
Rot at ion θ
about X -axis
Rot at ion θ
about Y -axis
Rot at ion θ
about Z -axis
Figure 33: Basic t ransformat ions
A.3 Sequences of Transformat ions
If T
1
and T
2
are t ransformat ions expressed as mat rices, t hen t he mat rix product s T
1
T
2
and
T
2
T
1
are also t ransformat ions. In general, T
1
T
2
= T
2
T
1
, corresponding t o t he fact t hat
t ransformat ions do not commut e.
Consider a t ranslat ion d along t he X -axis and a rot at ion R about t he Z axis. Assume
T =

1 0 0 d
0 1 0 0
0 0 1 0
0 0 0 1
¸
¸
¸
¸
¸
¸
¸
and R =

cos θ −sin θ 0 0
sin θ cos θ 0 0
0 0 1 0
0 0 0 1
¸
¸
¸
¸
¸
¸
¸
Then we have
T R =

cos θ −sin θ 0 d
sin θ cos θ 0 0
0 0 1 0
0 0 0 1
¸
¸
¸
¸
¸
¸
¸
and RT =

cos θ −sin θ 0 d cos θ
sin θ cos θ 0 d sin θ
0 0 1 0
0 0 0 1
¸
¸
¸
¸
¸
¸
¸
Applying t hese t ransformat ions t o a point p = (x, y, z , 1), we obt ain:
T R p =

x cos θ −y sin θ + d
x sin θ + y cos θ
z
1
¸
¸
¸
¸
¸
¸
¸
and RT p =

x cos θ −y sin θ + d cos θ
x sin θ + y cos θ + d sin θ
z
1
¸
¸
¸
¸
¸
¸
¸
A SPACES AND T RANSFORMAT IONS 53

r
r
r
'
d
E'
z
E
c
y

T
c
y
T
E
P

P
screen
Figure 34: Perspect ive t ransformat ion
These result s show t hat T R is a rot at ion followed by a t ranslat ion and RT is a t ranslat ion
followed by a rot at ion. In ot her words, t he t ransformat ions are applied in t he opposit e order
t o t heir appearance in t he mat rix product . This is not surprising, because we can writ e T R p
as T (R p).
If we view t ransformat ions as operat ing on t he coordinat e syst em rat her t han point s, t he
sequence of operat ions is reversed. (Algebraically, t he reversal can be expressed by t he law
(T
1
T
2
)
−1
= T
−1
2
T
−1
1
.) We can t hink of t he t ransformat ion T R as first moving t o a new
coordinat e syst em t ranslat ed from t he original syst em, and t hen rot at ing t he new coordinat es.
Similarly, RT is viewed as first rot at ing t he coordinat e syst em and t hen t ranslat ing it . Wit h
t his viewpoint , t he sequence of mat rices in a composit ion of t ransformat ions corresponds t o
t he sequence of operat ions. It is also closer t o t he way t hat graphics software, such as OpenGL,
act ually works.
A.4 Viewing
In order t o view a t hree-dimensional object on a two-dimensional screen, we must project it .
The simplest kind of project ion simply ignores one coordinat e. For example, t he t ransforma-
t ion [x, y, z , 1]
T
→(x, y) provides a screen posit ion for each point by ignoring it s z coordinat e.
A project ion of t his kind is called an orthographic or parallel project ion.
Ort hographic project ions do not give a st rong sensat ion of dept h because t he size of an object
does not depend on it s dist ance from t he viewer. An ort hographic project ion simulat es a view
from an infinit e dist ance away.
Perspect ive t ransformat ions provide a bet t er sense of dept h by drawing dist ant object s wit h
reduced size. The size reduct ion is a nat ural consequence of viewing t he object from a finit e
dist ance. In Figure 34, E represent s t he eye of t he viewer viewing a screen. Concept ually, t he
model is behind t he screen. An object at P in t he model, for example, appears on t he screen
at t he point P

.
The point P in t he model is [x, y, z , 1]
T
. (The x value does not appear in t he diagram because
it is perpendicular t o t he paper.) The t ransformed coordinat es on t he screen are (x

, y

): t here
is no z coordinat e because t he screen has only two dimensions. By similar t riangles:
x

d
=
x
z + d
A SPACES AND T RANSFORMAT IONS 54
y

d
=
y
z + d
and hence
x

=
x d
z + d
y

=
y d
z + d
To obt ain t he perspect ive t ransformat ion in mat rix form, we not e t hat

1 0 0 0
0 1 0 0
0 0 1 0
0 0 1/ d 1
¸
¸
¸
¸
¸
¸
¸

x
y
z
1
¸
¸
¸
¸
¸
¸
¸
=

x
y
z
z / d + 1
¸
¸
¸
¸
¸
¸
¸
Unlike t he previous point s we have seen, t he t ransformed point has a fourt h coordinat e t hat
is not equal t o 1. Homogenizing t his point gives
¸
x d
z + d
,
y d
z + d
,
z d
z + d
, 1

T
, as we obt ained
above.
The z component has no obvious physical significance but t here are advant ages in ret aining
it . Since t ransformed z values depend monot onically on t he original z values, t he t ransformed
values can be used for hidden surface eliminat ion. Moreover, t he t ransformat ion can be
invert ed only if t he z informat ion is ret ained. This is necessary for t ransforming normal
vect ors and for select ing object s from a scene.
B T HEORY OF ILLUMINAT ION 55
B Theory of Illuminat ion
To obt ain realist ic images in comput er graphics, we need t o know not only about light but
also what happens when light is reflect ed from an object int o our eyes. The nat ure of t his
reflect ion det ermines t he appearance of t he object . The general problem is t o comput e t he
apparent colour at each pixel t hat corresponds t o part of t he object on t he screen.
B.1 St eps t o Realist ic Illuminat ion
We provide various t echniques for solving t his problem, increasing t he realism at each st ep. In
each case, we define t he intensity, I , of a pixel in t erms of a formula. The first few t echniques
ignore colour.
Technique # 1. We assume t hat each object has an intrinsic brightness k
i
. Then
I = k
i
This t echnique can be used for simple graphics, but it is clearly unsat isfact ory. There is no
at t empt t o model propert ies of t he light or it s eff ect on t he object s.
Technique # 2. We assume t hat t here is ambient light (light from all direct ions) wit h
int ensity I
a
and t hat each object has an ambient reflection coefficient k
a
. This gives
I = I
a
k
a
In pract ice, t he eff ect of t echnique # 2 is very similar t o t hat of t echnique # 1.
Technique # 3. We assume t hat t here is a single, point source of light and t hat t he object
has diffuse or Lambertian reflect ive propert ies. This means t hat t he light reflect ed from t he
object depends only on t he incidence angle of t he light , not t he direct ion of t he viewer.
More precisely, suppose t hat : N is a vect or normal t o t he surface of t he object ; L is a vect or
corresponding t o t he direct ion of t he light ; and V is a vect or corresponding t o t he direct ion of
t he viewer. Figure 35 shows t hese vect ors: not e t hat V is not necessarily in t he plane defined
by L and N. Assume t hat all vect ors are normalized (|N| = |L| = |V| = 1). Then t he
apparent bright ness of t he object is proport ional t o N L. Not e t hat :
• V does not appear in t his expression and so t he bright ness does not depend on t he
viewer’s posit ion;
• t he bright ness is great est when N and L are parallel (N L = 1); and
• t he bright ness is smallest when N and L are ort hogonal (N L = 0).
We can account for Lambert ian reflect ion in t he following way. Suppose t hat t he beam of
light has cross-sect ion area A and it st rikes t he surface of t he object at an angle θ . Then t he
area illuminat ed is approximat ely A/ cos θ . Aft er st riking t he object , t he light is scat t ered
uniformly in all direct ions. The apparent bright ness t o t he viewer is inversely proport ional t o
B T HEORY OF ILLUMINAT ION 56
T
N
d
d
d
d
ds
L

R
$
$
$
$
$
$X
V
d
d
d
d
d
d
d
d
d
d
d
d
r
light
$
$
$
$
$
$
$
$
$
$
$
$
$
$
$
$
r
Viewer
Object
Figure 35: Illuminat ing an object
t he area illuminat ed, which means t hat it is proport ional t o cos θ , t he inner product of t he
light vect or and t he surface normal.
We int roduce I
p
, t he incident light int ensity from a point source, and k
d
, t he diffuse reflection
coefficient of t he object . Then
I = I
p
k
d
(N L)
If we include some ambient light , t his equat ion becomes
I = i
a
k
a
+ I
p
k
d
(N L)
The value of N L can be negat ive: t his will be t he case if t he light is underneat h t he surface
of t he object . We usually assume t hat such light does not cont ribut e t o t he illuminat ion of
t he surface. In calculat ions, we should use max(N L, 0) t o keep negat ive values out of our
result s.
Technique # 4. Light at t enuat es (get s smaller) wit h dist ance from t he source. The t heo-
ret ical rat e of at t enuat ion for a point source of light is quadrat ic. In pract ice, sources are not
t rue point s and t here is always some ambient light from reflect ing surfaces (except in out er
space). Consequent ly, we assume t hat at t enuat ion, f , is given by
f =
1
C + L d + Q d
2
where:
• d is t he dist ance between t he light and t he object ;
• C (const ant at t enuat ion) ensures t hat a close light source does not give an infinit e
amount of light ;
• L (linear t erm) allows for t he fact t hat t he source is not a point ; and
• Q (quadrat ic t erm) models t he t heoret ical at t enuat ion from a point source.
Then we have
I = i
a
k
a
+ f I
p
k
d
(N L)
B T HEORY OF ILLUMINAT ION 57
Technique # 5. Techniques # 1 t hrough # 4 ignore colour. We assume t hat :
• t he object has diffuse colour factors O
dr
, O
dg
, and O
db
;
• t he light has intensity colour factors corresponding t o ambient sources (I
ar
, I
ag
, and
I
ab
); and
• point sources (I
pr
, I
pg
, and I
pb
).
All of t hese numbers are in t he range [0, 1]. We now have t hree int ensity equat ions of t he
form
I
λ
= I

k
a
O

+ f I

k
d
O

(N L)
for λ = r, g, b.
Technique # 6. Lambert ian reflect ion is a property of dull object s such as clot h or chalk.
Many object s exhibit degrees of shininess: polished wood has some shininess and a mirror is t he
ult imat e in shininess. The t echnical name for shininess is specular reflection. A charact erist ic
feat ure of specular reflect ion is t hat it has a colour closer t o t he colour of t he light source
t han t he colour of t he object . For example, a brown t able made of polished wood t hat is
illuminat ed by a whit e light will have specular highlight s t hat are whit e, not brown.
Specular reflect ion depends on t he direct ion of t he viewer as well as t he light . We int roduce
a new vect or, R (t he reflection vector), which is t he direct ion in which t he light would be
reflect ed if t he object was a mirror (see Figure 35). The bright ness of specular reflect ion de-
pends on t he angle between R and V (t he angle of t he viewer). For Phong shading (developed
by Phong Bui-Tong), we assume t hat t he bright ness is proport ional t o (R V)
n
, where n = 1
corresponds t o a slight ly glossy surface and n = ∞ corresponds t o a perfect mirror. We now
have
I
λ
= I

k
a
O

+ f I

(k
d
O

(N L) + k
s
(R V)
n
)
where k
s
is t he specular reflection coefficient and n is t he specular reflection exponent.
Technique # 7. In pract ice, t he colour of specular reflect ion is not complet ely independent
of t he colour of t he object . To allow for t his, we can give t he object a specular colour O

.
Then we have
I
λ
= I

k
a
O

+ f I

(k
d
O

(N L) + k
s
O

(R V)
n
)
This equat ion represent s our final t echnique for light ing an object and is a close approximat ion
t o what OpenGL act ually does. The act ual calculat ion performed by OpenGL is:
V
λ
= O

+ M

O

+
n−1
¸
i=0

1
k
c
+ k
l
d + k
q
d
2

i
s
i
[I

O

+ (N L)I

O

+ (R V)
σ
I

O

]
i
B T HEORY OF ILLUMINAT ION 58
where
V
λ
= Vert ex bright ness
M

= Ambient light model
k
c
= Const ant at t enuat ion coeffi cient
k
l
= Linear at t enuat ion coeffi cient
k
q
= Quadrat ic at t enuat ion coeffi cient
d = Dist ance of light source from vert ex
s
i
= Spot light eff ect
I

= Ambient light
I

= Diff use light
I

= Specular light
O

= Emissive bright ness of mat erial
O

= Ambient bright ness of mat erial
O

= Diff use bright ness of mat erial
O

= Specular bright ness of mat erial
σ = Shininess of mat erial
t he subscript λ indicat es colour component s and t he subscript i denot es one of t he light s.
B.2 Mult iple Light Sources
If t here are several light sources, we simply add t heir cont ribut ions. If t he sum of t he con-
t ribut ions exceeds 1, we can eit her “clamp” t he value (t hat is, use 1 inst ead of t he act ual
result ) or reduce all values in proport ion so t hat t he great est value is 1. Clamping is cheaper
comput at ionally and usually suffi cient .
B.3 Polygon Shading
The object s in graphical models are usually defined as many small polygons, typically t riangles
or rect angles. We must choose a suit able colour for each visible pixel of a polygon: t his is
called polygon shading.
Flat Shading In flat shading, we comput e a vect or normal t o t he polygon and use it t o
comput e t he colour for every pixel of t he polygon. The comput at ion implicit ly assumes t hat :
• t he polygon is really flat (not an approximat ion t o a curved surface);
• N L is const ant (t he light source is infinit ely far away); and
• N V is const ant (t he viewer is infinit ely far away.)
Flat shading is effi cient comput at ionally but not very sat isfact ory: t he edges of t he polygons
t end t o be visible and we see a polyhedron rat her t han t he surface we are t rying t o approx-
imat e. (The edges are even more visible t han we might expect , due t o t he subject ive Mach
effect, which exaggerat es a change of colour along a line.)
B T HEORY OF ILLUMINAT ION 59
Smoot h Shading In smoot h shading, we comput e normals at t he vert ices of t he polygons,
averaging over t he polygons t hat meet at t he vert ex. If we are using polygons t o approximat e
a smoot h surface, t hese vect ors approximat e t he t rue surface normals at t he vert ices. We
comput e t he colour at each vert ex and t hen colour t he polygons by interpolating t he colours
at int erior pixels.
Gouraud Shading Gouraud shading is a form of smoot h shading t hat uses a part icular
kind of int erpolat ion for effi ciency.
1. Comput e t he normal at each vert ex of t he polygon mesh. For analyt ical surfaces, such
as spheres and cones, we can comput e t he normals exact ly. For surfaces approximat ed
by polygons, we use t he average of t he surface normals at each vert ex.
2. Comput e t he light int ensity for each colour at each vert ex using a lighting model (e.g.,
Technique # 7 above).
3. Int erpolat e int ensit ies along t he edges of t he polygons.
4. Int erpolat e int ensit ies along scan lines wit hin t he polygons.
Phong Shading Phong shading is similar t o Gouraud shading but int erpolat es t he normals
rat her t han t he int ensit ies. Phong shading requires more comput at ion t han Gouraud shading
but gives bet t er result s, especially for specular highlight s.
C FUNCT ION REFERENCE 60
C Funct ion Reference
Each funct ion of OpenGL is specified by a prot otype and a brief explanat ion. The expla-
nat ions are brief: you may find t he suggest ed examples help you t o underst and t hem. The
specificat ions follow some convent ions, list ed below.
• Funct ion descript ions are in alphabet ical sequence by name. The prefix (gl - , gl u- , or
gl ut - ) is not part of t he name.
• If a funct ion has many argument s of t he same type, t he argument types are omit t ed
from t he prot otype but specified in t he explanat ion t hat follows it .
• A name of t he form gl name{234}{s i f d}[ v] describes several funct ions. The name of
a part icular funct ion is obt ained by t aking one charact er from each “set ” {. . . } and
opt ionally adding t he charact er enclosed in bracket s [ . . . ] .
The digit gives t he number of argument s and t he let t er gives t he type. The final “v”, if
present , says t hat t here will be a single argument t hat is a point er t o an array.
When t he funct ion definit ion uses t his form, t he argument types are omit t ed because
t hey must conform t o t he funct ion name.
For example, t he funct ion referred t o as gl Ver t ex( ) in t hese not es may be called wit h any of
t he following argument list s.
• Two s hor t s specifying X and Y posit ions:
gl Ver t ex2s ( 3, 4) ;
• Four doubl es specifying X , Y , Z , and W values:
gl Ver t ex4d( 1. 0, 1. 0, 5. 0, 1. 0) ;
• A point er t o an array of t hree float s:
gl Ver t ex3f v( pt r ) ;
Funct ion Definit ions
voi d gl ut AddMenuEnt r y ( char *l abel , i nt s el ect i on) ;
Add an ent ry t o t he current menu. The first argument is t he t ext t hat t he user will see and
t he second argument is t he int eger t hat will be passed t o t he callback funct ion when t he user
select s t his ent ry.
C FUNCT ION REFERENCE 61
See also
gl ut Cr eat eMenu( ) .
voi d gl ut AddSubMenu ( char *l abel , i nt menu) ;
Add a sub-menu t o t he current menu. The first argument is t he t ext t hat t he user will see
and t he second argument is an int eger ret urned by gl ut Cr eat eMenu( ) .
See also
gl ut Cr eat eMenu( ) .
voi d gl ut At t achMenu ( i nt but t on) ;
Associat e t he current menu wit h a mouse but t on. The value of t he argument must be one of
GLUT_LEFT_BUTTON, GLUT_MI DDLE_BUTTON, or GLUT_RI GHT_BUTTON.
See also
gl ut Cr eat eMenu( ) .
voi d gl Begi n ( GLenum mode) ;
Marks t he beginning of a vert ex dat a list . The permit t ed values of mode are given in Table 3
on page 17.
See also
gl End( ) .
voi d gl ut Bi t mapChar act er ( voi d *f ont , i nt char act er ) ;
Displays one bit mapped charact er at t he current rast er posit ion and moves t he rast er posit ion
right by t he widt h of t he charact er. Table 9 list s t he permit t ed values of f ont .
See also
gl Ras t er Pos ( ) , gl ut St r okeChar act er ( ) .
i nt gl ut Bi t mapWi dt h( voi d *f ont , i nt char act er ) ;
Ret urns t he widt h of t he bit mapped charact er. Table 9 list s t he permit t ed values of f ont .
voi d gl Cl ear ( GLbi t f i el d mas k) ;
Clears t he specified buff ers. Table 10 shows t he names of t he mask bit s. Using mult iple calls
of gl Cl ear ( ) may be less effi cient t han using | t o “OR” mask bit s.
C FUNCT ION REFERENCE 62
Font name Descript ion
GLUT_BI TMAP_8_BY_13 fixed widt h, 8 13 pixels
GLUT_BI TMAP_9_BY_15 fixed widt h, 9 15 pixels
GLUT_BI TMAP_TI MES_ROMAN_10 proport ional widt h, 10 point s
GLUT_BI TMAP_TI MES_ROMAN_24 proport ional widt h, 24 point s
GLUT_BI TMAP_HELVETI CA_10 proport ional widt h, 10 point s
GLUT_BI TMAP_HELVETI CA_12 proport ional widt h, 12 point s
GLUT_BI TMAP_HELVETI CA_18 proport ional widt h, 18 point s
Table 9: Font s for gl ut Bi t mapChar act er ( )
Buff er Mask bit
Colour GL COLOR BUFFER BI T
Dept h GL DEPTHBUFFER BI T
Accumulat ion GL ACCUMBUFFER BI T
St encil GL STENCI L BUFFER BI T
Table 10: Mask bit s for clearing
voi d gl Cl ear Col or ( r ed, gr een, bl ue, al pha) ;
Set t he clearing colour used for clearing t he colour buff ers in RGBA mode. The argument s
are all of type GLf l oat and t hey are clamped t o t he range [0, 1]. Use t his funct ion t o set t he
background colour of your scene.
Default
voi d gl Cl ear Col or ( 0. 0, 0. 0, 0. 0, 0. 0) ;
voi d gl Col or {34}f [ v] ( . . . ) ;
Set t he current colour. The first t hree values give t he int ensit ies for red, green, and blue,
respect ively. The fourt h argument , if present , gives t he value of alpha t o be used for blending.
If v is present , t here is one argument t hat point s t o an array. The values of all argument s
should be in t he range [0, 1].
Calls t o gl Col or ( ) have no eff ect if light ing is enabled.
i nt gl ut Cr eat eMenu ( voi d ( *f unc) ( i nt s el ect i on) ) ;
Creat e a menu and regist er a callback funct ion t hat will be invoked when t he user makes
a select ion from t he menu. The value ret urned is an int eger t hat ident ifies t he menu. It is
used as an argument t o gl ut Cr eat eSubMenu( ) , t elling t he submenu which menu it belongs
t o. The value passed t o t he callback funct ion is an int eger corresponding t o t he it em select ed
from t he menu by t he user.
C FUNCT ION REFERENCE 63
See also
gl ut AddMenuEnt r y( ) , gl ut AddSubMenu( ) , gl ut At t achMenu( ) .
i nt gl ut Cr eat eSubWi ndow ( wi n, x, y, wi dt h, hei ght ) ;
All argument s are int egers. wi n is t he number of t he new window’s parent . ( x, y) is t he
locat ion of t he new window relat ive t o t he parent window’s origin. wi dt h and hei ght are
t he widt h and height of t he new window. The value ret urned is an int eger t hat ident ifies t he
window.
i nt gl ut Cr eat eWi ndow ( char *t i t l e) ;
Creat es a window wit h feat ures t hat have been previously defined by calls t o t he init ializat ion
funct ions gl ut I ni t Di s pl ayMode( ) , gl ut I ni t Wi ndowPos i t i on( ) , and gl ut I ni t Wi ndowSi ze( ) .
The st ring t i t l e will appear at t he t op of t he window. The window is not act ually displayed
on t he screen unt il gl ut Mai nLoop( ) has been ent ered.
The value ret urned is a unique ident ifier for t he window. It is used by programs t hat support
several graphics windows.
Call gl ut Cr eat eWi ndow( ) before calling gl Enabl e( ) t o t urn on special GL feat ures.
voi d gl ut Des t r oyWi ndow( i nt wi n) ;
Dest roy t he window wit h number wi n.
voi d gl Di s abl e ( GLenum capabi l i t y) ;
Turns off one of GL’s capabilit ies.
See also
gl Enabl e( ) .
voi d gl ut Di s pl ayFunc ( voi d ( *f unc) ( voi d) ) ;
Regist er a callback funct ion t hat displays t he model in t he graphics window. The display
funct ion has no argument s and does not ret urn a value.
See also
gl ut Pos t Redi s pl ay( ) .
voi d gl Enabl e ( GLenum capabi l i t y) ;
Turns on one of GL’s capabilit ies. There are many capabilit ies, including GL_DEPTH_TEST,
GL_FOG, and so on.
See also
gl Di s abl e( ) .
C FUNCT ION REFERENCE 64
voi d gl End( ) ;
Marks t he end of a vert ex dat a list int roduced by gl Begi n( ) ; .
char *gl uEr r or St r i ng ( i nt code) ;
Ret urn a st ring describing t he error indicat ed by code.
See also
gl Get Er r or ( ) ;
voi d gl Fl us h ( voi d) ;
Forces previously issued OpenGL commands t o begin execut ion. It is not usually necessary
t o call gl Fl us h( ) for programs run on a single-user syst em, but it is import ant for programs
t hat run on a network.
voi d gl Fr us t um ( l ef t , r i ght , bot t om, t op, near , f ar ) ;
Defines a project ion mat rix and mult iplies t he current project ion mat rix by it . The mat rix
defines a “viewing volume” for a perspect ive view in t he negat ive Z direct ion.
All argument s should be GLf l oat s and f ar > near > 0. The first four argument s det ermine
t he size of t he viewing “window”. Only object s whose dist ance from t he viewpoint is between
near and f ar will be drawn.
See Also
gl uPer s pect i ve( ) , gl Or t ho( ) .
i nt gl Get Er r or ( voi d) ;
Ret urn t he value of t he error flag. If t he result is GL_NO_ERROR, t hen no error has oc-
curred. Ot herwise, you can obt ain a st ring describing t he error by passing t he result t o
gl uEr r or St r i ng( ) .
i nt gl ut Get Wi ndow( voi d) ;
Ret urn t he value of t he current window. All funct ions t hat apply t o windows operat e on
t he current window. Event s (such as mouse clicks and keyst rokes) apply t o t he window t hat
cont ains t he cursor, not necessarily t he current window. The value of wi n is t he int eger
ret urned by a call t o gl ut Cr eat eWi ndow( ) .
See also
gl ut Set Wi ndow( ) .
voi d gl ut I dl eFunc ( voi d ( *f unc) ( voi d) ) ;
Regist er a callback funct ion t hat will be called when no ot her event s are being processed.
C FUNCT ION REFERENCE 65
Mode bit Descript ion
GLUT_RGB Use RGB colour values (default )
GLUT_RGBA Use RGB colour values (same as GLUT_RGB)
GLUT_I NDEX Use colour indexes
GLUT_SI NGLE Use a single colour buff er (default )
GLUT_DOUBLE Use two colour buff ers
GLUT_DEPTH Use a dept h buff er
GLUT_STENCI L Use a st encil buff er
GLUT_ALPHA Use a buff er wit h an alpha component
GLUT_STEREO Use a st ereo pair of windows
GLUT_ACCUM Use an accumulat ion buff er
Table 11: Display mode bit s
voi d gl ut I ni t ( i nt ar gc, char *ar gv[ ] ) ;
Init ialize t he GLUT library. This funct ion should be called before any ot her gl ut - funct ions.
The argument s have t he same type as t he argument s of mai n( ) and are, by convent ion, t he
same as t he argument s passed t o mai n( ) .
voi d gl ut I ni t Di s pl ayMode ( uns i gned i nt mode) ;
Specify a display mode. The argument is a bit field const ruct ed from const ant s chosen from
Table 11 and OR’d t oget her.
Default
gl ut I ni t Di s pl ayMode ( GLUT_RGBA | GLUT_SI NGLE | GLUT_DEPTH) ;
voi d gl ut I ni t Wi ndowPos i t i on ( i nt x, i nt y) ;
Set s t he init ial posit ion of t he graphics window t o be creat ed by gl ut Cr eat eWi ndow( ) . The
argument s give t he posit ion of t he t op left corner of t he window in screen coordinat es (Y = 0 at
t he t op of t he screen). If you do not call t his funct ion, or you call it wit h negat ive argument s,
t he underlying window syst em chooses t he window posit ion.
Default
gl ut Wi ndowPos i t i on ( - 1, - 1) ;
voi d gl ut I ni t Wi ndowSi ze ( i nt wi dt h, i nt hei ght ) ;
Set s t he init ial size of t he graphics window t hat is t o be creat ed by gl ut Cr eat eWi ndow( ) .
The argument s give t he size of t he window in pixels.
Default
gl ut I ni t Wi ndowSi ze ( 300, 300) ;
C FUNCT ION REFERENCE 66
See also
gl ut Res hapeFunc( ) .
voi d gl ut Keyboar dFunc ( voi d ( *f unc) ( key, x, y) ) ;
Regist er a callback funct ion t hat handles keyboard event s. The argument s passed t o t he
funct ion are t he uns i gned char code of t he key t hat was pressed, and t he current posit ion of
t he mouse.
See also
gl ut Speci al Func( ) .
voi d gl Li ght {i f }[ v] ( GLenum l i ght , GLenum name, GLf l oat val ues ) ;
Creat es t he specified light if it has not already been creat ed and defines some of it s propert ies.
The first argument must be GL_LI GHTn, where n = 0, 1, 2, . . . , 7. The second argument is a
paramet er name, and should be one of:
GL_AMBI ENT GL_SPOT_DI RECTI ON GL_CONSTANT_ATTENUATI ON
GL_DI FFUSE GL_SPOT_EXPONENT GL_LI NEAR_ATTENUATI ON
GL_SPECULAR GL_SPOT_CUTOFF GL_QUADRATI C_ATTENUATI ON
GL_POSI TI ON
The t hird argument gives t he value of t he paramet er. The most common form of call is
gl Li ght f v, in which case t he t hird argument is a point er t o an array of four GLf l oat s. See
Table 7 on page 38 for an explanat ion of t he paramet er names and values.
Default
GLf l oat bl ack[ ] = { 0. 0, 0. 0, 0. 0, 1. 0 };
GLf l oat whi t e[ ] = { 1. 0, 1. 0, 1. 0, 1. 0 };
GLf l oat pos [ ] = { 0. 0, 0. 0, 1. 0, 0. 0 };
GLf l oat di r [ ] = { 0. 0, 0. 0, - 1. 0 };
gl Li ght f v( GL_LI GHT0, GL_AMBI ENT, bl ack) ;
gl Li ght f v( GL_LI GHT0, GL_DI FFUSE, whi t e) ;
gl Li ght f v( GL_LI GHT0, GL_SPECULAR, whi t e) ;
gl Li ght f v( GL_LI GHT0, GL_POSI TI ON, pos ) ;
gl Li ght f v( GL_LI GHT0, GL_SPOT_DI RECTI ON, di r ) ;
gl Li ght f ( GL_LI GHT0, GL_SPOT_EXPONENT, 0. 0) ;
gl Li ght f ( GL_LI GHT0, GL_SPOT_CUTOFF, 180. 0) ;
gl Li ght f ( GL_LI GHT0, GL_CONSTANT_ATTENUATI ON, 1. 0) ;
gl Li ght f ( GL_LI GHT0, GL_LI NEAR_ATTENUATI ON, 0. 0) ;
gl Li ght f ( GL_LI GHT0, GL_QUADRATI C_ATTENUATI ON, 0. 0) ;
C FUNCT ION REFERENCE 67
voi d gl Li ght Model {i f }[ v] ( GLenum name, GLf l oat [ *] val ue) ;
Define propert ies of t he light ing model. The first argument is a paramet er name, and it should
be one of:
GL_LI GHT_MODEL_AMBI ENT
GL_LI GHT_MODEL_LOCAL_VI EW
GL_LI GHT_MODEL_TWO_SI DE
See Table 8 on page 39 for an explanat ion of t he meanings of t hese paramet ers and t heir
values.
Default
GLf l oat amb[ ] = { 0. 2, 0. 2, 0. 2, 1. 0 };
gl Li ght Model f v( GL_LI GHT_MODEL_AMBI ENT, amb) ;
gl Li ght Model f ( GL_LI GHT_MODEL_LOCAL_VI EWER, GL_FALSE) ;
gl Li ght Model f ( GL_LI GHT_MODEL_TWO_SI DE, GL_FALSE) ;
voi d gl Li neWi dt h ( GLf l oat wi dt h) ;
Set s t he widt h of lines. The default value of wi dt h is 1.0, and it s value must be great er t han
0.0.
voi d gl uLookAt ( ex, ey, ez, cx, cy, cz, ux, uy, uz) ;
Defines a viewing mat rix and mult iplies it t o t he right of t he current GL_MODELVI EWmat rix.
All of t he argument s have type GLf l oat .
The mat rix est ablishes a point of view for looking at t he scene. Your “eye” is at (e
x
, e
y
, e
z
)
and you are looking t owards t he point (c
x
, c
y
, c
z
). The vect or (u
x
, u
y
, u
z
) is point ing upwards.
voi d gl LoadI dent i t y ( voi d) ;
Set s t he current mat rix (t op of t he st ack) t o t he ident ity mat rix.
voi d gl ut Mai nLoop ( voi d) ;
Ent ers t he GLUT processing loop. Wit hin t his loop, event s are processed and t he correspond-
ing callback funct ions are invoked. This funct ion never ret urns: t he program is t erminat ed
by execut ing exi t ( ) or by t he user closing t he graphics window.
C FUNCT ION REFERENCE 68
gl Mat er i al {i f }[ v] ( GLenum f ace, GLenum name, GLf l oat [ *] val ue) ;
Defines a mat erial property for use in light ing. The first argument specifies which face of each
polygon is being defined. The allowed values are GL_FRONT, GL_BACK, and GL_FRONT_AND_BACK.
You are allowed t o call gl Mat er i al ( ) twice, wit h diff erent values for front and back polygons.
Back faces will not be rendered unless you request GL_LI GHT_MODEL_TWO_SI DEwhen you call
gl Li ght Model ( ) .
The second argument is t he name of a paramet er and t he t hird argument is t he corresponding
value. When v is included in t he funct ion name, t he t hird argument should be a point er t o an
array. See Table 6 on page 36 for an explanat ion of t he paramet er names and t heir meanings.
Default
GLf l oat di m[ ] = { 0. 2, 0. 2, 0. 2, 0. 8 };
GLf l oat br i ght [ ] = { 0. 8, 0. 8, 0. 8, 1. 0 };
GLf l oat bl ack[ ] = { 0. 0, 0. 0, 0. 0, 1. 0 };
GLf l oat s hi ne[ ] = { 0. 0 };
gl Mat er i al f v( GL_FRONT_AND_BACK, GL_AMBI ENT, di m) ;
gl Mat er i al f v( GL_FRONT_AND_BACK, GL_DI FFUSE, br i ght ) ;
gl Mat er i al f v( GL_FRONT_AND_BACK, GL_SPECULAR, bl ack) ;
gl Mat er i al f v( GL_FRONT_AND_BACK, GL_SHI NI NESS, s hi ne) ;
gl Mat er i al f v( GL_FRONT_AND_BACK, GL_EMI SSI ON, bl ack) ;
voi d gl Mat r i xMode ( GLenum mode) ;
Set s t he mat rix mode t o one of GL_MODELVI EW(default ), GL_PROJ ECTI ON, or GL_TEXTURE.
voi d gl ut Mot i onFunc ( voi d ( *f unc) ( i nt x, i nt y) ) ;
Regist er a callback funct ion for mouse movement s. The funct ion is called when t he mouse is
dragged wit h one of it s but t ons pressed, and it is given t he current mouse coordinat es.
See also
gl ut Pas s i veMot i onFunc( ) .
voi d gl ut Mous eFunc ( voi d ( *f unc) ( but t on, s t at e, x, y) ) ;
Regist er a callback funct ion t hat handles mouse event s. The callback funct ion must t ake four
argument s, all of type i nt : a mouse but t on (one of GLUT_LEFT_BUTTON, GLUT_MI DDLE_BUTTON,
or GLUT_RI GHT_BUTTON); t he st at e of t he but t on (eit her GLUT_UP or GLUT_DOWN); and t he
current posit ion of t he mouse.
voi d gl Nor mal 3{bs i df }( nx, ny, nz) ;
voi d gl Nor mal 3{bs i df }v( p) ;
Defines a normal vect or for t he current vert ex. In t he first form, t he user provides t he values
of t he component s. In t he second form, t he user provides a point er t o an array cont aining t he
values of t he component s.
C FUNCT ION REFERENCE 69
voi d gl Or t ho ( l ef t , r i ght , bot t om, t op, near , f ar ) ;
Defines an ort hographic project ion mat rix wit h viewing volume bounded by (x, y, z ) where
l ef t ≤ x ≤ r i ght , bot t om≤ y ≤ t op, and near ≤ −z ≤ f ar . The argument s are of type
GLf l oat .
voi d gl Or t ho2D ( l ef t , r i ght , bot t om, t op) ;
This funct ion is used mainly for two-dimensional graphics. The call
gl Or t ho2D ( l ef t , r i ght , bot t om, t op) ;
is equivalent t o
gl Or t ho ( l ef t , r i ght , bot t om, t op, - 1. 0, 1. 0) ;
voi d gl ut Pas s i veMot i onFunc ( voi d ( *f unc) ( i nt x, i nt y) ) ;
Regist er a callback funct ion for mouse movement s. The funct ion is called when t he mouse is
dragged wit hout any but t ons pressed, and it is given t he current mouse coordinat es.
voi d gl uPer s pect i ve ( al pha, as pect , near , f ar ) ;
Defines a project ion mat rix and mult iplies t he current project ion mat rix by it . All argument s
are GLf l oat s. The camera is sit uat ed at t he origin and is looking in t he negat ive Z direct ion.
al pha is t he vert ical angle of t he field of view in degrees: it must be posit ive and less t han
180

. A typical value is 28

, corresponding t o a 50mm lens on a 35mm camera. as pect is t he
aspect rat io (widt h/ height ) of t he image. Only object s whose dist ance from t he viewpoint is
between near and f ar (near ≤ −z ≤ f ar ) will be drawn.
See also
gl Fr us t um( ) , gl Or t ho( ) .
voi d gl Poi nt Si ze ( GLf l oat s i ze) ;
Set s t he size of a point . The default value of s i ze is 1.0 and it s value must be great er t han 0.
voi d gl Pol ygonMode ( GLenum f ace, GLenum mode) ;
Cont rols t he drawing mode for a polygon’s front and back faces. The value of f ace may
be GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK. The value of mode may be GL_POI NT (draw
vert exes), GL_LI NES (draw edges), or GL_FI LL (draw filled polygon).
Default
gl Pol ygonMode ( FRONT_AND_BACK, GL_FI LL) ;
C FUNCT ION REFERENCE 70
voi d gl PopMat r i x ( voi d) ;
Pops t he t op mat rix of t he current mat rix st ack. The value of t he popped mat rix is lost .
See also
gl Pus hMat r i x( ) .
voi d gl ut Pos t Redi s pl ay ( voi d) ;
Request s t hat t he graphics window be redrawn at t he next opport unity: gl ut Mai nLoop( ) will
event ually invoke t he callback funct ion regist ered by gl ut Di s pl ayFunc( ) .
voi d gl Pus hMat r i x ( voi d) ;
Makes a copy of t he current t ransformat ion mat rix and pushes it ont o t he st ack.
See also
gl PopMat r i x( ) , gl LoadI dent i t y( ) .
voi d gl Ras t er Pos {234}{s i f d}[ v] ( x, y, z, w) ;
Set t he current rast er posit ion. The argument s are used in t he same way as t he coordinat es of a
vert ex (t hat is, t ransformat ions are applied). This funct ion is typically used before displaying
a bit map or bit mapped charact er.
See also
gl ut Bi t mapChar act er ( ) .
voi d gl Rect {s i f d}[ v] ( x0, y0, x1, y1) ;
Draw a rect angle wit h t op left corner at ( x0, y0) and bot t om right corner ( x1, y1) . The
rect angle is in t he plane z = 0 and is drawn according t o t he current polygon drawing style.
The current t ransformat ion is applied t o t he coordinat es.
See also
gl Pol ygonMode( ) .
voi d gl ut Res hapeFunc ( voi d ( *f unc) ( i nt wi dt h, i nt hei ght ) ) ;
Regist er a callback funct ion t hat adjust s t he display aft er t he graphics window has been moved
or resized. The reshape funct ion must accept two argument s, t he new widt h and new height
of t he window in pixels, and does not ret urn a value.
Default
voi d def aul t _r es hape ( i nt wi dt h, i nt hei ght )
{
gl Vi ewpor t ( 0, 0, wi dt h, hei ght ) ;
}
C FUNCT ION REFERENCE 71
Ident ifier Descript ion
GLUT_CURSOR_LEFT_ARROW left arrow
GLUT_CURSOR_RI GHT_ARROW right arrow
GLUT_CURSOR_TOP_SI DE arrow point ing t o t op of window
GLUT_CURSOR_BOTTOM_SI DE arrow point ing t o bot t om of window
GLUT_CURSOR_LEFT_SI DE arrow point ing t o left side of window
GLUT_CURSOR_RI GHT_SI DE arrow point ing t o right side of window
GLUT_CURSOR_CURSOR_I NFO point ing hand
GLUT_CURSOR_DESTROY skull and crossbones
GLUT_CURSOR_HELP quest ion mark
GLUT_CURSOR_CYCLE rot at ing arrows
GLUT_CURSOR_SPRAY spray can
GLUT_CURSOR_WAI T wrist wat ch
GLUT_CURSOR_TEXT t ext insert ion marker
GLUT_CURSOR_CROSSHAI R small cross hair
GLUT_CURSOR_FULL_CROSS_HAI R full window cross hair
GLUT_CURSOR_NONE invisible cursor
Table 12: Cursor codes
gl Rot at e{f d} ( angl e, x, y, z) ;
Mult iples t he current mat rix by a mat rix t hat rot at es count erclockwise t hrough t he given
angle. The axis of rot at ion is a line from t he origin (0, 0, 0) t o t he point (x, y, z ).
voi d gl Scal e{f d} ( x, y, z) ;
Mult iples t he current mat rix by a mat rix t hat st ret ches or shrinks an object along each axis.
The object will be dist ort ed if t he argument s are not equal. The argument s may be posit ive
or negat ive. If an argument is −1, t he object is reflect ed in t he corresponding axis.
voi d gl ut Set Cur s or ( i nt s t yl e) ;
Change t he cursor image in t he current window. The value of s t yl e det ermines t he shape of
t he cursor; Table 12 shows some of t he possibilit ies.
voi d gl ut Set Wi ndow( i nt wi n) ;
Set t he current window t o be wi n. All funct ions t hat apply t o windows operat e on t he current
window. Event s (such as mouse clicks and keyst rokes) apply t o t he window t hat cont ains t he
cursor, not necessarily t he current window. The value of wi n is t he int eger ret urned by a call
t o gl ut Cr eat eWi ndow( ) .
See also
gl ut Get Wi ndow( ) .
C FUNCT ION REFERENCE 72
voi d gl ShadeModel ( GLenum mode) ;
Set s t he shading model t o eit her GL_SMOOTH(default ) or GL_FLAT.
voi d gl ut Speci al Func ( voi d ( *f unc) ( i nt key, i nt x, i nt y) ) ;
Regist ers a callback funct ion for special key codes, such as arrows, F keys, and so on. The
callback paramet ers x and y give t he posit ion of t he mouse when t he key was pressed. Not e
t hat t he keys esc, backspace, and delete have regular ASCII codes and are recognized by
gl ut Keyboar dFunc( ) .
The keys are ident ified by predefined const ant s: see Table 2 on page 12.
See also
gl ut Keyboar dFunc( ) .
voi d gl ut St r okeChar act er ( voi d *f ont , i nt char act er ) ;
Draws a st roked charact er at t he origin of t he current model view and advance t he model view
mat rix by t he widt h of t he charact er. St roked charact ers may be (and usually are) scaled.
There are two font s available:
GLUT STROKE ROMAN. A proport ionally spaced Roman font for ASCII charact ers 32 t hrough
127. All charact ers sit on a base line and reach up t o 119.05 unit s above and 33.33 unit s
below t he line.
GLUT MONOROMAN. A fixed-space Roman font for ASCII charact ers 32 t hrough 127. All char-
act ers sit on a base line and reach up t o 119.05 unit s above and 33.33 unit s below t he
line. Each charact er is 104.76 unit s wide.
See also
gl ut Bi t mapChar act er ( ) , gl ut St r okeWi dt h( ) .
i nt gl ut St r okeWi dt h ( voi d *f ont , i nt char act er ) ;
Ret urn t he widt h of t he given charact er. The font must be a st roked font .
voi d gl ut SwapBuf f er s ( voi d) ;
Exchange t he “front ” colour buff er and t he “back” colour buff er. OpenGL displays t he front
buff er while t he program is drawing int o t he back buff er. This works only if t he mode
GLUT_DOUBLE was select ed in t he call t o gl ut I ni t Di s pl ayMode( ) .
voi d gl Tr ans l at e{f d} ( x, y, z) ;
Mult iples t he current mat rix by a mat rix t hat t ranslat es (moves) an object from (X , Y, Z ) t o
(X + x, Y + y, Z + z ).
C FUNCT ION REFERENCE 73
voi d gl Ver t ex{234}{s i f d} ( x, y, z, w) ;
voi d gl Ver t ex{234}v ( p) ;
Specifies a vert ex. Up t o four coordinat es (x, y, z , and w) may be provided. z default s t o 0
and w default s t o 1. In t he first form, t he user provides t he coordinat es as argument s. In t he
second form, t he user provides a point er t o an array cont aining t he coordinat es.
voi d gl Vi ewpor t ( x, y, wi dt h, hei ght ) ;
Defines a pixel rect angle in t he viewing window int o which t he final image is t o be mapped.
The argument s are int egers. The lower-left corner of t he viewport is at (x, y) and t he viewport
has t he indicat ed widt h and height . The default viewport is t he ent ire viewing window.

CONTENTS

i

Contents
1 Introduction 1.1 1.2 1.3 1.4 Compiling and Executing an OpenGL Program . . . . . . . . . . . . . . . . . . A Simple OpenGL Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Drawing Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OpenGL Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 2 4 6 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2 Callbacks 2.1 2.2 2.3 2.4 The Idle Function

Keyboard Callback Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Mouse Event Callback Functions . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Reshaping the Graphics Window . . . . . . . . . . . . . . . . . . . . . . . . . . 13 17

3 Primitive Objects 3.1 3.2 3.3 3.4 3.5 3.6

The Coordinate System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Polygons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Hidden Surface Elimination . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 23

4 Transformations 4.1 4.2 4.3 4.4

Model View Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Projection Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Perspective Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Combining Viewpoint and Perspective . . . . . . . . . . . . . . . . . . . . . . . 29 32

5 Lighting 5.1 5.2 5.3 5.4 5.5 5.6

A Simple Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 Normal Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Defining Material Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 Defining the Lights . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 Defining a Lighting Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Putting It All Together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

LIST OF FIGURES 6 Odds and Ends 6.1 6.2

ii 41

Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 6.2.1 6.2.2 Bitmapped Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Stroked Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

6.3 6.4

Special Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Programming Hints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 49

A Spaces and Transformations

A.1 Scalar, Vector, Affine, and Euclidean Spaces . . . . . . . . . . . . . . . . . . . . 49 A.2 Matrix Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 A.3 Sequences of Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 A.4 Viewing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 B Theory of Illumination B.1 Steps to Realistic Illumination 55 . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

B.2 Multiple Light Sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 B.3 Polygon Shading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 C Function Reference 60

List of Figures
1 2 3 4 5 6 7 8 9 10 11 12 13 Make file for SGI machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Make file for Solaris machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . The basic OpenGL program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Displaying a bright red line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Drawing vertical yellow lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 3 4 5 9

Rotating a wire cube . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

A callback function that spins the cube . . . . . . . . . . . . . . . . . . . . . . 10 A keyboard callback function that selects an axis . . . . . . . . . . . . . . . . . 11 Quitting with the escape key . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 A callback function that responds to mouse buttons . . . . . . . . . . . . . . . 13 A callback function that responds to dragging the mouse . . . . . . . . . . . . . 13 A callback function that responds to window reshaping . . . . . . . . . . . . . . 14 Maintaining scaling invariants . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

. . . . . . . 31 A simple object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Pushing and popping . . . . . . . . . . . . . . . . . . . . . . 36 Parameters for glLightfv() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Constants for special keys . . . . . . . . . . 53 Illuminating an object . . . . . . . . . . . . . . 28 gluPerspective() with a small value of α . . . . . . . . . . . . . . . . . 42 Displaying a string of text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Using gluLookAt() and gluPerspective() . . . . 35 Using glMaterial() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 List of Tables 1 2 3 4 5 6 7 8 9 10 11 12 OpenGL Types . . . . . . . . . . 40 Code for a simple menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .LIST OF TABLES 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 iii Drawing primitives . . . . . . . . . . . . 71 . . . . . . . 39 Fonts for glutBitmapCharacter() . . . . . . . . . 47 Basic transformations . . . . . . . . . . . . . . . . . . . . . . 18 Default viewing volume . . 18 Labelling the corners of a cube . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Perspective transformation . . . . . . 65 Cursor codes . . . . . . 17 Options for drawing polygons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 A balancing act . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Obtaining and reporting OpenGL errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Parameters for glMaterialfv() . . . . . . . . . . . 20 Drawing a cube . . . . . . . . . . . . . . . . . . . . . . . . . 12 Primitive Specifiers . . . . . . . . . . . . . . . . . . 26 Perspective projection with glFrustum() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 gluPerspective() with a large value of α . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Common transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Reshaping with gluPerspective() . 62 Display mode bits . . . . . . . . 62 Mask bits for clearing . . . . . . . . . . . 37 Illuminating the sun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 Parameters for glLightModel() . . . . . . . . . . . . . . . . . . . . 27 Perspective projection using gluPerspective() . . . . . . . . . 33 Computing normals . . . . . . . . .

sgi. The OpenGL Utility Toolkit (GLUT) Programming Interface.1 Compiling and Executing an OpenGL Program In order to run an OpenGL program. 1997.ca. or Widows NT. Kilgard.cs. Function names begin with gl. Several versions of these libraries have been implemented. Since people are constantly changing their web pages and links. http://reality. Mark J. 3. 2.1 INTRODUCTION 1 Getting Started with OpenGL Peter Grogono January 1998 1 Introduction OpenGL consists of three libraries: the Graphics Library (GL). however.sgi. 1.com) and exploring.html. Mark Segal and Kurt Akeley.sgi. If so.1/glspec. Jackie Neider. you may find that the URLs above do not work. 1. The explanations and programs in these notes are based on the Silicon Graphics implementation. The main sources for these notes are listed below. try going to Silicon Graphics’ web site (www. write . and Tom Davis. Silicon Graphics.com/Technology/OpenGL/glspec1. Implementations are also available for PCs running linux. Mason Woo. The “official guide to learning OpenGL”.html. The easiest way to do this is to use a “makefile”. Silicon Graphics.1). I have tried to make this manual as accurate as possible. 1997. Another implementation. you must know not only the specifications of individual functions but also the way in which these functions work together in programs. Windows 95. The OpenGL Graphics System: a Specification (Version 1. http://www. If you find errors. has been installed on the “greek” machines. To compile a program using either of these makefiles. or glut. Appendix C contains specifications of all of the functions mentioned in these notes. OpenGL Programming Guide. Addison-Wesley. called Mesa. and the Graphics Library Utilities Toolkit (GLUT). the Graphics Library Utilities (GLU). glu. or misprints. Sections 2 through 6 provide examples of ways in which the functions can be used. Second Edition. and a few others as well. omissions. depending on which library they belong to.com/mjk/spec3/spec3.concordia.html. 1997.ca/~faculty/grogono/comp471. To use OpenGL effectively. You could also try links from my web pages for COMP 471: www. please send an e-mail message to me at grogono@cs. Figure 1 shows a makefile suitable for SGI machines and Figure 2 shows a makefile suitable for Solaris machines on greeknet (it does not work for lambda or other machines running Sun). you must tell the compiler where to find the header files and the linker where to find the libraries.concordia.

Currently (January 1998). The line numbers are not part of the program.h includes glu. Every OpenGL program should include GL/glut. Although OpenGL provides a standard API (application programmers’ interface). again without any extension. The program must contain the directive #include <GL/glut. Line 1. .1 INTRODUCTION CC = cc LDLIBS = -lglut -lGL -lGLU -lXmu -lX11 -lm INCLUDE = executable: $(CC) -g $(INCLUDE) $(PROG). Consequently. many implementations do not provide all of the specified features.o -L/pkg/glut/lib -R/pkg/glut/lib \ -lglut -L/pkg/mesa/lib -R/pkg/mesa/lib -lMesaGLU -lMesaGL \ -L/pkg/X11/lib -R/pkg/X11/lib -lXmu -lXt -lXext -lX11 \ -lsocket -lnsl -lm Figure 2: Make file for Solaris machines make PROG=name where “name” is the name of a C program without an extension. These steps apply to a program that consists of a single C source file. Although this program does nothing useful. but are used in the explanation below.h>.2 A Simple OpenGL Program Figure 3 shows a simple OpenGL program. 1.c gcc -o $(PROG) $(PROG).h. enter the following command: name where “name” is the name of your program.h and other header files required by GLUT. including interleaved arrays.h. you will have to write a suitable make file for it. that work on the Suns but do not work on the O2s. gl. the greeknet machines are running Version 1.c \ $(LDFLAGS) $(LDLIBS) -o $(PROG) Figure 1: Make file for SGI machines 2 executable: gcc -I/pkg/glut/include -I/pkg/mesa/include \ -I/pkg/X11/include -c $(PROG). there are a few features.1 in the Mesa implementation and the SGI machines in VA–03 are running Version 1. If you write a program with several source files. It may also contain directives to include header files from other libraries.0 in the SGI implementation. The file glut. To execute the program. it defines a pattern that is used by most OpenGL programs.

char *argv[]) { glutInit(&argc. The colour buffer. Deleting this line would not affect the execution of the program. glutInitWindowSize(800. In this program. glutInitWindowPosition(100. It is usually a good idea to clear various buffers before starting to draw new objects. Line 8. It is conventional to pass the command line arguments to this function because it may use some of them.. return 0. It is conventional to put “standard initialization” (the glut.. glutDisplayFunc(display). You must write a function that displays the graphical objects in your model. init(). Your program does not call this function explicitly. argv). glutCreateWindow("My first openGL program"). This call requests a graphics window 800 pixels wide and 600 pixels high. Line 15. Line 5. The function shown here clears the screen but does not display anything. The function glutInit() initializes the OpenGL library. 50). } void init (void) { } int main (int argc. Line 16. glutMainLoop(). cleared by this call. Its argument is a bit string. because the arguments shown are the default values. . The function glutInitDisplayMode() initializes the display.1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 INTRODUCTION #include <GL/glut.h> void display (void) { glClear(GL_COLOR_BUFFER_BIT). but it will be called at appropriate times by OpenGL. calls) in the main program and application dependent initialization in a function with a name like init() or myinit(). You will probably not need this feature. does nothing. Line 14. glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA). the function init() is defined in lines 8 through 10. is where the image of your model is actually stored. and is invoked at line 19. 600). } Figure 3: The basic OpenGL program 3 Line 3.

The call glColor3f(1. such as calls to glEnable(). . Section 2 describes callback functions. The last statement of an OpenGL program calls glutMainLoop(). Line 19. After executing the call.3 Drawing Objects All that remains is to describe additions to Figure 3. must come after glutCreateWindow(). 0. Line 20. and no blue”. 0. glEnd(). is used to display groups of primitive objects.0. This function processes events until the program is terminated. The value of mode determines the kind of object: in this case.0). The first one that we will consider is an improved display() function.. Line 21. GL_LINES tells OpenGL to expect one or more lines given as pairs of vertices. Line 18.0.0. This is a good place to perform any additional initialization that is needed.0. The call glFlush() forces previously executed OpenGL commands to begin execution. 1. . 0.1 INTRODUCTION void display (void) { glClear(GL_COLOR_BUFFER_BIT). If OpenGL is running on a workstation that communicates directly with its graphics subsystem. Figure 4 shows a function that displays a line. If we use the default viewing region. The window does not actually appear on the screen until glutMainLoop() has been called. glVertex2f(-1. This call creates the window using the settings given previously. glEnd().0). The construction glBegin(mode). 0). This call registers the callback function display(). as specified by the two calls to glVertex2f().0. 0) to (1. This call says that the left side of the graphics window should be 100 pixels from the left of the screen and the top of the graphics window should be 50 pixels below the top of the screen.. The text in the argument becomes the title of the window. no green. Well-written programs should provide the user with an easy way of stopping the program. Note that the Y value is measured from the top of the screen. OpenGL knows what function to call to display your model in the window. glFlush(). Some initialization.. glColor3f(1. the line goes from (−1.0.0.0. this line runs horizontally across the centre of the window. 0.0). } Figure 4: Displaying a bright red line 4 Line 17. as in Figure 3. In this case. glBegin(GL_LINES).0) specifies the colour of the line as “maximum red. for example by selecting Quit from a menu or by pressing the esc key. glVertex2f(1.

1. however. i <= 25.0). Similarly.0. You can set the background colour by executing glClearColor(r.0). 1. 1. 0. OpenGL allows you to define a viewing volume. It is important to use it if your program is running. The following code establishes a viewing volume with orthogonal projection. set the fourth argument of glClearColor to zero. The suffix “3f” indicates that glColor3f() requires three arguments of type GLfloat.0. Appendix C provides more details of this notational convention and explains why it is used.0. glBegin(GL_LINES).0. Each argument is a floatingpoint number in the range [0. giving a black background. To make the background blue. blue) or blending (alpha). only objects that are inside the viewing volume will appear on the screen. glVertex2f(x. or might be run. -1. g. i++) { float x = i / 25.0. for (i = -25. Figure 5 shows a display function that uses a loop to draw 51 vertical yellow (red + green) lines across the window. glVertex2f(x.0). and a during initialization. green.0). glClear(GL_COLOR_BUFFER_BIT). with appropriate values of r. The code between glBegin() and glEnd() is not restricted to gl calls. you could call glClearColor(0. g. The call glClear(GL_COLOR_BUFFER_BIT) clears the colour buffer to the background colour. 0. The default values are all zero. glVertex2f() requires two arguments of type GLfloat.1 INTRODUCTION void display (void) { int i. b. } Figure 5: Drawing vertical yellow lines 5 glFlush() will probably have no effect on the behaviour of the program. . unless you know how to use it. } glEnd().0. because otherwise attempts by the system to optimize packet transfers may prevent good graphics performance. a). 0. b. 1] specifying the amount of a colour (red. in a client/server context. Blending is an advanced feature. glColor3f(1. Section 3 describes some of the other primitive objects available in OpenGL.

bottom. The suffix column contains the letter that is used in function names. glOrtho(left. void init (void) { glClearColor(1. 1.0).0. near. glLoadIdentity(). the “f” in glVertex3f. 1. far). To obtain a realistic view of a three-dimensional model. right. top. initialization. as described in Section 4.4 OpenGL Types OpenGL defines a number of types that are usually equivalent to C types. near ≤ z ≤ far. and −2 < z < 2. if you want to write portable OpenGL programs. 1. The default projection is orthogonal with boundaries left = bottom = near = −1 and right = top = far = 1.0. 5. 2.0. glLoadIdentity().0.0. and z satisfy the following inequalities: left ≤ x ≤ right. you will need a perspective projection rather than an orthogonal projection. -2. The following version of init() sets the background colour to white and defines a viewing volume in which 0 < x < 5.1 describes coordinate systems. 0 < y < 5. glMatrixMode(GL_PROJECTION). it is better to use the OpenGL types: see Table 1. . glOrtho(0.1 INTRODUCTION glMatrixMode(GL_PROJECTION). bottom ≤ y ≤ top.0. 5.0. } The last three lines of this function illustrate the selection. y. You can use C types but. z) will be displayed only if x. 0. Section 3. 6 An object at (x. y. and transformation of the projection matrix. 0.3.0. for example. Section 4 describes matrix transformations in detail.0).

GLenum. GLclampf GLdouble.1 INTRODUCTION 7 Suffix b s i f d ub us ui Data type 8-bit integer 16-bit integer 32-bit integer 32-bit floating point 64-bit floating point 8-bit unsigned integer 16-bit unsigned integer 32-bit unsigned integer C Type signed char short int or long float double unsigned char unsigned short unsigned int OpenGL Type GLbyte GLshort GLint. GLclampd GLubyte. GLboolean GLushort GLuint. GLsizei GLfloat. GLbitfield Table 1: OpenGL Types .

2. It displays a wire-frame cube which is rotated about the X.” indicates which callback you are registering. 1. Typical OpenGL programs usually contain the following components: • declarations of global variables whose values affect the scene.. The program in Figure 6 illustrates these conventions. 2. and Z axes by the angles x_angle.1 The Idle Function OpenGL calls the idle function when it has nothing else to do. in which “. Notice that. There is one callback function that must be declared in all OpenGL programs: it is the display callback. • a display() function that uses the global variables to draw the scene. spin() does not call display() directly. Figure 7 shows an idle function that increments one of the angles by 1◦ (one degree) and requests that the model be redisplayed. Instead. after changing the angle. The global variable axis determines which angle is incremented. We will add callback functions to this program to rotate the cube. The axis of rotation is determined by the global variable axis..2 CALLBACKS 8 2 Callbacks GLUT handles events with callback functions. Instead. you have to violate the programming practices you have been taught and use global variables. We will use the idle function to make the cube in Figure 6 rotate. Since OpenGL defines the argument lists of callback functions.Func(). you usually cannot pass information in function arguments. The following call registers an idle function called spin(): glutIdleFunc(spin). and it is registered by calling glutDisplayFunc() with the name of the display function as its argument.. If you want to handle an event. and • one or more callback functions that respond to events by changing the values of the global variables. it calls glutPostRedisplay(). y_angle. and is the X-axis initially. The idle function must be declared. The main program must register the idle function. Then you register your function by passing its name as an argument to a function with a name of the form glut. Y . . you write a function that performs the desired action. which are stored as global variables with initial values zero. The comment “Callback registration here” in the main program shows where the callbacks should be registered. It has no arguments and returns no results. such as a keystroke or mouse movement. The most common application of the idle function is to provide continuous animation.. and z_angle. which informs glutMainLoop() to redisplay the model at the next convenient opportunity.

0). 1. glutWireCube(1.0. float z_angle = 0. 5. void display (void) { glClear(GL_COLOR_BUFFER_BIT). glMatrixMode(GL_MODELVIEW). } Figure 6: Rotating a wire cube . 0. 0. Y. glutMainLoop().0). glutInitWindowSize(SIZE. glutInitWindowPosition(100. float y_angle = 0. glRotatef(x_angle. 50). SIZE). glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB).0). 0. glutCreateWindow("Rotating a wire cube"). 5. init().0. -5. } void init (void) { glMatrixMode(GL_PROJECTION). glRotatef(z_angle.0. glRotatef(y_angle. Z } axis = X. -5. } int main (int argc.2 CALLBACKS 9 #include <GL/glut. 0. glutSwapBuffers().0.0. 5.0. char *argv[]) { glutInit(&argc.0.0.0. 0. enum { X. 1. argv). glOrtho(-5.0.0.0.0. 0. glLoadIdentity().h> #define SIZE 500 float x_angle = 0. 1. /* Callback registration here */ glutDisplayFunc(display).0).0. glLoadIdentity().0).

such as the arrow keys and “F” keys: 1. The following steps modify the cube program so that it responds to the keys ‘x’. case Y: y_angle += 1. Register a keyboard callback function.0. break. y. 2. 1. } Figure 7: A callback function that spins the cube 10 2. this function is called whenever the user presses a key. other keys are ignored. To make your program respond to other keys. The keyboard function is declared as in Figure 8. It receives three arguments: the key that was pressed. . glutKeyboardFunc(keyboard). or z has been pressed.2 Keyboard Callback Functions If the program has registered a keyboard callback function. It would be possible to rewrite keyboard() so that it called glutPostRedisplay() once only. and ‘z’ by changing the axis of rotation of the cube. after the switch statement.0. and delete. sc backspace. Register a special key callback function. default: break. and the current X and Y coordinates of the mouse. case Z: z_angle += 1. The callback function registered by glutKeyboardFunc() recognizes only keys corresponding to ASCII graphic characters and esc. glutSpecialFunc(special).2 CALLBACKS void spin (void) { switch (axis) { case X: x_angle += 1. break.0. The advantage of the code shown is that the scene is redisplayed only when one of the keys x. ‘y’. break. } glutPostRedisplay().

int y) { switch (key) { /* Code to handle special keys */ } } The arguments that OpenGL passes to special() are: the key code. The first callback function responds to pressing or releasing one of the mouse buttons. case ’z’: axis = Z.3 Mouse Event Callback Functions There are several ways of using the mouse and two ways of responding to mouse activity. case ’y’: axis = Y. 1. as defined in Table 2. int x. break. . Declare the special key function as follows: void special (int key. } } Figure 8: A keyboard callback function that selects an axis 11 2. the X coordinate of the mouse. and the Y coordinate of the mouse. break. break. glutPostRedisplay(). The keyboard callback function in Figure 9 is a useful default: it allows the user to quit the program by pressing the escape key. Register a mouse callback function. int x. glutPostRedisplay(). 2.2 CALLBACKS void keyboard (unsigned char key. default: break. int y) { switch (key) { case ’x’: axis = X. glutPostRedisplay().

} Figure 9: Quitting with the escape key glutMouseFunc(mouse_button). • The second argument specifies the button state. Register a callback function for mouse dragging events: glutMotionFunc(drag). Its value is one of GLUT_LEFT_BUTTON. Its value is one of GLUT_DOWN (the button has been pressed) or GLUT_UP (the button has been released).4 shows how you can avoid this problem. • The remaining two arguments are the X and Y coordinates of the mouse. Section 2. . the value of SIZE will be wrong. int x. or GLUT_RIGHT_BUTTON. If the user has changed the width of the window. int y) { if (key == ESCAPE) exit(0). The mouse callback function is passed four arguments. and the results will be different. The value of new_angle will be 0 if the mouse cursor is at the left of the OpenGL window and 360 if the mouse cursor is at the right of the window. 2. • The first argument specifies the button. 1.2 CALLBACKS GLUT_KEY_F1 GLUT_KEY_F2 GLUT_KEY_F3 GLUT_KEY_F4 GLUT_KEY_F5 GLUT_KEY_F6 GLUT_KEY_F7 GLUT_KEY_F8 GLUT_KEY_F9 GLUT_KEY_F10 GLUT_KEY_F11 GLUT_KEY_F12 GLUT_KEY_LEFT GLUT_KEY_RIGHT GLUT_KEY_UP GLUT_KEY_DOWN GLUT_KEY_PAGE_UP GLUT_KEY_PAGE_DOWN GLUT_KEY_HOME GLUT_KEY_END GLUT_KEY_INSERT 12 Table 2: Constants for special keys #define ESCAPE 27 void keyboard (unsigned char key. Figure 10 shows a mouse function that uses the mouse buttons to select the axis of rotation and the X position of the mouse to set the value of the corresponding angle. An OpenGL program can also respond to “dragging” events in which the user holds a mouse button down and moves the mouse. GLUT_MIDDLE_BUTTON.

} else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) { y_angle = new_angle. 2. if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { x_angle = new_angle.0 * y / SIZE. int state. you do not want the change to distort your image. glutPostRedisplay().0 * x / SIZE. provided that you have registered the appropriate callback function. glutPostRedisplay(). int y) { z_angle = 360. The main problem with reshaping is that the user is likely to change the shape of the window as well as its size.0 / SIZE. } } Figure 10: A callback function that responds to mouse buttons void drag (int x. int x.4 Reshaping the Graphics Window Whenever the user moves or resizes the graphics window. Figure 11 shows a motion function that uses the position of the mouse to set z_angle and x_angle. 1. glutPostRedisplay(). } Figure 11: A callback function that responds to dragging the mouse 13 2.2 CALLBACKS void mouse_button (int button. int y) { double new_angle = x * 360. The motion function is given the X and Y coordinates of the mouse. The function glutPassiveMotionFunc() registers a callback function that responds to mouse movement when no buttons have been pressed. glutPostRedisplay(). Register a callback function that will respond to window reshaping: . } else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { z_angle = new_angle. x_angle = 360. OpenGL informs your program.

width. int height) { GLfloat w. glutPostRedisplay(). h = (5.0). 2. The arguments are the width and height of the new window. -h. The code ensures that: • The ratio w/h is the same as the ratio width/height. height). Figure 12 shows a callback function that responds to a reshape request. ensuring that none of the model will be cut out of the scene. 5. The callback functions reshape() and drag() work together to maintain the following invariants: xpos = 0 xpos = 1 ypos = 0 ypos = 1 Note: at at at at the the the the left right bottom top .0.0. -5.2 CALLBACKS void reshape (int width.0 * height) / width. glMatrixMode(GL_PROJECTION). 0. it changes the view to match the shape of the new window in such a way that none of the scene is lost. and • The smaller of w and h is 5. it is a good idea to match the mouse coordinates to the borders of the graphics window. If your program uses the mouse position as a source of input. if (width > height) { w = (5.0. Figure 13 outlines a program that uses the mouse to set the global variables xpos and ypos. } else { w = 5. The function first calls glViewport() to update the viewport so that it includes the entire window. w. in pixels. h. Then.0. } glOrtho(-w. } Figure 12: A callback function that responds to window reshaping 14 glutReshapeFunc(reshape). glLoadIdentity(). glViewport(0. h. h = 5.0 * width) / height.

• The code does not ensure that 0 ≤ xpos ≤ 1 or 0 ≤ ypos ≤ 1 because of an oddity in the X window system that allows the user to drag the mouse outside an application’s window without the application giving up control. .2 CALLBACKS 15 • The Y = 0 is the top of the screen in mouse coordinates but the bottom of the screen in graphics coordinates. • The function reshape() computes the aspect ratio of the new window and passes it to gluPerspective() to set up a perspective projection.

0. glutPostRedisplay(). glMatrixMode(GL_PROJECTION). } int main (int argc. GLfloat xpos = 0. int screen_height = 400. glutMotionFunc(drag). 20. glutReshapeFunc(reshape).0).0.2 CALLBACKS 16 #include <GL/glut. height). int height) { screen_width = width. width.0 . (GLfloat) width / (GLfloat) height. gluPerspective(30.(GLfloat) my / screen_height.0. int my) { xpos = (GLfloat) mx / screen_width. glutDisplayFunc(display). argv). GLfloat ypos = 0.0. glutInitDisplayMode(GLUT_RGB). void display (void) { /* display the model using xpos and ypos */ } void drag (int mx. glutMainLoop(). 0. screen_height = height. glViewport(0. } void reshape (int width. } Figure 13: Maintaining scaling invariants . 1.h> int screen_width = 600. screen_height). ypos = 1. char *argv[]) { glutInit(&argc. glutInitWindowSize(screen_width. glutCreateWindow("Demonstration of reshaping"). glLoadIdentity(). glutPostRedisplay().

that the code specifies n vertices v0 . and so on (see Figure 14 (b)). Draw the triangle v0 v1 v2 . . v1 . . and so on (see Figure 14 (a)). Assume. . . to ensure both that the topology of the object is correct and that the vertices appear in counter-clockwise order (see Section 3. including points. It is not an error to provide extra vertices. Draw a single polygon using v0 . Mode Value GL_POINTS GL_LINES GL_LINE_STRIP GL_LINE_LOOP GL_TRIANGLES GL_TRIANGLE_STRIP GL_TRIANGLE_FAN GL_QUADS GL_QUAD_STRIP GL_POLYGON Effect Draw a point at each of the n vertices. OpenGL provides functions for drawing primitive objects. . n will normally be a multiple of 3. v1 v2 . n should be a multiple of something: e.4). Figure 14 shows how the vertices of triangle and quadrilateral collections are labelled. in each case. v1 . . There are a few functions for familiar objects. The label numbers are important. vn−2 vn−1 .. but OpenGL will ignore them. then the quadrilateral v2 v3 v5 v4 . Draw the quadrilateral v0 v1 v3 v2 . because you will have multiple calls for each vertex. . Draw the unconnected line segments v0 v1 ..g. . but you have to build other shapes yourself. then use v3 to draw a second triangle.. . Draw a closed loop of lines v0 v1 . Draw the triangle v0 v1 v2 . . and so on. vn−1 v0 . and polygons. and teapots. glEnd(). Draw the quadrilateral v0 v1 v2 v3 . Draw the triangle v0 v1 v2 . . vn−2 vn−1 . vn−1 . The code for drawing primitives has the general form glBegin(mode).3 PRIMITIVE OBJECTS 17 3 Primitive Objects The display() callback function usually contains code to render your model into graphical images. . v2 . . For some modes. There are also various short-cuts for drawing the sets of related polygons (usually triangles) that approximate three-dimensional surfaces.. then use v3 to draw a second triangle. toruses. such as spheres. . All models are built from primitive parts. v2 . Draw the connected line segments v0 v1 . . . lines. then the triangle v3 v4 v5 . vn−2 vn−1 . cones. cylinders. . then the quadrilateral v4 v5 v6 v7 . . for GL_TRIANGLES. v1 . The trade-off is that your program will run slightly more slowly.. . . The polygon drawn in mode GL_POLYGON must be convex. v2 v3 . Separate triangles are often easier to code than triangle strips or fans. and so on. Table 3 explains what OpenGL expects for each value of the parameter mode. and so on (see Figure 14 (c)). vn−1 as vertices (n ≥ 3). Table 3: Primitive Specifiers .

3. The following code changes the boundaries of the viewing volume but maintains an orthographic projection: glMatrixMode(GL_PROJECTION). . the viewing volume is the 2 × 2 cube bounded by −1 ≤ x ≤ 1. x and y must always be specified. The first two. y.3 PRIMITIVE OBJECTS v1 r r 18 5 7 r r ¨ v1 v3 ¨¨ ¢ ¢ ¨ r r ¢ ¢ ¢ ¢ r r vrrr vr  4 rr 0 rr r r  v v r ¢e ¨¨rr ¨ ¢ e rrr ¨ v1 r v5 e   ¢ ¡e er ¢   ¡ e ¨ ¡ e ¢ ¨¨ v4 ¢ ¡ r e¨ v0 r v3 v2 r rrr v2       r r v3 v0   d   r d  v4 v2 v6 (a) GL TRIANGLE STRIP (b) GL TRIANGLE FAN Figure 14: Drawing primitives (c) GL QUAD STRIP window border ¨ ¨¨ ¨ ¨ ¨¨ ¨ 1 ¨ ¨¨ ¨ ¨ ¨¨ ¨ c Y T y ¨ ¨¨ ¨ ¨ ¨¨ ¨ −1 ¨ −1 ¨ ¨¨ ¨¨ ¨ z % ¨ Z ¨ ¨¨ ¨1 E X −1 x 1 Figure 15: Default viewing volume 3. z. The z coordinate defaults to 0. The projection is orthographic (no perspective).1 The Coordinate System When we draw an object. and w. −1 ≤ y ≤ 1. a call to glVertex() may have 2. Objects are visible only if they are inside the viewing volume. (Appendix A. By default. and −1 ≤ z ≤ 1. with the screen in the plane z = 0: see Figure 15. The w coordinate defaults to 1.) Consequently.1 explains the use of w. as if we were viewing the window from infinitely far away. or (occasionally) 4 arguments. where will it be? OpenGL objects have four coordinates: x.

glOrtho(left. z) will be visible if left ≤ x ≤ right. 3. right. The way in which polygons are drawn is determined by calling glPolygonMode(face. bottom ≤ y ≤ top. Note the sign reversal in the Z-axis: this convention ensures that the coordinate system is right-handed. lines will be drawn as 10 × 10 pixel squares separated by 10 pixels (note that A16 = 10102 ). glLineStipple(factor. The pattern is a 16-bit number in which a 0-bit means “don’t draw” and a 1-bit means “do draw”. top.3 PRIMITIVE OBJECTS face GL_FRONT_AND_BACK (default) GL_FRONT GL_BACK mode GL_FILL (default) GL_LINE GL_POINT 19 Table 4: Options for drawing polygons glLoadIdentity(). Table 4 shows the possible values of face and mode. GL_LINES. 3.0. use the following code: glEnable(GL_LINE_STIPPLE). glLineStipple(10. and GL_LINE_LOOP are straightforward. mode).0). y. .0. glLineWidth(10. and −near ≤ z ≤ −far. The default value of size is 1. The factor indicates how much the pattern should be “stretched”. glEnable(GL_LINE_STIPPLE).3 Lines The width of a line is set by glLineWidth(size). The other modes all describe polygons of one sort or another. 0xAAAA). bottom. far). An object at (x. To draw stippled (or dashed) lines.4 Polygons The modes GL_POINTS. The default value of size is 1. GL_LINE_STRIP.2 Points The size of a point is set by glPointSize(size). Example: After the following code has been executed.. 3. pattern). near.

If mode is GL_FLAT. A set of three points defines a plane. which means that GL will use the colours provided at each vertex and interpolated colours for all other points. The distinction between front and back does not matter in the default mode. Example: Suppose that we want to draw a unit cube centered at the origin. Polygons must be convex. we declare a function face() that draws one face of the cube. we declare a function cube() that draws six faces. GL will draw non-planar “polygons”. if you draw a rectangle with red corners at the left and blue corners at the right. If we draw a solid object. We begin by declaring an array pt giving the coordinates of each vertex.3 PRIMITIVE OBJECTS 20 ¨¨ ¨ ¨ ¨¨ ¨ 1 ¨ 5 6 ¨¨ ¨ ¨ ¨¨ ¨ ¨ 2 ¨ ¨¨ ¨ ¨ ¨¨ ¨ 0 4 3 ¨ 7 ¨¨ ¨¨ ¨ ¨ ¨ Figure 16: Labelling the corners of a cube How do we decide which is the front of a polygon? The rule that GL uses is: if the vertices appear in a counter-clockwise order in the viewing window. in which the front and back sides of a polygon are treated in the same way. Figure 17 shows the code required. mode is GL_SMOOTH. the right edge will be blue. execute the following code: . If there are more than three points in a set. By default. providing the vertices in counter-clockwise order when viewed from outside the cube. but lighting and shading effects may be a bit strange. For example. If necessary. there may be no plane that contains them. and the other points will be shades of purple. such as a cube. Finally. convert a concave polygon to two or more convex polygons by adding internal edges. the left edge will be red. Stippling To draw stippled polygons. Next. Colouring The function call glShadeModel(mode) determines the colouring of polygons. the “front” of each face should be the “outside”. with vertices numbered as in Figure 16. the entire polygon has the same colour as its first vertex. we are looking at the front of the polygon. The effect of drawing a concave or re-entrant (self-intersecting) polygon is undefined.

2. } 1). -0. 6. face(0.5.5. 2. 6).5. 3. glVertex3fv(pt[v2]).5. 7). 4. 4). face(1.5 0. } void cube (void) { face(0. 0.5 }. -0. 5).5 -0.3 PRIMITIVE OBJECTS typedef GLfloat Point[3]. Figure 17: Drawing a cube glEnable(GL_POLYGON_STIPPLE). 0. 0.5 -0. This function is defined in Appendix C. Point { { { { { { { { pt[] = { -0. }. }. 7.5. the graphics system must display only the objects that the viewer can see. }.5. -0. Rectangles Since rectangles are used often. face(4. glPolygonStipple(pattern). Since the components of the model are typically . face(2.5 -0. glVertex3fv(pt[v1]).5. int v1.5 0. The argument pattern is a pointer to a 32 × 32 pixel bitmap (322 = 1024 bits = 128 bytes = 256 hex characters).5. -0.5 -0. 7. 0. 3. 1. 0. 3.5. 0.5.5. }. -0.5 Hidden Surface Elimination To obtain a realistic view of a collection of primitive objects. int v3) { glBegin(GL_POLYGON).5. -0.5. int v2. }. 5. 3). glVertex3fv(pt[v0]).5. -0. void face (int v0. 6. 0. 0. 21 0. glRect() for drawing rectangles in the z = 0 plane.5. glVertex3fv(pt[v3]). }. GL provides a special function. face(0. 5.5 0. glEnd(). } }.5.

because images will be alternately drawn and erased. each component of the array corresponds to a pixel in the viewing window. modify your program to use double buffering.). execute the following statement to enable the depth-buffer test: glEnable(GL_DEPTH_TEST). etc. however. In this mode. include the double buffer bit: glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE).3 PRIMITIVE OBJECTS 22 surfaces (triangles.6 Animation If your program has an idle callback function that changes the values of some global variables. To enable hidden surface elimination. • In the display() function. polygons. giving the effect of animation. modify the call to glClear() so that it clears the depthbuffer as well as the colour buffer: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT). To avoid flicker. the step that ensures that invisible surfaces are not rendered is called hidden surface elimination. . • During initialization and after creating the graphics window. • At the end of the display() function include the call glutSwapBuffers(). The depth buffer is a two-dimensional array of numbers. There are various ways of eliminating hidden surfaces. In general. The display will probably flicker. include the depth buffer bit: glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH). several points in the model will map to a single pixel. modify your graphics program as follows: • When you initialize the display mode. • When you initialize the display mode. OpenGL will display your model repeatedly. The depth-buffer is used to ensure that only the point closest to the viewer is actually displayed. OpenGL uses a depth buffer. 3. OpenGL renders the image into one buffer while displaying the contents of the other buffer.

the first three of these are called “model view” transformations and the last is called the “projection” transformation. glMatrixMode() selects the current matrix. or twist. works the other way round: you define the transformations first and then you draw the objects. (Appendix A provides an overview of the theory of representing transformations as matrices. The final value of M is I × T × R = T × R.4 TRANSFORMATIONS 23 4 Transformations The effect of a transformation is to move an object. glRotatef(). Note that model transformations and camera transformations are complementary: for every transformation that changes the model. OpenGL does not provide primitive functions for it. there is a corresponding inverse transformation that changes the camera and has the same effect on the screen. and glScalef(). In the example below. We can apply transformations to: the model. 4. and the other functions change it. I is the identity matrix. This seems backwards. spin. and × denotes matrix multiplication. M is the current matrix. In OpenGL.y.z). T is a translation matrix.x. The OpenGL functions that are used to effect transformations include glMatrixMode(). Consider the following pseudocode: Name Translate Rotate Scale Shear Perspective Effect Move or slide along a straight line Rotate.1 Model View Transformations A transformation is represented by a matrix. glLoadIdentity() initializes it. because we can interleave drawing and transformation operations. or set of objects.y. however. but actually provides greater flexibility in the drawing process.) OpenGL maintains two current matrices: the model view matrix and the projection matrix. the camera (or eye) position. parts of the model. glLoadIdentity(). and the camera “lens”. glTranslatef(x. glMatrixMode(GL MODELVIEW). glLoadIdentity(). OpenGL. glRotatef(a. about an axis through the origin Make an object larger or smaller Turn rectangles into parallelograms Give illusion of depth for 3D objects Table 5: Common transformations . The least important transformation is shearing. glTranslatef(). R is a rotation matrix. with respect to a coordinate system.z). Table 5 describes some common transformations. the left column shows typical code and the right column shows the effect in pseudocode. M := I M := M × T M := M × R You might think it natural to draw something and then transform it.

0. P2 will be displaced from the origin. glMatrixMode(GL_MODELVIEW). glutWireCube(1. Line 3 clears the buffer.0. The program balance. it is often simpler to think of the coordinates moving.5. Although we can think of a transformation as moving either the objects or the coordinate system.0. we rotate the coordinate system (line 8). 1. 15). draw the cone (line 9).0). The first object drawn is a unit cube (line 6).0.0. glLoadIdentity(). 0.0. the transformation T1 × T2) in effect. 15. In practice. line 7 translates the coordinate system up by 0. 0. glutWireSphere(0.0). Since the cone must sit on top of the cube. 1. glTranslatef(0. 0. 0... and . Then P3 is drawn with transformations T1 and T2 (that is.4 TRANSFORMATIONS 1 2 3 4 5 6 7 8 9 10 11 12 13 void display (void) { glClear(GL_COLOR_BUFFER_BIT). Consequently. 0. line 4 selects the model view matrix. which has already been drawn. because changing the position of the camera should change the entire scene. 0.0. glRotatef(-90. When the object P2 is drawn.5.c draws a sphere on the top of a cone which is standing on a cube. for example. the cube is at the origin. but we need a cone with its axis in the Y direction. Note that the rotation in line 10: 1..5 units. glTranslatef(0.0. 2. since no transformations are in effect. we usually define a camera transformation first.0).5. Figure 18 shows the display callback function that constructs this model (the line numbers are not part of the program). 15). } Figure 18: A balancing act 24 initialize model view matrix draw object P1 do transformation T1 draw object P2 do transformation T2 draw object P3 .5. The following example illustrates this way of thinking. The axis of the cone provided by GLUT is the Z axis. glutWireCone(0..0). transformation T1 is in effect. before drawing any objects. 0. the camera is positioned at the origin and is looking in the negative Z direction. By default. and rotate the coordinate system back again (line 10). and line 5 initialize the matrix. glRotatef(90. does not affect the cone. if T1 is a translation. This makes sense.0). 2. The object P1 is drawn without any transformations: it will appear exactly as defined in the original coordinate system. 15.0.

T (the translation). glPushMatrix(). It is always better to push and pop than to apply inverse transformations. Line 12 draws the sphere. but a better place to define it is the reshape function. draw the upper arm. the third column shows the matrix at the top of the stack after each function has executed. 15. we have to get back to a previous coordinate system. The projection matrix can be defined during initialization. with T occupying the top two places.0.) The function glPushMatrix() pushes the current matrix onto the stack. there are three matrices on the stack. Using these functions. 2.0. Line 11 moves the origin to the centre of the sphere. 4. Line 5 post-multiplies the top matrix by R. When pushing and popping matrices. however.0).0. At line 4.0. draw the lower arm.5 units (the height of the cone plus the radius of the sphere) above the top face of the cube. look at Figure 19. glutWireCone(0. To see this. The matrices are shown as I (the identity). 0. Sometimes. move to the elbow joint. and the function glPopMatrix() pops the current matrix off the stack (and loses it). restoring the stack to its value at line 3.2 Projection Transformations The usual practice in OpenGL coding is to define a projection matrix once and not to apply any transformations to it. does have an effect: the two calls do not cancel each other out. it is important to realize that the sequence glPopMatrix(). Note the difference between the stack entries at line 5 and line 7. 0. glRotatef(-90. and R (the rotation).5. Line 7 pushes the stack and copies the top matrix. If the user changes the shape of the viewing . 1. avoids confusion: if it it was not there. but a stack that can contain 32 model view matrices. implementations may provide more. The stack version is more efficient because it is faster to copy a matrix than it is to construct a new matrix and perform a matrix multiplication. There is not just one model view matrix. and the other columns show the matrices lower in the stack. 15). and draw the hand. glPopMatrix(). move to the wrist. Then what? How do we get back to the body to draw the right arm? The solution that OpenGL provides for this problem is a matrix stack. for instance: we could draw the body. The left column contains line numbers for identification. the second column contains code. we could rewrite lines 8–10 of the example as: glPushMatrix().0 + 0. Consider drawing a person. move to the left shoulder. The example demonstrates that we can start at the origin (the “centre” of the model) and move around drawing parts of the model. we would have a coordinate system with a horizontal Y axis and a vertical Z axis. Line 6 pops the product T · R off the stack. which is 2. (The specification of the API requires a stack depth of at least 32 matrices.4 TRANSFORMATIONS 25 2.

and maximum Z. The difference between an orthographic projection and a perspective projection lies in the shape of the viewing volume.0.0. as shown in Figure 20. glPushMatrix().0. 1.0. 1. OpenGL provides the function glFrustum() to define the frustum directly. and the top and bottom of the frustum determine the distances of the nearest and furthest points that are visible. The apex of the pyramid is at the eye.0. glRotatef(10. The viewing volume for a perspective projection is a frustum. right corresponds to maximum X.0. -1. -1. glLoadIdentity(). 4.0. glPushMatrix(). glPushMatrix().0). 1. glOrtho(-1. maximum X. A projection that captures this phenomenon in a two-dimensional view is called a perspective projection. or truncated pyramid. 0.3 Perspective Transformations It is not surprising that distant objects appear to be smaller than close objects: if an object is further from our eyes. We can think of the closer vertical plane as the screen: the closest objects lie in the plane of the screen and other objects lie behind it. the viewing volume for an orthographic projection is a cuboid (rectangular box). The sides of the pyramid determine the visibility of objects in the other two dimensions. glTranslatef(1. respectively: minimum X. minimum Z.0. This code defines an orthographic projection (no perspective) and defines the viewing volume to be a 2 × 2 × 2 unit cube centered at the origin. it will subtend a smaller angle at the eye and hence create a smaller image on the retina.0). bottom corresponds to minimum Y . As we have seen. 0. and top corresponds to maximum Y .0. 0. The callback function reshape() in Figure 12 on page 14 shows how to do this. .0). The six arguments are. glPopMatrix().0.4 TRANSFORMATIONS # 1 2 3 4 5 6 7 Code glLoadIdentity(). maximum Y . The following code illustrates the default settings: glMatrixMode(GL_PROJECTION). the program should respond by changing the projection transformation so that the view is not distorted. 1. Figure 19: Pushing and popping Stack I I T T T ·R T T I I T T I T 26 I I I window. minimum Y . The eye and the apex of the pyramid are at the point labelled O at the left of the diagram. The first four arguments determine the range of X and Y values as follows: left corresponds to minimum X. 0.

If we want a right-handed coordinate system.) Consequently. which is the width of the viewport divided by its height. The second argument. The value of alpha determines the vertical angle subtended by the viewport at the user’s eye. we should position our model somewhere on the negative Z axis. is the aspect ratio. and visible Z values lie in the range −far ≤ Z ≤ −near. The height of the window is h = 2 · near · tan(α/2). near and far. The model is a wire cube whose image .4 TRANSFORMATIONS  rr rr   rr   rr   rr   rr   33   33   3 33   33   3 33   33   33 r top   rr 33   r33 33  left 3   333  33 right  – 33 O – –– r r rr –––rr b & &––r– rr – – & ––– rr ––– bottom ––– ––– rr –––rr ––– r ' E near ' 27 far E Figure 20: Perspective projection with glFrustum() Note that near and far do not correspond directly to Z values. the screen coordinates have X pointing right and Y pointing up. Both projection transformations assume that our camera (or eye) is situated at the origin and is looking in the negative Z direction. its value must satisfy 0◦ < α < 180◦ . rather than positive Z? By convention. Both near and far must be positive. The function gluPerspective() provides another way of defining the frustum that is more intuitive and often convenient. The first argument defines the vertical angle that the viewport subtends at the eye in degrees. Figure 23 shows the effect of a small value of alpha. Thus w = ar · h = 2 · ar · near · tan(α/2). we won’t see anything. This angle is called α in Figure 21. The presence of the aspect-ratio argument makes it easy to use gluPerspective() in a window reshaping callback function: Figure 22 shows a typical example. The model view transformation and the projection transformation must work together in such a way that at least part of the model lies in the viewing volume. Z must point towards the viewer. The last two arguments. determine the nearest and furthest points visible. If it doesn’t. ar in Figure 21. (Why negative Z.

int height) { glViewport(0. 1. 0. The effect is that of viewing the cube from a large distance: the back of the cube is only slightly smaller than the front. } Figure 22: Reshaping with gluPerspective() occupies half of the viewport. @ @@@@ @@@ @@@ @@@ @@@@ @@ @@@@ @@@ @hh h α hhhh hhh hhhh hhh hhhh hhh hhhh view on screen Figure 23: gluPerspective() with a small value of α . gluPerspective(30. height). (GLfloat) width / (GLfloat) height. widht.0. glLoadidentity(). 20).4 TRANSFORMATIONS 3r 33 33 33 33 33 33 ‰ r rr 33 3 rr r w 3 3 rrr r 3 3 r 33rr r j T rr 33 3 r 33 h 33 3α – O r ––– r –––rr ––rr –c– – r –– rr ––– ––– r ––– ––– ––– ' E –r near ' 28 far E Figure 21: Perspective projection using gluPerspective() void reshape (int width. glMatrixMode(GL_PROJECTION).

The effect is of viewing the cube from a small distance: the back of the cube is much smaller than the front. Making alpha larger simulates “zooming out”: the image gets smaller. The . the angle for a regular 50 mm lens is about 27◦ . When the camera is used with a lens with focal length f mm. and the angle for a 100 mm telephoto lens is about 14◦ . Making alpha smaller without moving the model simulates “zooming in”: the image gets larger in the viewport. 2d 4. Although we can use alpha to manipulate the image in any way we please. The angle for a 24 mm wide-angle lens is about 53◦ . the vertical angle subtended by the field of view is 2 tan−1 (12/f ). there is a correct value for it. It takes nine arguments of type GLfloat. Suppose that the user is sitting at a distance d from a screen of height h: the appropriate value of alpha is given by α = 2 tan−1 For example. 12 2 × 24 h .4 TRANSFORMATIONS ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ α e e e e e e e e e e e e 29 d d         d d view on screen Figure 24: gluPerspective() with a large value of α Figure 24 shows the effect of a large value of alpha. The model is again a wire cube whose image occupies half of the viewport. if h = 12 in and d = 24 in. The vertical height of a 35 mm film frame is h = 24 mm. you may find the following comparisons helpful.4 Combining Viewpoint and Perspective The function gluLookAt() defines a model-view transformation that simulates viewing (“looking at”) the scene from a particular viewpoint. If you have used a 35 mm camera. so h/2 = 12 mm. then α = 2 tan−1 ≈ 28◦ .

The height of the viewing window is 2 (dist − 1) tan (alpha/2). Consequently. The idea is that the extension of the object in the Zdirection is less than 2. gluLookAt() sets the camera position to (0. 0 ). The perspective changes. the effect of the call to gluLookAt() is to move the origin to (0.0. 1. as explained above. glMatrixMode(GL_PROJECTION).0. the position of the camera relative to this point is (0. 5). but it is an expensive effect in movies or television because the zoom control of the lens must be coupled to the tracking motion of the camera. 1. consequently. 0. but in a different way. 0. respectively. the next three arguments are the coordinates of a point in the model towards which the camera is directed. Often. . 0. 0. 0. but the near and far planes defined by gluPerspective() are at z = −1 and z = −5. (For example.0 ). and the last three arguments are the components of a vector pointing upwards. 0. 0.0. In the call gluLookAt ( 0. 10.0. 0. 1. Changing the value of dist also changes the size of the image in the viewport. dist). gluLookAt ( 0.0). 1. giving the effect of approaching (if dist gets smaller and the object gets larger) or going away (if dist gets larger and the object gets smaller).0. glLoadIdentity(). 0) (that is. glLoadIdentity(). It is possible to change alpha and dist together in such a way that the size of a key object in the model stays the same while the perspective changes. −10). 0. introducing a call to gluLookAt() has the undesirable effect of making the image disappear altogether! In the following code.0. 0. Changing the value of alpha in Figure 25 changes the size of the object. 0.0. and the vector (0. the function is tricky to use in practice. 0. 0. Although the idea of gluLookAt() seems simple. the cube is beyond the far plane and is invisible. Hitchcock used this trick to good effect in his movies Vertigo and Marnie. 10. Figure 25 demonstrates how to use gluLookAt() and gluPerspective() together. the Y -axis) is pointing upwards. 0). 0. increasing alpha makes the viewing window larger and the object smaller.) This is a rather simple technique in OpenGL.0. glutWireCube(1. gluPerspective(30. The two important variables are alpha and dist. the point of interest in the model is at (0. To ensure that the object is visible. 10). consider a series of diagrams that starts with Figure 23 and ends with Figure 24.4 TRANSFORMATIONS 30 first three arguments define the camera (or eye) position with respect to the origin. glMatrixMode(GL_MODELVIEW). 1. 0. it can be enclosed completely by planes at z = dist − 1 and z = dist + 1.

glutCreateWindow("A Perspective View"). SIZE).0. init().0. } Figure 25: Using gluLookAt() and gluPerspective() .0. dist + 1. 1. glMatrixMode(GL_MODELVIEW). float alpha = 60.1. glLoadIdentity(). 0.0. } void init (void) { glMatrixMode(GL_PROJECTION). 0. void display (void) { glClear(GL_COLOR_BUFFER_BIT). glutInitWindowSize(SIZE. 0.0. 0. float dist = 5. glutMainLoop(). 0.0.0). 1.0. dist . glutInitWindowPosition(100.0).0. glutDisplayFunc(display). } int main (int argc. 50). glLoadIdentity(). gluLookAt ( 0.h> const int SIZE = 500.0.0 ).4 TRANSFORMATIONS 31 #include <GL/glut.0. char *argv[]) { glutInit(&argc. dist. gluPerspective(alpha.0. glutWireCube(1. 0. argv).

for example. 2. we must provide OpenGL with information about the objects in the scene and the lights that illuminate them. This is the simplest case. To obtain realistic lighting effects. this section describes some of the features that OpenGL provides for lighting a scene. Since OpenGL provides reasonable defaults for many properties. Define light sources. there is quite a lot of work to do. If we use the GLUT function glutSolidSphere(). but this does not help us to display a realistic image of a cube of one colour. with current technology. and 4. and this strengthens the illusion that it is three dimensional. glEnable(GL_LIGHT0). however. We can use the default model. this step is unnecessary. We can paint the faces of the cube in different colours. the best we can do is to create the illusion of three-dimensional objects on a two-dimensional screen. To light a model. normal vectors for each vertex of each object. we have to add only a few function calls to a program to obtain simple lighting effects. 1. but it is not enough. Define a lighting model. 3. looks like an irregular hexagon. Define normal vectors. material properties for each object. The following sections describe more of the details. its faces have different brightnesses. in which we add just two lines of code. 5.1 A Simple Example Suppose that we have a program that displays a sphere. We can use the default properties. 3. We must eliminate hidden surfaces by passing GLUT_DEPTH to glutInitDisplayMode() and by clearing GL_DEPTH_BUFFER_BIT in the display function. If a cube is illuminated by a single light source. The following steps would be necessary to illuminate a sphere. because normals are already defined for the sphere and other GLUT solid objects. . Define material properties. We can improve the illusion of depth by simulating the lighting of a scene. we must define: 1. the positions and other properties of the light sources. Appendix B outlines the theory of illumination. 2. A perspective projection of a uniformly-coloured cube. 4. a lighting model. For full realism. The following code should be executed during initialization: glEnable(GL_LIGHTING).5 LIGHTING 32 5 Lighting We talk about “three dimensional” graphics but. Perspective is one kind of illusion.

*/ glVertex3f(x1. glNormal3f(u1.z2). /* Normal for triangle 132. we provide a normal at each vertex.w1).z2). OpenGL will illuminate each rectangle as a flat surface. For example. there is a normal vector at right angles to it. /* Normal for triangle 012.y0. we are using flat polygons as approximations to curved surfaces.z1). We could provide a single normal for each triangle using the following code: glBegin(GL_TRIANGLES).v0. vertices 1 and 2 each have two normals. the code defines six vertices. each with its own normal. If.w0).v1. OpenGL will illuminate the rectangles as if they were curved surfaces.y2.z3).z1).y3.2 Normal Vectors For any plane surface. A pencil standing vertically on a horizontal desktop provides an appropriate mental image. glEnd().z0).y1. glVertex3f(x2. Consider the very simple object shown in Figure 26 consisting of two triangles. The normals at vertices 0 and 3 are perpendicular to the corresponding triangles. As far as OpenGL is concerned. glNormal3f(u0. instead. and provide a better illusion of a sphere. glVertex3f(x2.5 LIGHTING 33 €  f €€€ €€   f 3   f     f € 0  € €€ f   €€  f 2 1 Figure 26: A simple object 5. OpenGL associates normals with vertices rather than surfaces. .*/ glVertex3f(x0.y1. a sphere is constructed of many small rectangles whose edges are lines of latitude and longitude. glVertex3f(x1. there are two ways of specifying normals. In the following code. The other way of describing this object requires a normal for each vertex. Often. Consequently. If we provide a single normal for each rectangle. but it has an important advantage. Note that it is possible for two normals to be associated with the same vertex: in the code above. glVertex3f(x3. The normals at vertices 1 and 2 are computed by averaging the normals for the triangles. This seems surprising at first. each vertex definition is preceded by the definition of the corresponding normal. The function glNormal() defines a normal vector for any vertex definitions that follow it.y2.

y0. glEnd().v3.y3.wa). y1 . y/s. z) gives the vector (x/s. y2 . y3 . where s = x2 + y 2 + z 2 . each component of the arrays norm and vert is an array of three floats.z2). glNormal3f(ua. 34 /* Normal to triangle 012 */ /* Average */ /* Average */ /* Average */ /* Normal to triangle 132 */ /* Average */ We do not usually see code like this in OpenGL programs. because we can simply add the normal vectors at a vertex and then normalize the resulting vector. glNormal3f(ua. glVertex3fv(vert[i]). i++) { glNormal3fv(norm[i]). z2 ). Normalizing the vector (x. z1 ). glVertex3f(x1. } glEnd(). glNormal3f(u0. The following example is more typical. z3 ) is (a. If you include the statement glEnable(GL_NORMALIZE) in your initialization code.y2. However.z1).z2).z0).va. In practice. glBegin{GL_TRIANGLES} for (i = 0. glNormal3f(u3. and (x3 . OpenGL will normalize vectors for you.z3). Each normal vector should be normalized (!) in the sense that its length should be 1. glVertex3f(x2. i < MAX. . the division by n is not usually necessary.v0. glVertex3f(x0. glNormal3f(ua.wa). where a = + b = − c = + y2 − y 1 z2 − z 1 y3 − y 1 z3 − z 1 x2 − x 1 z2 − z 1 x3 − x 1 z3 − z 1 x2 − x 1 y2 − y 1 x3 − x 1 y3 − y 1 To compute the average of n vectors.wa). it is usually more efficient to normalize vectors yourself.y1.va. glNormal3f(ua. simply add them up and divide by n.wa). (x2 .5 LIGHTING glBegin(GL_TRIANGLES). glVertex3f(x1. glVertex3f(x3. c). glVertex3f(x2. b.y1.w3).z1).w0). because it is usually more convenient to store the data in arrays. z/s). Computing Normal Vectors The vector normal to a triangle with vertices (x1 . y.va.va.y2.

Point points[MAX_POINTS]. . The first argument determines which face we are defining. Y = yi .(y2-y1)*(x3-x1). Vector v) { 35 . OpenGL ignores glColor() calls. The function that defines the effect of lighting an object is glMaterialfv() and it requires three arguments. the normalized average vector of a set of vectors { (xi . 2. Instead. q. The second argument is a parameter name. only front faces should be visible. where X = xi . typedef float Point[3]. S S S i=1 i=1 i=1 Figure 27 shows a simple function that computes vector normal for a plane defined by three points p. typedef float Vector[3]. float z1 = points[p][Z].(x2-x1)*(z3-z1) v[Z] = + (x2-x1)*(y3-y1) } q. zi ) | i = 1. float x2 = points[q][X]. in most situations. float y3 = points[r][Y]. v[X] = + (y2-y1)*(z3-z1) v[Y] = . It is usually best to use GL_FRONT because. The third argument provides the value of the corresponding parameter: it is a pointer to an array. int r. and S = X 2 + Y 2 + Z 2 . 3. .5 LIGHTING enum { X. once with GL_FRONT and again with GL_BACK. 2. n } is i=n i=n i=n √ X Y Z . float y2 = points[q][Y]. (Recall that a face is at the “front” if its vertices are given in counterclockwise order as seen by the viewer. float x3 = points[r][X].3 Defining Material Properties When lighting is enabled. and r. Y. Z = zi .) You can specify different properties for front and back faces by calling glMaterialfv() twice. Z }. . float y1 = points[p][Y]. . GL_BACK. 1. void find_normal (int p. float z3 = points[r][Z]. int float x1 = points[p][X]. float z2 = points[q][Z]. Table 6 shows its possible values. the objects. it computes the colour of each point using information about the lights. chosen from an array of points.(z2-z1)*(y3-y1). . and their relative positions. or GL_FRONT_AND_BACK. The possible values are GL_FRONT. 5. Figure 27: Computing normals Formally. . + (z2-z1)*(x3-x1). . yi . .

0. For this reason.2. 0. it is usually white. if a specular colour is defined. 0. OpenGL provides the parameter name GL_AMBIENT_AND_DIFFUSE which sets the ambient and diffuse colours to the same value. 0. dull highlight. a light bulb in your model would have an emissive colour of white or almost white.5 LIGHTING Parameter GL_DIFFUSE GL_AMBIENT GL_AMBIENT_AND_DIFFUSE GL_SPECULAR GL_SHININESS GL_EMISSION Meaning diffuse colour of material ambient colour of material ambient and diffuse specular colour of material specular exponent emissive colour of material Default (0. 1.0. Define an emissive colour for an object if it is emitting light. Properties do not automatically revert to their defaults: if you want to restore a default value. The ambient colour of an object is its colour when it is illuminated by the ambient (or “background”) light in the scene.0 and 128. 5.0.0) 0. A low value gives a large.4 Defining the Lights To use lighting. the diffuse and ambient colours are almost the same. matte objects do not. polished surfaces give specular reflections but dull. The specular exponent determines the smoothness of a specular surface. Defining an emissive colour does not make the object a source of light: you must put a light source at the same position in the scene to provide the light.8. named GL_LIGHT0 through GL_LIGHT7. the second is a .0. consequently. Specular highlights usually have the colour of the light source. The diffuse colour of an object is its colour when it is directly illuminated.0. For example. bright highlight. you must do so explicitly. 0. for example.0.8.2. To enable light n. 0. 1. 1. you must first enable it by calling glEnable(GL_LIGHTING). 0. You must also enable each light that you want to use. Smooth. For most objects. There are three arguments: the first specifies a light.0) 36 Table 6: Parameters for glMaterialfv() The first column of Table 6 shows the parameter names accepted by glMaterialfv(). rather than the object. 1.0. The function glLightfv() specifies the properties of a light and is used in the same way as glMaterialfv().0 (0.0) (0.0) (0. 0.2. OpenGL provides eight lights. Figure 28 shows some examples of the use of glMaterialfv(). and the third column shows the value that will be provided if you do not call glMaterialfv(). “the book is blue”. the shininess of the dark blue sphere must be turned off before drawing the dull red cube. Its value must be between 0. For example.8. call glEnable(GL_LIGHTn). and a high value gives a small. the second column describes the meaning of the parameter. it is what we normally mean when we say. The specular colour of an object produces highlights when the object is directly illuminated.

5

LIGHTING /* Data GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat declarations */ off[] = { 0.0, 0.0, 0.0, 0.0 }; white[] = { 1.0, 1.0, 1.0, 1.0 }; red[] = { 1.0, 0.0, 0.0, 1.0 }; deep_blue[] = { 0.1, 0.5, 0.8, 1.0 }; shiny[] = { 50.0 }; dull[] = { 0.0; }

37

/* Draw a small, dark blue sphere with shiny highlights */ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, deep_blue); glMaterialfv(GL_FRONT, GL_SPECULAR, white); glMaterialfv(GL_FRONT, GL_SHININESS, shiny); glutSolidSphere(0.2, 10, 10); /* Draw a large, red cube made of non-reflective material */ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); glMaterialfv(GL_FRONT, GL_SPECULAR, off); glMaterialfv(GL_FRONT, GL_SHININESS, dull); glutSolidCube(10.0); /* Draw a white, glowing sphere */ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, off); glMaterialfv(GL_FRONT, GL_SPECULAR, off); glMaterialfv(GL_FRONT, GL_SHININESS, dull); glMaterialfv{GL_FRONT, GL_EMISSION, white); glutSolidSphere(10.0, 20, 20); Figure 28: Using glMaterial()

parameter name, and the third is a value for that parameter. Table 7 shows the parameter names and their default values. The diffuse colour is the colour of the directional light that appears to come from the light itself. It is the colour that we normally associate with the light. The default is bright white. The ambient colour is the contribution that the light makes to the ambient colour of the scene. Since ambient light pervades the scene, without appearing to come from any particular direction, the default value is black. The specular colour is the colour given to highlights in specular objects that are illuminated by this light. It is usually the same as the diffuse colour. For example, a brown bottle illuminated by a white light has white highlights. The position of the light can be specified in two ways: if the fourth component of the vector is 0, the light is called directional and the effect is that of a light source infinitely far way. If the fourth component is 1, the light source is called positional and the effect is that of a light at the corresponding point. For example: the vector (−1, 1, 0, 0) is a light source at the left of the scene (x = −1); above it (y = 1); infinitely far away and hence directional (w = 0). This vector would be suitable

5

LIGHTING Parameter GL_DIFFUSE GL_AMBIENT GL_SPECULAR GL_POSITION GL_CONSTANT ATTENUATION GL_LINEAR_ATTENUATION GL_QUADRATIC_ATTENUATION GL_SPOT_DIRECTION GL_SPOT_CUTOFF GL_SPOT_EXPONENT Meaning diffuse colour ambient colour specular colour position constant attenuation linear attenuation quadratic attenuation direction of spotlight cutoff angle of spotlight exponent of spotlight Default (1.0, 1.0, 1.0, 1.0) (0.0, 0.0, 0.0, 1.0) (1.0, 1.0, 1.0, 1.0) (0.0, 0.0, 1.0, 0.0) 1.0 0.0 0.0 (0.0, 0.0, −1.0) 180.0 0.0

38

Table 7: Parameters for glLightfv()

for sunlight. The vector (0, 1, −5, 1) is a light source at the top centre (x = 0, y = 1) of the scene; behind it (z = −5); and at a finite distance (w = 1). This vector would be suitable for an overhead light in a room. Directional lighting requires less computation than positional lighting because there are fewer angles to calculate. In the real world, the intensity of a light decreases with distance. OpenGL calls this decrease “attenuation”. There is no attenuation for a directional light because it is infinitely far away. OpenGL attenuates a positional light source by multiplying the intensity of the light by 1 C + L d + Q d2 where C is the constant attenuation factor, L is the linear attenuation factor, Q is the quadratic attenuation factor, and d is the distance between the light and the object. The default values are C = 1 and L = Q = 0. Including linear and/or quadratic attenuation factors increases the realism of the scene at the expense of extra computation. By default, a light radiates in all directions. A spotlight radiates a cone of light in a particular direction. Obviously, a directional light cannot be a spotlight. To turn a positional light into a spotlight, provide the following values: • GL_SPOT_DIRECTION determines the direction in which the spotlight is pointing. • GL_SPOT_CUTOFF determines the “spread” of the light. It is the angle between the axis of the cone and the edge of the light beam. The default value, 180◦ , corresponds to an omni-directional light (i.e. not a spotlight). If the angle is not 180◦ , it must be between 0◦ and 90◦ . The angle 5◦ gives a highly-focused searchlight effect; the angle 90◦ illuminates anything in front of the light but nothing behind it. • GL_SPOT_EXPONENT determines how the light varies from the axis to the edges of the cone. The default value, 0.0, gives uniform light across the cone; a higher value focuses the light towards the centre of the cone.

5

LIGHTING Parameter GL_LIGHT_MODEL_AMBIENT GL_LIGHT_MODEL_LOCAL_VIEWER GL_LIGHT_MODEL_TWO_SIDE Meaning ambient light intensity simulate a close viewpoint select two-sided lighting Default (0.2, 0.2, 0.2, 1.0) GL_FALSE GL_FALSE

39

Table 8: Parameters for glLightModel()

5.5

Defining a Lighting Model

The function glLightModel() defines a lighting model. The first argument is a parameter name and the second argument is a value for that parameter. Table 8 shows the possible parameter names, their meanings, and their default values. The ambient light intensity determines the colour of the light that pervades the scene, independently of any actual lights. Its default value, dark grey, ensures that you will see something even if your lights are not switched on or are pointing in the wrong direction. In reality, most scenes do have a certain amount of ambient light. For example, a sunlit scene is illuminated not only by the sun (directional and bright yellow) but also by the sky (ambient and light blue). Dark greenish-blue ambient light would be suitable for an underwater scene. For special applications, such as deep space scenes, set the ambient light to black. By default, OpenGL calculates specular reflections with the assumption that the scene is being viewed from infinitely far away. Specifying a local viewer by giving the value GL_TRUE provides more realistic results but requires a considerable amount of additional computation. By default, OpenGL illuminates only the front sides of polygons. (This is true even if you have defined material properties for both sides of your polygons.) In many cases, the back sides of polygons are invisible anyway. For example, the back sides of the polygons of a sphere face the inside of the sphere. Specifying two-sided illumination by giving the value GL_TRUE tells OpenGL to illuminate any face of a polygon that is visible, at the expense of additional computation.

5.6

Putting It All Together

It is usually best to build a lit scene incrementally. Start by enabling lighting and turning on a light: glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); At this point, you are using default values for the properties of the objects in your model and the lights. Next, add statements that provide explicit values when the defaults are not suitable. You will probably want to start by positioning your light (or lights) and then defining the surface properties of your objects. Some interactions may be surprising, although they are realistic. For example, a green object will appear black (and therefore invisible) in red light. Points to note:

. Lines 12 and 13 define the properties of the sun and display it as a solid sphere.. the planet and its moon are illuminated by the sun. } Figure 29: Illuminating the sun 40 • Remember that OpenGL is a state machine. a planet. GL_AMBIENT_AND_DIFFUSE. Once a call has been executed. -dist). It does not compute shadows and it does not recognize objects as obstacles in the light paths.0. its effects remain until undone. glLoadIdentity(). GLfloat pos[] = { 0. the calls that set position must be in your display() callback function. 40).0. Usually. GL_POSITION. If you want moving lights. 0. • If your lights do not move. Line 11 is a translation that moves the sun into the viewing volume. 0.0.. 40.0 }.6. void display (void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT). you will set light positions after choosing the viewpoint (e. GL_POSITION...0.g. glMaterialfv(GL_FRONT. 0. 0. glutSolidSphere(0. dir). .0. 0. For example.0. 1. sun_col). with gluLookAt()) and before making any other transformations. 1. 0. glLightfv(GL_LIGHT0.0.4. but the moon does not disappear when the planet is between it and the sun (lunar eclipse) and it does not throw a shadow on the planet (solar eclipse). 1. Line 14 moves the light source to the centre of the sun so that it will illuminate the planets and satellites drawn in lines 15ff.0 }. If you construct a “solar system” consisting of a sun.0.0. you can set them up during initialization. The code in Figure 29 demonstrates how to do this. 0.0 }.5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 LIGHTING GLfloat dir[] = { 0. • OpenGL has a rather simple view of illumination. pos). • An object which is a light source must be lit twice: once to make it visible and once to make it act as a light source. if you have a number of objects and you make the first one red. glLightfv(GL_LIGHT0. Line 10 introduces a directional light source on the Z axis to illuminate the sun. GLfloat sun_col[] = { 1. glTranslatef(0. all the others will be red unless you explicitly say otherwise.0. and a moon. glMatrixMode(GL_MODELVIEW).

Call glutAddMenuEntry(string. that you write int sub1 = glutCreateMenu(get_key).) To add a submenu to the main menu. Suppose. (That is. Follow the steps below to define a menu without submenus. however. Figure 30 shows an example of the code required for a simple menu. This time. 1. The format of menus is restricted but the functions are easy to use. 3. Write the callback function for the menu. string is the text that appears in the main menu to identify the submenu and num is the value returned by glutCreateMenu() in the first step.num) for each menu item. 6. To create a submenu. Call glutCreateMenu(func) to create the menu. . Complete the submenu with calls to glutAddMenuEntry(). call glutAddSubMenu(string. The value passed to it will be one of the constants that you chose in step 2. 4. Call glutAttachMenu(button) to “attach” the menu to a mouse button.6 ODDS AND ENDS 41 6 6. You must ensure that all selections have different values. build the menu “tree” bottom-up. call glutCreateMenu() as before. 1. num is a constant that will be returned by the callback function when the user selects this item. for example. 2. or GLUT_RIGHT_BUTTON.num). This function has one integer argument and returns nothing. Note that the main menu can contain both simple entries (added with glutAddMenuEntry()) and submenus (added with glutAddSubMenu()). The callback function choose colour() is not called by the program but will be called by GLUT when the user has invked the menu by pressing the right mouse button and has made a selection from the menu. 3.1 Odds and Ends Menus GLUT provides menus. func is the name of a function that will handle menu-selection events (see item 4 below). 2. button should be one of GLUT_LEFT_BUTTON. Write code for the main menu after the submenus.2 Text OpenGL provides two kinds of characters: bit-mapped characters and stroked characters. but do not attach it to a button. Follow the steps below to obtain menus with submenus. string is the string that will be displayed in the menu. GLUT_MIDDLE_BUTTON. The initialization function initialize menu() must be called explicitly by the application program. you should keep a copy of the integer that it returns.

case M_GREEN: /* Action for green selection. y). glutAttachMenu(GLUT_RIGHT_BUTTON). 6): . } Figure 30: Code for a simple menu 6. M_RED). Any transformations currently in effect are applied to the coordinates x and y.2. glutAddMenuEntry("Blue". M_BLUE). for example. The size of each character is determined by the size of pixels on the screen. } } void initialize_menu (void) { glutCreateMenu(choose_colour). */ break. and is fixed. glutAddMenuEntry("Red". glutAddMenuEntry("Green".1 Bitmapped Characters Bitmapped characters. the raster position is (4. glutAddMenuEntry("Quit". are bitmaps that are displayed on the screen without scaling or rotation. The call glRasterPos2f}(x. case M_BLUE: /* Action for blue selection. After executing the following code. default: break. */ break. as their name implies. M_QUIT). then display the character.6 ODDS AND ENDS #define M_RED #define M_GREEN #define M_BLUE 20 21 22 42 void choose_colour (int sel) { switch (sel) { case M_RED: /* Action for red selection.y) sets the raster position to the point (x. */ break. M_GREEN). Two steps are necessary to display a bitmapped character: first. set the raster position for the character.

string[i]). 0. The fonts . 6.0). int y. If there are no translations in the Z direction. 0)). and then moves the raster position right one character-width. ’z’). you will have to compute the line separation using the window height (in pixels) and the range of Y values defined by your projection transformation. The call glutBitmapCharacter(GLUT_BITMAP_9_BY_15. Bitmapped text can be tricky to use because there is no obvious relation between model coordinates and screen coordinates. for (i = 0.0. it is probably not in the viewing volume.0). If the text does not appear on the screen. If you have several lines of text. char *string) { int len. c). 1.0. which is not in the viewing volume of a perspective transformation.y. immediately after glLoadIdentity() in the display function). i < len. glLoadIdentity(). glRasterPos2f(x. and rotated. 5. i++) { glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24. after applying the transformations currently in effect to the point (0. One way to fix this problem is to call glRasterPos3f(x. Figure 31 shows a simple function that you can use to display a string of text at a given position. The call glutStrokeCharacter(font. glTranslatef(3. } } Figure 31: Displaying a string of text 43 glMatrixMode(GL_MODEL_VIEW). Table 9 on page 62 shows the available bitmapped fonts. displays the character with ASCII code c in the given font at the current position (that is. It is sometimes a good idea to display text before applying any model view transformations (that is. len = strlen(string).z). fixed-width font at the current raster position. translated. i. Thus we can display a string without having to change the raster position after each character. the text lies in the plane Z = 0.2. y). glRasterPos2f(1. displays the character ‘z’ in a 9 × 15 pixel.2 Stroked Characters Stroked characters are true objects that can be scaled.6 ODDS AND ENDS void display_string (int x.

you will usually want to scale them. 0. int len.6 ODDS AND ENDS 44 available are GLUT_MONO_ROMAN (fixed width) and GLUT_STROKE_ROMAN (proportional width).1) { buffer[len++] = key. int x. 1. glColor3f(1.0. *p).0. else if (len < LEN .0). stores them in a string. 0. glutSwapBuffers().0. char buffer[LEN]. 1. glRotatef(angle.0).0. *p. The following program illustrates the use of stroked fonts. It reads characters from the keyboard. glLoadIdentity(). } int main(int argc. for (p = buffer. int y) { if (key == 27) exit(0). glutPostRedisplay().0. 0. char **argv) { . and continuously rotates the string in the viewing window. 0.0. glClear(GL_COLOR_BUFFER_BIT).0. glMatrixMode(GL_MODELVIEW). glutPostRedisplay(). Since characters are about 120 units high.h> #define LEN 50 #define HEIGHT 600 #define WIDTH 800 float angle = 0. } void keys (unsigned char key.0). void display (void) { char *p.0. } } void spin (void) { angle += 2. glTranslatef(-400. 0. p++) glutStrokeCharacter(GLUT_STROKE_ROMAN. #include <GL/glut.

glutDisplayFunc(display). glutWireOctahedron (void). For a torus. For a sphere. Their prototypes are listed below. 6. this is not very pretty but may be useful during debugging. glutWireTetrahedron (void).4 Programming Hints Program Development. glLineWidth(3. glutSolidSphere (double radius. int stacks). len = 0.6 ODDS AND ENDS glutInit(&argc. glutSolidDodecahedron (void). int slices. glutWireIcosahedron (void). glutSolidOctahedron (void). glutSolidCone (double radius. glutIdleFunc(spin). A “solid” object looks like a solid. A “wire” object displays as a wire frame. glutWireCone (double radius. int slices. glutWireTorus (double inner. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB). Cones are analogous. HEIGHT). glutSolidIcosahedron (void).3 Special Objects The GLUT library provides several objects that are rather tedious to build. int slices. int sides.3."). int stacks). int rings). int slices. for (len = 0. These objects are fully defined. int stacks). as described in Figure 5. argv). len++) buffer[len] = ’\0’. double outer. with normals. glutSolidTeapot (double size). double outer.0). glutWireTeapot (double size). “slices” are lines of longitude and “stacks” are lines of latitude. This works well if you know exactly what you . double height. glutSolidTetrahedron (void). double height. ESC to quit. int stacks). glutKeyboardFunc(keys). glutMainLoop(). void void void void void void void void void void void void void void void void void void glutWireSphere (double radius. glutInitWindowSize(WIDTH. glutWireDodecahedron (void). int rings). glutWireCube (double size). glutCreateWindow("Enter your name. and they are useful for experimenting with lighting. glutSolidTorus (double inner. len < LEN. } 45 6. glutSolidCube (double size). The recommended way of developing a program is write a specification and a design before starting to code. int sides. “sides” run around the torus and “rings” run around the “tube”. but you should define its material properties yourself.

Then design other fish with different shapes and colours. but fail when put together. In this situation. incremental development may be the best strategy. ask yourself what is most likely to go wrong. only to discover the fatal flaw that makes it unworkable. display a moving ball that bounces off the rails at the sides of a table. the first step might be to make a very simple object. display fifteen (or as many as required) moving. such as pool balls in a simulated game of pool. In choosing the next step. The first version will contain each component in a minimal form. OpenGL is a “state machine” with a very large number of possible states: almost every function changes its state in one way or another. display a moving ball. display two moving balls that collide realistically. enhanced versions are incorporated into the system and the system is tested. The best way to avoid integration failure is to build a simplified version of the complete system at a very early stage. The problem that is most likely to arise with a team project is integration failure: team members build components of the project that work well individually. Debugging Debugging a graphics program is quite different from debugging other kinds of program. • Your application supposed to show a number of moving objects. • Your application is supposed to show an aircraft performing aerobatics. you may not know precisely what you want to do or whether you will be able to do it. The idea is to develop the program in small steps. When the motions are satisfactory. There are two problems here: modelling the aircraft and displaying complex motions. It may be possible to obtain some shapes simply by scaling the original fish. . The following examples illustrate the incremental development of some hypothetical programs. It may be worthwhile to give one of the members of the team the job of maintaining the system while its components are being constructed. • Your application is supposed to show an aquarium full of fish with various sizes and colours swimming around. Check first of all that you can model a single. Consequently. This strategy makes it less likely that you will complete 90% of your graphics project. As each component is developed. replace the cube by a plane. Conventional debugging tools may not be very helpful. ensuring that you have something working at each step. Team Projects. Working on a graphics project with a team can be a rewarding experience because a team can achieve significantly more than an individual in a given amount of time. grey fish and make it swim convincingly. The following increments might be used: display a stationary ball. When you are writing your first graphics programs. such as a wire cube. perform aerobatics. colliding balls. OpenGL programs are prone to integration failure because one component of the program will put OpenGL into a state that other components do not expect.6 ODDS AND ENDS 46 want to do and have accurate knowledge about the capabilities and limitations of the systems on which your program is going to run. but the mere appearance of the image may provide important information that is not usually available. Since the second is harder.

You can find out what is going on by using printf() statements to write in the text window. so that you can make the image change continuously in various ways.2). The performance of OpenGL programs depends on the platform they are running on. the OpenGL program will have access to a text window (stdout) and the graphics window. because this function usually has the most significant effect on the performance of your program. If efficiency is important for your application. The usual cause is that your model is outside the viewing volume. For example. • Check that you have included everything needed to obtain the effect you want.5). try running the program with and without lighting. because these machines use hardware to implement low-level operations such as depth-buffer comparison and polygon shading. Try removing transformations (especially gluLookAt()) or changing them. . By calling this function from various places in your code you can discover what OpenGL is doing or failing to do. Graphics programming often involves a trade-off between detail in the image and speed of the animation. Performance is affected by many factors. • OpenGL may detect errors. If an error is detected in a particular command. • In most development environments. • If illuminated surfaces look strange. Roughly speaking. if you haven’t already got one. that command has no effect. Efficiency Don’t invest a lot of time and effort into making your program efficient until you know you have to do so. you must initialize correctly. Consider this when using incremental development as described above: a cube that performs elegant aerobatics is small consolation if your airplane flies like a snail. But it is nevertheless a mistake to ignore performance issues when using another platform on the grounds that “it will be fast enough on SGI”. you may have computed the normals incorrectly (Section 5. gluErrorString(error_code)). but is strongly dependent on processor speed and graphics controller capabilities. but not both. if (error_code != GL_NO_ERROR) printf("GL error: %s. and clear the depth buffer bit (Section 3. you can have a very detailed image or fast animation. but it does not report them unless you ask it to do so.\n". OpenGL programs usually run well on SGI machines. and enable the depth test.6 ODDS AND ENDS void check_error () { GLenum error_code = glGetError(). Figure 32 shows a function that checks for errors and displays them in your command-line window. for hidden surface elimination. } Figure 32: Obtaining and reporting OpenGL errors 47 • A common and frustrating problem is a blank screen. One way to check this is to plot the normals by drawing a line from each grid-point of the surface in the direction of the normal at that point. put your effort into the display callback function. add an idle callback function.

or by using tesselators and evaluators. such as clipping planes and stencils. You can build models by providing sets of points. If you want fast movement.6 ODDS AND ENDS 48 Every features that you add to an OpenGL program will probably slow it down slightly. but provide improved performance. and jittering. . however. it provides facilities that simplify their implementation. textures. you should not find it hard to learn other features from a book such as OpenGL Programming Guide. Once you have mastered the basic principles of OpenGL programming. such as display lists. shadows. You can use the accumulation buffer for antialiasing. you may have to simplify appearance. Others. Advanced Features This introductory manual does not discuss many of the most interesting features of OpenGL. and fog all contribute to the appearance of the finished picture. depth of field simulation. All you need is time and imagination. but they all take time to compute. may be used both to enhance both capability and performance. reflections. Although OpenGL does not provide direct support for shadows and reflections. Normals. blurring. Some features. illumination. do not introduce new capabilities.

we move from a frame (x. x y z If M = mij is a 3 × 3 matrix. The solution is to use 4 × 4 matrices. we work with many coordinate frames (or “reference systems”) and move between them by using transformations. x y z = x−a = y−b = z−c • Rotate the frame about the z axis through an angle θ.) . consult the Appendix of Computer Graphics: Principles and Practice.1. distribution.1 Scalar. we have  = rx = sy = tz m11 m12 m13 x m11 x + m12 y + m13 z        m21 m22 m23   y  =  m21 x + m22 y + m23 z        z m31 x + m32 y + m33 z m31 m32 m33 which shows that we can represent a scaling or rotation. . y. c). etc. and divide) are defined for real numbers and they obey familiar laws such as commutation. by Foley and van Dam. but there is a mathematical justification that we present briefly in Section A. γ. association. subtract. we will use lower-case Greek letters (α. . z ). but this would be very tedious. z) to a new frame (x . multiply. x y z = x cos θ − y sin θ = x sin θ + y cos θ = z • Scale the axes by factors r. Instead. In the following examples. b. using a 3 × 3 matrix. Affine.      A. (In the following.) to denote scalars. s. . We can view this as an algebraic trick. For details. and t. The familiar operations (add.A SPACES AND TRANSFORMATIONS 49 A Spaces and Transformations We could build build graphical models and view them in a single coordinate frame. and Euclidean Spaces Scalar Space An element of a scalar space is just a real number. • Move the origin to (a. Vector. β. y . but not a translation.

. Vector subtraction (notation: u − v) is the inverse of addition. every vector can be written as (x. Q. P + α(Q − P ) is the sum of a point and a vector. (We will use bold lower-case Roman letters (u. . y. and hence a vector. then P + α(Q − P ) simplifies to P + (Q − P ) = Q. 1) and a vector to be a tuple (x. we get back to Q. y . we have v − v = 0. The sum of a point P and a vector v is a point (notation: P + v). Using component-wise addition and subtraction: • (x. then P + α(Q − P ) is between P and Q. z. The result is a vector and we have laws such as α(β v) = (αβ) v. The dimension of a vector space is the number of vectors in its smallest spanning set. The only operations we can perform on vectors are scaling and rotation. and hence a point.) to denote vectors.. We say that a set. z . y. vector addition is commutative and associative. We can also multiply a vector by a scalar (notation: α v).). y. This is just the limitation we found with 3 × 3 matrices above. Given a scalar α and points P. We can represent every vector in a n-dimensional vector space as a tuple of n real numbers. . . For example. z ∈ R. w. . 1) = (x − x . with x. note that: P and Q are points. y. y − y . . α(Q − P ) is a scalar times a vector. Q − P is an arrow (vector) representing a trip from Q to P . . Intuitively. and hence a vector. Continuing in this way. . An affine space also contains points (notation: P. then P + α(Q − P ) simplifies to P + 0 = P . The zero vector plays a special role in a vector space: it defines an origin. the expression P + α(Q − P ) is called the affine combination of the points P and Q by α. y. Q. by adding this vector to P . the unique zero vector . z. We cannot move the origin. If 0 < α < 1. .) We can add vectors (notation: u + v).A SPACES AND TRANSFORMATIONS 50 Vector Space A vector space is a collection of vectors that obey certain laws. v. . For any vector v. like a vector space. Representation of an Affine Space We define a point to be a tuple (x. If α = 1. 2. . of vectors spans a vector space V if every vector in V can be written as in the form α1 u1 + α2 u2 + · · · + αn un with u1 ∈ U. Q − P is the difference between two points. There is no absolute scale (like inches or centimetres) but we can represent ratios. 1) − (x . which we have not given here. If α = 0. 0). α (u + v) = α u + α v.) The set of points { P + α(Q − P ) | α ∈ R } is defined to be a line in affine space. y. 0): the difference between two points is a vector. z − z . un ∈ U . An affine transformation is a transformation that preserves certain ratios. and z are real numbers. . U . . (This reduction can be derived from the axioms of an affine space. The difference between two points P and Q is a vector (notation: P − Q). Points appear in two operations: 1. z) where x. in a 3-dimensional vector space. z. Affine Space An affine space. . To understand this expression. we can express many geometrical properties in terms of the axioms of an affine space. contains scalars and vectors with the same operations and laws. and we cannot translate a vector.

Euclidean Space We cannot make measurements in an affine space. we write [x. In running text. etc. and • (x. The important transformations are summarized in Figure 33. y. In particular. −ty . 1]T . we write points in the affine space as 4 × 1 matrices (column matrices). The inner product of vectors u = [ux . then cos α = 0 and α = 90◦ and the vectors u and v are orthogonal. translation moves the origin to the point [−tx . the translation that we could not do with 3 × 3 matrices is now possible. vy . y . The advantage of this representation is that all of the transformations that we need for graphics can be expressed as 4 × 4 matrices. y + y . y . y. −tz . y ± y . We introduce distance via inner products. z. The identity transformation doesn’t change anything. z. scaling multiplies x values by sx . z. z + z . It is possible to show formally that this representation satisfies the axioms of an affine space. uz . 0) = (x + x . uy . 0]T and v = [vx . vz . = √ v·v = 2 2 2 vx + vy + vz A. A space in which we can measure distances and angles in this way is called a Euclidean space. y. • The angle α between two vectors u and v is α where u·v cos α = u v If u · v = 0. 1]T (transpose of a 1 × 4 matrix) for a 4 × 1 matrix.        1 0 0 0 0 1 0 0 0 0 1 0 a b c 1               x y z 1           =     x+a y+b z+c 1        In this example and below. The space represented is actually a three-dimensional affine subspace of a four-dimensional vector space. . z ± z . 1): the sum of a point and a vector is a point. z . z . and a point is always the second (or final) term in a product. 1) + (x . and the rotations rotate the frame counterclockwise through an angle θ about the given axis. 0) ± (x . 0]T is u · v = ux vx + uy vy + uz vz The length of a vector v is v We define: • The distance between two points P and Q is P − Q . 0) = (x ± x .A SPACES AND TRANSFORMATIONS 51 • (x. 0): the sum or difference of vectors is a vector. Defining measurement in other ways yields non-Euclidean spaces of various kinds.2 Matrix Transformations We now have the machinery required to define transformations in three-dimensional Euclidean space as 4 × 4 matrices.

we obtain:    TRp =     x cos θ − y sin θ + d x sin θ + y cos θ z 1        and x cos θ − y sin θ + d cos θ   x sin θ + y cos θ + d sin θ  RT p =   z  1         .A SPACES AND TRANSFORMATIONS        52 0 1 0 0 0 tx  0 ty    1 tz   0 1         1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1               1 0 0 0 sx 0 0 0 sy 0 0 0 sz 0 0 0 Scale 0 0 0 1        Identity        Translation 0 0 0 1               1 0 0 0 cos θ − sin θ 0 sin θ cos θ 0 0 0 Rotation θ about X-axis cos θ 0 − sin θ 0 0 sin θ 0 1 0 0 0 cos θ 0 0 0 1               cos θ − sin θ sin θ cos θ 0 0 0 0 0 0 1 0 0 0 0 1        Rotation θ about Y -axis Figure 33: Basic transformations Rotation θ about Z-axis A. then the matrix products T1 T2 and T2 T1 are also transformations. z.3 Sequences of Transformations If T1 and T2 are transformations expressed as matrices. T1 T2 = T2 T1 . 1). Assume    T =                    1 0 0 0 0 1 0 0 0 0 1 0 d 0 0 1 and    R =    cos θ − sin θ sin θ cos θ 0 0 0 0  0 0 1 0 0 0 0 1 Then we have    TR =     cos θ − sin θ sin θ cos θ 0 0 0 0 0 0 1 0 d 0 0 1        and    RT =    cos θ − sin θ sin θ cos θ 0 0 0 0 0 d cos θ 0 d sin θ 1 0 0 1        Applying these transformations to a point p = (x. In general. corresponding to the fact that transformations do not commute. Consider a translation d along the X-axis and a rotation R about the Z axis. y.

z. for example. Similarly. If we view transformations as operating on the coordinate system rather than points. A.) We can think of the transformation T R as first moving to a new coordinate system translated from the original system. It is also closer to the way that graphics software. By similar triangles: x d = x z+d . y. 1]T . the model is behind the screen. An orthographic projection simulates a view from an infinite distance away. z. The size reduction is a natural consequence of viewing the object from a finite distance. the reversal can be expressed by the law −1 −1 (T1 T2 )−1 = T2 T1 . y ): there is no z coordinate because the screen has only two dimensions. With this viewpoint. A projection of this kind is called an orthographic or parallel projection. RT is viewed as first rotating the coordinate system and then translating it. This is not surprising.4 Viewing In order to view a three-dimensional object on a two-dimensional screen. the transformations are applied in the opposite order to their appearance in the matrix product. In other words. y) provides a screen position for each point by ignoring its z coordinate.) The transformed coordinates on the screen are (x . Conceptually. For example. actually works. Orthographic projections do not give a strong sensation of depth because the size of an object does not depend on its distance from the viewer. In Figure 34. The simplest kind of projection simply ignores one coordinate. E represents the eye of the viewer viewing a screen. y. 1]T → (x.A SPACES AND TRANSFORMATIONS r  T        y P   r  T   y    c c E r ' E' E z d 53 P screen Figure 34: Perspective transformation These results show that T R is a rotation followed by a translation and RT is a translation followed by a rotation. Perspective transformations provide a better sense of depth by drawing distant objects with reduced size. The point P in the model is [x. we must project it. such as OpenGL. An object at P in the model. (The x value does not appear in the diagram because it is perpendicular to the paper. the transformation [x. (Algebraically. because we can write T R p as T (R p). the sequence of matrices in a composition of transformations corresponds to the sequence of operations. appears on the screen at the point P . and then rotating the new coordinates. the sequence of operations is reversed.

Since transformed z values depend monotonically on the original z values. The z component has no obvious physical significance but there are advantages in retaining it. we note that        1 0 0 0 0 0 1 0 0 1 0 1/d 0 0 0 1        x y z 1         =       x y z z/d + 1        Unlike the previous points we have seen. Homogenizing this point gives . . the transformation can be inverted only if the z information is retained. 1 . Moreover. This is necessary for transforming normal vectors and for selecting objects from a scene. the transformed point has a fourth coordinate that T xd yd zd is not equal to 1. .A SPACES AND TRANSFORMATIONS y d y z+d 54 = and hence x = xd z+d yd z+d y = To obtain the perspective transformation in matrix form. as we obtained z +d z +d z +d above. . the transformed values can be used for hidden surface elimination.

of a pixel in terms of a formula. We can account for Lambertian reflection in the following way. Technique #3. Technique #1. The nature of this reflection determines the appearance of the object. Suppose that the beam of light has cross-section area A and it strikes the surface of the object at an angle θ. There is no attempt to model properties of the light or its effect on the objects. I. Then I = ki This technique can be used for simple graphics. More precisely. we need to know not only about light but also what happens when light is reflected from an object into our eyes. We assume that there is a single. B. In each case. Note that: • V does not appear in this expression and so the brightness does not depend on the viewer’s position. We assume that each object has an intrinsic brightness ki . not the direction of the viewer. we define the intensity. We assume that there is ambient light (light from all directions) with intensity Ia and that each object has an ambient reflection coefficient ka . Then the apparent brightness of the object is proportional to N · L. Figure 35 shows these vectors: note that V is not necessarily in the plane defined by L and N. point source of light and that the object has diffuse or Lambertian reflective properties. • the brightness is greatest when N and L are parallel (N · L = 1). but it is clearly unsatisfactory.1 Steps to Realistic Illumination We provide various techniques for solving this problem. The first few techniques ignore colour. the effect of technique #2 is very similar to that of technique #1. L is a vector corresponding to the direction of the light.B THEORY OF ILLUMINATION 55 B Theory of Illumination To obtain realistic images in computer graphics. Assume that all vectors are normalized ( N = L = V = 1). increasing the realism at each step. and V is a vector corresponding to the direction of the viewer. This means that the light reflected from the object depends only on the incidence angle of the light. suppose that: N is a vector normal to the surface of the object. This gives I = Ia ka In practice. The apparent brightness to the viewer is inversely proportional to . After striking the object. and • the brightness is smallest when N and L are orthogonal (N · L = 0). The general problem is to compute the apparent colour at each pixel that corresponds to part of the object on the screen. Technique #2. the light is scattered uniformly in all directions. Then the area illuminated is approximately A/ cos θ.

the inner product of the light vector and the surface normal.B THEORY OF ILLUMINATION r d d d d 56 light d N d d T R Viewer d $r Ld $$ s    d   $$$ V $$$ d   X $$ d  $$$$ d $ $ Object Figure 35: Illuminating an object the area illuminated. We usually assume that such light does not contribute to the illumination of the surface. • C (constant attenuation) ensures that a close light source does not give an infinite amount of light. and kd . is given by 1 f = C + L d + Q d2 where: • d is the distance between the light and the object. • L (linear term) allows for the fact that the source is not a point. In practice. this equation becomes I = ia ka + Ip kd (N · L) The value of N · L can be negative: this will be the case if the light is underneath the surface of the object. the incident light intensity from a point source. 0) to keep negative values out of our results. Technique #4. we should use max(N · L. Then I = Ip kd (N · L) If we include some ambient light. Consequently. sources are not true points and there is always some ambient light from reflecting surfaces (except in outer space). f . We introduce Ip . we assume that attenuation. The theoretical rate of attenuation for a point source of light is quadratic. which means that it is proportional to cos θ. and • Q (quadratic term) models the theoretical attenuation from a point source. the diffuse reflection coefficient of the object. Light attenuates (gets smaller) with distance from the source. Then we have I = ia ka + f Ip kd (N · L) . In calculations.

not brown. We introduce a new vector. Lambertian reflection is a property of dull objects such as cloth or chalk. In practice. and Iab ). We assume that: 57 Technique #5. where n = 1 corresponds to a slightly glossy surface and n = ∞ corresponds to a perfect mirror. a brown table made of polished wood that is illuminated by a white light will have specular highlights that are white. We now have Iλ = Iaλ ka Odλ + f Ipλ (kd Odλ (N · L) + ks (R · V)n ) where ks is the specular reflection coefficient and n is the specular reflection exponent. Technique #6. Specular reflection depends on the direction of the viewer as well as the light.B THEORY OF ILLUMINATION Techniques #1 through #4 ignore colour. Ipg . we assume that the brightness is proportional to (R · V)n . For Phong shading (developed by Phong Bui-Tong). Then we have Iλ = Iaλ ka Odλ + f Ipλ (kd Odλ (N · L) + ks Osλ (R · V)n ) This equation represents our final technique for lighting an object and is a close approximation to what OpenGL actually does. we can give the object a specular colour Osλ . The technical name for shininess is specular reflection. • the object has diffuse colour factors Odr . the colour of specular reflection is not completely independent of the colour of the object. g. The actual calculation performed by OpenGL is: n−1 Vλ = Oeλ + Maλ Oaλ + i=0 1 kc + k l d + k q d2 si [Iaλ Oaλ + (N · L)Idλ Odλ + (R · V)σ Isλ Osλ ]i i . The brightness of specular reflection depends on the angle between R and V (the angle of the viewer). All of these numbers are in the range [0. • the light has intensity colour factors corresponding to ambient sources (Iar . Odg . Iag . and Ipb ). which is the direction in which the light would be reflected if the object was a mirror (see Figure 35). For example. Many objects exhibit degrees of shininess: polished wood has some shininess and a mirror is the ultimate in shininess. Technique #7. R (the reflection vector ). b. A characteristic feature of specular reflection is that it has a colour closer to the colour of the light source than the colour of the object. We now have three intensity equations of the form Iλ = Iaλ ka Odλ + f Ipλ kd Odλ (N · L) for λ = r. 1]. and Odb . To allow for this. and • point sources (Ipr .

We must choose a suitable colour for each visible pixel of a polygon: this is called polygon shading. we can either “clamp” the value (that is. we compute a vector normal to the polygon and use it to compute the colour for every pixel of the polygon. Clamping is cheaper computationally and usually sufficient. due to the subjective Mach effect. • N · L is constant (the light source is infinitely far away). B. we simply add their contributions. B. The computation implicitly assumes that: • the polygon is really flat (not an approximation to a curved surface). Flat Shading In flat shading. which exaggerates a change of colour along a line. and • N · V is constant (the viewer is infinitely far away.3 Polygon Shading The objects in graphical models are usually defined as many small polygons.B THEORY OF ILLUMINATION 58 where Vλ = Vertex brightness Maλ = Ambient light model kc = Constant attenuation coefficient kl = Linear attenuation coefficient kq = Quadratic attenuation coefficient d = Distance of light source from vertex si = Spotlight effect Iaλ = Ambient light Idλ = Diffuse light Isλ = Specular light Oeλ = Emissive brightness of material Oaλ = Ambient brightness of material Odλ = Diffuse brightness of material Osλ = Specular brightness of material σ = Shininess of material the subscript λ indicates colour components and the subscript i denotes one of the lights. use 1 instead of the actual result) or reduce all values in proportion so that the greatest value is 1. (The edges are even more visible than we might expect.) . If the sum of the contributions exceeds 1. typically triangles or rectangles.) Flat shading is efficient computationally but not very satisfactory: the edges of the polygons tend to be visible and we see a polyhedron rather than the surface we are trying to approximate.2 Multiple Light Sources If there are several light sources.

. Compute the light intensity for each colour at each vertex using a lighting model (e. Gouraud Shading Gouraud shading is a form of smooth shading that uses a particular kind of interpolation for efficiency.. we compute normals at the vertices of the polygons. For surfaces approximated by polygons. Interpolate intensities along scan lines within the polygons. We compute the colour at each vertex and then colour the polygons by interpolating the colours at interior pixels. we use the average of the surface normals at each vertex. 4. For analytical surfaces. such as spheres and cones. Interpolate intensities along the edges of the polygons. Phong Shading Phong shading is similar to Gouraud shading but interpolates the normals rather than the intensities. averaging over the polygons that meet at the vertex.g. Technique #7 above). these vectors approximate the true surface normals at the vertices. 1. we can compute the normals exactly. If we are using polygons to approximate a smooth surface. 3. Compute the normal at each vertex of the polygon mesh. Phong shading requires more computation than Gouraud shading but gives better results. especially for specular highlights.B THEORY OF ILLUMINATION 59 Smooth Shading In smooth shading. 2.

• Two shorts specifying X and Y positions: glVertex2s(3. For example. int selection). The specifications follow some conventions.]. glu-. The name of a particular function is obtained by taking one character from each “set” {. • Four doubles specifying X. The prefix (gl-. The final “v”. Z.. the argument types are omitted because they must conform to the function name.C FUNCTION REFERENCE 60 C Function Reference Each function of OpenGL is specified by a prototype and a brief explanation.0). listed below.} and optionally adding the character enclosed in brackets [. Add an entry to the current menu. or glut-) is not part of the name..0. The first argument is the text that the user will see and the second argument is the integer that will be passed to the callback function when the user selects this entry. 1.0. the function referred to as glVertex() in these notes may be called with any of the following argument lists.0. . • Function descriptions are in alphabetical sequence by name. When the function definition uses this form. The explanations are brief: you may find the suggested examples help you to understand them. • A name of the form glname{234}{sifd}[v] describes several functions. says that there will be a single argument that is a pointer to an array.. 1. Y . • If a function has many arguments of the same type. the argument types are omitted from the prototype but specified in the explanation that follows it. 5. Function Definitions void glutAddMenuEntry (char *label. • A pointer to an array of three floats: glVertex3fv(ptr).. 4). if present. and W values: glVertex4d(1. The digit gives the number of arguments and the letter gives the type.

61 void glutAddSubMenu (char *label. int menu). Displays one bitmapped character at the current raster position and moves the raster position right by the width of the character. See also glutCreateMenu(). Using multiple calls of glClear() may be less efficient than using | to “OR” mask bits. . int glutBitmapWidth(void *font. Table 9 lists the permitted values of font. Associate the current menu with a mouse button. Clears the specified buffers. glutStrokeCharacter(). void glutAttachMenu (int button). See also glutCreateMenu(). int character). void glClear (GLbitfield mask). The value of the argument must be one of GLUT_LEFT_BUTTON. See also glRasterPos(). Add a sub-menu to the current menu. Marks the beginning of a vertex data list. Table 10 shows the names of the mask bits. int character). void glBegin (GLenum mode). or GLUT_RIGHT_BUTTON. Table 9 lists the permitted values of font.C FUNCTION REFERENCE See also glutCreateMenu(). The first argument is the text that the user will see and the second argument is an integer returned by glutCreateMenu(). The permitted values of mode are given in Table 3 on page 17. GLUT_MIDDLE_BUTTON. void glutBitmapCharacter (void *font. See also glEnd(). Returns the width of the bitmapped character.

Calls to glColor() have no effect if lighting is enabled. there is one argument that points to an array. It is used as an argument to glutCreateSubMenu(). The first three values give the intensities for red. blue. void glColor{34}f[v] (. 24 points proportional width. green. The fourth argument. 1].0). Create a menu and register a callback function that will be invoked when the user makes a selection from the menu. int glutCreateMenu (void (*func)(int selection)). and blue. alpha)... 0.C FUNCTION REFERENCE Font name GLUT_BITMAP_8_BY_13 GLUT_BITMAP_9_BY_15 GLUT_BITMAP_TIMES_ROMAN_10 GLUT_BITMAP_TIMES_ROMAN_24 GLUT_BITMAP_HELVETICA_10 GLUT_BITMAP_HELVETICA_12 GLUT_BITMAP_HELVETICA_18 Description fixed width. Set the clearing colour used for clearing the colour buffers in RGBA mode. if present. 12 points proportional width. 0. The arguments are all of type GLfloat and they are clamped to the range [0. 8 × 13 pixels fixed width. 18 points 62 Table 9: Fonts for glutBitmapCharacter() Buffer Colour Depth Accumulation Stencil Mask bit GL GL GL GL COLOR BUFFER BIT DEPTH BUFFER BIT ACCUM BUFFER BIT STENCIL BUFFER BIT Table 10: Mask bits for clearing void glClearColor (red. . telling the submenu which menu it belongs to.). gives the value of alpha to be used for blending. 10 points proportional width. The values of all arguments should be in the range [0. 0.0. green.0. 10 points proportional width.0. Use this function to set the background colour of your scene. Default void glClearColor (0. 1]. The value passed to the callback function is an integer corresponding to the item selected from the menu by the user. The value returned is an integer that identifies the menu. Set the current colour. respectively. If v is present. 9 × 15 pixels proportional width.

Call glutCreateWindow() before calling glEnable() to turn on special GL features. height). Destroy the window with number win. Turns off one of GL’s capabilities. glutInitWindowPosition(). including GL_DEPTH_TEST. x. See also glEnable(). void glEnable (GLenum capability). The display function has no arguments and does not return a value. width. void glutDestroyWindow(int win). win is the number of the new window’s parent. The value returned is an integer that identifies the window. void glutDisplayFunc (void (*func)(void)). The string title will appear at the top of the window. See also glDisable(). (x. width and height are the width and height of the new window. and glutInitWindowSize(). 63 int glutCreateSubWindow (win. Turns on one of GL’s capabilities. glutAttachMenu(). void glDisable (GLenum capability). and so on. There are many capabilities. y. It is used by programs that support several graphics windows. All arguments are integers. int glutCreateWindow (char *title). The window is not actually displayed on the screen until glutMainLoop() has been entered. Register a callback function that displays the model in the graphics window. GL_FOG.C FUNCTION REFERENCE See also glutAddMenuEntry(). The value returned is a unique identifier for the window. glutAddSubMenu().y) is the location of the new window relative to the parent window’s origin. Creates a window with features that have been previously defined by calls to the initialization functions glutInitDisplayMode(). . See also glutPostRedisplay().

char *gluErrorString (int code). right. bottom. Return the value of the error flag. you can obtain a string describing the error by passing the result to gluErrorString(). Register a callback function that will be called when no other events are being processed. not necessarily the current window. int glutGetWindow(void). If the result is GL_NO_ERROR. Forces previously issued OpenGL commands to begin execution. The first four arguments determine the size of the viewing “window”. Events (such as mouse clicks and keystrokes) apply to the window that contains the cursor. The matrix defines a “viewing volume” for a perspective view in the negative Z direction.. Otherwise. void glFlush (void). near. Defines a projection matrix and multiplies the current projection matrix by it. It is not usually necessary to call glFlush() for programs run on a single-user system. but it is important for programs that run on a network. All functions that apply to windows operate on the current window. int glGetError (void). See also glGetError(). void glutIdleFunc (void (*func)(void)). . glOrtho(). See also glutSetWindow(). Return a string describing the error indicated by code. void glFrustum (left. top. then no error has occurred. The value of win is the integer returned by a call to glutCreateWindow(). All arguments should be GLfloats and far > near > 0. See Also gluPerspective(). far). Only objects whose distance from the viewpoint is between near and far will be drawn. Return the value of the current window.C FUNCTION REFERENCE 64 void glEnd(). Marks the end of a vertex data list introduced by glBegin().

Specify a display mode. char *argv[]). void glutInitWindowPosition (int x. int y). The arguments have the same type as the arguments of main() and are. This function should be called before any other glut.C FUNCTION REFERENCE Mode bit GLUT_RGB GLUT_RGBA GLUT_INDEX GLUT_SINGLE GLUT_DOUBLE GLUT_DEPTH GLUT_STENCIL GLUT_ALPHA GLUT_STEREO GLUT_ACCUM Description Use Use Use Use Use Use Use Use Use Use RGB colour values (default) RGB colour values (same as GLUT_RGB) colour indexes a single colour buffer (default) two colour buffers a depth buffer a stencil buffer a buffer with an alpha component a stereo pair of windows an accumulation buffer 65 Table 11: Display mode bits void glutInit (int argc. the underlying window system chooses the window position. -1). The argument is a bitfield constructed from constants chosen from Table 11 and OR’d together. Default glutWindowPosition (-1. Sets the initial size of the graphics window that is to be created by glutCreateWindow(). Default glutInitWindowSize (300. int height). void glutInitDisplayMode (unsigned int mode). The arguments give the size of the window in pixels. If you do not call this function. Default glutInitDisplayMode (GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH). Initialize the GLUT library. The arguments give the position of the top left corner of the window in screen coordinates (Y = 0 at the top of the screen). 300). Sets the initial position of the graphics window to be created by glutCreateWindow(). the same as the arguments passed to main(). void glutInitWindowSize (int width. . or you call it with negative arguments. by convention.functions.

0 }. . 7.0. Creates the specified light if it has not already been created and defines some of its properties. GLfloat white[] = { 1. 66 void glutKeyboardFunc (void (*func)(key. 1.0).0). GL_DIFFUSE. GL_SPOT_CUTOFF. 180. glLightf(GL_LIGHT0. GL_QUADRATIC_ATTENUATION. The arguments passed to the function are the unsigned char code of the key that was pressed. Default GLfloat black[] = { 0. GL_SPECULAR.0). The second argument is a parameter name. y)). . dir). 0. 0.0. glLightfv(GL_LIGHT0. Register a callback function that handles keyboard events. GL_POSITION.0. GL_SPOT_EXPONENT. glLightf(GL_LIGHT0. GL_LINEAR_ATTENUATION.0. GLfloat values). GL_CONSTANT_ATTENUATION. GLenum name. 0. where n = 0. pos).0. glLightfv(GL_LIGHT0. 0. 1. 2. void glLight{if}[v] (GLenum light. glLightfv(GL_LIGHT0.0.0 }.0. The first argument must be GL_LIGHTn. 1. .0 }.0. The most common form of call is glLightfv. See Table 7 on page 38 for an explanation of the parameter names and values. GLfloat dir[] = { 0.0. .0. 1. GLfloat pos[] = { 0.0). white).0. glLightf(GL_LIGHT0. 1. glLightfv(GL_LIGHT0. glLightfv(GL_LIGHT0. and the current position of the mouse. glLightf(GL_LIGHT0. 0. GL_AMBIENT. 0.0 }. -1. white). 1. x. glLightf(GL_LIGHT0. See also glutSpecialFunc(). and should be one of: GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_POSITION GL_SPOT_DIRECTION GL_SPOT_EXPONENT GL_SPOT_CUTOFF GL_CONSTANT_ATTENUATION GL_LINEAR_ATTENUATION GL_QUADRATIC_ATTENUATION The third argument gives the value of the parameter. 0. 0. 1. GL_SPOT_DIRECTION. black).C FUNCTION REFERENCE See also glutReshapeFunc(). .0). in which case the third argument is a pointer to an array of four GLfloats.

cx. Enters the GLUT processing loop. This function never returns: the program is terminated by executing exit() or by the user closing the graphics window. GL_FALSE). 0. glLightModelf(GL_LIGHT_MODEL_TWO_SIDE. Define properties of the lighting model. cz. uz). Sets the current matrix (top of the stack) to the identity matrix.2. ez.0 }. GL_FALSE). uy. ey . Your “eye” is at (ex . GLfloat [*] value). Sets the width of lines. The vector (ux . glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER. uy . ux. cy . All of the arguments have type GLfloat. uz ) is pointing upwards. void glutMainLoop (void).2. cz ). The first argument is a parameter name. 0. The matrix establishes a point of view for looking at the scene.2. and it should be one of: GL_LIGHT_MODEL_AMBIENT GL_LIGHT_MODEL_LOCAL_VIEW GL_LIGHT_MODEL_TWO_SIDE See Table 8 on page 39 for an explanation of the meanings of these parameters and their values. void glLoadIdentity (void). Defines a viewing matrix and multiplies it to the right of the current GL_MODELVIEW matrix. void glLineWidth (GLfloat width).0. events are processed and the corresponding callback functions are invoked. 1. Default GLfloat amb[] = { 0. cy. . amb). Within this loop. ez ) and you are looking towards the point (cx . void gluLookAt (ex.C FUNCTION REFERENCE 67 void glLightModel{if}[v] (GLenum name. ey. and its value must be greater than 0. glLightModelfv(GL_LIGHT_MODEL_AMBIENT.0. The default value of width is 1.

0. dim). The first argument specifies which face of each polygon is being defined. You are allowed to call glMaterial() twice. y)). or GL_TEXTURE.2. nz). Defines a material property for use in lighting. GL_DIFFUSE. glMaterialfv(GL_FRONT_AND_BACK. GL_EMISSION. the third argument should be a pointer to an array. glMaterialfv(GL_FRONT_AND_BACK. Back faces will not be rendered unless you request GL_LIGHT_MODEL_TWO_SIDE when you call glLightModel(). GL_SHININESS. the user provides a pointer to an array containing the values of the components. void glutMouseFunc (void (*func)(button. bright). glMaterialfv(GL_FRONT_AND_BACK.8 }. In the first form. void glNormal3{bsidf}(nx. Defines a normal vector for the current vertex. See also glutPassiveMotionFunc().8. x. void glNormal3{bsidf}v(p). Register a callback function for mouse movements.C FUNCTION REFERENCE 68 glMaterial{if}[v] (GLenum face. void glutMotionFunc (void (*func)(int x. or GLUT_RIGHT_BUTTON). When v is included in the function name. GL_BACK.0 }. int y)). 0. ny. black). glMaterialfv(GL_FRONT_AND_BACK. 0. GLfloat[*] value). 0. and GL_FRONT_AND_BACK. Default GLfloat dim[] = { 0. all of type int: a mouse button (one of GLUT_LEFT_BUTTON. The callback function must take four arguments.0. black).0 }. See Table 6 on page 36 for an explanation of the parameter names and their meanings. and the current position of the mouse. the user provides the values of the components. Register a callback function that handles mouse events. In the second form. GLenum name.8. shine).0 }. glMaterialfv(GL_FRONT_AND_BACK. The second argument is the name of a parameter and the third argument is the corresponding value. GL_SPECULAR.0. . The allowed values are GL_FRONT. 1. with different values for front and back polygons. and it is given the current mouse coordinates. GL_PROJECTION. 1. Sets the matrix mode to one of GL_MODELVIEW (default).2.2. the state of the button (either GLUT_UP or GLUT_DOWN). void glMatrixMode (GLenum mode).0. GL_AMBIENT. 0. GLfloat black[] = { 0. state.8. GLUT_MIDDLE_BUTTON. GLfloat shine[] = { 0. The function is called when the mouse is dragged with one of its buttons pressed. 0. 0. GLfloat bright[] = { 0.

far).0 and its value must be greater than 0. See also glFrustum(). Only objects whose distance from the viewpoint is between near and far (near ≤ −z ≤ far) will be drawn. or GL_FRONT_AND_BACK. bottom. right. All arguments are GLfloats. and near ≤ −z ≤ far. near. void gluPerspective (alpha. alpha is the vertical angle of the field of view in degrees: it must be positive and less than 180◦ . aspect is the aspect ratio (width/height) of the image. The value of face may be GL_FRONT.C FUNCTION REFERENCE 69 void glOrtho (left.0). right. void glPolygonMode (GLenum face. The value of mode may be GL_POINT (draw vertexes). The function is called when the mouse is dragged without any buttons pressed. This function is used mainly for two-dimensional graphics. right. top. The camera is situated at the origin and is looking in the negative Z direction. glOrtho(). right. The arguments are of type GLfloat. GL_BACK. The call glOrtho2D (left. GL_FILL). y. Controls the drawing mode for a polygon’s front and back faces. Default glPolygonMode (FRONT_AND_BACK. GLenum mode). bottom. . 1. The default value of size is 1. is equivalent to glOrtho (left. Sets the size of a point. GL_LINES (draw edges). -1. top. aspect. void glOrtho2D (left. and it is given the current mouse coordinates. far). Defines an orthographic projection matrix with viewing volume bounded by (x. int y)). void glPointSize (GLfloat size).0. bottom ≤ y ≤ top. A typical value is 28◦ . bottom. Register a callback function for mouse movements. bottom. void glutPassiveMotionFunc (void (*func)(int x. top). near. top). corresponding to a 50mm lens on a 35mm camera. Defines a projection matrix and multiplies the current projection matrix by it. z) where left ≤ x ≤ right. or GL_FILL (draw filled polygon).

See also glutBitmapCharacter(). Requests that the graphics window be redrawn at the next opportunity: glutMainLoop() will eventually invoke the callback function registered by glutDisplayFunc(). y1). The arguments are used in the same way as the coordinates of a vertex (that is. 0. void glPushMatrix (void). See also glPolygonMode(). glLoadIdentity(). y0) and bottom right corner (x1. This function is typically used before displaying a bitmap or bitmapped character. The current transformation is applied to the coordinates. y1). Makes a copy of the current transformation matrix and pushes it onto the stack. Draw a rectangle with top left corner at (x0. See also glPushMatrix(). void glutReshapeFunc (void (*func)(int width. void glutPostRedisplay (void). height). Default void default_reshape (int width.C FUNCTION REFERENCE 70 void glPopMatrix (void). the new width and new height of the window in pixels. The value of the popped matrix is lost. and does not return a value. The rectangle is in the plane z = 0 and is drawn according to the current polygon drawing style. z. y0. The reshape function must accept two arguments. Set the current raster position. int height)). x1. Pops the top matrix of the current matrix stack. See also glPopMatrix(). y. transformations are applied). int height) { glViewport(0. void glRasterPos{234}{sifd}[v] (x. Register a callback function that adjusts the display after the graphics window has been moved or resized. width. w). } . void glRect{sifd}[v] (x0.

Change the cursor image in the current window. x. y. the object is reflected in the corresponding axis. The value of style determines the shape of the cursor. y. The arguments may be positive or negative. not necessarily the current window. z). . Multiples the current matrix by a matrix that rotates counterclockwise through the given angle. Set the current window to be win. z). Multiples the current matrix by a matrix that stretches or shrinks an object along each axis. All functions that apply to windows operate on the current window. Table 12 shows some of the possibilities. void glutSetCursor (int style). Events (such as mouse clicks and keystrokes) apply to the window that contains the cursor. void glScale{fd} (x. The value of win is the integer returned by a call to glutCreateWindow(). y. 0. z). The axis of rotation is a line from the origin (0. 0) to the point (x. See also glutGetWindow(). The object will be distorted if the arguments are not equal. void glutSetWindow(int win). If an argument is −1.C FUNCTION REFERENCE Identifier GLUT_CURSOR_LEFT_ARROW GLUT_CURSOR_RIGHT_ARROW GLUT_CURSOR_TOP_SIDE GLUT_CURSOR_BOTTOM_SIDE GLUT_CURSOR_LEFT_SIDE GLUT_CURSOR_RIGHT_SIDE GLUT_CURSOR_CURSOR_INFO GLUT_CURSOR_DESTROY GLUT_CURSOR_HELP GLUT_CURSOR_CYCLE GLUT_CURSOR_SPRAY GLUT_CURSOR_WAIT GLUT_CURSOR_TEXT GLUT_CURSOR_CROSSHAIR GLUT_CURSOR_FULL_CROSS_HAIR GLUT_CURSOR_NONE Description left arrow right arrow arrow pointing to top of window arrow pointing to bottom of window arrow pointing to left side of window arrow pointing to right side of window pointing hand skull and crossbones question mark rotating arrows spray can wrist watch text insertion marker small cross hair full window cross hair invisible cursor 71 Table 12: Cursor codes glRotate{fd} (angle.

Exchange the “front” colour buffer and the “back” colour buffer. and so on.05 units above and 33. Sets the shading model to either GL_SMOOTH (default) or GL_FLAT. Y + y. See also glutBitmapCharacter(). The callback parameters x and y give the position of the mouse when the key was pressed. A fixed-space Roman font for ASCII characters 32 through 127.76 units wide. int glutStrokeWidth (void *font. This works only if the mode GLUT_DOUBLE was selected in the call to glutInitDisplayMode(). void glTranslate{fd} (x. int x. OpenGL displays the front buffer while the program is drawing into the back buffer.C FUNCTION REFERENCE 72 void glShadeModel (GLenum mode).33 units below the line. Return the width of the given character. z). The font must be a stroked font. int character). The keys are identified by predefined constants: see Table 2 on page 12. such as arrows.33 units below the line. void glutStrokeCharacter (void *font. y. int character). F keys. Each character is 104. All characters sit on a base line and reach up to 119. Z + z). Draws a stroked character at the origin of the current model view and advance the model view matrix by the width of the character. void glutSwapBuffers (void). and delete have regular ASCII codes and are recognized by glutKeyboardFunc(). Z) to (X + x. Note that the keys esc. Stroked characters may be (and usually are) scaled. All characters sit on a base line and reach up to 119. GLUT MONO ROMAN. int y)). backspace. . Y. Registers a callback function for special key codes. There are two fonts available: GLUT STROKE ROMAN. glutStrokeWidth(). Multiples the current matrix by a matrix that translates (moves) an object from (X.05 units above and 33. A proportionally spaced Roman font for ASCII characters 32 through 127. void glutSpecialFunc (void (*func)(int key. See also glutKeyboardFunc().

Defines a pixel rectangle in the viewing window into which the final image is to be mapped. the user provides a pointer to an array containing the coordinates.C FUNCTION REFERENCE 73 void glVertex{234}{sifd} (x. and w) may be provided. The lower-left corner of the viewport is at (x. y) and the viewport has the indicated width and height. Up to four coordinates (x. y. In the first form. z. The arguments are integers. The default viewport is the entire viewing window. z. the user provides the coordinates as arguments. . void glViewport (x. In the second form. width. z defaults to 0 and w defaults to 1. void glVertex{234}v (p). y. height). w). Specifies a vertex. y.

Sign up to vote on this title
UsefulNot useful