Você está na página 1de 41

OPENGL WITH 2D & 3D GRAPHICS

OpenGL with 2D Graphics


Instructi ns! Copy code for each example into a new source file and execute. Read explanations of each example to understand the concepts.
"#" E$a%p&e "!GL'"He&& #cpp
#include <windows.h> #include <GL/glut.h> /* // for MS Windows // GLUT, include glu.h and gl.h

andler for window!re"aint e#ent. $all %ac& when the window first a""ears and whene#er the window needs to %e re!"ainted. */ #oid dis"la'() * gl$lear$olor(+.+f, +.+f, +.+f, ,.+f)- // Set %ac&ground color to %lac& and o"a.ue gl$lear(GL/$0L01/2U3341/25T)// $lear the color %uffer (%ac&ground) // 6raw a 1ed ,7, S.uare centered at origin gl2egin(GL/8U96S)// 4ach set of : #ertices for; a .uad gl$olor<f(,.+f, +.+f, +.+f)- // 1ed gl=erte7>f(!+.?f, !+.?f)// 7, ' gl=erte7>f( +.?f, !+.?f)gl=erte7>f( +.?f, +.?f)gl=erte7>f(!+.?f, +.?f)gl4nd()gl3lush()@ /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glut$reateWindow(D0"enGL Setu" TestD)- // $reate a window with the gi#en title glut5nitWindowSiCe(<>+, <>+)// Set the windowEs initial width B height glut5nitWindowFosition(?+, ?+)- // Fosition the windowEs initial to"!left corner glut6is"la'3unc(dis"la')- // 1egister dis"la' call%ac& handler for window re!"aint glutMainLoo"()// 4nter the e#ent!"rocessing loo" return +@ // 1ender now

Explanation of the code


#include <windows.h>

The header "windows.h" is needed for the Windows platform only.


#include <GL/glut.h>

We also included the GLUT header, which is guaranteed to include " glu.h" for GL Utility! and "gl.h" for Core "penGL!. The rest ( the pr )ra% is e$p&aine* in su+se,uent secti ns#

2# Intr *ucti n
"penGL "pen Graphics Li#rary! is a cross$platform, hardware$accelerated, language$independent, industrial standard %&' for producing () including *)! graphics. +odern computers ha,e dedicated G&U Graphics &rocessing Unit! with its own memory to speed up graphics rendering. "penGL is the software interface to graphics hardware. 'n other words, "penGL graphic rendering commands issued #y your applications could #e directed to the graphic hardware and accelerated.

