Title: CSC461%20Lecture%209:%20GLUT%20Callbacks
1CSC461 Lecture 9GLUT Callbacks
- Objectives
- Introduce double buffering for smooth animations
- Programming event input with GLUT
2GLUT callbacks
- GLUT recognizes a subset of the events recognized
by any particular window system (Windows, X,
Macintosh) - glutDisplayFunc
- glutMouseFunc
- glutReshapeFunc
- glutKeyFunc
- glutIdleFunc
- glutMotionFunc, glutPassiveMotionFunc
3Double Buffering
- Instead of one color buffer, we use two
- Front Buffer displayed but not written to
- Back Buffer written to but not altered
- Program then requests a double buffer in main.c
- glutInitDisplayMode(GL_RGB GL_DOUBLE)
- At the end of the display callback buffers are
swapped
void mydisplay() glClear() . / draw
graphics here / . glutSwapBuffers()
4Using the idle callback
- The idle callback is executed whenever there are
no events in the event queue - glutIdleFunc(myidle)
- Useful for animations
void myidle() / change something / t
dt glutPostRedisplay() Void mydisplay()
glClear() / draw something that depends on
t / glutSwapBuffers()
5Rotating Square
void display() glClear(GL_COLOR_BUFFER_BIT)
glBegin(GL_POLYGON) thetartheta/((23.14
159)/360.0) glVertex2f(cos(thetar),
sin(thetar)) glVertex2f(-sin(thetar),
cos(thetar)) glVertex2f(-cos(thetar),-sin(thetar
)) glVertex2f(sin(thetar), -cos(thetar))
glEnd()
void idle() theta2 if
(thetagt360.0) theta-360.0
glutPostRedisplay()
Specify the display and idle callbacks in main.c
6Using globals
- The form of all GLUT callbacks is fixed
- void mydisplay()
- void mymouse(GLint button, GLint state, GLint x,
GLint y) - Must use globals to pass information to callbacks
float t /global / void mydisplay() / draw
something that depends on t
7The mouse callback
- glutMouseFunc(mymouse)
- void mymouse(GLint button, GLint state, GLint x,
GLint y) - Returns
- which button (GLUT_LEFT_BUTTON,
GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON) caused
event - state of that button (GL_UP, GLUT_DOWN)
- Position in window
8Positioning
- The position in the screen window is usually
measured in pixels with the origin at the
top-left corner - Consequence of refresh done from top to bottom
- OpenGL uses a world coordinate system with origin
at the bottom left - Must invert y coordinate returned by callback by
height of window - y h y
9Obtaining the window size
- To invert the y position we need the window
height - Height can change during program execution
- Track with a global variable
- New height returned to reshape callback that we
will look at in detail soon - Can also use enquiry functions
- glGetIntv(State_comp, ptr)
- glGetFloatv(State_com, ptr)
- to obtain any value that is part of the state
- State_comp could be GL_MODELVIEW_MATRIX,
GL_PROJECTION_MATRIX, GL_VIEWPORT, etc.
10Window Management
- Multiple windows and subwindows
- Creating a window returns a window id
- GLInt id
- glutCreateWindow(A New Window)
- Change the current window
- glutSetWindow(GLInt id)
- Operations performed on the current window
11Terminating a program
- In our original programs, there was no way to
terminate them through OpenGL - We can use the simple mouse callback
void mouse(int btn, int state, int x, int y)
if(btnGLUT_RIGHT_BUTTON stateGLUT_DOWN)
exit(0)
12Using the mouse position
- In the next example, we draw a small square at
the location of the mouse each time the left
mouse button is clicked - This example does not use the display callback
but one is required by GLUT We can use the empty
display callback function - mydisplay()
13Drawing squares at cursor location
- void myMouse(int btn, int state, int x, int y)
-
- if(btnGLUT_RIGHT_BUTTON stateGLUT_DOWN)
- exit(0)
- if(btnGLUT_LEFT_BUTTON stateGLUT_DOWN)
- drawSquare(x, y)
-
- void drawSquare(int x, int y)
-
- yw-y / invert y position /
- glColor3ub( (char) rand()256, (char) rand
)256, (char) rand()256) / a random color / - glBegin(GL_POLYGON)
- glVertex2f(xsize, ysize)
- glVertex2f(x-size, ysize)
- glVertex2f(x-size, y-size)
- glVertex2f(xsize, y-size)
- glEnd()
-
14Using the motion callback
- We can draw squares (or anything else)
continuously as long as a mouse button is
depressed by using the motion callback - glutMotionFunc(drawSquare)
- We can draw squares without depressing a button
using the passive motion callback - glutPassiveMotionFunc(drawSquare)
15Using the keyboard
- Register function
- glutKeyboardFunc(mykey)
- Callback
- void mykey(unsigned char key,int x, int y)
- Passed in ASCII code of the key depressed and
mouse location - Note GLUT does not recognize key release as an
event
void mykey() if(key Q key q)
exit(0)
16Special and Modifier Keys
- GLUT defines the special keys in glut.h
- Function key 1 GLUT_KEY_F1
- Up arrow key GLUT_KEY_UP
- if(key GLUT_KEY_F1
- Can also check of one of the modifiers
- GLUT_ACTIVE_SHIFT
- GLUT_ACTIVE_CTRL
- GLUT_ACTIVE_ALT
- is depressed by
- glutGetModifiers()
- Allows emulation of three-button mouse with one-
or two-button mice
17Reshaping the window
- We can reshape and resize the OpenGL display
window by pulling the corner of the window - What happens to the display?
- Must redraw from application
- Two possibilities
- Display part of world
- Display whole world but force to fit in new
window - Can alter aspect ratio
18Reshape possiblities
original
reshaped
19The Reshape callback
- Register function
- glutReshapeFunc(myreshape)
- Callback
- void myreshape(int w, int h)
- Passed in width and height of new window (in
pixels) - A redisplay is posted automatically at end of
execution of the callback - GLUT has a default reshape callback but you
probably want to define your own - The reshape callback is good place to put camera
functions because it is invoked when the window
is first opened
20Example Reshape
- This reshape preserves shapes by making the
viewport and world window have the same aspect
ratio
void myReshape(int w, int h) glViewport(0,
0, w, h) glMatrixMode(GL_PROJECTION) /
switch matrix mode / glLoadIdentity()
if (w lt h) gluOrtho2D(-2.0, 2.0,
-2.0(GLfloat)h/(GLfloat)w,
2.0(GLfloat)h/(GLfloat)w) else
gluOrtho2D(-2.0(GLfloat)w/(GLfloat)h,
2.0(GLfloat)w/(GLfloat)h, -2.0, 2.0)
glMatrixMode(GL_MODELVIEW) / return to
modelview mode /