Download - Getting Started With OpenGL Peter Grogono
-
8/8/2019 Getting Started With OpenGL Peter Grogono
1/77
Getting Started with OpenGL
Course Notes for COMP 471 and COMP 676
Peter Grogono
January 1998
(Updated by Kim Lanziner, June 1998)
c Peter Grogono, 1998.Th ese notes may be photocopied for st udents t aking courses
in graphics programming at Concordia University.
Department of Computer Science
Concordia University
1455 de Maisonneuve Blvd. West
Mont real, Qu ebec, H3G 1M8
-
8/8/2019 Getting Started With OpenGL Peter Grogono
2/77
C O N T E N T S i
Contents
1 Int ro duct ion 1
1.1 C om pilin g a nd E xecu t in g a n O p en GL P r ogr am . . . . . . . . . . . . . . . . . . 1
1.2 A Simple Op enGL P rogram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.3 Drawing Ob ject s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Op enGL Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2 C allbacks 8
2.1 T he Idle Funct ion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2 K eyb oa rd C allb ack Fu nct ion s . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3 Mou se E vent Callb ack Fu nct ion s . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.4 R esh ap in g t he G rap hics W in dow . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3 P rim it ive O b ject s 17
3.1 T he Coord inat e Syst em . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.2 Point s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3 Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.4 P olygons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.5 Hid den Su rface E limin at ion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.6 Animat ion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4 Transform at ions 23
4.1 Mod el View Tr an sfor mat ion s . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.2 P roject ion Tran sform at ion s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.3 P er sp ect ive Tr an sfor ma t ion s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.4 C omb in in g Viewp oint an d P er sp ect ive . . . . . . . . . . . . . . . . . . . . . . . 29
5 Light ing 32
5.1 A Simple E xample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.2 Normal Vect ors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.3 Defin in g Ma t er ia l P r op er t ies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.4 Defining t he Light s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.5 Defin in g a Light in g Mod el . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.6 P ut t ing It All Toget her . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
-
8/8/2019 Getting Started With OpenGL Peter Grogono
3/77
LIST OF FIGURE S ii
6 O dds and E nds 41
6.1 Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.2 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.2.1 Bit map ped C har act er s . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
6.2.2 St roked C haract er s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.3 Sp ecial Ob ject s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
6.4 P rogramming Hint s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
A Spaces and Transform at ions 49
A.1 Sca la r, Vect or , Affi n e, a nd Eu clid ea n Sp aces . . . . . . . . . . . . . . . . . . . . 49
A.2 Mat rix Tr an sfor mat ion s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
A.3 Sequ en ces of Tr an sfor mat ion s . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
A.4 Viewing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
B T heory of Illum inat ion 55
B.1 St ep s t o R ea list ic Illu min at ion . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
B.2 Mu lt ip le Light Sou rces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
B.3 P olygon Shading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
C Funct ion R eference 60
List of Figures
1 Make file for SGI machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2 Make file for Solar is mach in es . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
3 T he basic Op enGL program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
4 Displayin g a bright red line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
5 Drawing vert ical yellow lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
6 Rot at ing a wire cube . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
7 A callb ack fu nct ion t hat sp in s t he cu be . . . . . . . . . . . . . . . . . . . . . . 10
8 A key b oa rd ca llb ack fu nct ion t h at select s a n a xis . . . . . . . . . . . . . . . . . 11
9 Q uit t in g wit h t h e escape key . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
10 A ca llb ack fu nct ion t ha t resp on ds t o m ou se b ut t on s . . . . . . . . . . . . . . . 13
11 A callback function that responds to dragging the m ouse . . . . . . . . . . . . . 13
12 A callback function that responds to window reshaping . . . . . . . . . . . . . . 14
13 Ma int a in in g sca lin g invar ia nt s . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
-
8/8/2019 Getting Started With OpenGL Peter Grogono
4/77
L I ST O F T A B L E S iii
14 Drawing primit ives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
15 Default viewin g volume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
16 Lab ellin g t he cor ner s of a cu be . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
17 Drawing a cub e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
18 A balancing act . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
19 P ushing and p oppin g . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
20 Perspective projection with g l F r u s t u m( ) . . . . . . . . . . . . . . . . . . . . . 27
21 Perspective projection using g l u P e r s p e c t i v e ( ) . . . . . . . . . . . . . . . . . . 28
22 Reshaping with g l u P e r s p e c t i v e ( ) . . . . . . . . . . . . . . . . . . . . . . . . . 28
23 g l u P e r s p e c t i v e ( ) with a small value of . . . . . . . . . . . . . . . . . . . . 28
24 g l u P e r s p e c t i v e ( ) with a large value of . . . . . . . . . . . . . . . . . . . . . 29
25 Usin g g l u Lo o k At ( ) an d g l u P e r s p e c t i v e ( ) . . . . . . . . . . . . . . . . . . . . 31
26 A simple ob ject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
27 Comput ing normals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
28 Usin g g l Ma t e r i a l ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
29 Illumin at ing t he su n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
30 Cod e for a simple menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
31 Disp layin g a st rin g of t ext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
32 O bt a in in g a nd r ep or t in g O pen GL er ror s . . . . . . . . . . . . . . . . . . . . . . 47
33 Basic t ransformat ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
34 P er sp ect ive t ran sfor mat ion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
35 Illumin at ing an ob ject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
List of Tables
1 Op enGL Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2 Const ant s for sp ecial keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3 P rimit ive Sp ecifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4 Op tion s for d rawin g p olygon s . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5 Common t ransformat ions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
6 P a ra met er s for g l Ma t e r i a l f v ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . 36
7 P a ra met er s for g l Li g h t f v ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
8 P a ra met er s for g l L i g h t Mo d e l ( ) . . . . . . . . . . . . . . . . . . . . . . . . . . 39
9 Font s for g l u t Bi t ma p Ch a r a c t e r ( ) . . . . . . . . . . . . . . . . . . . . . . . . . 62
10 Mask b it s for clearing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
11 Display mode bit s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
12 Cursor codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
-
8/8/2019 Getting Started With OpenGL Peter Grogono
5/77
1 IN T R O D UC T I ON 1
Getting Started with OpenGL
Peter Grogono
J anuary 1998
1 Int ro d uct io n
OpenGL consists of three libraries: the Graphics Library (GL); the Graphics Library Utilities
(GLU); and the Graphics Library Utilities Toolkit (GLUT). Function names begin with g l ,
g l u , or g l u t , depending on which library they belong to.
Several versions of t hese libraries have been implemented. T he explanations and programs
in t hese notes are based on t he Silicon Gr aphics implementat ion. Another implementation,
called Mesa, ha s b een inst alled on t he greek machines. Implementa t ions a re also available
for PCs running linux, Windows 95, or Widows NT.
The main sources for these notes are listed below.
1. OpenGL Programming Guide. Mason Woo, Jackie Neider, and Tom Davis. SecondEdition, Addison-Wesley, 1997. Th e offi cial guide t o learning Op enGL.
2. The OpenGL Utility Toolkit (GLUT) Programming Interface . Mark J . Kilgard. SiliconGraphics, 1997. h t t p : / / r e a l i t y . s g i . c o m/ mj k / s p e c 3 / s p e c 3 . h t ml .
3. The OpenGL Graphics System: a Specification (Version 1.1). Mark Segal and KurtAkeley. Silicon Gra ph ics, 1997.
h t t p : / / www. s g i . c o m/ T e c h n o l o g y / Op e n GL / g l s p e c 1 . 1 / g l s p e c . h t ml .
Since people are constant ly changing t heir web pages and links, you may find th at th e URLs
above do not work. If so, tr y going t o Silicon G raph ics web site ( www. s g i . c o m) an d exploring.
You could also try links from my web pages for COMP 471:
www. c s . c o n c o r d i a . c a / ~ f a c u l t y / g r o g o n o / c o mp 4 7 1 . h t ml .
Appendix C contains specifications of all of the functions mentioned in these notes, and a few
others as well. To use OpenGL eff ect ively, however, you must know not only t he specificat ions
of individual functions but also the way in which these functions work together in programs.
Sections 2 through 6 provide examples of ways in which the functions can be used.
I have tried t o make th is manual as accurat e as possible. If you find errors, omissions, or
misprints, please send an e-mail message to me at [email protected].
1.1 Compiling and Executing an OpenGL P rogram
In order t o run an O penGL program, you must t ell t he compiler where t o find t he header files
and th e linker where to find t he libraries. Th e easiest way t o do t his is to u se a makefile.
Figure 1 shows a makefile suitab le for SGI machines an d Figure 2 shows a makefile suitable for
Solaris machines on greeknet (it does not work for l a mb d a or other machines running Sun).
To compile a program using either of these makefiles, write
-
8/8/2019 Getting Started With OpenGL Peter Grogono
6/77
1 IN T R O D UC T I ON 2
C C = c c
L D L I B S = - l g l u t - l G L - l GL U - l Xmu - l X1 1 - l m
I NCLUDE =
e x e c u t a b l e :
$ ( CC) - g $ ( I NCLUDE) $ ( P ROG) . c \
$ ( LDF LAGS ) $ ( LDLI BS ) - o $ ( P ROG)
Figure 1: Make file for SGI machines
e x e c u t a b l e :
g c c - I / p k g / g l u t / i n c l u d e - I / p k g / me s a / i n c l u d e \
- I / p k g / X1 1 / i n c l u d e - c $ ( P ROG) . c
g c c - o $ ( P ROG) $ ( P ROG) . o - L / p k g / g l u t / l i b - R/ p k g / g l u t / l i b \
- l g l u t - L/ p k g / me s a / l i b - R/ p k g / me s a / l i b - l Me s a GLU - l Me s a GL \
- L / p k g / X1 1 / l i b - R/ p k g / X1 1 / l i b - l Xmu - l Xt - l Xe x t - l X1 1 \
- l s o c k e t - l n s l - l m
Figure 2: Make file for Solaris machines
ma k e P ROG= n a me
where n a me is the name of a C program without an extension. Th e program must containth e directive # i n c l u d e < GL/ g l u t . h > . It may also contain directives to include header files
from other libraries.
To execute the program, enter the following command:
n a me
where n a me is the name of your program, again without any extension.
Th ese steps apply t o a program th at consists of a single C source file. If you write a program
with several source files, you will have to write a suitable make file for it.
Alth ough OpenGL provides a standard API (application programmers interface), many im-
plementations do not provide all of the specified features. Currently (J anuary 1998), the
greeknet machines are running Version 1.1 in the Mesa implementation and the SGI machines
in VA03 are r unn ing Version 1.0 in t he SGI implementat ion. Consequently, t here are a few
features, including interleaved arrays, that work on the Suns but do not work on the O2s.
1.2 A Simple Ope nGL P rogram
Figure 3 shows a simple OpenGL p rogram. Although th is program does nothing useful, it
defines a patt ern that is used by most OpenGL programs. The line numbers are not part of
the program, but are used in the explanation below.
Line 1. Every OpenGL program should include GL/ g l u t . h . The file g l u t . h includes g l u . h ,
g l . h and other header files required by GLUT.
-
8/8/2019 Getting Started With OpenGL Peter Grogono
7/77
1 IN T R O D UC T I ON 3
1 # i n c l u d e < GL / g l u t . h >
2
3 v o i d d i s p l a y ( v o i d )
4 {
5 g l C l e a r ( GL _ C OL OR _ B UF F E R_ B I T ) ;
6 }
7
8 v o i d i n i t ( v o i d )
9 {
1 0 }
1 1
1 2 i n t ma i n ( i n t a r g c , c h a r * a r g v [ ] )
1 3 {
1 4 g l u t I n i t ( &a r g c , a r g v ) ;
1 5 g l u t I n i t D i s p l a y Mo d e ( GL UT _ S I N GL E | G L UT _ R GB A) ;
1 6 g l u t I n i t Wi n d o wS i z e ( 8 0 0 , 6 0 0 ) ;
1 7 g l u t I n i t Wi n d o wP o s i t i o n ( 1 0 0 , 5 0 ) ;
1 8 g l u t Cr e a t e Wi n d o w ( " My f i r s t o p e n G L p r o g r a m" ) ;1 9 i n i t ( ) ;
2 0 g l u t Di s p l a y F u n c ( d i s p l a y ) ;
2 1 g l u t Ma i n L o o p ( ) ;
2 2 r e t u r n 0 ;
2 3 }
Figure 3: The basic OpenGL program
Line 3. You must write a function that displays t he graphical objects in your model. T he
function shown here clears the screen but does not display anything. Your program does
not call this function explicitly, but it will be called at appropriate times by OpenGL.
Line 5. It is usually a good idea t o clear various buff ers before starting t o draw new objects.
The colour buff er, cleared by this call, is where t he image of your model is actually
stored.
Line 8. It is conventional to put standard initialization (the g l u t . . . calls) in the ma i n
program and application dependent initialization in a function with a name like i n i t ( )
or my i n i t ( ) . In t his program, the function i n i t ( ) is defined in lines 8 through 10, does
nothing, and is invoked at line 19.
Line 14. Th e function g l u t I n i t ( ) initializes the OpenGL library. It is conventional to passth e command line arguments t o t his function because it may use some of them. You
will probably not need th is feature.
Line 15. Th e function g l u t I n i t Di s p l a y Mo d e ( ) initializes the display. Its argument is a bit
string.
Deleting th is line would not aff ect th e execution of the program, b ecause the arguments
shown are the default values.
Line 16. This call requests a graphics window 800 pixels wide and 600 pixels high.
-
8/8/2019 Getting Started With OpenGL Peter Grogono
8/77
1 IN T R O D UC T I ON 4
v o i d d i s p l a y ( v o i d )
{
g l Cl e a r ( GL_ COLOR_ BUF F ER _ BI T ) ;
g l Co l o r 3 f ( 1 . 0 , 0 . 0 , 0 . 0 ) ;
g l Be g i n ( GL_ LI NES ) ;
g l Ve r t e x 2 f ( - 1 . 0 , 0 . 0 ) ;
g l Ve r t e x 2 f ( 1 . 0 , 0 . 0 ) ;
g l E n d ( ) ;
g l F l u s h ( ) ;
}
Figure 4: Displaying a bright red line
Line 17. This call says that the left side of the graphics window should be 100 pixels from
th e left of the screen and th e t op of the graphics window should be 50 pixels b elow t he
top of the screen. Note that the Y value is measured from the t op of the screen.
Line 18. Th is call creates t he window using the sett ings given previously. T he t ext in t he
argument becomes the title of t he window. The window does not actually appear on
th e screen until g l u t Ma i n Lo o p ( ) has been called.
Line 19. This is a good place to perform any additional initialization that is needed. Some
initialization, such as calls to g l E n a b l e ( ) , must come after g l u t Cr e a t e Wi n d o w( ) .
Line 20. This call registers th e callback function d i s p l a y ( ) . After executing th e call,
OpenGL knows what function to call t o display your model in th e window. Section 2
describes callback functions.
Line 21. The last statement of an OpenGL program calls g l u t Ma i n Lo o p ( ) . This functionprocesses events until the program is terminated. Well-written programs should provide
th e user with an easy way of stopping t he p rogram, for example by selecting Quit from
a menu or by pressing the esc key.
1.3 Dr awing Obje ct s
All t hat remains is t o describe additions to Figure 3. The first one that we will consider is
an improved d i s p l a y ( ) function. Figure 4 shows a function t hat displays a line. T he call
g l Co l o r 3 f ( 1 . 0 , 0 . 0 , 0 . 0 ) specifies the colour of the line as maximum red, no green, and no
blue.
The construction g l B e g i n ( mode ) ; . . . ; g l E n d ( ) ; is used t o display groups of primitiveobjects. The value ofmode determines th e kind of ob ject : in th is case, GL_ LI NES tells OpenGLto expect one or more lines given as pairs of vertices.
In this case, the line goes from (1, 0) t o (1, 0), as specified by the two calls to g l Ve r t e x 2 f ( ) .If we use th e default viewing region, as in Figure 3, th is line ru ns h orizontally across th e
centre of the window.
The call g l F l u s h ( ) forces previously executed OpenGL commands to begin execut ion. If
OpenGL is run ning on a workstat ion th at communicates d irectly with its graphics subsystem,
-
8/8/2019 Getting Started With OpenGL Peter Grogono
9/77
1 IN T R O D UC T I ON 5
v o i d d i s p l a y ( v o i d )
{
i n t i ;
g l Cl e a r ( GL_ COLOR_ BUF F ER _ BI T ) ;
g l Co l o r 3 f ( 1 . 0 , 1 . 0 , 0 . 0 ) ;
g l Be g i n ( GL_ LI NES ) ;
f o r ( i = - 2 5 ; i < = 2 5 ; i + + )
{
f l o a t x = i / 2 5 . 0 ;
g l Ve r t e x 2 f ( x , - 1 . 0 ) ;
g l Ve r t e x 2 f ( x , 1 . 0 ) ;
}
g l E n d ( ) ;
}
Figure 5: Drawing vertical yellow lines
g l F l u s h ( ) will probably have no eff ect on the b ehaviour of the program. It is important
to use it if your program is running, or might be run, in a client/ server context, however,
because otherwise at tempt s by th e system to optimize packet tran sfers may prevent good
graphics performance.
T he suffi x 3 f indicates that g l Co l o r 3 f ( ) requires th ree arguments of type GLf l o a t . Sim-
ilarly, g l Ve r t e x 2 f ( ) requires two arguments of type GLf l o a t . Appendix C provides more
details of t his notat ional convention and explains why it is used.
The code between g l Be g i n ( ) an d g l E n d ( ) is not restricted to g l calls. Figure 5 shows a
display function t hat uses a loop to draw 51 vertical yellow (red + green) lines across t he
window. Section 3 describes some of the other primitive objects available in OpenGL.
Th e call g l Cl e a r ( GL _ COLOR_ BUF F E R_ BI T ) clears the colour buff er to th e background colour.
You can set the background colour by executing
g l C l e a r Co l o r ( r , g , b , a ) ;
with appropriate values of r , g , b , and a during initialization. Each argument is a floating-
point nu mber in t he range [0, 1] specifying th e amount of a colour ( r ed, g reen, b lue) or blending
(a lpha). The default values are all zero, giving a black background. To make the background
blue, you could call
g l Cl e a r Co l o r ( 0 . 0 , 0 . 0 , 1 . 0 , 0 . 0 ) ;
Blending is an advanced feature; unless you know how to use it, set the fourth argument of
g l Cl e a r Co l o r to zero.
OpenGL allows you to define a viewing volume ; only objects that are inside the viewing
volume will appear on th e screen. Th e following code estab lishes a viewing volume with
orthogonal projection.
-
8/8/2019 Getting Started With OpenGL Peter Grogono
10/77
1 IN T R O D UC T I ON 6
g l Ma t r i x Mo d e ( GL _ P ROJ E CT I ON) ;
g l L o a d I d e n t i t y ( ) ;
g l Or t h o ( l e f t , r i g h t , b o t t o m, t o p , n e a r , f a r ) ;
An object at ( x , y , z ) will be displayed only ifx , y , and z satisfy the following inequalities:
l e f t x r i g h t ,b o t t o m y t o p,
n e a r z f a r .
Th e default projection is orthogonal with boundaries l e f t = b o t t o m = n e a r = 1 andr i g h t = t o p = f a r = 1. T he following version ofi n i t ( ) sets th e background colour to white
and defines a viewing volume in which 0 < x < 5, 0 < y < 5, and 2 < z < 2. Section 3.1describes coordinate systems.
v o i d i n i t ( v o i d )
{g l Cl e a r Co l o r ( 1 . 0 , 1 . 0 , 1 . 0 , 0 . 0 ) ;
g l Ma t r i x Mo d e ( GL _ P ROJ E CT I ON) ;
g l L o a d I d e n t i t y ( ) ;
g l O r t h o ( 0 . 0 , 5 . 0 , 0 . 0 , 5 . 0 , - 2 . 0 , 2 . 0 ) ;
}
Th e last th ree lines of th is function illustr ate th e selection, initialization, and tr ansformation
of th e projection mat rix. Section 4 describes matr ix tran sformations in d etail. To obt ain a
realistic view of a three-dimensional model, you will need a perspective projection rather than
an orthogonal projection, as described in Section 4.3.
1 .4 O pe nG L T y pe s
OpenGL defines a number of types that are usually equivalent to C types. You can use C
types but, if you want to write portable OpenGL programs, it is better to use the OpenGL
types: see Table 1. The suffi x column contains t he lett er t hat is used in function names; for
example, the f in g l Ve r t e x 3 f.
-
8/8/2019 Getting Started With OpenGL Peter Grogono
11/77
1 IN T R O D UC T I ON 7
Suffi x Dat a typ e C Type OpenGL Typ e
b 8-bit int eger s i g n e d c h a r GL b y t e
s 16-bit int eger s h o r t GL s h o r t
i 32-bit int eger i n t or l o n g GL i n t , GLs i z e i
f 32-bit floating point f l o a t GL f l o a t , GL c l a mp f
d 64-bit floating point d o u b l e GL d o u b l e , GLc l a mp d
u b 8-bit unsigned integer u n s i g n e d c h a r GLu b y t e , GL b o o l e a n
u s 16-bit unsigned int eger u n s i g n e d s h o r t GLu s h o r t
u i 32-bit unsigned int eger u n s i g n e d i n t GL u i n t , GL e n u m, GLb i t f i e l d
Table 1: OpenGL Types
-
8/8/2019 Getting Started With OpenGL Peter Grogono
12/77
2 CA L LB A CK S 8
2 C allb acks
GLUT handles events with callback functions. If you want to handle an event, such as a
keystroke or mouse movement, you write a function th at performs the desired action. Th en
you register your function by passing its name as an argument to a function with a name of
th e form g l u t . . . F u n c ( ) , in which . . . indicates which callback you are registering.Since OpenGL defines the argument lists of callback functions, you usually cannot pass infor-
mation in function arguments. Instead, you have t o violate t he programming practices you
have been t aught an d use global variables. Typical Op enGL programs usually contain th e
following component s:
declarat ions of global variables whose values aff ect t he scene; a d i s p l a y ( ) function th at uses t he global variables to draw t he scene; and one or more callback functions that respond to events by changing the values of the
global variables.
T he program in F igure 6 illustrat es th ese conventions. It displays a wire-frame cub e which is
rotated about the X , Y, and Z axes by the angles x _ a n g l e , y _ a n g l e , and z _ a n g l e , which
are st ored as global variables wit h initial values zero. We will add callback functions to t his
program to rotate the cube. The comment Ca l l b a c k r e g i s t r a t i o n h e r e in the m ain
program shows where the callbacks should be registered.
There is one callback function that must be declared in all OpenGL programs: it is the
display callback, and it is registered by calling g l u t Di s p l a y F u n c ( ) with the name of the
display function as its argument.
2.1 The Idle Funct i on
OpenGL calls the idle function when it has noth ing else t o do. T he most common app lication
of the idle function is to provide continuous animation. We will use the idle function to make
th e cube in Figure 6 rotat e. Th e axis of rotat ion is determined by t he global variable a x i s ,
and is the X -axis initially.
1. T he main program must register th e idle function. Th e following call registers an idle
function called s p i n ( ) :
g l u t I d l e F u n c ( s p i n ) ;
2. T he idle function must be declared. It has no arguments and returns no results. Figure 7
shows an idle function that increments one of the angles by 1 (one degree) and requests
that the model b e redisplayed. The global variable a x i s determines which angle is
incremented.
Notice that, after changing the angle, s p i n ( ) does not call d i s p l a y ( ) directly. Instead, it
calls g l u t P o s t R e d i s p l a y ( ) , which informs g l u t Ma i n Lo o p ( ) to redisplay t he model at the
next convenient opportunity.
-
8/8/2019 Getting Started With OpenGL Peter Grogono
13/77
2 CA L LB A CK S 9
# i n c l u d e < GL/ g l u t . h >
# d e f i n e S I ZE 5 0 0
f l o a t x _ a n g l e = 0 . 0 ;
f l o a t y _ a n g l e = 0 . 0 ;
f l o a t z _ a n g l e = 0 . 0 ;
e n u m { X, Y, Z } a x i s = X;
v o i d d i s p l a y ( v o i d )
{
g l Cl e a r ( GL_ COLOR_ BUF F ER _ BI T ) ;
g l Ma t r i x Mo d e ( GL _ MODE L VI E W) ;
g l L o a d I d e n t i t y ( ) ;
g l Ro t a t e f ( x _ a n g l e , 1 . 0 , 0 . 0 , 0 . 0 ) ;g l Ro t a t e f ( y _ a n g l e , 0 . 0 , 1 . 0 , 0 . 0 ) ;
g l Ro t a t e f ( z _ a n g l e , 0 . 0 , 0 . 0 , 1 . 0 ) ;
g l u t Wi r e Cu b e ( 1 . 0 ) ;
g l u t S wa p Bu f f e r s ( ) ;
}
v o i d i n i t ( v o i d )
{
g l Ma t r i x Mo d e ( GL _ P ROJ E CT I ON) ;
g l L o a d I d e n t i t y ( ) ;
g l Or t h o ( - 5 . 0 , 5 . 0 , - 5 . 0 , 5 . 0 , - 5 . 0 , 5 . 0 ) ;}
i n t ma i n ( i n t a r g c , c h a r * a r g v [ ] )
{
g l u t I n i t ( &a r g c , a r g v ) ;
g l u t I n i t Di s p l a y Mo d e ( GLUT _ DOUBLE | GLUT_ RGB) ;
g l u t I n i t Wi n d o wS i z e ( S I Z E , S I Z E) ;
g l u t I n i t Wi n d o wP o s i t i o n ( 1 0 0 , 5 0 ) ;
g l u t Cr e a t e Wi n d o w( " Ro t a t i n g a wi r e c u b e " ) ;
i n i t ( ) ;
/ * Ca l l b a c k r e g i s t r a t i o n h e r e * /
g l u t Di s p l a y F u n c ( d i s p l a y ) ;
g l u t Ma i n Lo o p ( ) ;
}
Figure 6: Rotating a wire cube
-
8/8/2019 Getting Started With OpenGL Peter Grogono
14/77
2 CA L LB A CK S 10
v o i d s p i n ( v o i d )
{
s wi t c h ( a x i s )
{
c a s e X:
x _ a n g l e + = 1 . 0 ;
b r e a k ;
c a s e Y:
y _ a n g l e + = 1 . 0 ;
b r e a k ;
c a s e Z :
z _ a n g l e + = 1 . 0 ;
b r e a k ;
d e f a u l t :
b r e a k ;
}
g l u t P o s t R e d i s p l a y ( ) ;
}
Figure 7: A callback function that spins the cube
2.2 Keyboard Callback Functions
If the program has registered a keyboard callback function, this function is called whenever
th e user presses a key. Th e following st eps modify t he cube pr ogram so that it responds t o
the keys x , y , and z by changing th e axis of rotat ion of the cube.
1. Register a keyboard callback function.
g l u t Ke y b o a r d F u n c ( k e y b o a r d ) ;
2. T he keyboard function is declared as in Figure 8. It receives t hree arguments: th e key
that was pressed, and the current X an d Y coordinates of the mouse.
It would be possible to rewrite k e y b o a r d ( ) so that it called g l u t P o s t R e d i s p l a y ( ) once only,
after the s wi t c h stat ement. Th e advantage of t he code shown is t hat th e scene is redisplayed
only when one of the keys x , y , or z has been pressed; other keys are ignored.The callback function registered by g l u t Ke y b o a r d F u n c ( ) recognizes only keys corresponding
to ASCII graphic characters and esc, sc backspace, and delete. To make your program
respond to other keys, such as the arrow keys and F keys:
1. Register a sp ecial key callback function.
g l u t S p e c i a l F u n c ( s p e c i a l ) ;
-
8/8/2019 Getting Started With OpenGL Peter Grogono
15/77
2 CA L LB A CK S 11
v o i d k e y b o a r d ( u n s i g n e d c h a r k e y , i n t x , i n t y )
{
s wi t c h ( k e y )
{
c a s e x :
a x i s = X;
g l u t P o s t R e d i s p l a y ( ) ;
b r e a k ;
c a s e y :
a x i s = Y;
g l u t P o s t R e d i s p l a y ( ) ;
b r e a k ;
c a s e z :
a x i s = Z ;
g l u t P o s t R e d i s p l a y ( ) ;
b r e a k ;
d e f a u l t :
b r e a k ;}
}
Figure 8: A keyboard callback function t hat selects an axis
2. Declare t he sp ecial key function as follows:
v o i d s p e c i a l ( i n t k e y , i n t x , i n t y )
{
s wi t c h ( k e y )
{
/ * Co d e t o h a n d l e s p e c i a l k e y s * /
}
}
The arguments that OpenGL passes to s p e c i a l ( ) are: the key code, as defined in
Table 2; the X coordinate of the mouse; and the Y coordinat e of t he mouse.
The keyboard callback function in Figure 9 is a useful default: it allows the user to quit the
program by pressing the escape key.
2.3 Mouse Event Callback Functions
There are several ways of using the mouse and two ways of responding to mouse activity. The
first callback function responds to pressing or releasing one of the mouse buttons.
1. Register a mouse callback funct ion.
-
8/8/2019 Getting Started With OpenGL Peter Grogono
16/77
2 CA L LB A CK S 12
GL UT _ KE Y_ F 1 GL UT _ KE Y_ F 8 GL UT _ KE Y_ UP
GL UT _ KE Y_ F 2 GL UT _ KE Y_ F 9 GL UT _ KE Y_ DOWN
G L UT _ K E Y_ F 3 G L UT _ KE Y _ F 1 0 GL U T _ K E Y_ P A GE _ U P
G L UT _ K E Y_ F 4 G L UT _ KE Y _ F 1 1 GL U T _ K E Y_ P A GE _ D OWN
G L UT _ K E Y_ F 5 G L UT _ KE Y _ F 1 2 GL U T _ K E Y_ HO ME
GL UT _ KE Y_ F 6 GL UT _ KE Y_ L E F T GL UT _ KE Y_ E ND
G L UT _ K E Y_ F 7 G L UT _ K E Y_ R I G HT G L UT _ K E Y_ I N S E R T
Table 2: Constants for special keys
# d e f i n e ES CAP E 2 7
v o i d k e y b o a r d ( u n s i g n e d c h a r k e y , i n t x , i n t y )
{
i f ( k e y = = E S C AP E )
e x i t ( 0 ) ;}
Figure 9: Quitting with t he escape key
g l u t Mo u s e F u n c ( mo u s e _ b u t t o n ) ;
2. T he mouse callback funct ion is passed four arguments.
The first argument specifies the but ton. Its value is one of GLUT_ LE F T_ BUTTON ,GLUT _ MI DDLE _ BUTT ON, or GLUT _ RI GHT_ BUTT ON.
Th e second argument specifies the but ton stat e. Its value is one ofGL UT _ DOWN (thebutton has been pressed) or GLUT _ UP (the button has been released).
The remaining two arguments are the X an d Y coordinates of the mouse.Figure 10 shows a mouse function that uses the mouse butt ons to select the axis of
rotation and the X position of the mouse to set the value of the corresponding angle.
T he value ofn e w_ a n g l e will be 0 if the mouse cursor is at t he left of th e Op enGL window
and 360 if the mouse cursor is at th e right of th e window. If the user has changed t he
widt h of the window, th e value of S I Z E will be wrong, and th e results will be d iff erent;
Section 2.4 shows how you can avoid this problem.
An Op enGL program can also respond to dragging events in which th e user holds a mouse
button down and moves the mouse.
1. Register a callback function for mouse dr agging events:
g l u t Mo t i o n F u n c ( d r a g ) ;
-
8/8/2019 Getting Started With OpenGL Peter Grogono
17/77
2 CA L LB A CK S 13
v o i d mo u s e _ b u t t o n ( i n t b u t t o n , i n t s t a t e , i n t x , i n t y )
{
d o u b l e n e w_ a n g l e = x * 3 6 0 . 0 / S I ZE ;
i f ( b u t t o n = = GLUT_ LE F T_ BUTTON && s t a t e = = GLUT_ DOWN)
{
x _ a n g l e = n e w_ a n g l e ;
g l u t P o s t R e d i s p l a y ( ) ;
}
e l s e i f ( b u t t o n = = GLUT_ MI DDLE_ BUTTON && s t a t e = = GLUT_ DOWN)
{
y _ a n g l e = n e w_ a n g l e ;
g l u t P o s t R e d i s p l a y ( ) ;
}
e l s e i f ( b u t t o n = = GLUT_ RI GHT_ BUTTON && s t a t e = = GLUT_ DOWN)
{
z _ a n g l e = n e w_ a n g l e ;
g l u t P o s t R e d i s p l a y ( ) ;
}}
Figure 10: A callback function that responds to mouse buttons
v o i d d r a g ( i n t x , i n t y )
{
z _ a n g l e = 3 6 0 . 0 * x / S I Z E ;
x _ a n g l e = 3 6 0 . 0 * y / S I Z E ;
g l u t P o s t R e d i s p l a y ( ) ;
}
Figure 11: A callback function that responds to dragging the mouse
2. T he motion function is given t he X an d Y coordinat es of th e mouse. Figure 11 shows
a motion function that uses the position of the mouse to set z _ a n g l e an d x _ a n g l e .
The function g l u t P a s s i v e Mo t i o n F u n c ( ) registers a callback function that responds to mouse
movement when no buttons have been pressed.
2.4 Reshaping the Graphics W indow
Whenever th e user moves or resizes t he graphics window, OpenGL informs your program,
provided th at you have registered th e appr opriate callback function. Th e main p roblem with
reshaping is t hat th e user is likely t o change the shape of t he window as well as its size; you
do not want the change to distort your image.
1. Register a callback function th at will respond t o window reshaping:
-
8/8/2019 Getting Started With OpenGL Peter Grogono
18/77
2 CA L LB A CK S 14
v o i d r e s h a p e ( i n t wi d t h , i n t h e i g h t )
{
G L f l o a t w , h ;
g l Vi e wp o r t ( 0 , 0 , wi d t h , h e i g h t ) ;
g l Ma t r i x Mo d e ( GL _ P ROJ E CT I ON) ;
g l L o a d I d e n t i t y ( ) ;
i f ( wi d t h > h e i g h t )
{
w = ( 5 . 0 * wi d t h ) / h e i g h t ;
h = 5 . 0 ;
}
e l s e
{
w = 5 . 0 ;
h = ( 5 . 0 * h e i g h t ) / w i d t h ;
}
g l Or t h o ( - w , w , - h , h , - 5 . 0 , 5 . 0 ) ;
g l u t P o s t R e d i s p l a y ( ) ;}
Figure 12: A callback function th at responds t o window reshaping
g l u t Re s h a p e F u n c ( r e s h a p e ) ;
2. Figure 12 shows a callback function that responds t o a reshape request. The argu-
ments are t he width and height of th e new window, in pixels. Th e function first calls
g l Vi e wp o r t ( ) to updat e the viewport so that it includes t he entire window. Then, it
changes t he view t o mat ch th e shape of the new window in such a way t hat none of th e
scene is lost. The code ensures that:
The ratio w/ h is the same as the ratio wi d t h / h e i g h t ; and The smaller of w an d h is 5.0, ensuring that none of the model will be cut out of
the scene.
If your program uses the mouse position as a source of input, it is a good idea to match the
mouse coordinates t o t he b orders of the graphics window. Figure 13 out lines a program th at
uses t he mouse t o set th e global variables x p o s an d y p o s . Th e callback functions r e s h a p e ( )
an d d r a g ( ) work together to maintain the following invariants:
x p o s = 0 a t t h e left
x p o s = 1 a t t h e r ight
y p o s = 0 a t t h e b ot t om
y p o s = 1 at t he t op
Note:
-
8/8/2019 Getting Started With OpenGL Peter Grogono
19/77
2 CA L LB A CK S 15
T he Y = 0 is t he t op of the screen in mouse coordinates but the bott om of the screenin graphics coordinates.
The code does not ensure that 0 x p o s 1 or 0 y p o s 1 because of an oddity inthe X window system that allows the user to drag the mouse outside an applications
window without the application giving up control.
T he function r e s h a p e ( ) computes the aspect ratio of the new window and passes it tog l u P e r s p e c t i v e ( ) to set up a perspective projection.
-
8/8/2019 Getting Started With OpenGL Peter Grogono
20/77
2 CA L LB A CK S 16
# i n c l u d e < GL/ g l u t . h >
i n t s c r e e n _ wi d t h = 6 0 0 ;
i n t s c r e e n _ h e i g h t = 4 0 0 ;GLf l o a t x p o s = 0 . 0 ;
GLf l o a t y p o s = 0 . 0 ;
v o i d d i s p l a y ( v o i d )
{
/ * d i s p l a y t h e mo d e l u s i n g x p o s a n d y p o s * /
}
v o i d d r a g ( i n t mx , i n t my )
{
x p o s = ( GLf l o a t ) mx / s c r e e n _ wi d t h ;
y p o s = 1 . 0 - ( GLf l o a t ) my / s c r e e n _ h e i g h t ;
g l u t P o s t R e d i s p l a y ( ) ;
}
v o i d r e s h a p e ( i n t wi d t h , i n t h e i g h t )
{
s c r e e n _ wi d t h = wi d t h ;
s c r e e n _ h e i g h t = h e i g h t ;
g l Vi e wp o r t ( 0 , 0 , wi d t h , h e i g h t ) ;
g l Ma t r i x Mo d e ( GL _ P ROJ E CT I ON) ;
g l L o a d I d e n t i t y ( ) ;
g l u P e r s p e c t i v e ( 3 0 . 0 , ( GLf l o a t ) wi d t h / ( GLf l o a t ) h e i g h t , 1 . 0 , 2 0 . 0 ) ;g l u t P o s t R e d i s p l a y ( ) ;
}
i n t ma i n ( i n t a r g c , c h a r * a r g v [ ] )
{
g l u t I n i t ( &a r g c , a r g v ) ;
g l u t I n i t Di s p l a y Mo d e ( GL UT _ RGB) ;
g l u t I n i t Wi n d o wS i z e ( s c r e e n _ wi d t h , s c r e e n _ h e i g h t ) ;
g l u t C r e a t e Wi n d o w( " De mo n s t r a t i o n o f r e s h a p i n g " ) ;
g l u t Di s p l a y F u n c ( d i s p l a y ) ;
g l u t Mo t i o n F u n c ( d r a g ) ;g l u t Re s h a p e F u n c ( r e s h a p e ) ;
g l u t Ma i n Lo o p ( ) ;
}
Figure 13: Maintaining scaling invariants
-
8/8/2019 Getting Started With OpenGL Peter Grogono
21/77
3 P R IM IT I V E O BJ EC T S 17
3 P rim it iv e O b ject s
T he d i s p l a y ( ) callback function u sually contains code to render your model into graphical
images. All models are b uilt from primitive part s. Th ere are a few functions for familiar
objects, such as spheres, cones, cylinders, toruses, and teapots, but you have to build other
shapes yourself. Op enGL provides functions for drawing primitive objects, including points,lines, and polygons. There are also various short-cuts for drawing the sets of related polygons
(usually triangles) that approximate three-dimensional surfaces.
The code for drawing primitives has the general form
g l Be g i n ( mo d e ) ;
. . . . .
g l E n d ( ) ;
Table 3 explains what OpenGL expects for each value of the parameter mo d e . Assume, in
each case, that the code specifies n vertices v0, v1, v2, . . . , v n1. For some modes, n should be
a multiple of something: e.g., for GL_ TRI ANGLE S , n will normally be a multiple of 3. It is notan error t o provide extra vertices, but OpenGL will ignore them. T he polygon drawn in mode
GL_ P OLYGON must be convex.
Figure 14 shows how t he vertices of t riangle and quadrilateral collections are labelled. T he
label numbers are important, to ensure both that the topology of the object is correct and
that the vertices appear in counter-clockwise order (see Section 3.4).
Separate t riangles are often easier to code t han triangle strips or fans. The t rade-off is that
your program will run slightly more slowly, because you will have multiple calls for each vertex.
Mode Value Eff ect
GL_ P OI NT S Draw a point at each of the n vertices.
GL_ LI NES Draw the unconnected line segments v0v1, v2v3, . . . vn2vn1.
GL_ LI NE _ S TR I P Draw the connected line segments v0v1, v1v2, . . . , vn2vn1.
GL_ LI NE _ LOOP Draw a closed loop of lines v0v1, v1, v2, . . . , vn2vn1, vn1v0.
GL_ TRI ANGLES Draw the triangle v0v1v2, t hen the triangle v3v4v5, and so on.
GL_ TRI ANGLE _ S TR I P Draw the triangle v0v1v2, t hen use v3 to draw a second triangle,
and so on (see Figure 14 (a)).
GL_ TRI ANGLE_ F AN Draw the triangle v0v1v2, t hen use v3 to draw a second triangle,
and so on (see Figure 14 (b)).
GL_ QUADS Draw the quadrilateral v0v1v2v3, then the quadrilateral v4v5v6v7,and so on.
GL_ QUAD_ S TR I P Draw the quadrilateral v0v1v3v2, then the quadrilateral v2v3v5v4,
and so on (see Figure 14 (c)).
GL_ P OLYGON Draw a single polygon using v0, v1, . . . , vn1 as vertices (n 3).
Table 3: Primitive Specifiers
-
8/8/2019 Getting Started With OpenGL Peter Grogono
22/77
3 P R IM IT I V E O BJ EC T S 18
rv0
rv1
r
v2
r
v3
r
v4
rv5
e
eee
eee
e
rrrr
r
v0
rv1
rv2
r
v3
r
v4
dd
rrrr
r
v0
r
v1
r
v2
r
v3
r
v4
r
v5
r
v6
r
v7
rrrr
rrrr
(a) GL TRI ANGLE S TRI P (b ) GL TRI ANGLE F AN (c) GL QUAD S TRI P
Figure 14: Drawing primitives
window b order
c
1 x 11
y
1
1
z
1 E X
TY
%Z
Figure 15: Default viewing volume
3.1 The Coordinat e Syst e m
When we draw an object, where will it be? OpenGL objects have four coordinates: x , y , z ,
an d w. The first two, x an d y must always be specified. T he z coordinate defaults to 0. The
w coordinat e defaults t o 1. (Appendix A.1 explains t he use of w.) Consequently, a call t o
g l Ve r t e x ( ) may have 2, 3, or (occasionally) 4 arguments.
Objects are visible only if they are inside the viewing volume . By default, the viewing
volume is the 2 2 cube bounded by 1 x 1, 1 y 1, and 1 z 1, with thescreen in the plane z = 0: see Figure 15. Th e projection is orthographic (no perspective),
as if we were viewing the window from infinitely far away.
The following code changes the boundaries of the viewing volume but maintains an ortho-
graphic projection:
g l Ma t r i x Mo d e ( GL _ P ROJ E CT I ON) ;
-
8/8/2019 Getting Started With OpenGL Peter Grogono
23/77
3 P R IM IT I V E O BJ EC T S 19
f a c e mo d e
GL_ F RONT_ AND_ BACK (default) GL_ F I L L (default)
GL _ F RONT GL _ L I NE
GL _ BACK GL _ P OI NT
Table 4: Options for drawing polygons
g l L o a d I d e n t i t y ( ) ;
g l Or t h o ( l e f t , r i g h t , b o t t o m, t o p , n e a r , f a r ) ;
An object at ( x , y , z ) will be visible if l e f t x r i g h t , b o t t o m y t o p , and n e a r z f a r . Note the sign reversal in t he Z-axis: this convention ensures that the coordinatesystem is right-handed.
3.2 P o int s
The size of a point is set by g l P o i n t S i z e ( s i z e ) . The default value of s i z e is 1.0.
3 .3 Lin es
The width of a line is set by g l L i n e Wi d t h ( s i z e ) . The default value of s i z e is 1.0.
To draw stippled (or dashed) lines, use the following code:
g l E n a b l e ( GL_ LI NE_ S T I P P LE ) ;
g l L i n e S t i p p l e ( f a c t o r , p a t t e r n ) ;
T he p a t t e r n is a 16-bit number in which a 0-bit means dont draw and a 1-bit means do
draw. The f a c t o r indicates how much the pattern should be stretched.
E xample: After the following code has been executed, lines will be drawn as 10 10 pixelsquares separated by 10 pixels (note that A16 = 1 0 1 0 2).
g l E n a b l e ( GL_ LI NE_ S T I P P LE ) ;
g l L i n e Wi d t h ( 1 0 . 0 ) ;
g l L i n e S t i p p l e ( 1 0 , 0 x AAAA) ;
3 .4 P o ly go ns
The modes GL_ P OI NT S , GL_ LI NES , GL_ LI NE _ S TR I P , and GL_ LI NE _ LOOP are straightforward.
Th e other modes all describe polygons of one sort or anot her.
The way in which polygons are drawn is determined by calling g l P o l y g o n Mo d e ( f a c e , mo d e ) ; .
Table 4 shows the possible values of f a c e an d mo d e .
-
8/8/2019 Getting Started With OpenGL Peter Grogono
24/77
3 P R IM IT I V E O BJ EC T S 20
0
12
3
4
56
7
Figure 16: Labelling t he corners of a cube
How do we decide which is the front of a polygon? Th e rule th at GL u ses is: if the vertices
appear in a counter-clockwise order in the viewing window, we are looking at the front of the
polygon. If we draw a solid object, such as a cube, t he front of each face should be the
outside. T he distinction between front and b ack does not mat ter in th e default mode, in
which th e front and back sides of a p olygon are t reated in t he same way.
E xample: Suppose that we want to draw a unit cube centered at the origin, with vertices
numbered as in Figure 16. Figure 17 shows t he code required.
We begin by d eclaring an array p t giving t he coordinates of each vert ex. Next, we declare a
function f a c e ( ) th at draws one face of the cube. Finally, we declare a function c u b e ( ) thatdraws six faces, providing the vertices in counter-clockwise order when viewed from outside
the cube.
Polygons must be convex . Th e eff ect of drawing a concave or re-entrant (self-intersecting)
polygon is und efined. If necessary, convert a concave p olygon t o t wo or more convex polygons
by adding internal edges.
Colouring The function call g l S h a d e Mo d e l ( mo d e ) determines the colouring of polygons.
By default, mo d e is GL _ S MOOT H, which means th at GL will use t he colours provided at each
vertex and interpolated colours for all other points. For example, if you draw a rectangle with
red corners at the left and blue corners at the right, the left edge will be red, the right edgewill be blue, and the other points will be shades of purple.
If mo d e is GL_ F LAT , the entire polygon has the same colour as its first vertex.
A set of th ree points defines a plane. If there are more th an t hree points in a set, th ere may b e
no plane that contains them. GL will draw non-planar polygons, but lighting and shading
eff ects may be a bit strange.
Stippling To draw stippled polygons, execute the following code:
-
8/8/2019 Getting Started With OpenGL Peter Grogono
25/77
3 P R IM IT I V E O BJ EC T S 21
t y p e d e f GLf l o a t P o i n t [ 3 ] ;
P o i n t p t [ ] = {
{ - 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 } } ;
v o i d f a c e ( i n t v 0 , i n t v 1 , i n t v 2 , i n t v 3 )
{
g l B e g i n ( GL_ P OLYGON) ;
g l Ve r t e x 3 f v ( p t [ v 0 ] ) ;
g l Ve r t e x 3 f v ( p t [ v 1 ] ) ;
g l Ve r t e x 3 f v ( p t [ v 2 ] ) ;g l Ve r t e x 3 f v ( p t [ v 3 ] ) ;
g l E n d ( ) ;
}
v o i d c u b e ( v o i d )
{
f a c e ( 0 , 3 , 2 , 1 ) ;
f a c e ( 2 , 3 , 7 , 6 ) ;
f a c e ( 0 , 4 , 7 , 3 ) ;
f a c e ( 1 , 2 , 6 , 5 ) ;
f a c e ( 4 , 5 , 6 , 7 ) ;f a c e ( 0 , 1 , 5 , 4 ) ;
}
Figure 17: Drawing a cube
g l E n a b l e ( GL _ P OLYGON_ S TI P P LE ) ;
g l P o l y g o n S t i p p l e ( p a t t e r n ) ;
Th e argument p a t t e r n is a pointer to a 32 32 pixel b itmap (322 = 1024 bits = 128 bytes =256 hex chara cters).
Rectangles Since rectangles are used often, GL provides a special function, g l Re c t ( ) for
drawing r ectan gles in th e z = 0 plane. This function is defined in Appendix C.
3.5 Hidden Surface Elimination
To obtain a r ealistic view of a collection of primitive objects, t he graphics system must display
only t he objects th at th e viewer can see. Since the components of the model are typically
-
8/8/2019 Getting Started With OpenGL Peter Grogono
26/77
3 P R IM IT I V E O BJ EC T S 22
surfaces (triangles, polygons, etc.), the step that ensures that invisible surfaces are not ren-
dered is called hidden surface elimination . Th ere are various ways of eliminat ing hidden
surfaces; OpenGL uses a d ep t h b uff e r.
Th e depth buff er is a t wo-dimensional array of numbers; each component of t he array corre-
sponds to a pixel in th e viewing window. In general, several p oints in t he model will map to
a single pixel. Th e dept h-buff er is used to ensure that only t he point closest to t he viewer isactua lly displayed.
To enable hidden surface elimination, modify your graphics program as follows:
When you initialize the display mode, include t he depth buff er bit:
g l u t I n i t Di s p l a y Mo d e ( GLUT_ RGBA | GLUT _ DEP TH) ;
During init ialization a nd after creating t he graphics window, execute t he following stat e-ment to enable the depth-buff er test:
g l E n a b l e ( GL _ DEP TH_ TE S T ) ;
In the d i s p l a y ( ) function, modify the call to g l Cl e a r ( ) so that it clears the depth-buff er as well as the colour buff er:
g l Cl e a r ( GL _ COLOR_ BUF F ER _ BI T | GL_ DEP TH_ BUF F ER _ BI T ) ;
3 .6 A n im at io n
If your p rogram h as an idle callback function t hat changes t he values of some global variables,
OpenGL will display your model repeatedly, giving the eff ect of animation. T he display will
probably flicker, however, because images will b e alternat ely drawn an d erased. To avoid
flicker, modify your program to use d o ub le b u ff e ri ng. In t his mode, OpenGL renders the
image into one buff er while displaying the contents of t he other buff er.
When you initialize t he display mode, include the d ouble buff er bit:
g l u t I n i t Di s p l a y Mo d e ( GLUT _ RGBA | GLUT _ DOUBLE) ;
At the end of the d i s p l a y ( ) function include the call
g l u t S wa p Bu f f e r s ( ) ;
-
8/8/2019 Getting Started With OpenGL Peter Grogono
27/77
4 T R A N SFO R M AT I ON S 23
4 Transformations
The eff ect of a transformation is to move an object, or set of objects, with respect to a
coordinat e system. Table 5 describes some common tr ansformations. T he least important
transformation is shearing; OpenGL does not provide primitive functions for it.
We can apply t ransformations t o: th e model; part s of the model; th e camera (or eye) p osition;
and the camera lens.
In OpenGL, the first three of these are called model view transformations and the last is
called th e projection t ransformation. Note t hat model transformations and camera tr ans-
formations are complementary: for every tr ansformation th at changes t he model, t here is a
corresponding inverse transformat ion t hat changes t he camera and has t he same eff ect on t he
screen.
The OpenGL functions that are used to eff ect transformations include g l Ma t r i x Mo d e ( ) ,
g l L o a d I d e n t i t y ( ) , g l Tr a n s l a t e f ( ) , g l Ro t a t e f ( ) , and g l S c a l e f ( ) .
4.1 Model View Transformations
A transformation is represented by a matrix. (Appendix A provides an overview of the
th eory of representing t ransformat ions as mat rices.) Op enGL maintains two curr ent mat rices:
t he m o d e l v i ew m a t ri x and the projection matrix. g l Ma t r i x Mo d e ( ) selects the current
matrix; g l L o a d I d e n t i t y ( ) initializes it; and th e other functions change it. In t he example
below, t he left column shows typical code and t he right column shows th e eff ect in pseudocode.
M is the current matrix, I is the identity matrix, T is a translation matrix, R is a rotation
matrix, and denotes mat rix multiplication. T he final value ofM is I T R = T R .
g l Ma t r i x Mo d e ( GL MODE L VI E W) ;
g l L o a d I d e n t i t y ( ) ; M := I
g l T r a n s l a t e f ( x , y , z ) ; M := M Tg l R o t a t e f ( a , x , y , z ) ; M := M R
You might think it natural to draw something and then transform it. OpenGL, however, works
th e oth er way round: you define the transformations first an d t hen you dr aw the objects. Th is
seems backwards, but actually provides greater flexibility in the drawing process, because we
can interleave drawing and transformation operations. Consider the following pseudocode:
Name Eff ect
Translate Move or slide along a straight line
R otate R otate, spin, or twist, about an axis through the origin
Scale Make an object larger or sm aller
Shear Turn rectangles into parallelograms
Perspective Give illusion of dept h for 3D objects
Table 5: Common tr ansformations
-
8/8/2019 Getting Started With OpenGL Peter Grogono
28/77
4 T R A N SFO R M AT I ON S 24
1 v o i d d i s p l a y ( v o i d )
2 {
3 g l C l e a r ( GL _ C OL OR _ B UF F E R _ B I T ) ;
4 g l Ma t r i x Mo d e ( G L _ MO DE L V I E W) ;
5 g l L o a d I d e n t i t y ( ) ;
6 g l u t Wi r e C u b e ( 1 . 0 ) ;
7 g l T r a n s l a t e f ( 0 . 0 , 0 . 5 , 0 . 0 ) ;
8 g l R o t a t e f ( - 9 0 . 0 , 1 . 0 , 0 . 0 , 0 . 0 ) ;
9 g l u t Wi r e C o n e ( 0 . 5 , 2 . 0 , 1 5 , 1 5 ) ;
1 0 g l R o t a t e f ( 9 0 . 0 , 1 . 0 , 0 . 0 , 0 . 0 ) ;
1 1 g l T r a n s l a t e f ( 0 . 0 , 2 . 5 , 0 . 0 ) ;
1 2 g l u t Wi r e S p h e r e ( 0 . 5 , 1 5 , 1 5 ) ;
1 3 }
Figure 18: A balancing act
i n i t i a l i z e mo d e l v i e w ma t r i x
d r a w o b j e c t P 1
d o t r a n s f o r ma t i o n T1
d r a w o b j e c t P 2
d o t r a n s f o r ma t i o n T2
d r a w o b j e c t P 3
. . . . .
Th e object P 1 is drawn without any transformations: it will appear exactly as defined in the
original coordinate system. When t he object P 2 is drawn, transformation T 1 is in eff ect; if
T 1 is a translation, for example, P 2 will be displaced from the origin. Then P 3 is drawn with
transformations T 1 an d T 2 (that is, the transformation T 1 T 2 ) in eff ect.In practice, we usually define a camera transformation first, before drawing any objects. This
makes sense, because changing the position of the camera should change the entire scene. By
default, th e camera is positioned at th e origin an d is looking in th e negative Z direction.
Although we can think of a transformation as moving either the objects or the coordinate sys-
tem, it is often simpler to think of the coordinates moving. The following example illustrates
this way of thinking.
The program b a l a n c e . c draws a sphere on the top of a cone which is standing on a cube.
Figure 18 shows th e display callback function t hat construct s t his model (th e line numbers
are not part of the p rogram).
Line 3 clears t he buff er, line 4 selects th e model view matrix, and line 5 initialize the matr ix.
Th e first object drawn is a unit cube (line 6); since no transformations are in eff ect, th e cube
is at the origin. Since the cone must sit on t op of the cube, line 7 translates t he coordinate
system up by 0.5 units.
Th e axis of the cone provided by GLUT is the Z axis, but we need a cone with its axis in t he
Y direction. Consequently, we rotat e t he coordinate system (line 8), draw t he cone (line 9),
and rotate the coordinate system back again (line 10). Note that the rotation in line 10:
1. d oes not aff ect th e cone, which has already been drawn; and
-
8/8/2019 Getting Started With OpenGL Peter Grogono
29/77
4 T R A N SFO R M AT I ON S 25
2. avoids confusion: if it it was not there, we would have a coordinate system with a
horizontal Y axis and a vertical Z axis.
Line 11 moves the origin to the centre of the sphere, which is 2.0 + 0.5 units (the height of the
cone plus t he radius of th e sphere) ab ove the top face of t he cube. Line 12 draws the sphere.
The example demonstrates that we can start at the origin (the centre of the model) andmove around drawing parts of the model. Sometimes, however, we have to get back to a
previous coordinate system. Consider drawing a person, for instance: we could draw t he
body, move t o t he left shoulder, d raw t he upp er arm, move to th e elbow joint, draw t he lower
arm, move to the wrist, and draw the hand. Then what? How do we get back t o the b ody to
draw the right arm?
The solution that OpenGL provides for this problem is a matrix stack. There is not just one
model view matrix, but a stack that can contain 32 model view matrices. (The specification of
the API requires a stack depth of at least 32 matrices; implementations may provide more.)
The function g l P u s h Ma t r i x ( ) pushes t he current matrix onto t he stack, and the function
g l P o p Ma t r i x ( ) pops the current matrix off the stack (and loses it). Using these functions,
we could rewrite lines 810 of the example as:
g l P u s h Ma t r i x ( ) ;
g l Ro t a t e f ( - 9 0 . 0 , 1 . 0 , 0 . 0 , 0 . 0 ) ;
g l u t Wi r e Co n e ( 0 . 5 , 2 . 0 , 1 5 , 1 5 ) ;
g l P o p Ma t r i x ( ) ;
Th e stack version is more effi cient because it is faster t o copy a mat rix than it is to constr uct
a new matrix and perform a matrix multiplication. It is always better to push and pop than
to apply inverse transformations.
When pushing and popping matrices, it is important to realize that the sequence
g l P o p Ma t r i x ( ) ;
g l P u s h Ma t r i x ( ) ;
does have an eff ect: th e two calls do not cancel each other out. To see th is, look at Figure 19.
Th e left column contains line numbers for identification, th e second column contains code,
the third column shows the matrix at the top of the stack after each function has executed,
and the other columns show t he mat rices lower in the stack. The matrices are shown as I
(the identity), T (the translation), and R (the rotation). At line 4, t here are t hree matrices
on the stack, with T occupying the top two places. Line 5 post-multiplies the top matrix by
R . Line 6 pops the product T R off the stack, restoring the stack t o its value at line 3. Line 7pushes th e stack and copies t he top matrix. Note t he diff erence between th e stack entries atline 5 and line 7.
4.2 P rojection Transformations
The usual practice in OpenGL coding is to define a projection matrix once and not to apply
any tran sformations t o it. T he projection mat rix can be defined du ring initialization, but a
better place to define it is the reshape function. If the user changes the shape of the viewing
-
8/8/2019 Getting Started With OpenGL Peter Grogono
30/77
4 T R A N SFO R M AT I ON S 26
# Code St ack
1 g l L o a d I d e n t i t y ( ) ; I
2 g l P u s h Ma t r i x ( ) ; I I
3 g l T r a n s l a t e f ( 1 . 0 , 0 . 0 , 0 . 0 ) ; T I
4 g l P u s h Ma t r i x ( ) ; T T I
5 g l Ro t a t e f ( 1 0 . 0 , 0 . 0 , 1 . 0 , 0 . 0 ) ; T R T I 6 g l P o p Ma t r i x ( ) ; T I
7 g l P u s h Ma t r i x ( ) ; T T I
Figure 19: Pushing and popping
window, the program should respond by changing the projection transformation so that the
view is not distort ed. Th e callback function r e s h a p e ( ) in Figure 12 on page 14 shows how
to do this.
The following code illustrates the default settings:
g l Ma t r i x Mo d e ( GL _ P ROJ E CT I ON) ;
g l L o a d I d e n t i t y ( ) ;
g l Or t h o ( - 1 . 0 , 1 . 0 , - 1 . 0 , 1 . 0 , - 1 . 0 , 1 . 0 ) ;
This code defines an orthographic projection (no perspective) and defines the viewing vol-
um e to be a 2 2 2 unit cube centered at the origin. The six arguments are, respectively:minimum X , maximum X , minimum Y, maximum Y, minimum Z, and maximum Z.
4.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, it will subtend a smaller angle at the eye and hence create a smaller
image on the retina. A projection that captures this phenomenon in a two-dimensional view
is called a perspective projection .
Th e diff erence between an orthographic projection and a perspective projection lies in th e
shape of the viewing volume. As we have seen, the viewing volume for an orthographic
projection is a cuboid (rectan gular box). Th e viewing volume for a perspective projection
is a frustum , or truncated pyramid. The apex of the pyramid is at the eye; and t he top
and bottom of the frustum determine the distances of the nearest and furthest points that
are visible. The sides of the pyramid determine t he visibility of objects in the other two
dimensions.
OpenGL provides th e function g l F r u s t u m( ) to define the frustum directly, as shown in Fig-
ure 20. The eye and the ap ex of the pyramid are at the p oint labelled O at the left of the
diagram. We can th ink of the closer vertical plane as t he screen: th e closest objects lie in th e
plane of the screen and other objects lie b ehind it. The first four arguments determine t he
range of X an d Y values as follows: l e f t corresponds to minimum X ; r i g h t corresponds to
maximum X ; b o t t o m corresponds to minimum Y; and t o p corresponds to maximum Y.
-
8/8/2019 Getting Started With OpenGL Peter Grogono
31/77
4 T R A N SFO R M AT I ON S 27
rrrr
rrrr
O
3333
3333
3333
3333
3333
333333
3333
rrrrrrrrrrrr
rrrr
rrrr
rrrr
near' E
far' E
top
right
left
bottom&
&&b
Figure 20: Perspective projection with g l F r u s t u m( )
Note that n e a r an d f a r do not correspond directly to Z values. Both n e a r an d f a r must be
positive, and visible Z values lie in the range f a r Z n e a r .
Th e function g l u P e r s p e c t i v e ( ) provides another way of defining the frustum that is moreintuitive and often convenient. The first argument defines the vertical angle that the viewport
subtends at th e eye in degrees. Th is angle is called in F igure 21; its value must satisfy
0 < < 180. Th e height of t he window is h = 2 n e a r tan( /2). The second argument, a rin Figure 21, is the aspect ratio, which is the width of the viewport divided by its height.
Thus w = a r h = 2 a r n e a r tan( /2). The last two arguments, n e a r an d f a r , determinethe nearest and furthest points visible.
The presence of t he aspect-ratio argument makes it easy t o use g l u P e r s p e c t i v e ( ) 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 t hat at least part of the model lies in t he viewing volume. If it doesnt, we wont see
anything.
Both projection transformations assume that our camera (or eye) is situat ed at the origin
and is looking in the negative Z direction. (Why negative Z, rather than positive Z? By
convention, the screen coordinates have X pointing right and Y pointing up. If we want a
right-handed coordinate system, Z must point towards t he viewer.) Consequently, we should
position our model somewhere on the negative Z axis.
The value ofa l p h a determines the vertical angle subtended by the viewport at the users eye.
Figure 23 shows the eff ect of a small value of a l p h a . The model is a wire cube whose image
-
8/8/2019 Getting Started With OpenGL Peter Grogono
32/77
4 T R A N SFO R M AT I ON S 28
rrrrrrrr
rrrrr
rrr
3333
3333333
3333
3333
3333
3333
333
O
r
r
r
r
r
near' E
far' E
wrrr
r
rrrrj
h
T
c
Figure 21: Perspective projection using g l u P e r s p e c t i v e ( )
v o i d r e s h a p e ( i n t wi d t h , i n t h e i g h t )
{
g l Vi e wp o r t ( 0 , 0 , wi d h t , h e i g h t ) ;
g l Ma t r i x Mo d e ( GL _ P ROJ E CT I ON) ;
g l L o a d i d e n t i t y ( ) ;
g l u P e r s p e c t i v e ( 3 0 . 0 , ( GLf l o a t ) wi d t h / ( GLf l o a t ) h e i g h t , 1 , 2 0 ) ;
}
Figure 22: Reshaping with g l u P e r s p e c t i v e ( )
occupies half of the viewport. The eff ect is that of viewing the cube from a large distance:
the back of the cube is only slightly smaller than the front.
view on screen
@@@@@@@@
@@@@@@@@
@@@@@@@@
@@@@@
hhhhhhhhhhhhhhhhhhhhhhhhhhhhh
Figure 23: g l u P e r s p e c t i v e ( ) with a small value of
-
8/8/2019 Getting Started With OpenGL Peter Grogono
33/77
4 T R A N SFO R M AT I ON S 29
dd
dd
view on screen
e
ee
ee
ee
ee
ee
ee
Figure 24: g l u P e r s p e c t i v e ( ) with a large value of
Figure 24 shows t he eff ect of a large value ofa l p h a . Th e model is again a wire cube whose
image occupies half of the viewport. T he eff ect is of viewing t he cube from a small distance:
the back of the cube is much smaller than the front.
Making a l p h a smaller with out moving th e model simulates zooming in: th e image gets
larger in the viewport. Making a l p h a larger simulates zooming out: t he image get s smaller.
Although we can use a l p h a to manipulate t he image in any way we please, th ere is a correctvalue for it. Suppose that the user is sitt ing at a distance d from a screen of height h: t h e
appropriate value of a l p h a is given by
= 2 t an1
h
2 d
.
For example, ifh = 12in and d = 24in, then
= 2 t an1
12
2 24
28.
If you have used a 35mm camera, you may find the following comparisons helpful. The
vertical height of a 35 mm film frame is h = 24m m , so h/2 = 12 mm. When t he camera is
used with a lens with focal length f mm, the vertical angle subtended by the field of view is
2 tan1(12/ f ). T he angle for a 24m m wide-angle lens is about 53; the angle for a regular
50mm lens is about 27; and the angle for a 100mm telephoto lens is about 14.
4.4 Combining Viewpoint and Perspective
The function g l u Lo o k At ( ) defines a model-view t ransformat ion t hat simulat es viewing (look-
ing at) th e scene from a p art icular viewpoint. It takes nine arguments of type GLf l o a t . T h e
-
8/8/2019 Getting Started With OpenGL Peter Grogono
34/77
4 T R A N SFO R M AT I ON S 30
first three arguments define the camera (or eye) position with respect to the origin; the next
three arguments are the coordinates of a point in the model towards which the camera is
directed; and t he last t hree arguments are t he components of a vector p ointing upwards. In
th e call
g l u L o o k At ( 0 . 0 , 0 . 0 , 1 0 . 0 ,0 . 0 , 0 . 0 , 0 . 0 ,
0 . 0 , 1 . 0 , 0 . 0 ) ;
the p oint of interest in t he model is at (0, 0, 0), the position of the camera relative to this
point is (0, 0, 10), and the vector (0, 1, 0) (that is, the Y-axis) is pointing upwards.
Although the idea of g l u Lo o k At ( ) seems simple, the function is tricky to use in practice.
Often, introducing a call to g l u Lo o k At ( ) has t he undesirable eff ect of making the image
disappear altogeth er! In th e following code, t he eff ect of the call t o g l u Lo o k At ( ) is to move
the origin to (0, 0, 10); but the near and far planes defined by g l u P e r s p e c t i v e ( ) are atz = 1 and z = 5, respectively. Consequently, th e cube is b eyond t he far p lane and isinvisible.
g l Ma t r i x Mo d e ( GL _ P ROJ E CT I ON) ;
g l L o a d I d e n t i t y ( ) ;
g l u P e r s p e c t i v e ( 3 0 , 1 , 1 , 5 ) ;
g l Ma t r i x Mo d e ( GL _ MODE L VI E W) ;
g l L o a d I d e n t i t y ( ) ;
g l u L o o k At ( 0 , 0 , 1 0 , 0 , 0 , 0 , 0 , 1 , 0 ) ;
g l u t Wi r e Cu b e ( 1 . 0 ) ;
Figure 25 demonstrates how to use g l u Lo o k At ( ) an d g l u P e r s p e c t i v e ( ) together. The t wo
important variables are a l p h a an d d i s t . Th e idea is th at th e extension of th e object in th e Z-direction is less than 2; consequently, it can be enclosed completely by planes at z = d i s t 1an d z = d i s t + 1. To ensure that the object is visible, g l u Lo o k At ( ) sets the camera position
to (0, 0, d i s t ).
Changing t he value ofa l p h a in Figure 25 changes the size of the object, as explained above.
Th e height of the viewing window is 2 (d i s t 1) tan (a l p h a /2); increasing a l p h a makes theviewing window larger and the object smaller.
Changing the value of d i s t also changes the size of the image in the viewport, but in a
diff erent way. Th e perspective changes, giving the eff ect of approaching (ifd i s t gets smaller
and th e object gets larger) or going away (if d i s t gets larger and th e object gets smaller).
It is possible t o change a l p h a an d d i s t together in such a way that the size of a key objectin t he model st ays t he same while the perspective changes. (For example, consider a series
of diagrams th at starts with Figure 23 and ends with Figure 24.) This is a rather simple
technique in Op enGL, but it is an expensive eff ect in movies or t elevision because th e zoom
control of the lens must be coupled to th e t racking motion of the camera. Hitchcock used th is
trick t o good eff ect in his movies Vertigo an d Marnie.
-
8/8/2019 Getting Started With OpenGL Peter Grogono
35/77
4 T R A N SFO R M AT I ON S 31
# i n c l u d e < GL/ g l u t . h >
c o n s t i n t S I ZE = 5 0 0 ;
f l o a t a l p h a = 6 0 . 0 ;
f l o a t d i s t = 5 . 0 ;
v o i d d i s p l a y ( v o i d )
{
g l Cl e a r ( GL_ COLOR_ BUF F ER _ BI T ) ;
g l Ma t r i x Mo d e ( GL _ MODE L VI E W) ;
g l L o a d I d e n t i t y ( ) ;
g l u Lo o k A t ( 0 . 0 , 0 . 0 , d i s t ,
0 . 0 , 0 . 0 , 0 . 0 ,
0 . 0 , 1 . 0 , 0 . 0 ) ;
g l u t Wi r e Cu b e ( 1 . 0 ) ;
}
v o i d i n i t ( v o i d )
{
g l Ma t r i x Mo d e ( GL _ P ROJ E CT I ON) ;
g l L o a d I d e n t i t y ( ) ;
g l u P e r s p e c t i v e ( a l p h a , 1 . 0 , d i s t - 1 . 0 , d i s t + 1 . 0 ) ;
}
i n t ma i n ( i n t a r g c , c h a r * a r g v [ ] )
{
g l u t I n i t ( &a r g c , a r g v ) ;
g l u t I n i t Wi n d o wS i z e ( S I Z E , S I Z E) ;
g l u t I n i t Wi n d o wP o s i t i o n ( 1 0 0 , 5 0 ) ;
g l u t C r e a t e Wi n d o w( " A P e r s p e c t i v e Vi e w" ) ;
i n i t ( ) ;
g l u t Di s p l a y F u n c ( d i s p l a y ) ;
g l u t Ma i n Lo o p ( ) ;
}
Figure 25: Using g l u Lo o k At ( ) an d g l u P e r s p e c t i v e ( )
-
8/8/2019 Getting Started With OpenGL Peter Grogono
36/77
5 L IG HT I N G 32
5 Lig ht in g
We talk ab out th ree dimensional graphics but, with current technology, th e best we can do
is to create the illusion of three-dimensional objects on a two-dimensional screen. Perspective
is one kind of illusion, but it is not enough. A perspective projection of a uniformly-coloured
cube, for example, looks like an irregular hexagon. We can paint th e faces of the cube indiff erent colours, but th is does not help us t o display a realistic image of a cube of one colour.
We can improve the illusion of depth by simulating the lighting of a scene. If a cube is
illuminat ed by a single light source, it s faces have diff erent br ightn esses, and t his strengt hens
th e illusion th at it is thr ee dimensional. Appendix B out lines t he t heory of illumination; th is
section describes some of the features that OpenGL provides for lighting a scene.
To light a model, we must provide OpenGL with information about the objects in the scene
and t he lights th at illuminate th em. To obtain realistic lighting eff ects, we must define:
1. normal vect ors for each vert ex of each object;
2. material properties for each object;
3. th e positions and other pr operties of the light sources; and
4. a lighting model.
Since OpenGL provides reasonable defaults for many properties, we have to add only a few
function calls t o a program to obtain simple lighting eff ects. For full realism, however, t here
is quite a lot of work to do.
5 .1 A Sim p le E x am p le
Suppose that we have a program th at displays a sphere. We must eliminat e hidden surfaces
by passing GLUT _ DEP TH t o g l u t I n i t Di s p l a y Mo d e ( ) and by clearing GL_ DE P TH_ BUF F ER _ BI T
in the display function. The following steps would be necessary to illuminate a sphere.
1. Define normal vectors. If we use t he GLUT function g l u t S o l i d S p h e r e ( ) , this step is
unnecessary, because normals are already defined for the sphere and other GLUT solid
objects.
2. Define mat erial propert ies. We can use the default properties.
3. Define light sources. T he following code should b e executed dur ing initialization:
g l E n a b l e ( GL_ LI GHT I NG) ;
g l E n a b l e ( GL_ LI GHT0 ) ;
4. Define a lighting model. We can use the default model.
Th is is t he simplest case, in which we add just two lines of code. T he following sections
describe more of the details.
-
8/8/2019 Getting Started With OpenGL Peter Grogono
37/77
5 L IG HT I N G 33
fffff
ff
0
1
2
3
Figure 26: A simple object
5.2 N ormal Vec t ors
For any plane surface, there is a normal vector at right angles t o it. A p encil standingvertically on a horizontal desktop provides an appropriate mental image.
OpenGL associates normals with vertices rather than surfaces. This seems surprising at first,but it has an important advantage. Often, we are using flat polygons as approximations t o
curved surfaces. For example, a sphere is const ruct ed of many small r ect angles whose edges
are lines of latitude and longitude. If we provide a single normal for each rectangle, OpenGL
will illuminate each rectangle as a flat surface. If, inst ead, we provide a n ormal at each vert ex,
OpenGL will illuminate the rectangles as if they were curved surfaces, and provide a better
illusion of a sphere.
Consequently, th ere are two ways of specifying normals. Consider th e very simple object
shown in Figure 26 consisting of t wo tr iangles. We could provide a single normal for each
tr iangle using t he following code:
g l B e g i n ( GL _ T RI ANGL E S ) ;g l No r ma l 3 f ( u 0 , v 0 , w0 ) ; / * No r ma l f o r t r i a n g l e 0 1 2 . * /
g l Ve r t e x 3 f ( x 0 , y 0 , z 0 ) ;
g l Ve r t e x 3 f ( x 1 , y 1 , z 1 ) ;
g l Ve r t e x 3 f ( x 2 , y 2 , z 2 ) ;
g l No r ma l 3 f ( u 1 , v 1 , w1 ) ; / * No r ma l f o r t r i a n g l e 1 3 2 . * /
g l Ve r t e x 3 f ( x 1 , y 1 , z 1 ) ;
g l Ve r t e x 3 f ( x 3 , y 3 , z 3 ) ;
g l Ve r t e x 3 f ( x 2 , y 2 , z 2 ) ;
g l E n d ( ) ;
The function g l No r ma l ( ) defines a normal vector for any vert ex definitions t hat follow it.Note that it is possible for two normals t o b e associated with the same vertex: in t he code
above, vert ices 1 and 2 each have t wo normals. As far as OpenGL is concerned, th e code
defines six vertices, each with its own normal.
Th e other way of describing t his object requires a normal for each vert ex. T he normals at
vertices 0 and 3 are p erpendicular t o t he corresponding tr iangles. Th e normals at vert ices 1
and 2 are comput ed by averaging t he normals for th e t riangles. In t he following code, each
vertex definition is preceded by the definition of the corresponding normal.
-
8/8/2019 Getting Started With OpenGL Peter Grogono
38/77
5 L IG HT I N G 34
g l B e g i n ( GL _ T RI ANGL E S ) ;
g l No r ma l 3 f ( u 0 , v 0 , w0 ) ; / * No r ma l t o t r i a n g l e 0 1 2 * /
g l Ve r t e x 3 f ( x 0 , y 0 , z 0 ) ;
g l No r ma l 3 f ( u a , v a , wa ) ; / * Av e r a g e * /
g l Ve r t e x 3 f ( x 1 , y 1 , z 1 ) ;
g l No r ma l 3 f ( u a , v a , wa ) ; / * Av e r a g e * / g l Ve r t e x 3 f ( x 2 , y 2 , z 2 ) ;
g l No r ma l 3 f ( u a , v a , wa ) ; / * Av e r a g e * /
g l Ve r t e x 3 f ( x 1 , y 1 , z 1 ) ;
g l No r ma l 3 f ( u 3 , v 3 , w3 ) ; / * No r ma l t o t r i a n g l e 1 3 2 * /
g l Ve r t e x 3 f ( x 3 , y 3 , z 3 ) ;
g l No r ma l 3 f ( u a , v a , wa ) ; / * Av e r a g e * /
g l Ve r t e x 3 f ( x 2 , y 2 , z 2 ) ;
g l E n d ( ) ;
We do not usually see code like this in OpenGL programs, because it is usually more convenient
to store th e dat a in arr ays. T he following example is more typical; each component of thearrays n o r m an d v e r t is an array of three f l o a t s.
g l Be g i n { GL_ TR I ANGL E S }
f o r ( i = 0 ; i < MAX; i + + )
{
g l No r ma l 3 f v ( n o r m[ i ] ) ;
g l Ve r t e x 3 f v ( v e r t [ i ] ) ;
}
g l E n d ( ) ;
Each normal vector should be n ormalized (!) in t he sense that its length should be 1. Nor-malizing the vector ( x , y , z ) gives the vector (x/ s, y/ s, z/ s ), where s =
x 2 + y2 + z2.
If you include the statement g l E n a b l e ( GL _ NORMALI ZE ) in your initialization code, OpenGL
will normalize vectors for you. However, it is usually more effi cient to normalize vectors
yourself.
Computing Normal Vectors The vector normal to a triangle with vertices (x 1, y1, z1),
(x 2, y2, z2), and (x 3, y3, z3) is (a,b,c), where
a = +
y2 y1 z2 z1y3
y1 z3
z1
b = x 2 x 1 z2 z1x 3 x 1 z3 z1
c = +
x 2 x 1 y2 y1x