We use ( sets of li#raries in our "penGL programs1. Core "penGL GL!- consists of hundreds of commands, which #egin with a prefix " gl" e.g., gl$olor, gl=erte7, glTranslate, gl1otate!. The Core "penGL models an o#.ect ,ia a set of geometric primiti,es such as point, line and polygon. 2. "penGL Utility Li#rary GLU!- #uilt on$top of the core "penGL to pro,ide important utilities such as setting camera ,iew and pro.ection! and more #uilding models such as /radric surfaces and polygon tessellation!. GLU commands start with a prefix " glu" e.g., gluLoo&9t, gluFers"ecti#e!. 3. "penGL Utilities Tool0it GLUT!- "penGL is designed to #e independent of the windowing system or operating system. GLUT is needed to interact with the "perating 1ystem such as creating a window, handling 0ey and mouse inputs!2 it also pro,ides more #uilding models such as sphere and torus!. GLUT commands start with a prefix of " glut" e.g., glut$reatewindow, glutMouse3unc!. GLUT is platform independent, which is #uilt on top of platform$specific "penGL extension such as GL3 for 3 Window 1ystem, WGL for +icrosoft Window, and %GL, CGL or Cocoa for +ac "1. 4. 5uoting from the opengl.org- "GLUT is designed for constructing small to medium si6ed "penGL programs. While GLUT is well$suited to learning "penGL and de,eloping simple "penGL applications, GLUT is not a full$featured tool0it so large applications re/uiring sophisticated user interfaces are #etter off using nati,e window system tool0its. GLUT is simple, easy, and small."

3# -erte$. Pri%iti/e an* C & r


3#" E$a%p&e 2! -erte$. Pri%iti/e an* C & r 0GL'2Pri%iti/e#cpp1 Try #uilding and running this "penGL C7C88 program/* * GL+>Fri;iti#e.c""A =erte7, Fri;iti#e and $olor * 6raw Si;"le >6 colored Sha"esA .uad, triangle and "ol'gon. */ #include <windows.h> // for MS Windows #include <GL/glut.h> // GLUT, include glu.h and gl.h /* 5nitialiCe 0"enGL Gra"hics */ #oid initGL() * // Set DclearingD or %ac&ground color gl$lear$olor(+.+f, +.+f, +.+f, ,.+f)- // 2lac& and o"a.ue @ /* andler for window!re"aint e#ent. $all %ac& when the window first a""ears and whene#er the window needs to %e re!"ainted. */ #oid dis"la'() * gl$lear(GL/$0L01/2U3341/25T)- // $lear the color %uffer with current clearing color // 6efine sha"es enclosed within a gl2egin(GL/8U96S)// gl$olor<f(,.+f, +.+f, +.+f)- // gl=erte7>f(!+.Gf, +.,f)// gl=erte7>f(!+.>f, +.,f)// gl=erte7>f(!+.>f, +.Hf)gl=erte7>f(!+.Gf, +.Hf)"air of gl2egin and gl4nd 4ach set of : #ertices for; a .uad 1ed
6efine #ertices in counter!cloc&wise ($$W) order

so that the nor;al (front!face) is facing 'ou

gl$olor<f(+.+f, ,.+f, +.+f)- // Green gl=erte7>f(!+.Hf, !+.If)gl=erte7>f(!+.,f, !+.If)gl=erte7>f(!+.,f, +.+f)gl=erte7>f(!+.Hf, +.+f)gl$olor<f(+.>f, +.>f, +.>f)- // 6ar& Gra' gl=erte7>f(!+.Jf, !+.Hf)-

gl$olor<f(,.+f, ,.+f, ,.+f)- // White gl=erte7>f(!+.?f, !+.Hf)gl$olor<f(+.>f, +.>f, +.>f)- // 6ar& Gra' gl=erte7>f(!+.?f, !+.<f)gl$olor<f(,.+f, ,.+f, ,.+f)- // White gl=erte7>f(!+.Jf, !+.<f)gl4nd()gl2egin(GL/T159KGL4S)// 4ach set of < #ertices for; a triangle gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f(+.,f, !+.If)gl=erte7>f(+.Hf, !+.If)gl=erte7>f(+.:f, !+.,f)gl$olor<f(,.+f, +.+f, +.+f)- // 1ed gl=erte7>f(+.<f, !+.:f)gl$olor<f(+.+f, ,.+f, +.+f)- // Green gl=erte7>f(+.Jf, !+.:f)gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f(+.If, !+.Jf)gl4nd()gl2egin(GL/F0LLG0K)// These #ertices for; a closed "ol'gon gl$olor<f(,.+f, ,.+f, +.+f)- // Lellow gl=erte7>f(+.:f, +.>f)gl=erte7>f(+.If, +.>f)gl=erte7>f(+.Hf, +.:f)gl=erte7>f(+.If, +.If)gl=erte7>f(+.:f, +.If)gl=erte7>f(+.<f, +.:f)gl4nd()gl3lush()@ /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glut$reateWindow(D=erte7, Fri;iti#e B $olorD)- // $reate window with the gi#en title glut5nitWindowSiCe(<>+, <>+)// Set the windowEs initial width B height glut5nitWindowFosition(?+, ?+)- // Fosition the windowEs initial to"!left corner glut6is"la'3unc(dis"la')// 1egister call%ac& handler for window re!"aint e#ent initGL()// 0ur own 0"enGL initialiCation glutMainLoo"()// 4nter the e#ent!"rocessing loo" return +@ // 1ender now

The expected output and the coordinates are as follows. Ta0e note that 4 shapes ha,e pure color, and * shapes ha,e color #lending from their ,ertices.

The program is explained in the program in the following sections. 3#2 OpenGL as a State 2achine "penGL operates as a state machine, and maintain a set of state variables such as the foreground color, #ac0ground color, and many more!. 'n a state machine, once the ,alue of a state ,aria#le is set, the ,alue persists until a new ,alue is gi,en. 9or example, we set the "clearing" #ac0ground! color to #lac0 once in initGL(). We use this setting to clear the window in the dis"la'() repeatedly dis"la'() is called #ac0 whene,er there is a window re$ paint re/uest! $ the clearing color is not changed in the entire program.
// 5n initGL(), set the DclearingD or %ac&ground color gl$lear$olor(+.+f, +.+f, +.+f, ,.+f)- // %lac& and o"a.ue // 5n dis"la'(), clear the color %uffer (i.e., set %ac&ground) with the current DclearingD color gl$lear(GL/$0L01/2U3341/25T)-

%nother example- 'f we use gl$olor function to set the current foreground color to "red", then "red" will #e used for all the su#se/uent ,ertices, until we use another gl$olor function to change the foreground color. In a state machine, everything shall remain until you explicitly change it! 3#3 Na%in) C n/enti n ( r OpenGL 3uncti ns %n "penGL functions

#egins with lowercase gl for core "penGL!, glu for "penGL Utility! or glut for "penGL Utility Tool0it!. followed #y the purpose of the function, in camel case initial$capitali6ed!, e.g., gl$olor to specify the drawing color, gl=erte7 to define the position of a ,ertex. followed #y specifications for the parameters, e.g., gl$olor<f ta0es three float parameters. gl=ecte7>i ta0es two int parameters. This is needed as C7C88 Language does not support function o,erloading. )ifferent ,ersions of the function need to #e written for different parameter lists.!

The con,ention can #e expressed as followsreturnType glFunction[234][sifd] (type value, ...)returnType glFunction[234][sifd]v (type *value)// >, < or : "ara;eters // an arra' "ara;eter

The function may ta0e *, (, or 4 parameters, in type of s GLshort!, i GLint!, f GLfloat! or d GLdou%le!. The :#: for ,ector! denotes that the parameters are 0ept in an array of *, (, or 4 elements, and pass into the function as an array pointer. "penGL defines its own data types

1igned 'ntegers- GL%'te ;$#it!, GLshort <=$#it!, GLint (*$#it!. Unsigned 'ntegers- GLu%'te ;$#it!, GLushort <=$#it!, GLuint (*$#it!. 9loating$point num#ers- GLfloat (*$#it!, GLdou%le =4$#it!, GLcla;"f and GLcla;"d #etween >.> and <.>!.
GL%oolean GLsiCei GLenu;

unsigned char with > for false and non$> for true!.

(*$#it non$negati,e integers!. (*$#it enumerated integers!.

The "penGL types are defined ,ia t'"edef in "gl.h" as followst'"edef t'"edef t'"edef t'"edef t'"edef t'"edef t'"edef t'"edef t'"edef t'"edef t'"edef t'"edef t'"edef t'"edef t'"edef unsigned int unsigned char unsigned int #oid signed char short int unsigned char unsigned short unsigned int int float float dou%le dou%le GLenu;GL%ooleanGL%itfieldGL#oidGL%'teGLshortGLintGLu%'teGLushortGLuintGLsiCeiGLfloatGLcla;"fGLdou%leGLcla;"d-

/* /* /* /* /* /* /* /* /* /* /*

,!%'te >!%'te :!%'te ,!%'te >!%'te :!%'te :!%'te single single dou%le dou%le

signed */ signed */ signed */ unsigned */ unsigned */ unsigned */ signed */ "recision float "recision float "recision float "recision float

*/ in M+,,N */ */ in M+,,N */

"penGL:s constants #egins with "GL/", "GLU/" or "GLUT/", in uppercase separated with underscores, e.g., GL/$0L01/2U3341/25T. 9or examples,
gl=erte7<f(,.,f, >.>f, <.<f)gl=erte7>i(:, ?)gl$olor:f(+.+f, +.+f, +.+f, ,.+f)// < GLfloat "ara;eters // > GLint "ara;aters // : GLfloat "ara;eters

GLdou%le a=erte7MN O *,.,, >.>, <.<@gl=erte7<f#(a=erte7)// an arra' of < GLfloat #alues

3#4 One5ti%e Initia&i6ati n initGL01 The initGL() is meant for carrying out one$time "penGL initiali6ation tas0s, such as setting the clearing color. initGL() is in,o0ed once and only once! in ;ain(). 3#7 Ca&&+ac8 Han*&er *isp&a901

The function dis"la'() is 0nown as a callback event handler. %n e,ent handler pro,ides the response to a particular event such as 0ey$press, mouse$clic0, window$paint!. The function dis"la'() is meant to #e the handler for window paint e,ent. The "penGL graphics system calls #ac0 dis"la'() in response to a window$paint re/uest to re$paint the window e.g., window first appears, window is restored after minimi6ed, and window is resi6ed!. Call#ac0 means that the function is in,o0ed #y the system, instead of called #y your program. The 6is"la'() runs when the window first appears and once per su#se/uent re$paint re/uest. "#ser,e that we included "penGL graphics rendering code inside the dis"la'() function, so as to re$draw the entire window when the window first appears and upon each re$paint re/uest. 3#: Settin) up GL;T 5 %ain01 GLUT pro,ides high$le,el utilities to simplify "penGL programming, especially in interacting with the "perating 1ystem such as creating a window, handling 0ey and mouse inputs!. The following GLUT functions were used in the a#o,e program
glut5nit-

initiali6es GLUT, must #e called #efore other GL7GLUT functions. 't ta0es the same arguments as the ;ain().
#oid glutInit(int *argc, char **argv) glut$reateWindow- creates a window with the int glutCreateWindow(char *title) glut5nitWindowSiCe- specifies the initial

gi,en title.

window width and height, in pixels.

#oid glutInitWindowSize(int width, int height) glut5nitWindowFosition- positions the top$left corner of

the initial window at x, y!. The coordinates x, y!, in term of pixels, is measured in window coordinates, i.e., origin >, >! is at the top$left corner of the screen2 x$axis pointing right and y$axis pointing down.
#oid glutInitWindow osition(int x, int y) glut6is"la'3unc- registers the call#ac0 function

or e,ent handler! for handling window$paint e,ent. The "penGL graphic system calls #ac0 this handler when it recei,es a window re$paint re/uest. 'n the example, we register the function dis"la'() as the handler.
#oid glut!ispla"#unc(#oid (*func)(#oid)) glutMainLoo"- enters the infinite e,ent$processing

loop, i.e, put the "penGL graphics system to wait for e,ents such as re$paint!, and trigger respecti,e e,ent handlers such as dis"la'()!.
#oid glut$ain%oop()

'n the ;ain() function of the exampleglut5nit(Bargc, arg#)glut$reateWindow(D=erte7, Fri;iti#e B $olorD)glut5nitWindowSiCe(<>+, <>+)glut5nitWindowFosition(?+, ?+)-

We initiali6e the GLUT and create a window with a title, an initial si6e and position.
glut6is"la'3unc(dis"la')-

We register dis"la'() function as the call#ac0 handler for window$paint e,ent. That is, dis"la'() runs when the window first appears and whene,er there is a re/uest to re$paint the window.
initGL()-

We call the initGL() to perform all the one$time initiali6ation operations. 'n this example, we set the clearing #ac0ground! color once, and use it repeata#ly in the dis"la'() function.
glutMainLoo"()-

We then put the program into the e,ent$handling loop, awaiting for e,ents such as window$paint re/uest! to trigger off the respecti,e e,ent handlers such as dis"la'()!. 3#< C & r We use gl$olor function to set the !oreground color, and gl$lear$olor function to set the background or clearing! color.
#oid #oid #oid #oid glColor3f(GLfloat red, GLfloat green, GLfloat blue) glColor3fv(GLfloat *colorRGB) glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) glColor4fv(GLfloat *colorRGBA)

#oid glClearColor(GLcla;"f red, GLcla;"f green, GLcla;"f blue, GLcla;"f alpha) // GLcla;"f in the range of +.+f to ,.+f

?otes

Color is typically specified in float in the range +.+f and ,.+f. Color can #e specified using RG@ Red$Green$@lue! or RG@% Red$Green$@lue$%lpha! components. The :%: or alpha! specifies the transparency or opacity! index, with ,alue of < denotes opa/ue non$transparent and cannot see$thru! and ,alue of > denotes total transparent. We shall discuss alpha later.

'n the a#o,e example, we set the #ac0ground color ,ia gl$lear$olor in initGL(), with RA>, GA>, @A> #lac0! and %A< opa/ue and cannot see through!.
// 5n initGL(), set the DclearingD or %ac&ground color gl$lear$olor(+.+f, +.+f, +.+f, ,.+f)- // 2lac& and o"ague

'n dis"la'(), we set the ,ertex color ,ia gl$olor<f for su#se/uent ,ertices. 9or example, RA<, GA>, @A> red!.
// 5n dis"la'(), set the foreground color of the "i7el gl$olor<f(,.+f, +.+f, +.+f)- // 1ed

3#= Ge %etric Pri%iti/es 'n "penGL, an o#.ect is made up of geometric primiti,es such as triangle, /uad, line segment and point. % primiti,e is made up of one or more ,ertices. "penGL supports the following primiti,es-

% geometric primiti,e is defined #y specifying its ,ertices ,ia gl=erte7 function, enclosed within a pair gl2egin and gl4nd.
#oid gl&egin(GLenu; shape) #oid gl'ertex[234][sifd] (type x, type y, type z, ...) #oid gl'ertex[234][sifd]v (type *coords) #oid glEnd() gl2egin specifies the type of geometric o#.ect, such as GL/F05KTS, GL/L5K4S, GL/8U96S, GL/T159KGL4S, and GL/F0LLG0K. 9or types that end with :S:, you can define multiple o#.ects of the same type in each gl2egin7gl4nd pair. 9or example, for GL/T159KGL4S, each set of three gl=erte7:s defines a triangle.

The ,ertices are usually specified in float precision. 't is #ecause integer is not suita#le for trigonometric operations needed to carry out transformations such as rotation!. &recision of float is sufficient for carrying out intermediate operations, and render the o#.ects finally into pixels on screen with resolution of says ;>>x=>>, integral precision!. dou%le precision is often not necessary. 'n the a#o,e examplegl2egin(GL/8U96S).... : .uads with ,>7 gl=erte7() .... gl4nd()-

we define ( color /uads GL/8U96S! with <*x gl=erte7() functions.


gl$olor<f(,.+f, +.+f, +.+f)-

gl=erte7>f(!+.Gf, gl=erte7>f(!+.>f, gl=erte7>f(!+.>f, gl=erte7>f(!+.Gf,

+.,f)+.,f)+.Hf)+.Hf)-

We set the color to red RA<, GA>, @A>!. %ll su#se/uent ,ertices will ha,e the color of red. Ta0e note that in "penGL, color and many properties! is applied to ,ertices rather than primiti,e shapes. The color of the primiti,e shape is interpolated from its ,ertices. We similarly define a second /uad in green. 9or the third /uad as follows!, the ,ertices ha,e different color. The color of the /uad surface is interpolated from its ,ertices, resulting in shades of white to dar0 gray, as shown in the output.
gl$olor<f(+.>f, +.>f, +.>f)gl=erte7>f(!+.Jf, !+.Hf)gl$olor<f(,.+f, ,.+f, ,.+f)gl=erte7>f(!+.?f, !+.Hf)gl$olor<f(+.>f, +.>f, +.>f)gl=erte7>f(!+.?f, !+.<f)gl$olor<f(,.+f, ,.+f, ,.+f)gl=erte7>f(!+.Jf, !+.<f)// 6ar& Gra' // White // 6ar& Gra' // White

3#> 2D C r*inate S9ste% an* the De(au&t -iew 0THIS TOPIC WILL ?E DISC;SSED LATER ?;T GO THRO;GH IT AS WE HA-E TAC@LED A ?IT O3 IT IN O;R PROGRA2S1 The following diagram shows the "penGL *) Coordinate 1ystem, which corresponds to the e,eryday *) Cartesian coordinates with origin located at the #ottom$left corner.

The default "penGL *) clipping area i.e., what is captured #y the camera! is an orthographic ,iew with x and y in the range of $<.> and <.>, i.e., a *x* s/uare with centered at the origin. This clipping$area is mapped to the viewport on the screen. Biewport is measured in pixels.

1tudy the a#o,e example to con,ince yourself that the *) shapes created are positioned correctly on the screen.

4# C&ippin)5Area & -iewp rt


Try dragging the corner of the window to ma0e it #igger or smaller. "#ser,e that all the shapes are distorted. We can handle the re$si6ing of window ,ia a call#ac0 handler resha"e(), which can #e programmed to ad.ust the "penGL clipping$area according to the window:s aspect ratio.

Clipping %rea- "lipping area refers to the area that can #e seen i.e., captured #y the camera!, measured in "penGL coordinates. The function glu0rtho>6 can #e used to set the clipping area of *) orthographic ,iew. "#.ects outside the clipping area will #e clipped away and cannot #e seen.
#oid glu(rtho2!(GLdou%le left, GLdou%le right, GLdou%le bottom, GLdou%le top) // The default cli""ing area is (!,.+, ,.+, !,.+, ,.+) in 0"enGL coordinates, // i.e., >7> s.uare centered at the origin.

To set the clipping area, we need to issue a series of commands as follows- we first select the so$called pro#ection matrix for operation, and reset the pro.ection matrix to identity. We then choose the *) orthographic ,iew with the desired clipping area, ,ia glu0rtho>6().
// Set to >6 orthogra"hic "roPection glMatri7Mode(GL/F10Q4$T50K)// glLoad5dentit'()// glu0rtho>6(!,.+, ,.+, !,.+, ,.+)- // with the s"ecified cli""ing area Select the FroPection ;atri7 for o"eration 1eset FroPection ;atri7 Set cli""ing areaEs left, right, %otto;, to"

Biewport- $iewport refers to the display area on the window screen!, which is measured in pixels in screen coordinates excluding the title #ar!. The clipping area is mapped to the ,iewport. We can use gl=iew"ort function to configure the ,iewport.
#oid gl'iewport(GLint xTopLeft, GLint yTopLeft, GLsiCei width, GLsiCei height)

1uppose the clipping area:s left, right, #ottom, top! is $<.>, <.>, $<.>, <.>! in "penGL coordinates! and the ,iewport:s xTopLeft, xTopRight, width, height! is >, >, =4>, 4;>! in screen coordinates in pixels!, then the #ottom$left corner $<.>, $<.>! maps to >, >! in the ,iewport, the top$right corner <.>, <.>! maps

to =(C, 4DC!. 't is o#,ious that if the aspect ratios for the clipping area and the ,iewport are not the same, the shapes will #e distorted. Ta0e note that in the earlier example, the windows: si6e of (*>x(*> has a s/uare shape, with an aspect ratio consistent with the default *x* s/uarish clipping$area. 4#" E$a%p&e 3! C&ippin)5area an* -iewp rt 0GL'3-iewp rt#cpp1
/* * GL+<=iew"ort.c""A $li""ing!area and =iew"ort * 5;"le;enting resha"e to ensure sa;e as"ect ratio %etween the * cli""ing!area and the #iew"ort. */ #include <windows.h> // for MS Windows #include <GL/glut.h> // GLUT, include glu.h and gl.h /* 5nitialiCe 0"enGL Gra"hics */ #oid initGL() * // Set DclearingD or %ac&ground color gl$lear$olor(+.+f, +.+f, +.+f, ,.+f)- // 2lac& and o"a.ue @ #oid dis"la'() * gl$lear(GL/$0L01/2U3341/25T)-// $lear the color %uffer with current clearing color // 6efine sha"es enclosed within a gl2egin(GL/8U96S)// gl$olor<f(,.+f, +.+f, +.+f)- // gl=erte7>f(!+.Gf, +.,f)// gl=erte7>f(!+.>f, +.,f)// gl=erte7>f(!+.>f, +.Hf)gl=erte7>f(!+.Gf, +.Hf)"air of gl2egin and gl4nd 4ach set of : #ertices for; a .uad 1ed 6efine #ertices in counter!cloc&wise ($$W) order so that the nor;al (front!face) is facing 'ou

gl$olor<f(+.+f, ,.+f, +.+f)- // Green gl=erte7>f(!+.Hf, !+.If)gl=erte7>f(!+.,f, !+.If)gl=erte7>f(!+.,f, +.+f)gl=erte7>f(!+.Hf, +.+f)gl$olor<f(+.>f, +.>f, +.>f)gl=erte7>f(!+.Jf, !+.Hf)gl$olor<f(,.+f, ,.+f, ,.+f)gl=erte7>f(!+.?f, !+.Hf)gl$olor<f(+.>f, +.>f, +.>f)gl=erte7>f(!+.?f, !+.<f)gl$olor<f(,.+f, ,.+f, ,.+f)gl=erte7>f(!+.Jf, !+.<f)gl4nd()// 6ar& Gra' // White // 6ar& Gra' // White

gl2egin(GL/T159KGL4S)// 4ach set of < #ertices for; a triangle gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f(+.,f, !+.If)gl=erte7>f(+.Hf, !+.If)gl=erte7>f(+.:f, !+.,f)gl$olor<f(,.+f, +.+f, +.+f)- // 1ed gl=erte7>f(+.<f, !+.:f)gl$olor<f(+.+f, ,.+f, +.+f)- // Green gl=erte7>f(+.Jf, !+.:f)gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f(+.If, !+.Jf)gl4nd()gl2egin(GL/F0LLG0K)// These #ertices for; a closed "ol'gon gl$olor<f(,.+f, ,.+f, +.+f)- // Lellow gl=erte7>f(+.:f, +.>f)gl=erte7>f(+.If, +.>f)gl=erte7>f(+.Hf, +.:f)gl=erte7>f(+.If, +.If)gl=erte7>f(+.:f, +.If)-

gl=erte7>f(+.<f, +.:f)gl4nd()gl3lush()@ )* +andler for window re,size event- Called .ac/ when the window first appears and whenever the window is re,sized with its new width and height *) void reshape01%sizei width2 1%sizei height3 4 )) 1%sizei for non,negative integer )) Co5pute aspect ratio of the new window if 0height 66 73 height 6 89 )) :o prevent divide ." 7 1%float aspect 6 01%float3width ) 01%float3height9 )) Set the viewport to cover the new window gl'iewport072 72 width2 height39 )) Set the aspect ratio of the clipping area to 5atch the viewport gl$atrix$ode01%; <(=EC:I(>39 )) :o operate on the ro?ection 5atrix gl%oadIdentit"039 )) <eset the pro?ection 5atrix if 0width @6 height3 4 )) aspect @6 82 set the height fro5 ,8 to 82 with larger width glu(rtho2!0,8-7 * aspect2 8-7 * aspect2 ,8-72 8-739 A else 4 )) aspect B 82 set the width to ,8 to 82 with larger height glu(rtho2!0,8-72 8-72 ,8-7 ) aspect2 8-7 ) aspect39 A A /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glut5nitWindowSiCe(C472 4D7)- // Set the windowEs initial width B height ! non!s.uare glut5nitWindowFosition(?+, ?+)- // Fosition the windowEs initial to"!left corner glut$reateWindow(D=iew"ort Transfor;D)- // $reate window with the gi#en title glut6is"la'3unc(dis"la')// 1egister call%ac& handler for window re!"aint e#ent glut<eshape#unc0reshape39 // 1egister call%ac& handler for window re!siCe e#ent initGL()// 0ur own 0"enGL initialiCation glutMainLoo"()// 4nter the infinite e#ent!"rocessing loo" return +@ // 1ender now

% resha"e() function, which is called #ac0 when the window first appears and whene,er the window is re$si6ed, can #e used to ensure consistent aspect ratio #etween clipping$area and ,iewport, as shown in the a#o,e example. The graphics su#$system passes the window:s width and height, in pixels, into the resha"e().
GLfloat as"ect O (GLfloat)width / (GLfloat)height-

We compute the aspect ratio of the new re$si6ed window, gi,en its new width and height pro,ided #y the graphics su#$system to the call#ac0 function resha"e().
gl=iew"ort(+, +, width, height)-

We set the ,iewport to co,er the entire new re$si6ed window, in pixels. Try setting the ,iewport to co,er only a /uarter lower$right /uadrant! of the window ,ia gl=iew"ort(+, +, width/>, height/>).
glMatri7Mode(GL/F10Q4$T50K)glLoad5dentit'()if (width >O height) * glu0rtho>6(!,.+ * as"ect, ,.+ * as"ect, !,.+, ,.+)@ else * glu0rtho>6(!,.+, ,.+, !,.+ / as"ect, ,.+ / as"ect)@

We set the aspect ratio of the clipping area to match the ,iewport. To set the clipping area, we first choose the operate on the pro.ection matrix ,ia glMatri7Mode(GL/F10Q4$T50K). "penGL has two matrices, a

pro.ection matrix which deals with camera pro.ection such as setting the clipping area! and a model$,iew matrix for transforming the o#.ects from their local spaces to the common world space!. We reset the pro.ection matrix ,ia glLoad5dentit'(). 9inally, we in,o0e glu0rtho>6() to set the clipping area with an aspect ratio matching the ,iewport. The shorter side has the range from $< to 8<, as illustrated #elow-

