1/22/13
1
Computer Graphics
OpenGL Viewing Pipeline
and Event Handling
Review – OpenGL Software
GLUT
GLU
OpenGL X, Win32, Mac O/S
software and/or hardware
application program
1/22/13
2
All models built from: Points, Lines, Polygons
Reading:
Chapter 2 of the Redbook http://www.glprogramming.com/red/chapter02.html
Review – glVertex*
glVertex3fv( v )
Number of components
2 - (x,y) 3 - (x,y,z) 4 - (x,y,z,w)
Data Type b - byte ub - unsigned byte s - short us - unsigned short i - int ui - unsigned int f - float d - double
Vector
omit “v” for scalar form
glVertex2f( x, y )
1/22/13
3
Review – Simple Examples glBegin( GL_POINTS ); glVertex2i(100, 100); glVertex2i(400, 100); glVertex2i(250, 400); glEnd();
x
y
500
500
x
y
500
500 GLfloat vc[3][2] = {{100,100}, {400,100}, {250,400}}; glBegin( GL_LINE_LOOP ); glVertex2iv(vc[0]); glVertex2iv(vc[1]); glVertex2iv(vc[2]); glEnd();
Drawing Stuff glBegin ( drawing mode ); glVertex... ... glEnd();
GL_QUAD_STRIP
GL_POLYGON
GL_TRIANGLE_STRIP GL_TRIANGLE_FAN
GL_POINTS
GL_LINES
GL_LINE_LOOP GL_LINE_STRIP
GL_TRIANGLES GL_QUADS
v0 v1
v2 v3
v0
v1 v2
v3
v0 v1
v2 v3
v5 v4
v6 v7
v5 v4
v6 v7
v5
v4
Drawing Modes
1/22/13
4
Color Interpolation glBegin (GL_LINES) glColor3f (1.0,0.0,0.0); // red glVertex2f(1.0,0.0); glColor3f (1.0,1.0,0.0); // yellow glVertex2f(0.0,1.0); glEnd();
• We get a line that starts out red and turns yellow (assuming we left the default as glShadeModel(GL_SMOOTH) instead of GL_FLAT)
Line Properties • Changing the width
– glLineWidth (float) – default is 1.0
• Creating dashed and dotted lines – glEnable (GL_LINE_STIPPLE) – glDisable (…) – glLineStipple (int repeatfactor, short pattern)
• (1, 0xAAAA) yields - - - - - - - - • (2, 0xAAAA) yields -- -- -- --
1/22/13
5
Polygon Properties • Fill Pattern
– glEnable (GL_POLYGON_STIPPLE); – glPolygonStipple ( mask );
• GLubyte mask[] = {0x00, 0x03, … • mask is 32x32 bitmap
• Polygon Outline – glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); – default is GL_FILL – note that you can make the front filled while the
back is outlined!!!
OpenGL’s State Machine • Once an attribute is set, it stays that value
until you later change it.
• Examples setting state:
glColor3f( 1.0, 0.0, 0.0 ); glClearColor( 1.0, 1.0, 1.0, 1.0 ); glPointSize( 4.0 ); glLineWidth( 2.0 );
1/22/13
6
Try it Out • Create an image of your choice. Use a stipple
pattern for filling in part of your image. • Start with skeleton_code2D.cpp posted on the
class page. • Example: A mouse
OpenGL Viewing Pipeline
1/22/13
7
OpenGL Viewing Pipeline • World window • Screen (GLUT) Window • Viewport
Creating a Screen (GLUT) Window • Also referred to as Display window • glutInitWindowPosition (xTopLeft, yTopLeft);
– Position in pixels from the top-left corner of the screen • glutInitWindowSize (width, height); • glutCreateWindow (“Title of Display Window”); • glClearColor (red, green, blue, alpha)
– Specify the background color
1/22/13
8
Screen Window
OpenGL (0, 0)
xTopLeft
yTopLeft
width
height
glutInitWindowPosition (xTopLeft, yTopLeft); glutInitWindowSize (width, height); /* All measurements here are in pixels */
Multiple Screen Windows • Multiple windows may be created within an
OpenGL program – Need window ids to manage multiple windows – windowID = glutCreateWindow(“Window1”); – glutDestroyWindow (windowID)
• General functions (like glutInitDisplayMode) are applied to the current display window. We can set the current window to a specific window with: – glutSetWindow (windowID);
1/22/13
9
Display Callback Function • Each separate GLUT window can have its own
function to specify what will be drawn inside. E.g., – glutSetWindow (w1); – glutDisplayFunction (wireframeDisplay); – glutSetWindow (w2); – glutDisplayFunction (solidDisplay);
• Display callback functions are called only when GLUT determines that the display content should be renewed.
• To update the display manually call glutPostRedisplay();
World Coordinate System • Screen coordinate system is not easy to use
20 feet
10 feet
• Use application-specific coordinates instead • Called world coordinates
1/22/13
10
Define a World Window
• Rectangular window in world coordinates, specifying which part of the world to draw
World Window • Also known as clipping window
Define by
left, right, bot, top (world coordinates)
left right
bot
top
Use OpenGL command:
gluOrtho2D(left, right, bot, top);
1/22/13
11
gluOrtho2D • Usage:
glMatrixMode (GL_PROJECTION) glLoadIdentity (); /* reset, so that new viewing parameters are not combined with old ones */ gluOrtho2D (xleft, xright, ybot, ytop);
To Draw on the Screen • Define a screen window (call glutInitWindowSize / glutCreateWindow) • Define a world window (call gluOrtho2D function) • Define a viewport (call the glViewport function) • Perform world to viewport mapping (OpenGL internals will do this for you)
1/22/13
12
World vs. Viewport • The world window selects what we want to
see in our virtual 2D world. • The viewport indicates where it is to be
viewed within the screen window • By default the viewport has the same location
and dimensions of the GLUT display window – But it can be modified so that only a part of the
display window is used for OpenGL display
Setting up a Viewport • glViewport (x, y, width, height);
• All parameters are given in integer screen coordinates (pixels) relative to the lower-left corner of the screen window.
• If we do not invoke this function, by default, a viewport with the same size and position of the display window is used (i.e., all of the GLUT window is used for OpenGL display)
(0,0) Screen window
Viewport
1/22/13
13
A Simple Example DrawQuad() { glViewport(0,0,300,200); glMatrixMode(GL_PROJECTION); glLoadIndentity(); glOrtho2D(-1,1,-1,1); glBegin(GL_QUADS); glColor3f(1,1,0); glVertex2i(-0.5,-0.5); glVertex2i(+0.5,-0.5); glVertex2i(+0.5,+0.5); glVertex2i(-0.5,+0.5); glEnd(); }
(0,0)
(300,200)
viewport
How big is the quad?
World to Viewport Mapping • The objects in the world window will be drawn
onto the viewport
Wleft Wright
Wbot
Wtop
(x’, y’)
Viewport
(x, y)
Vleft Vright
Vbot
Vtop
World Window
1/22/13
14
World to Viewport Mapping • How to calculate (x’, y’) from (x, y)?
Wleft Wright
Wbot
Wtop
(x’, y’)
Viewport
(x, y)
Vleft Vright
Vbot
Vtop
World Window
World to Viewport Mapping • Basic principle: the mapping should be
proportional
(x,y) (x’, y’)
(x – Wleft) / (Wright – Wleft) = (x’ – Vleft) / (Vright– Vleft) (y - Wbot) / (Wtop – Wbot) = (y’ – Vbot) / (Vtop – Vbot)
(Wleft Wbot)
(Wright Wtop)
(Vleft Vbot)
(Vright Vtop)
1/22/13
15
Distortion Happens When … • World window and display window have
different aspect ratios • Aspect ratio = Width / Height
Compare Aspect Ratios
World window Aspect Ratio = R
Display window Aspect Ratio = W / H
W
H
R > W / H
1/22/13
16
Match Aspect Ratios
World window Aspect Ratio = R
Display window Aspect Ratio = W / H
W
H
R > W / H
R ?
Match Aspect Ratios
World window Aspect Ratio = R
Display window Aspect Ratio = W / H
W
H
R > W / H
R W/R
1/22/13
17
Compare Aspect Ratios
World window Aspect Ratio = R
Display window Aspect Ratio = W / H
W
H
R < W / H
Match the Aspect Ratios
World window Aspect Ratio = R
Display window Aspect Ratio = W / H
W
H
R < W / H
?
1/22/13
18
Match the Aspect Ratios
World window Aspect Ratio = R
Display window Aspect Ratio = W / H
W
H
R < W / H
H*R
glViewport(0, 0, H*R, H)
When to Call glViewport? • Initialization • When the user resizes the display window void resize(int W, int H) {
glViewport(0,0,W, H); }
• You can provide your own to make sure the aspect ratio is fixed.
1/22/13
19
Hands-on Session • The viewport.cpp Program • Compile, Run & Play • Fix the Reshape routine to preserve the
aspect ratio of the image (text)
OpenGL 2D Viewing Example • 2 Viewports • One triangle is displayed in
two colors and orientations in 2 viewports
glClear (GL_COLOR_BUFFER_BIT); glColor3f(0.0, 0.0, 1.0); glViewport(0, 0, 300, 300); drawCenteredTriangle(); glColor3f(1.0, 0.0, 0.0); glViewport(300, 0, 300, 300); glRotatef(90.0, 0.0, 0.0, 1.0); drawCenteredTriangle();
glutInitWindowSize (600, 300);
1/22/13
20
Event Handling in OpenGL
Types of Events • Mouse click event
• Mouse motion event
• Key press event
• Window reshape event
1/22/13
21
Event Based Programming
Opera4ng System
void Mouse( int b, int x, int y) { // code here to execute // when mouse is pressed } void Keyboard( char k, int x, int y ) { // code here to execute // when key is pressed } void main( int argc, char ** argv ) { // code here telling OS which function // above to associate with each event }
Callback func4on: executed when an event occurs Register a callback func4on: tell OS what func4on to associate with an event
Mouse Click Events void Mouse( int button, int state, int x, int y) { …. }
Title Here x
y
(0,0) (500,0)
(0,500) x
y
(0,0) (500,0)
(0,500)
Screen (GLUT) window x, y is in pixels in
screen coordinates
World window x, y is in
world coordinates
1/22/13
22
Screen vs. World Window • glutInitWindowSize(500, 500);
– Set the screen (display) window to 500 by 500 pixels
• glOrtho2D(0, 500, 0, 500); – Specifies the world (clipping) window in world coordinates – Arguments are in order: leftx, rightx, bottomy, topy – OpenGL maps world-to-screen coordinates
Converting Screen to World Coordinates Title Here X x
y
(0,0) (500,0)
(0,500) x
y
(0,0) (500,0)
(0,500)
Title Here X x
y
(0,0) (500,0)
(0,500)
x
y
(250,0) (-‐250,0)
(0,250)
Mouse click at x=400, y=100 corresponds to world coordinates:
Mouse click at x=400, y=100 corresponds to world coordinates: (0,-‐250)
1/22/13
23
Hands-on Session • The events.cpp Program
• Compile, Run & Play
• Understand all event-related code – Registering callbacks
– Keyboard, Mouse, MouseMotion
Hands-on Session 1. Make your earlier image change when the left
mouse button is clicked. Example:
2. Add a keyboard event that causes the image to zoom in when ‘+’ is pressed and to zoom out when ‘-’ is pressed. Zooming in and out should be with respect to the center of the image. You will need to resize your viewing window for this.
1/22/13
24
Summary • Screen vs. world coordinate system
• Viewports
• Event-based programming
• Callback function
• Registering a callback function