We need to register the resha"e() call#ac0 handler with GLUT ,ia glut1esha"e3unc() in the ;ain() as followsint ;ain(int argc, char** arg#) * glut5nitWindowSiCe(I:+, :G+)...... glut1esha"e3unc(resha"e)@

'n the a#o,e ;ain() function, we specify the initial window si6e to I:+7:G+, which is non$s/uarish. Try re$si6ing the window and o#ser,e the changes. ?ote that the resha"e() runs at least once when the window first appears. 't is then called #ac0 whene,er the window is re$shaped. "n the other hand, the initGL() runs once and only once!2 and the dis"la'() runs in response to window re$paint re/uest e.g., after the window is re$si6ed!.

7# Trans&ati n & R tati n


'n the a#o,e sample, we positioned each of the shapes #y defining their ,ertices with respecti,e to the same origin called world space!. 't too0 me /uite a while to figure out the a#solute coordinates of these ,ertices. 'nstead, we could position each of the shapes #y defining their ,ertices with respecti,e to their own center called model space or local space!. We can then use translation and7or rotation to position the shapes at the desired locations in the world space, as shown in the following re,ised dis"la'() function. 7#" E$a%p&e 4! Trans&ati n an* R tati n 0GL'42 *e&Trans( r%#cpp1
/* * GL+:ModelTransfor;.c""A Model Transfor; ! Translation and 1otation * Transfor; "ri;iti#es fro; their ;odel s"aces to world s"ace. */ #include <windows.h> // for MS Windows #include <GL/glut.h> // GLUT, include glu.h and gl.h

/* 5nitialiCe 0"enGL Gra"hics */ #oid initGL() * // Set DclearingD or %ac&ground color gl$lear$olor(+.+f, +.+f, +.+f, ,.+f)- // 2lac& and o"a.ue @ /* andler for window!re"aint e#ent. $all %ac& when the window first a""ears and whene#er the window needs to %e re!"ainted. */ #oid dis"la'() * gl$lear(GL/$0L01/2U3341/25T)// $lear the color %uffer gl$atrix$ode01%;$(!E%'IEW39 )) :o operate on $odel,'iew 5atrix gl%oadIdentit"039 )) <eset the 5odel,view 5atrix gl:ranslatef0,7-Ef2 7-4f2 7-7f39 gl&egin01%;FGH!S39 glColor3f08-7f2 7-7f2 7-7f39 gl'ertex2f0,7-3f2 ,7-3f39 gl'ertex2f0 7-3f2 ,7-3f39 gl'ertex2f0 7-3f2 7-3f39 gl'ertex2f0,7-3f2 7-3f39 glEnd039 )) :ranslate left and up )) Each set of 4 vertices for5 a Iuad )) <ed
)) !efine vertices in counter,cloc/wise 0CCW3 order )) so that the nor5al 0front,face3 is facing "ou

gl:ranslatef07-8f2 ,7-Jf2 7-7f39 )) :ranslate right and down gl&egin01%;FGH!S39 )) Each set of 4 vertices for5 a Iuad glColor3f07-7f2 8-7f2 7-7f39 )) 1reen gl'ertex2f0,7-3f2 ,7-3f39 gl'ertex2f0 7-3f2 ,7-3f39 gl'ertex2f0 7-3f2 7-3f39 gl'ertex2f0,7-3f2 7-3f39 glEnd039 gl:ranslatef0,7-3f2 ,7-2f2 7-7f39 )) :ranslate left and down gl&egin01%;FGH!S39 )) Each set of 4 vertices for5 a Iuad glColor3f07-2f2 7-2f2 7-2f39 )) !ar/ 1ra" gl'ertex2f0,7-2f2 ,7-2f39 glColor3f08-7f2 8-7f2 8-7f39 )) White gl'ertex2f0 7-2f2 ,7-2f39 glColor3f07-2f2 7-2f2 7-2f39 )) !ar/ 1ra" gl'ertex2f0 7-2f2 7-2f39 glColor3f08-7f2 8-7f2 8-7f39 )) White gl'ertex2f0,7-2f2 7-2f39 glEnd039 gl:ranslatef08-8f2 7-2f2 7-7f39 )) :ranslate right and up gl&egin01%;:<IH>1%ES39 )) Each set of 3 vertices for5 a triangle glColor3f07-7f2 7-7f2 8-7f39 )) &lue gl'ertex2f0,7-3f2 ,7-2f39 gl'ertex2f0 7-3f2 ,7-2f39 gl'ertex2f0 7-7f2 7-3f39 glEnd039 gl:ranslatef07-2f2 ,7-3f2 7-7f39 )) :ranslate right and down gl<otatef08D7-7f2 7-7f2 7-7f2 8-7f39 )) <otate 8D7 degree gl&egin01%;:<IH>1%ES39 )) Each set of 3 vertices for5 a triangle glColor3f08-7f2 7-7f2 7-7f39 )) <ed gl'ertex2f0,7-3f2 ,7-2f39 glColor3f07-7f2 8-7f2 7-7f39 )) 1reen gl'ertex2f0 7-3f2 ,7-2f39 glColor3f07-7f2 7-7f2 8-7f39 )) &lue gl'ertex2f0 7-7f2 7-3f39 glEnd039 gl<otatef0,8D7-7f2 7-7f2 7-7f2 8-7f39 )) Gndo previous rotate gl:ranslatef0,7-8f2 8-7f2 7-7f39 )) :ranslate right and down gl&egin01%; (%K1(>39 )) :he vertices for5 one closed pol"gon glColor3f08-7f2 8-7f2 7-7f39 )) Kellow gl'ertex2f0,7-8f2 ,7-2f39 gl'ertex2f0 7-8f2 ,7-2f39 gl'ertex2f0 7-2f2 7-7f39 gl'ertex2f0 7-8f2 7-2f39 gl'ertex2f0,7-8f2 7-2f39

gl'ertex2f0,7-2f2 glEnd039 gl3lush()@ /*

7-7f39

// 1ender now

andler for window re!siCe e#ent. $alled %ac& when the window first a""ears and whene#er the window is re!siCed with its new width and height */ #oid resha"e(GLsiCei width, GLsiCei height) * // GLsiCei for non!negati#e integer // $o;"ute as"ect ratio of the new window if (height OO +) height O ,// To "re#ent di#ide %' + GLfloat as"ect O (GLfloat)width / (GLfloat)height// Set the #iew"ort to co#er the new window gl=iew"ort(+, +, width, height)// Set the as"ect ratio of the cli""ing area to ;atch the #iew"ort glMatri7Mode(GL/F10Q4$T50K)- // To o"erate on the FroPection ;atri7 glLoad5dentit'()if (width >O height) * // as"ect >O ,, set the height fro; !, to ,, with larger width glu0rtho>6(!,.+ * as"ect, ,.+ * as"ect, !,.+, ,.+)@ else * // as"ect < ,, set the width to !, to ,, with larger height glu0rtho>6(!,.+, ,.+, !,.+ / as"ect, ,.+ / as"ect)@ @ /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glut5nitWindowSiCe(I:+, :G+)- // Set the windowEs initial width B height ! non!s.uare glut5nitWindowFosition(?+, ?+)- // Fosition the windowEs initial to"!left corner glut$reateWindow(DModel Transfor;D)- // $reate window with the gi#en title glut6is"la'3unc(dis"la')// 1egister call%ac& handler for window re!"aint e#ent glut1esha"e3unc(resha"e)- // 1egister call%ac& handler for window re!siCe e#ent initGL()// 0ur own 0"enGL initialiCation glutMainLoo"()// 4nter the infinite e#ent!"rocessing loo" return +@ glMatri7Mode(GL/M064L=54W)- // To o"erate on ;odel!#iew ;atri7 glLoad5dentit'()// 1eset

Translation and rotation are parts of so$called model trans!orm, which transform from the o#.ects from the local space or model space! to the common world space. To carry out model transform, we set the matrix mode to mode$,iew matrix GL/M064L=54W! and reset the matrix. Recall that in the pre,ious example, we set the matrix mode to pro.ection matrix GL/F10Q4$T50K! to set the clipping area.! "penGL is operating as a state machine. That is, once a state is set, the ,alue of the state persists until it is changed. 'n other words, once the coordinates are translated or rotated, all the su#se/uent operations will #e #ased on this coordinates. Translation is done ,ia glTranslate function#oid gltranslatef (GLfloat x, GLfloat y, GLfloat z) // where (7, ', C) is the translational #ector

Ta0e note that glTranslatef function must #e placed outside the gl2egin7gl4nd, where as gl$olor can #e placed inside gl2egin7gl4nd. Rotation is done ,ia gl1otatef function#oid gl<otatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z) // where angle s"ecifies the rotation in degree, (x, y, z) for;s the a7is of rotation.

Ta0e note that the rotational angle is measured in degrees instead of radians! in "penGL. 'n the a#o,e example, we translate within the x$y plane 6A>! and rotate a#out the 6$axis which is normal to the x$y plane!.

:# Ani%ati n
:#" I*&e 3uncti n To perform animation e.g., rotating the shapes!, you could register an idle() call#ac0 handler with GLUT, ,ia glut5dle3unc command. The graphic system will call #ac0 the idle() function when there is no other e,ent to #e processed.
#oid glut5dle3unc(#oid (*func)(#oid))

'n the idle() function, you could issue glutFost1edis"la' command to post a window re$paint re/uest, which in turn will acti,ate dis"la'() function.
#oid idle() * glutFost1edis"la'()@ // Fost a re!"aint re.uest to acti#ate dis"la'()

Ta0e note that the a#o,e is e/ui,alent to registering dis"la'() as the idle function.
// ;ain glut5dle3unc(dis"la')-

:#2 D u+&e ?u((erin) )ou#le #uffering uses two display #uffers to smoothen animation. The next screen is prepared in a back #uffer, while the current screen is held in a !ront #uffer. "nce the preparation is done, you can use glutSwa"2uffer command to swap the front and #ac0 #uffers. To use dou#le #uffering, you need to ma0e two changes1. 'n the ;ain(), include this line #efore creating the windowglut5nit6is"la'Mode(GLUT/60U2L4)// Set dou%le %uffered ;ode

2. 'n the dis"la'() function, replace gl3lush() with glutSwa"2uffers(), which swap the front and #ac0 #uffers. )ou#le #uffering should #e used in animation. 9or static display, single #uffering is sufficient. +any graphics hardware always dou#le #uffered, so it is hard to see the differences.! :#3 E$a%p&e 7! Ani%ati n usin) I*&e 3uncti n 0GL'7I*&e3unc#cpp1 The following program rotates all the shapes created in our pre,ious example using idle function with dou#le #uffering.
/* * GL+?5dle3unc.c""A Translation and 1otation * Transfor; "ri;iti#es fro; their ;odel s"aces to world s"ace (Model Transfor;). */ #include <windows.h> // for MS Windows #include <GL/glut.h> // GLUT, include glu.h and gl.h // Glo%al #aria%le 1%float angle 6 7-7f9 )) Current rotational angle of the shapes

/* 5nitialiCe 0"enGL Gra"hics */ #oid initGL() * // Set DclearingD or %ac&ground color gl$lear$olor(+.+f, +.+f, +.+f, ,.+f)- // 2lac& and o"a.ue @ )* Called .ac/ when there is no other event to .e handled *) void idle03 4 glut ost<edispla"039 )) ost a re,paint reIuest to activate displa"03 A /* andler for window!re"aint e#ent. $all %ac& when the window first a""ears and whene#er the window needs to %e re!"ainted. */ #oid dis"la'() * gl$lear(GL/$0L01/2U3341/25T)// $lear the color %uffer gl$atrix$ode01%;$(!E%'IEW39 )) :o operate on $odel,'iew 5atrix gl%oadIdentit"039 )) <eset the 5odel,view 5atrix gl ush$atrix039 gl:ranslatef0,7-Ef2 7-4f2 7-7f39 gl<otatef0angle2 7-7f2 7-7f2 8-7f39 gl2egin(GL/8U96S)gl$olor<f(,.+f, +.+f, +.+f)gl=erte7>f(!+.<f, !+.<f)gl=erte7>f( +.<f, !+.<f)gl=erte7>f( +.<f, +.<f)gl=erte7>f(!+.<f, +.<f)gl4nd()gl op$atrix039 )) )) )) // // Save 5odel,view 5atrix setting :ranslate rotate ." angle in degrees 4ach set of : #ertices for; a .uad 1ed

)) <estore the 5odel,view 5atrix

gl ush$atrix039 )) Save 5odel,view 5atrix setting gl:ranslatef0,7-4f2 ,7-3f2 7-7f39 )) :ranslate gl<otatef0angle2 7-7f2 7-7f2 8-7f39 )) rotate ." angle in degrees gl2egin(GL/8U96S)gl$olor<f(+.+f, ,.+f, +.+f)- // Green gl=erte7>f(!+.<f, !+.<f)gl=erte7>f( +.<f, !+.<f)gl=erte7>f( +.<f, +.<f)gl=erte7>f(!+.<f, +.<f)gl4nd()gl op$atrix039 )) <estore the 5odel,view 5atrix gl ush$atrix039 )) Save 5odel,view 5atrix setting gl:ranslatef0,7-Jf2 ,7-Ef2 7-7f39 )) :ranslate gl<otatef0angle2 7-7f2 7-7f2 8-7f39 )) rotate ." angle in degrees gl2egin(GL/8U96S)gl$olor<f(+.>f, +.>f, +.>f)- // 6ar& Gra' gl=erte7>f(!+.>f, !+.>f)gl$olor<f(,.+f, ,.+f, ,.+f)- // White gl=erte7>f( +.>f, !+.>f)gl$olor<f(+.>f, +.>f, +.>f)- // 6ar& Gra' gl=erte7>f( +.>f, +.>f)gl$olor<f(,.+f, ,.+f, ,.+f)- // White gl=erte7>f(!+.>f, +.>f)gl4nd()gl op$atrix039 )) <estore the 5odel,view 5atrix gl ush$atrix039 )) Save 5odel,view 5atrix setting gl:ranslatef07-4f2 ,7-3f2 7-7f39 )) :ranslate gl<otatef0angle2 7-7f2 7-7f2 8-7f39 )) rotate ." angle in degrees gl2egin(GL/T159KGL4S)gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f(!+.<f, !+.>f)gl=erte7>f( +.<f, !+.>f)gl=erte7>f( +.+f, +.<f)gl4nd()gl op$atrix039 )) <estore the 5odel,view 5atrix gl ush$atrix039 )) Save 5odel,view 5atrix setting gl:ranslatef07-Cf2 ,7-Cf2 7-7f39 )) :ranslate gl<otatef08D7-7f L angle2 7-7f2 7-7f2 8-7f39 )) <otate 8D7Langle degree gl2egin(GL/T159KGL4S)-

gl$olor<f(,.+f, +.+f, +.+f)- // 1ed gl=erte7>f(!+.<f, !+.>f)gl$olor<f(+.+f, ,.+f, +.+f)- // Green gl=erte7>f( +.<f, !+.>f)gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f( +.+f, +.<f)gl4nd()gl op$atrix039 )) <estore the 5odel,view 5atrix gl ush$atrix039 )) Save 5odel,view 5atrix setting gl:ranslatef07-Ef2 7-4f2 7-7f39 )) :ranslate gl<otatef0angle2 7-7f2 7-7f2 8-7f39 )) rotate ." angle in degrees gl2egin(GL/F0LLG0K)gl$olor<f(,.+f, ,.+f, +.+f)- // Lellow gl=erte7>f(!+.,f, !+.>f)gl=erte7>f( +.,f, !+.>f)gl=erte7>f( +.>f, +.+f)gl=erte7>f( +.,f, +.>f)gl=erte7>f(!+.,f, +.>f)gl=erte7>f(!+.>f, +.+f)gl4nd()gl op$atrix039 )) <estore the 5odel,view 5atrix glutSwap&uffers039 )) !ou.le .uffered , swap the front and .ac/ .uffers

)) Change the rotational angle after each displa"03 angle L6 7-2f9 @ /* andler for window re!siCe e#ent. $alled %ac& when the window first a""ears and whene#er the window is re!siCed with its new width and height */ #oid resha"e(GLsiCei width, GLsiCei height) * // GLsiCei for non!negati#e integer // $o;"ute as"ect ratio of the new window if (height OO +) height O ,// To "re#ent di#ide %' + GLfloat as"ect O (GLfloat)width / (GLfloat)height// Set the #iew"ort to co#er the new window gl=iew"ort(+, +, width, height)// Set the as"ect ratio of the cli""ing area to ;atch the #iew"ort glMatri7Mode(GL/F10Q4$T50K)- // To o"erate on the FroPection ;atri7 glLoad5dentit'()if (width >O height) * // as"ect >O ,, set the height fro; !, to ,, with larger width glu0rtho>6(!,.+ * as"ect, ,.+ * as"ect, !,.+, ,.+)@ else * // as"ect < ,, set the width to !, to ,, with larger height glu0rtho>6(!,.+, ,.+, !,.+ / as"ect, ,.+ / as"ect)@ @ /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glutInit!ispla"$ode01%G:;!(G&%E39 )) Ena.le dou.le .uffered 5ode glut5nitWindowSiCe(I:+, :G+)- // Set the windowEs initial width B height ! non!s.uare glut5nitWindowFosition(?+, ?+)- // Fosition the windowEs initial to"!left corner glut$reateWindow(D9ni;ation #ia 5dle 3unctionD)-// $reate window with the gi#en title glut6is"la'3unc(dis"la')// 1egister call%ac& handler for window re!"aint e#ent glut1esha"e3unc(resha"e)// 1egister call%ac& handler for window re!siCe e#ent glutIdle#unc0idle39 )) <egister call.ac/ handler if no other event initGL()// 0ur own 0"enGL initialiCation glutMainLoo"()// 4nter the infinite e#ent!"rocessing loo" return +@

'n the a#o,e example, instead of accumulating all the translations and undoing the rotations, we use glFushMatri7 to sa,e the current state, perform transformations, and restore the sa,ed state ,ia glFo"Matri7. 'n the a#o,e example, we can also use glLoad5dentit' to reset the matrix #efore the next transformations.!

GLfloat angle O +.+f-

// $urrent rotational angle of the sha"es

We define a glo#al ,aria#le called angle to 0eep trac0 of the rotational angle of all the shapes. We will later use gl1otatef to rotate all the shapes to this angle.
angle RO +.>f-

%t the end of each refresh in dis"la'()!, we update the rotational angle of all the shapes.
glutSwa"2uffers()glut5nit6is"la'Mode(GLUT/60U2L4)// Swa" front! and %ac& fra;e%uffer // 5n ;ain(), ena%le dou%le %uffered ;ode

'nstead of gl3lush() which flushes the frame#uffer for display immediately, we ena#le dou#le #uffering and use glutSwa"2uffer() to swap the front$ and #ac0$#uffer during the B1ync for smoother display.
#oid idle() * glutFost1edis"la'()@ glut5dle3unc(idle)// Fost a re!"aint re.uest to acti#ate dis"la'() // 5n ;ain() ! 1egister call%ac& handler if no other e#ent

We define an idle() function, which posts a re$paint re/uest and in,o0e dis"la'(), if there is no e,ent outstanding. We register this idle() function in ;ain() ,ia glut5dle3unc().

:#4 D u+&e ?u((erin) & Re(resh Rate When dou#le #uffering is ena#led, glutSwa"2uffers synchroni6es with the screen refresh inter,al B1ync!. That is, the #uffers will #e swapped at the same time when the monitor is putting up a new frame. %s the result, idle() function, at #est, refreshes the animation at the same rate as the refresh rate of the monitor =>E6 for LC)7LF) monitor!. 't may operates at half the monitor refresh rate if the computations ta0es more than < refresh inter,al!, one$third, one$fourth, and so on, #ecause it need to wait for the B1ync. :#7 Ti%er 3uncti n With idle(), we ha,e no control to the refresh inter,al. We could register a Ti;er() function with GLUT ,ia glutTi;er3unc. The Ti;er() function will #e called #ac0 at the specified fixed inter,al.
#oid glutTi;er3unc(unsigned int millis, #oid (*func)(int value), value) // where millis is the dela' in ;illiseconds, value will %e "assed to the ti;er function.

:#: E$a%p&e :! Ani%ati n /ia Ti%er 3uncti n 0GL':Ti%er3unc#cpp1 The following modifications rotate all the shapes created in the earlier example counter$cloc0wise #y * degree per (> milliseconds.
/* * GL+ITi;er3unc.c""A Translation and 1otation * Transfor; "ri;iti#es fro; their ;odel s"aces to world s"ace (Model Transfor;). */ #include <windows.h> // for MS Windows #include <GL/glut.h> // GLUT, include glu.h and gl.h // glo%al #aria%le GLfloat angle O +.+f- // rotational angle of the sha"es int refreshMills O <+- // refresh inter#al in ;illiseconds

/* 5nitialiCe 0"enGL Gra"hics */ #oid initGL() * // Set DclearingD or %ac&ground color gl$lear$olor(+.+f, +.+f, +.+f, ,.+f)- // 2lac& and o"a.ue @ )* Called .ac/ when ti5er expired *) void :i5er0int value3 4 glut ost<edispla"039 )) ost re,paint reIuest to activate displa"03 glut:i5er#unc0refresh$ills2 :i5er2 739 )) next :i5er call 5illiseconds later A /* andler for window!re"aint e#ent. $all %ac& when the window first a""ears and whene#er the window needs to %e re!"ainted. */ #oid dis"la'() * gl$lear(GL/$0L01/2U3341/25T)// $lear the color %uffer glMatri7Mode(GL/M064L=54W)// To o"erate on Model!=iew ;atri7 glLoad5dentit'()// 1eset the ;odel!#iew ;atri7 glFushMatri7()glTranslatef(!+.?f, +.:f, +.+f)gl1otatef(angle, +.+f, +.+f, ,.+f)gl2egin(GL/8U96S)gl$olor<f(,.+f, +.+f, +.+f)gl=erte7>f(!+.<f, !+.<f)gl=erte7>f( +.<f, !+.<f)gl=erte7>f( +.<f, +.<f)gl=erte7>f(!+.<f, +.<f)gl4nd()glFo"Matri7()// // // // // Sa#e ;odel!#iew ;atri7 setting Translate rotate %' angle in degrees 4ach set of : #ertices for; a .uad 1ed

// 1estore the ;odel!#iew ;atri7

glFushMatri7()// Sa#e ;odel!#iew ;atri7 setting glTranslatef(!+.:f, !+.<f, +.+f)// Translate gl1otatef(angle, +.+f, +.+f, ,.+f)- // rotate %' angle in degrees gl2egin(GL/8U96S)gl$olor<f(+.+f, ,.+f, +.+f)- // Green gl=erte7>f(!+.<f, !+.<f)gl=erte7>f( +.<f, !+.<f)gl=erte7>f( +.<f, +.<f)gl=erte7>f(!+.<f, +.<f)gl4nd()glFo"Matri7()// 1estore the ;odel!#iew ;atri7 glFushMatri7()// Sa#e ;odel!#iew ;atri7 setting glTranslatef(!+.Hf, !+.?f, +.+f)// Translate gl1otatef(angle, +.+f, +.+f, ,.+f)- // rotate %' angle in degrees gl2egin(GL/8U96S)gl$olor<f(+.>f, +.>f, +.>f)- // 6ar& Gra' gl=erte7>f(!+.>f, !+.>f)gl$olor<f(,.+f, ,.+f, ,.+f)- // White gl=erte7>f( +.>f, !+.>f)gl$olor<f(+.>f, +.>f, +.>f)- // 6ar& Gra' gl=erte7>f( +.>f, +.>f)gl$olor<f(,.+f, ,.+f, ,.+f)- // White gl=erte7>f(!+.>f, +.>f)gl4nd()glFo"Matri7()// 1estore the ;odel!#iew ;atri7 glFushMatri7()// Sa#e ;odel!#iew ;atri7 setting glTranslatef(+.:f, !+.<f, +.+f)// Translate gl1otatef(angle, +.+f, +.+f, ,.+f)- // rotate %' angle in degrees gl2egin(GL/T159KGL4S)gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f(!+.<f, !+.>f)gl=erte7>f( +.<f, !+.>f)gl=erte7>f( +.+f, +.<f)gl4nd()glFo"Matri7()// 1estore the ;odel!#iew ;atri7 glFushMatri7()// Sa#e ;odel!#iew ;atri7 setting glTranslatef(+.If, !+.If, +.+f)// Translate gl1otatef(,G+.+f R angle, +.+f, +.+f, ,.+f)- // 1otate ,G+Rangle degree

gl2egin(GL/T159KGL4S)gl$olor<f(,.+f, +.+f, +.+f)- // 1ed gl=erte7>f(!+.<f, !+.>f)gl$olor<f(+.+f, ,.+f, +.+f)- // Green gl=erte7>f( +.<f, !+.>f)gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f( +.+f, +.<f)gl4nd()glFo"Matri7()// 1estore the ;odel!#iew ;atri7 glFushMatri7()// Sa#e ;odel!#iew ;atri7 setting glTranslatef(+.?f, +.:f, +.+f)// Translate gl1otatef(angle, +.+f, +.+f, ,.+f)- // rotate %' angle in degrees gl2egin(GL/F0LLG0K)gl$olor<f(,.+f, ,.+f, +.+f)- // Lellow gl=erte7>f(!+.,f, !+.>f)gl=erte7>f( +.,f, !+.>f)gl=erte7>f( +.>f, +.+f)gl=erte7>f( +.,f, +.>f)gl=erte7>f(!+.,f, +.>f)gl=erte7>f(!+.>f, +.+f)gl4nd()glFo"Matri7()// 1estore the ;odel!#iew ;atri7 glutSwa"2uffers()// 6ou%le %uffered ! swa" the front and %ac& %uffers

// $hange the rotational angle after each dis"la'() angle RO >.+f@ /* andler for window re!siCe e#ent. $alled %ac& when the window first a""ears and whene#er the window is re!siCed with its new width and height */ #oid resha"e(GLsiCei width, GLsiCei height) * // GLsiCei for non!negati#e integer // $o;"ute as"ect ratio of the new window if (height OO +) height O ,// To "re#ent di#ide %' + GLfloat as"ect O (GLfloat)width / (GLfloat)height// Set the #iew"ort to co#er the new window gl=iew"ort(+, +, width, height)// Set the as"ect ratio of the cli""ing area to ;atch the #iew"ort glMatri7Mode(GL/F10Q4$T50K)- // To o"erate on the FroPection ;atri7 glLoad5dentit'()if (width >O height) * // as"ect >O ,, set the height fro; !, to ,, with larger width glu0rtho>6(!,.+ * as"ect, ,.+ * as"ect, !,.+, ,.+)@ else * // as"ect < ,, set the width to !, to ,, with larger height glu0rtho>6(!,.+, ,.+, !,.+ / as"ect, ,.+ / as"ect)@ @ /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glut5nit6is"la'Mode(GLUT/60U2L4)- // 4na%le dou%le %uffered ;ode glut5nitWindowSiCe(I:+, :G+)- // Set the windowEs initial width B height ! non!s.uare glut5nitWindowFosition(?+, ?+)- // Fosition the windowEs initial to"!left corner glut$reateWindow(D9ni;ation #ia 5dle 3unctionD)-// $reate window with the gi#en title glut6is"la'3unc(dis"la')- // 1egister call%ac& handler for window re!"aint e#ent glut1esha"e3unc(resha"e)- // 1egister call%ac& handler for window re!siCe e#ent glut:i5er#unc072 :i5er2 739 // 3irst ti;er call i;;ediatel' initGL()// 0ur own 0"enGL initialiCation glutMainLoo"()// 4nter the infinite e#ent!"rocessing loo" return +@ #oid Ti;er(int #alue) * glutFost1edis"la'()// Fost re!"aint re.uest to acti#ate dis"la'() glutTi;er3unc(refreshMills, Ti;er, +)- // ne7t Ti;er call ;illiseconds later @

We replace the idle() function #y a ti;er() function, which post a re$paint re/uest to in,o0e dis"la'(), after the timer expired.
glutTi;er3unc(+, Ti;er, +)// 3irst ti;er call i;;ediatel'

'n ;ain(), we register the ti;er() function, and acti,ate the ti;er() immediately with initial timer A >!. :#< 2 re GL;T (uncti ns

glut5nit6is"la'Mode- re/uests a display with the specified mode, such as color mode GLUT/1G2, GLUT/1G29, GLUT/5K64S!, single7dou#le #uffering GLUT/S5KGL4, GLUT/60U2L4!, ena#le depth GLUT/64FT !, .oined with a #it 01 :T:. #oid glut5nit6is"la'Mode(unsigned int display ode)

9or example,
glut5nit6is"la'Mode(GLUT/1G29 T GLUT/60U2L4 T GLUT/64FT )// Use 1G29 color, ena%le dou%le %uffering and ena%le de"th %uffer

:#= E$a%p&e <! A ? uncin) ?a&& 0GL'<? uncin)?a&&#cpp1 This example shows a #all #ouncing inside the window. Ta0e note that circle is not a primiti,e geometric shape in "penGL. This example uses T159KGL4/39K to compose a circle.

/* * GL+H2ouncing2all.c""A */ #include <windows.h> // #include <GL/glut.h> // #include <Math.h> // #define F5 <.,:,?J>I?f

9 %all %ouncing inside the window for MS Windows GLUT, includes glu.h and gl.h Keeded for sin, cos

// Glo%al #aria%les char titleMN O D2ouncing 2all (>6)D- // Windowed ;odeEs title int windowWidth O I:+// Windowed ;odeEs width int window eight O :G+// Windowed ;odeEs height int windowFosS O ?+// Windowed ;odeEs to"!left corner 7 int windowFosL O ?+// Windowed ;odeEs to"!left corner '

GLfloat %all1adius O +.?f// 1adius of the %ouncing %all GLfloat %allS O +.+f// 2allEs center (7, ') "osition GLfloat %allL O +.+fGLfloat %allSMa7, %allSMin, %allLMa7, %allLMin- // 2allEs center (7, ') %ounds GLfloat 7S"eed O +.+>f// 2allEs s"eed in 7 and ' directions GLfloat 'S"eed O +.++Hfint refreshMillis O <+// 1efresh "eriod in ;illiseconds // FroPection cli""ing area GLdou%le cli"9reaSLeft, cli"9reaS1ight, cli"9reaL2otto;, cli"9reaLTo"/* 5nitialiCe 0"enGL Gra"hics */ #oid initGL() * gl$lear$olor(+.+, +.+, +.+, ,.+)- // Set %ac&ground (clear) color to %lac& @ /* $all%ac& handler for window re!"aint e#ent */ #oid dis"la'() * gl$lear(GL/$0L01/2U3341/25T)- // $lear the color %uffer glMatri7Mode(GL/M064L=54W)// To o"erate on the ;odel!#iew ;atri7 glLoad5dentit'()// 1eset ;odel!#iew ;atri7 glTranslatef(%allS, %allL, +.+f)- // Translate to (7Fos, 'Fos) // Use triangular seg;ents to for; a circle gl2egin(GL/T159KGL4/39K)gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f(+.+f, +.+f)// $enter of circle int nu;Seg;ents O ,++GLfloat anglefor (int i O +- i <O nu;Seg;ents- iRR) * // Last #erte7 sa;e as first #erte7 angle O i * >.+f * F5 / nu;Seg;ents- // <I+ deg for all seg;ents gl=erte7>f(cos(angle) * %all1adius, sin(angle) * %all1adius)@ gl4nd()glutSwa"2uffers()// Swa" front and %ac& %uffers (of dou%le %uffered ;ode)

// 9ni;ation $ontrol ! co;"ute the location for the ne7t refresh %allS RO 7S"eed%allL RO 'S"eed// $hec& if the %all e7ceeds the edges if (%allS > %allSMa7) * %allS O %allSMa77S"eed O !7S"eed@ else if (%allS < %allSMin) * %allS O %allSMin7S"eed O !7S"eed@ if (%allL > %allLMa7) * %allL O %allLMa7'S"eed O !'S"eed@ else if (%allL < %allLMin) * %allL O %allLMin'S"eed O !'S"eed@ @ /* $all %ac& when the windows is re!siCed */ #oid resha"e(GLsiCei width, GLsiCei height) * // $o;"ute as"ect ratio of the new window if (height OO +) height O ,// To "re#ent di#ide %' + GLfloat as"ect O (GLfloat)width / (GLfloat)height// Set the #iew"ort to co#er the new window gl=iew"ort(+, +, width, height)// Set the as"ect ratio of the cli""ing area to ;atch the #iew"ort glMatri7Mode(GL/F10Q4$T50K)- // To o"erate on the FroPection ;atri7 glLoad5dentit'()// 1eset the "roPection ;atri7 if (width >O height) * cli"9reaSLeft O !,.+ * as"ectcli"9reaS1ight O ,.+ * as"ect-

cli"9reaL2otto; O !,.+cli"9reaLTo" O ,.+@ else * cli"9reaSLeft O !,.+cli"9reaS1ight O ,.+cli"9reaL2otto; O !,.+ / as"ectcli"9reaLTo" O ,.+ / as"ect@ glu0rtho>6(cli"9reaSLeft, cli"9reaS1ight, cli"9reaL2otto;, cli"9reaLTo")%allSMin O cli"9reaSLeft R %all1adius%allSMa7 O cli"9reaS1ight ! %all1adius%allLMin O cli"9reaL2otto; R %all1adius%allLMa7 O cli"9reaLTo" ! %all1adius@ /* $alled %ac& when the ti;er e7"ired */ #oid Ti;er(int #alue) * glutFost1edis"la'()// Fost a "aint re.uest to acti#ate dis"la'() glutTi;er3unc(refreshMillis, Ti;er, +)- // su%se.uent ti;er call at ;illiseconds @ /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glut5nit6is"la'Mode(GLUT/60U2L4)- // 4na%le dou%le %uffered ;ode glut5nitWindowSiCe(windowWidth, window eight)- // 5nitial window width and height glut5nitWindowFosition(windowFosS, windowFosL)- // 5nitial window to"!left corner (7, ') glut$reateWindow(title)// $reate window with gi#en title glut6is"la'3unc(dis"la')// 1egister call%ac& handler for window re!"aint glut1esha"e3unc(resha"e)// 1egister call%ac& handler for window re!sha"e glutTi;er3unc(+, Ti;er, +)// 3irst ti;er call i;;ediatel' initGL()// 0ur own 0"enGL initialiCation glutMainLoo"()// 4nter e#ent!"rocessing loo" return +@

<# Han*&in) @e9+ ar* Inputs with GL;T


We can register call#ac0 functions to handle 0ey#oard inputs for normal and special 0eys, respecti,ely.

glutUe'%oard3unc- registers call#ac0 handler for 0ey#oard e,ent. #oid glutMe".oard#unc (#oid (*func)(unsigned char !ey, int x, int y) // !ey is the char "ressed, e.g., EaE or >H for 4S$ // (x, y) is the ;ouse location in WindowsE coordinates glutS"ecial3unc- registers call#ac0 handler for special 0ey such as arrow 0eys and

function

0eys!.
#oid glutSpecial#unc (#oid (*func)(int special"ey, int x, int y) // special"eyA GLUT/U4L/* (* for L43T, 15G T, UF, 60WK, 0M4, 4K6, F9G4/UF, F9G4/60WK, 3,,...3,>). // (x, y) is the ;ouse location in WindowsE coordinates

<#" E$a%p&e =! Switchin) +etween 3u&&5Screen an* Win* we*5% *e 0GL'=3u&&Screen#cpp1 9or the #ouncing #all program, the following special$0ey handler toggles #etween !ull screen and windowed modes using 9< 0ey.
/* * GL+G3ullScreen.c""A Switching %etween full!screen ;ode and windowed!;ode */ #include <windows.h> // for MS Windows #include <GL/glut.h> // GLUT, includes glu.h and gl.h #include <Math.h> // Keeded for sin, cos #define F5 <.,:,?J>I?f // Glo%al #aria%les char titleMN O D3ull!Screen B Windowed ModeD// Windowed ;odeEs title

int int int int

windowWidth window eight windowFosS windowFosL

O O O O

I:+:G+?+?+-

// // // //

Windowed Windowed Windowed Windowed

;odeEs ;odeEs ;odeEs ;odeEs

width height to"!left corner 7 to"!left corner '

GLfloat %all1adius O +.?f// 1adius of the %ouncing %all GLfloat %allS O +.+f// 2allEs center (7, ') "osition GLfloat %allL O +.+fGLfloat %allSMa7, %allSMin, %allLMa7, %allLMin- // 2allEs center (7, ') %ounds GLfloat 7S"eed O +.+>f// 2allEs s"eed in 7 and ' directions GLfloat 'S"eed O +.++Hfint refreshMillis O <+// 1efresh "eriod in ;illiseconds // FroPection cli""ing area GLdou%le cli"9reaSLeft, cli"9reaS1ight, cli"9reaL2otto;, cli"9reaLTo".ool fullScreen$ode 6 true9 )) #ull,screen or windowed 5odeN /* 5nitialiCe 0"enGL Gra"hics */ #oid initGL() * gl$lear$olor(+.+, +.+, +.+, ,.+)- // Set %ac&ground (clear) color to %lac& @ /* $all%ac& handler for window re!"aint e#ent */ #oid dis"la'() * gl$lear(GL/$0L01/2U3341/25T)- // $lear the color %uffer glMatri7Mode(GL/M064L=54W)// To o"erate on the ;odel!#iew ;atri7 glLoad5dentit'()// 1eset ;odel!#iew ;atri7 glTranslatef(%allS, %allL, +.+f)- // Translate to (7Fos, 'Fos) // Use triangular seg;ents to for; a circle gl2egin(GL/T159KGL4/39K)gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f(+.+f, +.+f)// $enter of circle int nu;Seg;ents O ,++GLfloat anglefor (int i O +- i <O nu;Seg;ents- iRR) * // Last #erte7 sa;e as first #erte7 angle O i * >.+f * F5 / nu;Seg;ents- // <I+ deg for all seg;ents gl=erte7>f(cos(angle) * %all1adius, sin(angle) * %all1adius)@ gl4nd()glutSwa"2uffers()// Swa" front and %ac& %uffers (of dou%le %uffered ;ode)

// 9ni;ation $ontrol ! co;"ute the location for the ne7t refresh %allS RO 7S"eed%allL RO 'S"eed// $hec& if the %all e7ceeds the edges if (%allS > %allSMa7) * %allS O %allSMa77S"eed O !7S"eed@ else if (%allS < %allSMin) * %allS O %allSMin7S"eed O !7S"eed@ if (%allL > %allLMa7) * %allL O %allLMa7'S"eed O !'S"eed@ else if (%allL < %allLMin) * %allL O %allLMin'S"eed O !'S"eed@ @ /* $all %ac& when the windows is re!siCed */ #oid resha"e(GLsiCei width, GLsiCei height) * // $o;"ute as"ect ratio of the new window if (height OO +) height O ,// To "re#ent di#ide %' + GLfloat as"ect O (GLfloat)width / (GLfloat)height// Set the #iew"ort to co#er the new window gl=iew"ort(+, +, width, height)-

// Set the as"ect ratio of the cli""ing area to ;atch the #iew"ort glMatri7Mode(GL/F10Q4$T50K)- // To o"erate on the FroPection ;atri7 glLoad5dentit'()// 1eset the "roPection ;atri7 if (width >O height) * cli"9reaSLeft O !,.+ * as"ectcli"9reaS1ight O ,.+ * as"ectcli"9reaL2otto; O !,.+cli"9reaLTo" O ,.+@ else * cli"9reaSLeft O !,.+cli"9reaS1ight O ,.+cli"9reaL2otto; O !,.+ / as"ectcli"9reaLTo" O ,.+ / as"ect@ glu0rtho>6(cli"9reaSLeft, cli"9reaS1ight, cli"9reaL2otto;, cli"9reaLTo")%allSMin O cli"9reaSLeft R %all1adius%allSMa7 O cli"9reaS1ight ! %all1adius%allLMin O cli"9reaL2otto; R %all1adius%allLMa7 O cli"9reaLTo" ! %all1adius@ /* $alled %ac& when the ti;er e7"ired */ #oid Ti;er(int #alue) * glutFost1edis"la'()// Fost a "aint re.uest to acti#ate dis"la'() glutTi;er3unc(refreshMillis, Ti;er, +)- // su%se.uent ti;er call at ;illiseconds @ )* Call.ac/ handler for special,/e" event *) void specialMe"s0int /e"2 int x2 int "3 4 switch 0/e"3 4 case 1%G:;MEK;#8O )) #8O :oggle .etween full,screen and windowed 5ode fullScreen$ode 6 PfullScreen$ode9 )) :oggle state if 0fullScreen$ode3 4 )) #ull,screen 5ode window osQ 6 glut1et01%G:;WI>!(W;Q39 )) Save para5eters for restoring later window osK 6 glut1et01%G:;WI>!(W;K39 windowWidth 6 glut1et01%G:;WI>!(W;WI!:+39 window+eight 6 glut1et01%G:;WI>!(W;+EI1+:39 glut#ullScreen039 )) Switch into full screen A else 4 )) Windowed 5ode glut<eshapeWindow0windowWidth2 window+eight39 )) Switch into windowed 5ode glut ositionWindow0window osQ2 window osQ39 )) osition top,left corner A .rea/9 A A /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glut5nit6is"la'Mode(GLUT/60U2L4)- // 4na%le dou%le %uffered ;ode glut5nitWindowSiCe(windowWidth, window eight)- // 5nitial window width and height glut5nitWindowFosition(windowFosS, windowFosL)- // 5nitial window to"!left corner (7, ') glut$reateWindow(title)// $reate window with gi#en title glut6is"la'3unc(dis"la')// 1egister call%ac& handler for window re!"aint glut1esha"e3unc(resha"e)// 1egister call%ac& handler for window re!sha"e glutTi;er3unc(+, Ti;er, +)// 3irst ti;er call i;;ediatel' glutSpecial#unc0specialMe"s39 )) <egister call.ac/ handler for special,/e" event glut#ullScreen039 )) ut into full screen initGL()// 0ur own 0"enGL initialiCation glutMainLoo"()// 4nter e#ent!"rocessing loo" return +@

<#2 E$a%p&e >! @e95C ntr &&e* 0GL'>@e9C ntr &#cpp1 9or the #ouncing #all program, the following 0ey and special$0ey handlers pro,ide exits with F1C *D!, increase7decrease y speed with up$7down$arrow 0ey, increase7decrease x speed with left$7right$arrow 0ey, increase7decrease #all:s radius with &ageUp7&age)own 0ey.

/* * GL+JUe'$ontrol.c""A 9 */ #include <windows.h> // #include <GL/glut.h> // #include <Math.h> // #define F5 <.,:,?J>I?f

&e'!controlled %ouncing %all for MS Windows GLUT, include glu.h and gl.h Keeded for sin, cos

// Glo%al #aria%les char titleMN O D3ull!Screen int windowWidth O I:+int window eight O :G+int windowFosS O ?+int windowFosL O ?+-

B Windowed ModeD// Windowed ;odeEs // Windowed ;odeEs // Windowed ;odeEs // Windowed ;odeEs

// Windowed ;odeEs title width height to"!left corner 7 to"!left corner '

GLfloat %all1adius O +.?f// 1adius of the %ouncing %all GLfloat %allS O +.+f// 2allEs center (7, ') "osition GLfloat %allL O +.+fGLfloat %allSMa7, %allSMin, %allLMa7, %allLMin- // 2allEs center (7, ') %ounds GLfloat 7S"eed O +.+>f// 2allEs s"eed in 7 and ' directions GLfloat 'S"eed O +.++Hfint refreshMillis O <+// 1efresh "eriod in ;illiseconds // FroPection cli""ing area GLdou%le cli"9reaSLeft, cli"9reaS1ight, cli"9reaL2otto;, cli"9reaLTo"%ool fullScreenMode O true- // 3ull!screen or windowed ;odeV /* 5nitialiCe 0"enGL Gra"hics */ #oid initGL() * gl$lear$olor(+.+, +.+, +.+, ,.+)- // Set %ac&ground (clear) color to %lac& @ /* $all%ac& handler for window re!"aint e#ent */ #oid dis"la'() * gl$lear(GL/$0L01/2U3341/25T)- // $lear the color %uffer glMatri7Mode(GL/M064L=54W)// To o"erate on the ;odel!#iew ;atri7 glLoad5dentit'()// 1eset ;odel!#iew ;atri7 glTranslatef(%allS, %allL, +.+f)- // Translate to (7Fos, 'Fos) // Use triangular seg;ents to for; a circle gl2egin(GL/T159KGL4/39K)gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f(+.+f, +.+f)// $enter of circle int nu;Seg;ents O ,++GLfloat anglefor (int i O +- i <O nu;Seg;ents- iRR) * // Last #erte7 sa;e as first #erte7 angle O i * >.+f * F5 / nu;Seg;ents- // <I+ deg for all seg;ents gl=erte7>f(cos(angle) * %all1adius, sin(angle) * %all1adius)@ gl4nd()glutSwa"2uffers()// Swa" front and %ac& %uffers (of dou%le %uffered ;ode)

// 9ni;ation $ontrol ! co;"ute the location for the ne7t refresh %allS RO 7S"eed%allL RO 'S"eed// $hec& if the %all e7ceeds the edges if (%allS > %allSMa7) * %allS O %allSMa77S"eed O !7S"eed@ else if (%allS < %allSMin) * %allS O %allSMin7S"eed O !7S"eed@ if (%allL > %allLMa7) * %allL O %allLMa7'S"eed O !'S"eed@ else if (%allL < %allLMin) * %allL O %allLMin'S"eed O !'S"eed@

@ /* $all %ac& when the windows is re!siCed */ #oid resha"e(GLsiCei width, GLsiCei height) * // $o;"ute as"ect ratio of the new window if (height OO +) height O ,// To "re#ent di#ide %' + GLfloat as"ect O (GLfloat)width / (GLfloat)height// Set the #iew"ort to co#er the new window gl=iew"ort(+, +, width, height)// Set the as"ect ratio of the cli""ing area to ;atch the #iew"ort glMatri7Mode(GL/F10Q4$T50K)- // To o"erate on the FroPection ;atri7 glLoad5dentit'()// 1eset the "roPection ;atri7 if (width >O height) * cli"9reaSLeft O !,.+ * as"ectcli"9reaS1ight O ,.+ * as"ectcli"9reaL2otto; O !,.+cli"9reaLTo" O ,.+@ else * cli"9reaSLeft O !,.+cli"9reaS1ight O ,.+cli"9reaL2otto; O !,.+ / as"ectcli"9reaLTo" O ,.+ / as"ect@ glu0rtho>6(cli"9reaSLeft, cli"9reaS1ight, cli"9reaL2otto;, cli"9reaLTo")%allSMin O cli"9reaSLeft R %all1adius%allSMa7 O cli"9reaS1ight ! %all1adius%allLMin O cli"9reaL2otto; R %all1adius%allLMa7 O cli"9reaLTo" ! %all1adius@ /* $alled %ac& when the ti;er e7"ired */ #oid Ti;er(int #alue) * glutFost1edis"la'()// Fost a "aint re.uest to acti#ate dis"la'() glutTi;er3unc(refreshMillis, Ti;er, +)- // su%se.uent ti;er call at ;illiseconds @ )* Call.ac/ handler for nor5al,/e" event *) void /e".oard0unsigned char /e"2 int x2 int "3 4 switch 0/e"3 4 case 2JO )) ESC /e" exit0739 .rea/9 A A )* Call.ac/ handler for special,/e" event *) void specialMe"s0int /e"2 int x2 int "3 4 switch 0/e"3 4 case 1%G:;MEK;#8O )) #8O :oggle .etween full,screen and windowed 5ode fullScreen$ode 6 PfullScreen$ode9 )) :oggle state if 0fullScreen$ode3 4 )) #ull,screen 5ode window osQ 6 glut1et01%G:;WI>!(W;Q39 )) Save para5eters for restoring later window osK 6 glut1et01%G:;WI>!(W;K39 windowWidth 6 glut1et01%G:;WI>!(W;WI!:+39 window+eight 6 glut1et01%G:;WI>!(W;+EI1+:39 glut#ullScreen039 )) Switch into full screen A else 4 )) Windowed 5ode glut<eshapeWindow0windowWidth2 window+eight39 )) Switch into windowed 5ode glut ositionWindow0window osQ2 window osQ39 )) osition top,left corner A .rea/9 case 1%G:;MEK;<I1+:O )) <ightO increase x speed xSpeed *6 8-7Ef9 .rea/9 case 1%G:;MEK;%E#:O )) %eftO decrease x speed xSpeed *6 7-REf9 .rea/9 case 1%G:;MEK;G O )) GpO increase " speed "Speed *6 8-7Ef9 .rea/9 case 1%G:;MEK;!(W>O )) !ownO decrease " speed "Speed *6 7-REf9 .rea/9 case 1%G:;MEK; H1E;G O )) age,GpO increase .allSs radius

.all<adius *6 8-7Ef9 .allQ$in 6 clipHreaQ%eft L .all<adius9 .allQ$ax 6 clipHreaQ<ight , .all<adius9 .allK$in 6 clipHreaK&otto5 L .all<adius9 .allK$ax 6 clipHreaK:op , .all<adius9 .rea/9 case 1%G:;MEK; H1E;!(W>O )) age,!ownO decrease .allSs radius .all<adius *6 7-REf9 .allQ$in 6 clipHreaQ%eft L .all<adius9 .allQ$ax 6 clipHreaQ<ight , .all<adius9 .allK$in 6 clipHreaK&otto5 L .all<adius9 .allK$ax 6 clipHreaK:op , .all<adius9 .rea/9 A A /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glut5nit6is"la'Mode(GLUT/60U2L4)- // 4na%le dou%le %uffered ;ode glut5nitWindowSiCe(windowWidth, window eight)- // 5nitial window width and height glut5nitWindowFosition(windowFosS, windowFosL)- // 5nitial window to"!left corner (7, ') glut$reateWindow(title)// $reate window with gi#en title glut6is"la'3unc(dis"la')// 1egister call%ac& handler for window re!"aint glut1esha"e3unc(resha"e)// 1egister call%ac& handler for window re!sha"e glutTi;er3unc(+, Ti;er, +)// 3irst ti;er call i;;ediatel' glutS"ecial3unc(s"ecialUe's)- // 1egister call%ac& handler for s"ecial!&e' e#ent glutUe'%oard3unc(&e'%oard)// 1egister call%ac& handler for s"ecial!&e' e#ent glut3ullScreen()// Fut into full screen initGL()// 0ur own 0"enGL initialiCation glutMainLoo"()// 4nter e#ent!"rocessing loo" return +@

=# Han*&in) 2 use Inputs with GL;T


1imilarly, we can register call#ac0 function to handle mouse$clic0 and mouse$motion.

glutMouse3unc- registers call#ac0 handler for mouse clic0. #oid glutMouse3unc(#oid (*func)(int button, int state, int x, int y) // (x, y) is the ;ouse!clic& location. // buttonA GLUT/L43T/2UTT0K, GLUT/15G T/2UTT0K, GLUT/M566L4/2UTT0K // stateA GLUT/UF, GLUT/60WK glutMotion3unc- registers call#ac0 handler for mouse motion when the mouse is clic0ed and

mo,ed!.
#oid glutMotion3unc(#oid (*func)(int x, int y) // where (x, y) is the ;ouse location in WindowEs coordinates

=#" E$a%p&e "'! 2 use5C ntr &&e* 0GL"'2 useC ntr &#cpp1 9or the #ouncing #all program, the following mouse handler pause the mo,ement with left$mouse clic0, and resume with right$mouse clic0.
/* * GL,+Mouse$ontrol.c""A */ #include <windows.h> // #include <GL/glut.h> // #include <Math.h> // #define F5 <.,:,?J>I?f 9 ;ouse!controlled %ouncing %all for MS Windows GLUT, include glu.h and gl.h Keeded for sin, cos

// Glo%al #aria%les char titleMN O D3ull!Screen int windowWidth O I:+int window eight O :G+int windowFosS O ?+-

B Windowed ModeD// Windowed ;odeEs // Windowed ;odeEs // Windowed ;odeEs

// Windowed ;odeEs title width height to"!left corner 7

int windowFosL

O ?+-

// Windowed ;odeEs to"!left corner '

GLfloat %all1adius O +.?f// 1adius of the %ouncing %all GLfloat %allS O +.+f// 2allEs center (7, ') "osition GLfloat %allL O +.+fGLfloat %allSMa7, %allSMin, %allLMa7, %allLMin- // 2allEs center (7, ') %ounds GLfloat 7S"eed O +.+>f// 2allEs s"eed in 7 and ' directions GLfloat 'S"eed O +.++Hfint refreshMillis O <+// 1efresh "eriod in ;illiseconds // FroPection cli""ing area GLdou%le cli"9reaSLeft, cli"9reaS1ight, cli"9reaL2otto;, cli"9reaLTo"%ool fullScreenMode O true- // 3ull!screen or windowed ;odeV .ool paused 6 false9 )) $ove5ent paused or resu5ed 1%float xSpeedSaved2 "SpeedSaved9 )) :o support resu5e /* 5nitialiCe 0"enGL Gra"hics */ #oid initGL() * gl$lear$olor(+.+, +.+, +.+, ,.+)- // Set %ac&ground (clear) color to %lac& @ /* $all%ac& handler for window re!"aint e#ent */ #oid dis"la'() * gl$lear(GL/$0L01/2U3341/25T)- // $lear the color %uffer glMatri7Mode(GL/M064L=54W)// To o"erate on the ;odel!#iew ;atri7 glLoad5dentit'()// 1eset ;odel!#iew ;atri7 glTranslatef(%allS, %allL, +.+f)- // Translate to (7Fos, 'Fos) // Use triangular seg;ents to for; a circle gl2egin(GL/T159KGL4/39K)gl$olor<f(+.+f, +.+f, ,.+f)- // 2lue gl=erte7>f(+.+f, +.+f)// $enter of circle int nu;Seg;ents O ,++GLfloat anglefor (int i O +- i <O nu;Seg;ents- iRR) * // Last #erte7 sa;e as first #erte7 angle O i * >.+f * F5 / nu;Seg;ents- // <I+ deg for all seg;ents gl=erte7>f(cos(angle) * %all1adius, sin(angle) * %all1adius)@ gl4nd()glutSwa"2uffers()// Swa" front and %ac& %uffers (of dou%le %uffered ;ode)

// 9ni;ation $ontrol ! co;"ute the location for the ne7t refresh %allS RO 7S"eed%allL RO 'S"eed// $hec& if the %all e7ceeds the edges if (%allS > %allSMa7) * %allS O %allSMa77S"eed O !7S"eed@ else if (%allS < %allSMin) * %allS O %allSMin7S"eed O !7S"eed@ if (%allL > %allLMa7) * %allL O %allLMa7'S"eed O !'S"eed@ else if (%allL < %allLMin) * %allL O %allLMin'S"eed O !'S"eed@ @ /* $all %ac& when the windows is re!siCed */ #oid resha"e(GLsiCei width, GLsiCei height) * // $o;"ute as"ect ratio of the new window if (height OO +) height O ,// To "re#ent di#ide %' + GLfloat as"ect O (GLfloat)width / (GLfloat)height// Set the #iew"ort to co#er the new window gl=iew"ort(+, +, width, height)-

// Set the as"ect ratio of the cli""ing area to ;atch the #iew"ort glMatri7Mode(GL/F10Q4$T50K)- // To o"erate on the FroPection ;atri7 glLoad5dentit'()// 1eset the "roPection ;atri7 if (width >O height) * cli"9reaSLeft O !,.+ * as"ectcli"9reaS1ight O ,.+ * as"ectcli"9reaL2otto; O !,.+cli"9reaLTo" O ,.+@ else * cli"9reaSLeft O !,.+cli"9reaS1ight O ,.+cli"9reaL2otto; O !,.+ / as"ectcli"9reaLTo" O ,.+ / as"ect@ glu0rtho>6(cli"9reaSLeft, cli"9reaS1ight, cli"9reaL2otto;, cli"9reaLTo")%allSMin O cli"9reaSLeft R %all1adius%allSMa7 O cli"9reaS1ight ! %all1adius%allLMin O cli"9reaL2otto; R %all1adius%allLMa7 O cli"9reaLTo" ! %all1adius@ /* $alled %ac& when the ti;er e7"ired */ #oid Ti;er(int #alue) * glutFost1edis"la'()// Fost a "aint re.uest to acti#ate dis"la'() glutTi;er3unc(refreshMillis, Ti;er, +)- // su%se.uent ti;er call at ;illiseconds @ /* $all%ac& handler for nor;al!&e' e#ent */ #oid &e'%oard(unsigned char &e', int 7, int ') * switch (&e') * case >HA // 4S$ &e' e7it(+)%rea&@ @ /* $all%ac& handler for s"ecial!&e' e#ent */ #oid s"ecialUe's(int &e', int 7, int ') * switch (&e') * case GLUT/U4L/3,A // 3,A Toggle %etween full!screen and windowed ;ode fullScreenMode O WfullScreenMode// Toggle state if (fullScreenMode) * // 3ull!screen ;ode windowFosS O glutGet(GLUT/W5K60W/S)- // Sa#e "ara;eters for restoring later windowFosL O glutGet(GLUT/W5K60W/L)windowWidth O glutGet(GLUT/W5K60W/W56T )window eight O glutGet(GLUT/W5K60W/ 45G T)glut3ullScreen()// Switch into full screen @ else * // Windowed ;ode glut1esha"eWindow(windowWidth, window eight)- // Switch into windowed ;ode glutFositionWindow(windowFosS, windowFosS)// Fosition to"!left corner @ %rea&case GLUT/U4L/15G TA // 1ightA increase 7 s"eed 7S"eed *O ,.+?f- %rea&case GLUT/U4L/L43TA // LeftA decrease 7 s"eed 7S"eed *O +.J?f- %rea&case GLUT/U4L/UFA // U"A increase ' s"eed 'S"eed *O ,.+?f- %rea&case GLUT/U4L/60WKA // 6ownA decrease ' s"eed 'S"eed *O +.J?f- %rea&case GLUT/U4L/F9G4/UFA // Fage!U"A increase %allEs radius %all1adius *O ,.+?f%allSMin O cli"9reaSLeft R %all1adius%allSMa7 O cli"9reaS1ight ! %all1adius%allLMin O cli"9reaL2otto; R %all1adius%allLMa7 O cli"9reaLTo" ! %all1adius%rea&case GLUT/U4L/F9G4/60WKA // Fage!6ownA decrease %allEs radius %all1adius *O +.J?f%allSMin O cli"9reaSLeft R %all1adius%allSMa7 O cli"9reaS1ight ! %all1adius%allLMin O cli"9reaL2otto; R %all1adius-

%allLMa7 O cli"9reaLTo" ! %all1adius%rea&@ @ )* Call.ac/ handler for 5ouse event *) void 5ouse0int .utton2 int state2 int x2 int "3 4 if 0.utton 66 1%G:;%E#:;&G::(> TT state 66 1%G:;!(W>3 4 )) ause)resu5e paused 6 Ppaused9 )) :oggle state if 0paused3 4 xSpeedSaved 6 xSpeed9 )) Save para5eters for restore later "SpeedSaved 6 "Speed9 xSpeed 6 79 )) Stop 5ove5ent "Speed 6 79 A else 4 xSpeed 6 xSpeedSaved9 )) <estore para5eters "Speed 6 "SpeedSaved9 A A A /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glut5nit6is"la'Mode(GLUT/60U2L4)- // 4na%le dou%le %uffered ;ode glut5nitWindowSiCe(windowWidth, window eight)- // 5nitial window width and height glut5nitWindowFosition(windowFosS, windowFosL)- // 5nitial window to"!left corner (7, ') glut$reateWindow(title)// $reate window with gi#en title glut6is"la'3unc(dis"la')// 1egister call%ac& handler for window re!"aint glut1esha"e3unc(resha"e)// 1egister call%ac& handler for window re!sha"e glutTi;er3unc(+, Ti;er, +)// 3irst ti;er call i;;ediatel' glutS"ecial3unc(s"ecialUe's)- // 1egister call%ac& handler for s"ecial!&e' e#ent glutUe'%oard3unc(&e'%oard)// 1egister call%ac& handler for s"ecial!&e' e#ent glut3ullScreen()// Fut into full screen glut$ouse#unc05ouse39 )) <egister call.ac/ handler for 5ouse event initGL()// 0ur own 0"enGL initialiCation glutMainLoo"()// 4nter e#ent!"rocessing loo" return +@

3D Graphics with OpenGL

?9 E$a%p&es
"# E$a%p&e "! 3D Shapes 0OGL'"Shape3D#cpp1
This example displays a () color$cu#e and a pyramid. The cu#e is made of = /uads, each ha,ing different colors. The hallow pyramid is made up of 4 triangle, with different colors on each of the ,ertices.
/* * 0GL+,Sha"e<6.c""A <6 Sha"es */ #include <windows.h> // for MS Windows #include <GL/glut.h> // GLUT, include glu.h and gl.h /* Glo%al #aria%les */ char titleMN O D<6 Sha"esD/* 5nitialiCe 0"enGL Gra"hics */ #oid initGL() * gl$lear$olor(+.+f, +.+f, +.+f, ,.+f)- // Set %ac&ground color to %lac& and o"a.ue gl$lear6e"th(,.+f)// Set %ac&ground de"th to farthest gl4na%le(GL/64FT /T4ST)// 4na%le de"th testing for C!culling gl6e"th3unc(GL/L48U9L)// Set the t'"e of de"th!test glShadeModel(GL/SM00T )// 4na%le s;ooth shading

gl int(GL/F41SF4$T5=4/$0114$T50K/ 5KT, GL/K5$4ST)@ /*

// Kice "ers"ecti#e corrections

andler for window!re"aint e#ent. $alled %ac& when the window first a""ears and whene#er the window needs to %e re!"ainted. */ #oid dis"la'() * gl$lear(GL/$0L01/2U3341/25T T GL/64FT /2U3341/25T)- // $lear color and de"th %uffers glMatri7Mode(GL/M064L=54W)// To o"erate on ;odel!#iew ;atri7 // 1ender a color!cu%e consisting of I .uads with different colors glLoad5dentit'()// 1eset the ;odel!#iew ;atri7 glTranslatef(,.?f, +.+f, !H.+f)- // Mo#e right and into the screen gl2egin(GL/8U96S)// 2egin drawing the color cu%e with I .uads // To" face (' O ,.+f) // 6efine #ertices in counter!cloc&wise ($$W) order with nor;al "ointing out gl$olor<f(+.+f, ,.+f, +.+f)// Green gl=erte7<f( ,.+f, ,.+f, !,.+f)gl=erte7<f(!,.+f, ,.+f, !,.+f)gl=erte7<f(!,.+f, ,.+f, ,.+f)gl=erte7<f( ,.+f, ,.+f, ,.+f)// 2otto; face (' O !,.+f) gl$olor<f(,.+f, +.?f, +.+f)// 0range gl=erte7<f( ,.+f, !,.+f, ,.+f)gl=erte7<f(!,.+f, !,.+f, ,.+f)gl=erte7<f(!,.+f, !,.+f, !,.+f)gl=erte7<f( ,.+f, !,.+f, !,.+f)// 3ront face (C O ,.+f) gl$olor<f(,.+f, +.+f, +.+f)gl=erte7<f( ,.+f, ,.+f, ,.+f)gl=erte7<f(!,.+f, ,.+f, ,.+f)gl=erte7<f(!,.+f, !,.+f, ,.+f)gl=erte7<f( ,.+f, !,.+f, ,.+f)// 1ed

// 2ac& face (C O !,.+f) gl$olor<f(,.+f, ,.+f, +.+f)// Lellow gl=erte7<f( ,.+f, !,.+f, !,.+f)gl=erte7<f(!,.+f, !,.+f, !,.+f)gl=erte7<f(!,.+f, ,.+f, !,.+f)gl=erte7<f( ,.+f, ,.+f, !,.+f)// Left face (7 O !,.+f) gl$olor<f(+.+f, +.+f, ,.+f)// 2lue gl=erte7<f(!,.+f, ,.+f, ,.+f)gl=erte7<f(!,.+f, ,.+f, !,.+f)gl=erte7<f(!,.+f, !,.+f, !,.+f)gl=erte7<f(!,.+f, !,.+f, ,.+f)// 1ight face (7 O ,.+f) gl$olor<f(,.+f, +.+f, ,.+f)// Magenta gl=erte7<f(,.+f, ,.+f, !,.+f)gl=erte7<f(,.+f, ,.+f, ,.+f)gl=erte7<f(,.+f, !,.+f, ,.+f)gl=erte7<f(,.+f, !,.+f, !,.+f)gl4nd()- // 4nd of drawing color!cu%e // 1ender a "'ra;id consists of : triangles glLoad5dentit'()// 1eset the ;odel!#iew ;atri7 glTranslatef(!,.?f, +.+f, !I.+f)- // Mo#e left and into the screen gl2egin(GL/T159KGL4S)// // 3ront gl$olor<f(,.+f, +.+f, +.+f)gl=erte7<f( +.+f, ,.+f, +.+f)gl$olor<f(+.+f, ,.+f, +.+f)gl=erte7<f(!,.+f, !,.+f, ,.+f)gl$olor<f(+.+f, +.+f, ,.+f)gl=erte7<f(,.+f, !,.+f, ,.+f)// 1ight 2egin drawing the "'ra;id with : triangles // 1ed // Green // 2lue

gl$olor<f(,.+f, +.+f, +.+f)gl=erte7<f(+.+f, ,.+f, +.+f)gl$olor<f(+.+f, +.+f, ,.+f)gl=erte7<f(,.+f, !,.+f, ,.+f)gl$olor<f(+.+f, ,.+f, +.+f)gl=erte7<f(,.+f, !,.+f, !,.+f)-

// 1ed // 2lue // Green

// 2ac& gl$olor<f(,.+f, +.+f, +.+f)// 1ed gl=erte7<f(+.+f, ,.+f, +.+f)gl$olor<f(+.+f, ,.+f, +.+f)// Green gl=erte7<f(,.+f, !,.+f, !,.+f)gl$olor<f(+.+f, +.+f, ,.+f)// 2lue gl=erte7<f(!,.+f, !,.+f, !,.+f)// Left gl$olor<f(,.+f,+.+f,+.+f)// 1ed gl=erte7<f( +.+f, ,.+f, +.+f)gl$olor<f(+.+f,+.+f,,.+f)// 2lue gl=erte7<f(!,.+f,!,.+f,!,.+f)gl$olor<f(+.+f,,.+f,+.+f)// Green gl=erte7<f(!,.+f,!,.+f, ,.+f)gl4nd()// 6one drawing the "'ra;id glutSwa"2uffers()@ /* andler for window re!siCe e#ent. $alled %ac& when the window first a""ears and whene#er the window is re!siCed with its new width and height */ #oid resha"e(GLsiCei width, GLsiCei height) * // GLsiCei for non!negati#e integer // $o;"ute as"ect ratio of the new window if (height OO +) height O ,// To "re#ent di#ide %' + GLfloat as"ect O (GLfloat)width / (GLfloat)height// Set the #iew"ort to co#er the new window gl=iew"ort(+, +, width, height)// Set the as"ect ratio of the cli""ing #olu;e to ;atch the #iew"ort glMatri7Mode(GL/F10Q4$T50K)- // To o"erate on the FroPection ;atri7 glLoad5dentit'()// 1eset // 4na%le "ers"ecti#e "roPection with fo#', as"ect, CKear and C3ar gluFers"ecti#e(:?.+f, as"ect, +.,f, ,++.+f)@ /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glut5nit6is"la'Mode(GLUT/60U2L4)- // 4na%le dou%le %uffered ;ode glut5nitWindowSiCe(I:+, :G+)// Set the windowEs initial width B height glut5nitWindowFosition(?+, ?+)- // Fosition the windowEs initial to"!left corner glut$reateWindow(title)// $reate window with the gi#en title glut6is"la'3unc(dis"la')// 1egister call%ac& handler for window re!"aint e#ent glut1esha"e3unc(resha"e)// 1egister call%ac& handler for window re!siCe e#ent initGL()// 0ur own 0"enGL initialiCation glutMainLoo"()// 4nter the infinite e#ent!"rocessing loo" return +@ // Swa" the front and %ac& fra;e %uffers (dou%le %uffering)

GL;T Setup 5 %ain01

The program contains a initGL(), dis"la'() and resha"e() functions. The ;ain() program<. glut'nit Gargc, arg,!2 'nitiali6es the GLUT. *. glut'nitWindow1i6e =4>, 4;>!2 glut'nitWindow&osition H>, H>!2 glutCreateWindow title!2 Creates a window with a title, initial width and height positioned at initial top$left corner. 3. glut)isplay9unc display!2 Registers dis"la'() as the re$paint e,ent handler. That is, the graphics su#$system calls #ac0 dis"la'() when the window first appears and whene,er there is a re$paint re/uest. 4. glutReshape9unc reshape!2 Registers resha"e() as the re$si6ed e,ent handler. That is, the graphics su#$system calls #ac0 resha"e() when the window first appears and whene,er the window is re$si6ed. 5. glut'nit)isplay+ode GLUTI)"U@LF!2 Fna#les dou#le #uffering. 'n dis"la'(), we use glutSwa"2uffers() to signal to the G&U to swap the front$#uffer and #ac0$#uffer during the next B1ync Bertical 1ynchroni6ation!. 6. initGL !2 'n,o0es the initGL() once to perform all one$time initiali6ation tas0s. D. glut+ainLoop !2 9inally, enters the e,ent$processing loop.

One5Ti%e Initia&i6ati n Operati ns 5 initGL01

The initGL() function performs the one$time initiali6ation tas0s. 't is in,o0ed from ;ain() once and only once!. glClearColor >.>f, >.>f, >.>f, <.>f!2 77 1et #ac0ground color to #lac0 and opa/ue glClear)epth <.>f!2 77 1et #ac0ground depth to farthest 77 'n display !

glClear GLIC"L"RI@U99FRI@'T J GLI)F&TEI@U99FRI@'T!2 1et the clearing #ac0ground! color to #lac0 RA>, GA>, @A>! and opa/ue %A<!, and the clearing #ac0ground! depth to the farthest KA<!. 'n dis"la'(), we in,o0e gl$lear() to clear the color and depth #uffer, with the clearing color and depth, #efore rendering the graphics. @esides the color #uffer and depth #uffer, "penGL also maintains an accumulation bu!!er and a stencil bu!!er which shall #e discussed later.! glFna#le GLI)F&TEITF1T!2 77 Fna#le depth testing for 6$culling gl)epth9unc GLILF5U%L!2 77 1et the type of depth$test We need to ena#le depth$test to remo,e the hidden surface, and set the function used for the depth test. gl1hade+odel GLI1+""TE!2 77 Fna#le smooth shading We ena#le smooth shading in color transition. The alternati,e is GL/3L9T. Try it out and see the difference. glEint GLI&FR1&FCT'BFIC"RRFCT'"?IE'?T, GLI?'CF1T!2 77 ?ice perspecti,e corrections 'n graphics rendering, there is often a trade$off #etween processing speed and ,isual /uality. We can use gl int() to decide on the trade$off. 'n this case, we as0 for the #est perspecti,e correction, which may in,ol,e more processing. The default is GL/60KT/$914.
De(inin) the C & r5cu+e an* P9ra%i*

"penGL:s o#.ect is made up of primiti,es such as triangle, /uad, polygon, point and line!. % primiti,e is defined ,ia one or more ,ertices. The color$cu#e is made up of = /uads. Fach /uad is made up of 4 ,ertices, defined in counter$cloc0wise CCW! order, such as the normal ,ector is pointing out, indicating the front face. %ll the 4 ,ertices ha,e the same color. The color$cu#e is defined in its local space called model space! with origin at the center of the cu#e with sides of * units. 1imilarly, the pyramid is made up of 4 triangles without the #ase!. Fach triangle is made up of ( ,ertices, defined in CCW order. The H ,ertices of the pyramid are assigned different colors. The color of the triangles are interpolated and #lend smoothly! from its ( ,ertices. %gain, the pyramid is defined in its local space with origin at the center of the pyramid.

2 *e& Trans( r%

The o#.ects are defined in their local spaces model spaces!. We need to transform them to the common world space, 0nown as model trans!orm.

To perform model transform, we need to operate on the so$called model view matrix "penGL has a few transformation matrices!, #y setting the current matrix mode to model$,iew matrixgl+atrix+ode GLI+")FLB'FW!2 77 To operate on model$,iew matrix We perform translations on cu#e and pyramid, respecti,ely, to position them on the world space77 Color$cu#e glLoad'dentity !2 77 Reset model$,iew matrix glTranslatef <.Hf, >.>f, $D.>f!2 77 +o,e right and into the screen 77 &yramid glLoad'dentity !2 glTranslatef $<.Hf, >.>f, $=.>f!2 77 +o,e left and into the screen
-iew Trans( r%

The default camera position isgluLoo&9t(+.+, +.+, +.+, +.+, +.+, !,++.+, +.+, ,.+, +.+)

That is, 4L4O(+,+,+) at the origin, 9TO(+,+,!,++) pointing at negati,e$6 axis into the screen!, and UFO(+,,,+) corresponds to y$axis. "penGL graphics rendering pipeline performs so$called view trans!orm to #ring the world space to camera:s view space. 'n the case of the default camera position, no transform is needed.
-iewp rt Trans( r%

,oid reshape GLsi6ei width, GLsi6ei height! L glBiewport >, >, width, height!2 The graphics su#$system calls #ac0 resha"e() when the window first appears and whene,er the window is resi6ed, gi,en the new window:s width and height, in pixels. We set our application ,iewport to co,er the entire window, top$left corner at >, >! of width and height, with default ;inX of > and ;a7X of <. We also use the same aspect ratio of the ,iewport for the pro.ection ,iew frustum to pre,ent distortion. 'n the ,iewport, a pixel has x, y! ,alue as well as 6$,alue for depth processing.

Pr Aecti n Trans( r%

GLfloat aspect A GLfloat!width 7 GLfloat!height2 77 Compute aspect ratio of window gl+atrix+ode GLI&R"MFCT'"?!2 77 To operate on the &ro.ection matrix glLoad'dentity !2 77 Reset glu&erspecti,e 4H.>f, aspect, >.<f, <>>.>f!2 77 &erspecti,e pro.ection- fo,y, aspect, near, far % camera has limited field of ,iew. The pro.ection models the ,iew captured #y the camera. There are two types of pro.ection- perspecti,e pro.ection and orthographic pro.ection. 'n perspecti,e pro.ection, o#.ect further to the camera appears smaller compared with o#.ect of the same si6e nearer to the camera. 'n orthographic pro.ection, the o#.ects appear the same regardless of the 6$,alue. "rthographic pro.ection

is a special case of perspecti,e pro.ection where the camera is placed ,ery far away. We shall discuss the orthographic pro.ection in the later example. To set the pro.ection, we need to operate on the pro.ection matrix. Recall that we operated on the model$ ,iew matrix in model transform.! We set the matrix mode to pro.ection matrix and reset the matrix. We use the gluFers"ecti#e() to ena#le perspecti,e pro.ection, and set the fo,y ,iew angle from the #ottom$plane to the top$plane!, aspect ratio width7height!, 6?ear and 69ar of the $iew %rustum truncated pyramid!. 'n this example, we set the fo,y to 4HN. We use the same aspect ratio as the ,iewport to a,oid distortion. We set the 6?ear to >.< and 69ar to <>> 6A$<>>!. Ta0e that note the color$cu#e <.H, >, $D! and the pyramid $<.H, >, $=! are contained within the Biew 9rustum. The pro#ection trans!orm transforms the view !rustum to a *x*x< cu#oid clipping volume centered on the near plane 6A>!. The su#se/uent viewport trans!orm transforms the clipping volume to the viewport in screen space. The ,iewport is set earlier ,ia the gl=iew"ort() function.

2# E$a%p&e 2! 3D Shape with Ani%ati n 0OGL'2Ani%ati n#cpp1


Let:s modify the pre,ious example to carry out animation rotating the cu#e and pyramid!.
/* * 0GL+>9ni;ation.c""A <6 Sha"es with ani;ation */ #include <windows.h> // for MS Windows #include <GL/glut.h> // GLUT, include glu.h and gl.h /* Glo%al #aria%les */ char titleMN O D<6 Sha"es with ani;ationD1%float angle "ra5id 6 7-7f9 )) <otational angle for p"ra5id [>EW] 1%float angleCu.e 6 7-7f9 )) <otational angle for cu.e [>EW] int refresh$ills 6 8E9 )) refresh interval in 5illiseconds [>EW] /* 5nitialiCe 0"enGL Gra"hics */ #oid initGL() * gl$lear$olor(+.+f, +.+f, +.+f, ,.+f)- // Set %ac&ground color to %lac& and o"a.ue gl$lear6e"th(,.+f)// Set %ac&ground de"th to farthest gl4na%le(GL/64FT /T4ST)// 4na%le de"th testing for C!culling gl6e"th3unc(GL/L48U9L)// Set the t'"e of de"th!test glShadeModel(GL/SM00T )// 4na%le s;ooth shading gl int(GL/F41SF4$T5=4/$0114$T50K/ 5KT, GL/K5$4ST)- // Kice "ers"ecti#e corrections @ /* andler for window!re"aint e#ent. $alled %ac& when the window first a""ears and whene#er the window needs to %e re!"ainted. */ #oid dis"la'() * gl$lear(GL/$0L01/2U3341/25T T GL/64FT /2U3341/25T)- // $lear color and de"th %uffers glMatri7Mode(GL/M064L=54W)// To o"erate on ;odel!#iew ;atri7 // 1ender a color!cu%e consisting of I .uads with different colors glLoad5dentit'()// 1eset the ;odel!#iew ;atri7 glTranslatef(,.?f, +.+f, !H.+f)- // Mo#e right and into the screen gl<otatef0angleCu.e2 8-7f2 8-7f2 8-7f39 )) <otate a.out 0828283,axis [>EW] gl2egin(GL/8U96S)// 2egin drawing the color cu%e with I .uads // To" face (' O ,.+f) // 6efine #ertices in counter!cloc&wise ($$W) order with nor;al "ointing out gl$olor<f(+.+f, ,.+f, +.+f)// Green gl=erte7<f( ,.+f, ,.+f, !,.+f)gl=erte7<f(!,.+f, ,.+f, !,.+f)gl=erte7<f(!,.+f, ,.+f, ,.+f)gl=erte7<f( ,.+f, ,.+f, ,.+f)// 2otto; face (' O !,.+f) gl$olor<f(,.+f, +.?f, +.+f)// 0range gl=erte7<f( ,.+f, !,.+f, ,.+f)-

gl=erte7<f(!,.+f, !,.+f, ,.+f)gl=erte7<f(!,.+f, !,.+f, !,.+f)gl=erte7<f( ,.+f, !,.+f, !,.+f)// 3ront face (C O ,.+f) gl$olor<f(,.+f, +.+f, +.+f)gl=erte7<f( ,.+f, ,.+f, ,.+f)gl=erte7<f(!,.+f, ,.+f, ,.+f)gl=erte7<f(!,.+f, !,.+f, ,.+f)gl=erte7<f( ,.+f, !,.+f, ,.+f)// 1ed

// 2ac& face (C O !,.+f) gl$olor<f(,.+f, ,.+f, +.+f)// Lellow gl=erte7<f( ,.+f, !,.+f, !,.+f)gl=erte7<f(!,.+f, !,.+f, !,.+f)gl=erte7<f(!,.+f, ,.+f, !,.+f)gl=erte7<f( ,.+f, ,.+f, !,.+f)// Left face (7 O !,.+f) gl$olor<f(+.+f, +.+f, ,.+f)// 2lue gl=erte7<f(!,.+f, ,.+f, ,.+f)gl=erte7<f(!,.+f, ,.+f, !,.+f)gl=erte7<f(!,.+f, !,.+f, !,.+f)gl=erte7<f(!,.+f, !,.+f, ,.+f)// 1ight face (7 O ,.+f) gl$olor<f(,.+f, +.+f, ,.+f)// Magenta gl=erte7<f(,.+f, ,.+f, !,.+f)gl=erte7<f(,.+f, ,.+f, ,.+f)gl=erte7<f(,.+f, !,.+f, ,.+f)gl=erte7<f(,.+f, !,.+f, !,.+f)gl4nd()- // 4nd of drawing color!cu%e // 1ender a "'ra;id consists of : triangles glLoad5dentit'()// 1eset the ;odel!#iew ;atri7 glTranslatef(!,.?f, +.+f, !I.+f)- // Mo#e left and into the screen gl<otatef0angle "ra5id2 8-7f2 8-7f2 7-7f39 )) <otate a.out the 0828273,axis [>EW] gl2egin(GL/T159KGL4S)// // 3ront gl$olor<f(,.+f, +.+f, +.+f)gl=erte7<f( +.+f, ,.+f, +.+f)gl$olor<f(+.+f, ,.+f, +.+f)gl=erte7<f(!,.+f, !,.+f, ,.+f)gl$olor<f(+.+f, +.+f, ,.+f)gl=erte7<f(,.+f, !,.+f, ,.+f)// 1ight gl$olor<f(,.+f, +.+f, +.+f)gl=erte7<f(+.+f, ,.+f, +.+f)gl$olor<f(+.+f, +.+f, ,.+f)gl=erte7<f(,.+f, !,.+f, ,.+f)gl$olor<f(+.+f, ,.+f, +.+f)gl=erte7<f(,.+f, !,.+f, !,.+f)2egin drawing the "'ra;id with : triangles // 1ed // Green // 2lue

// 1ed // 2lue // Green

// 2ac& gl$olor<f(,.+f, +.+f, +.+f)// 1ed gl=erte7<f(+.+f, ,.+f, +.+f)gl$olor<f(+.+f, ,.+f, +.+f)// Green gl=erte7<f(,.+f, !,.+f, !,.+f)gl$olor<f(+.+f, +.+f, ,.+f)// 2lue gl=erte7<f(!,.+f, !,.+f, !,.+f)// Left gl$olor<f(,.+f,+.+f,+.+f)// 1ed gl=erte7<f( +.+f, ,.+f, +.+f)gl$olor<f(+.+f,+.+f,,.+f)// 2lue gl=erte7<f(!,.+f,!,.+f,!,.+f)gl$olor<f(+.+f,,.+f,+.+f)// Green gl=erte7<f(!,.+f,!,.+f, ,.+f)gl4nd()// 6one drawing the "'ra;id

glutSwa"2uffers()-

// Swa" the front and %ac& fra;e %uffers (dou%le %uffering)

)) Gpdate the rotational angle after each refresh [>EW] angle "ra5id L6 7-2f9 angleCu.e ,6 7-8Ef9 @ )* Called .ac/ when ti5er expired [>EW] *) void ti5er0int value3 4 glut ost<edispla"039 )) ost re,paint reIuest to activate displa"03 glut:i5er#unc0refresh$ills2 ti5er2 739 )) next ti5er call 5illiseconds later A /* andler for window re!siCe e#ent. $alled %ac& when the window first a""ears and whene#er the window is re!siCed with its new width and height */ #oid resha"e(GLsiCei width, GLsiCei height) * // GLsiCei for non!negati#e integer // $o;"ute as"ect ratio of the new window if (height OO +) height O ,// To "re#ent di#ide %' + GLfloat as"ect O (GLfloat)width / (GLfloat)height// Set the #iew"ort to co#er the new window gl=iew"ort(+, +, width, height)// Set the as"ect ratio of the cli""ing #olu;e to ;atch the #iew"ort glMatri7Mode(GL/F10Q4$T50K)- // To o"erate on the FroPection ;atri7 glLoad5dentit'()// 1eset // 4na%le "ers"ecti#e "roPection with fo#', as"ect, CKear and C3ar gluFers"ecti#e(:?.+f, as"ect, +.,f, ,++.+f)@ /* Main functionA GLUT runs as a console a""lication starting at ;ain() */ int ;ain(int argc, char** arg#) * glut5nit(Bargc, arg#)// 5nitialiCe GLUT glut5nit6is"la'Mode(GLUT/60U2L4)- // 4na%le dou%le %uffered ;ode glut5nitWindowSiCe(I:+, :G+)// Set the windowEs initial width B height glut5nitWindowFosition(?+, ?+)- // Fosition the windowEs initial to"!left corner glut$reateWindow(title)// $reate window with the gi#en title glut6is"la'3unc(dis"la')- // 1egister call%ac& handler for window re!"aint e#ent glut1esha"e3unc(resha"e)- // 1egister call%ac& handler for window re!siCe e#ent initGL()// 0ur own 0"enGL initialiCation glut:i5er#unc072 ti5er2 739 )) #irst ti5er call i55ediatel" [>EW] glutMainLoo"()// 4nter the infinite e#ent!"rocessing loo" return +@

The new codes areGLfloat angle&yramid A >.>f2 77 Rotational angle for pyramid O?FWP GLfloat angleCu#e A >.>f2 77 Rotational angle for cu#e O?FWP int refresh+ills A <H2 77 refresh inter,al in milliseconds O?FWP We define two glo#al ,aria#les to 0eep trac0 of the current rotational angles of the cu#e and pyramid. We also define the refresh period as <H msec == frames per second!. ,oid timer int ,alue! L glut&ostRedisplay !2 77 &ost re$paint re/uest to acti,ate display ! glutTimer9unc refresh+ills, timer, >!2 77 next timer call milliseconds later Q To perform animation, we define a function called ti;er(), which posts a re$paint re/uest to acti,ate dis"la'() when the timer expired, and then run the timer again. 'n ;ain(), we perform the first ti;er() call ,ia glutTi;er3unc(+, ti;er, +). glRotatef angleCu#e, <.>f, <.>f, <.>f!2 77 Rotate the cu#e a#out <,<,<!$axis O?FWP ...... glRotatef angle&yramid, <.>f, <.>f, >.>f!2 77 Rotate a#out the <,<,>!$axis O?FWP ...... angle&yramid 8A >.*f2 77 update pyramid:s angle

angleCu#e $A >.<Hf2 77 update cu#e:s angle 'n dis"la'(), we rotate the cu#e and pyramid #ased on their rotational angles, and update the angles after each refresh.

3# E$a%p&e 3! Orth )raphic Pr Aecti n 0OGL'3Orth )raphic#cpp1


%s mentioned, "penGL support two type of pro.ections- perspecti,e and orthographic. 'n orthographic pro.ection, an o#.ect appears to #e the same si6e regardless of the depth. "rthographic is a special case of perspecti,e pro.ection, where the camera is placed ,ery far away. To use orthographic pro.ection, change the resha"e() function to in,o0e gl0rtho().
#oid resha"e(GLsiCei width, GLsiCei height) * // GLsiCei for non!negati#e integer // $o;"ute as"ect ratio of the new window if (height OO +) height O ,// To "re#ent di#ide %' + GLfloat as"ect O (GLfloat)width / (GLfloat)height// Set the #iew"ort to co#er the new window gl=iew"ort(+, +, width, height)// Set the as"ect ratio of the cli""ing #olu;e to ;atch the #iew"ort glMatri7Mode(GL/F10Q4$T50K)- // To o"erate on the FroPection ;atri7 glLoad5dentit'()// 1eset )) Set up orthographic pro?ection view [>EW] if 0width @6 height3 4 )) aspect @6 82 set the height fro5 ,8 to 82 with larger width gl(rtho0,3-7 * aspect2 3-7 * aspect2 ,3-72 3-72 7-82 87739 A else 4 )) aspect B 82 set the width to ,8 to 82 with larger height gl(rtho0,3-72 3-72 ,3-7 ) aspect2 3-7 ) aspect2 7-82 87739 A @

'n this example, we set the cross$section of ,iew$,olume according to the aspect ratio of the ,iewport, and depth from >.< to <>>, corresponding to 6A$>.< to 6A$<>>. Ta0e note that the cu#e and pyramid are contained within the ,iew$,olume.

Você também pode gostar