This document discusses callback functions in OpenGL and GLUT. It provides examples of registering callback functions to handle events like displaying, resizing windows, and mouse/keyboard input. Callback functions allow graphics programs to be event-driven by linking functions to events. The examples demonstrate changing color with keys, moving triangles with mouse clicks, and shaking triangles with mouse motion using callback functions and global variables. Reading suggestions are provided to further understand OpenGL state machines, double buffering, and GLUT functions.
1. SER332
Introduction to Graphics and
Game Development
Lecture 04:
Callback functions
Javier Gonzalez-Sanchez
javiergs@asu.edu
PERALTA 230U
Office Hours: By appointment
7. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 7
Double Buffering
§ Double buffering is necessary for almost all OpenGL
applications:
§ Render into back buffer
§ Swap buffers when finished rendering a frame: The old
back buffer becomes the front buffer that is displayed. The
old front buffer becomes the back buffer that is rendered
into.
§ What happens when you do not use double buffering?
§ flickering artifacts, tearing artifacts
§ Commands:
§ glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
§ glutSwapBuffers(); //instead of glFlush()
9. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 9
Callback Functions
• Callback functions refresh
o void (*func)(void) – what is this thing?
• Virtually all interactive graphics programs are event driven
• Glut uses callbacks to handle events
o Windows system invokes a particular procedure when an event of
particular type occurs.
o MOST IMPORTANT: display event. It is signaled when window first
displays and whenever portions of the window reveals from
blocking window
o glutDisplayFunc(void (*func)(void)) registers the display callback
function
10. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 10
Callbacks Functions
• glutDisaplyFunc(void (*func)(void))
whenever GLUT decides to redisplay the window, the registerd
callback is executed.
• glutReshapeFunc(void (*func)(int w, int h))
indicates what action should be taken when the window is resized.
• glutKeyboardFunc(void (*func)(unsigned char key, int x,
int y)) glutMouseFunc(void (*func)(int button, int state,
int x, int y))
glutSpecialFunc(void (*func)(unsigned char key, int x,
int y))
allow you to link a keyboard key or a mouse button with a routine
that's invoked when the key or mouse button is pressed or released.
• glutMotionFunc(void (*func)(int x, int y))
registers a routine to call back when the mouse is moved while a
mouse button is also pressed.
• glutIdleFunc(void (*func)(void))
registers a function that's to be executed if no other events are
pending – use for animation or continuous update
12. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 12
// lets play with global variables
float triangle_color_R = 1.0f;
float triangle_color_G = 0.843f;
float triangle_color_B = 0.0f;
float corner_x = -0.7f;
float corner_y = 0.7f;
int mouse_button;
int mouse_button_state;
int shake =10;
// myInit
void myInit() {
glClearColor(0.764f, 0.129f, 0.282f, 1.0); // maroon
// projection transformations
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0); // units inside
}
13. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 13
// display callback code
void myDisplay() {
glClear(GL_COLOR_BUFFER_BIT); // clear the window
glColor3f(triangle_color_R, triangle_color_G, triangle_color_B); //gold
glBegin(GL_POLYGON); // fill connected polygon
glVertex2f(corner_x, corner_y);
glVertex2f(corner_x+1.30, corner_y);
glVertex2f(corner_x, corner_y-1.30);
glEnd();
glBegin(GL_POLYGON); // fill connected polygon
glVertex2f(corner_x+1.40, corner_y-0.1);
glVertex2f(corner_x+0.1, corner_y-1.40);
glVertex2f(corner_x+1.40, corner_y-1.40);
glEnd();
glutSwapBuffers(); //forces issued commands to execute
}
14. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 14
// keyboard callback code
void myKeyboard(unsigned char key, int x, int y) {
switch (key) {
case 'q': case 'Q':
exit(0); // exit the program
break;
case 'i': case 'I':
int mod = glutGetModifiers();
if (mod == GLUT_ACTIVE_ALT) { // if ALT key
triangle_color_R = 1.0f;
triangle_color_G = 1.0f;
triangle_color_B = 1.0f;
} else {
triangle_color_R = 1.0f;
triangle_color_G = 0.843f;
triangle_color_B = 0.0f;
}
glutPostRedisplay(); // update the display
break;
}
}
15. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 15
Key Modifiers
int glutGetModifiers(void)
to detect if any modifier key is pressed
§ GLUT_ACTIVE_SHIFT SHIFT key
§ GLUT_ACTIVE_CTRL CTRL key
§ GLUT_ACTIVE_ALT ALT key
16. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 16
//special key callback code
void mySpecialKeys(int key, int x, int y) {
switch (key) {
case GLUT_KEY_UP:
triangle_color_R = triangle_color_R + 0.1;
break;
case GLUT_KEY_DOWN:
triangle_color_R = triangle_color_G - 0.1;
break;
case GLUT_KEY_LEFT:
triangle_color_B = triangle_color_B + 0.1;
break;
case GLUT_KEY_RIGHT:
triangle_color_B = triangle_color_B - 0.1;
break;
}
glutPostRedisplay();
}
17. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 17
Special Keys
§ GLUT_KEY_F1 F1 function key
§ …
§ GLUT_KEY_F12 F12 function key
§ GLUT_KEY_LEFT Left function key
§ GLUT_KEY_RIGHT Up function key
§ GLUT_KEY_UP Right function key
§ GLUT_KEY_DOWN Down function key
§ GLUT_KEY_PAGE_UP Page Up function key
§ GLUT_KEY_PAGE_DOWN Page Down function key
§ GLUT_KEY_HOME Home function key
§ GLUT_KEY_END End function key
§ GLUT_KEY_INSERT Insert function key
18. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 18
// mouse callback function
void myMouseClick(int button, int state, int x, int y) {
// button: GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON
// state: GLUT_DOWN, GLUT_UP
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
corner_x = (x/250.0) -1; // from 0 : 500 to -1 : 1
corner_y =- ((y/250.0)-1);
}
mouse_button = button;
mouse_button_state = state;
glutPostRedisplay();
}
20. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 20
Mouse Passive Motion Callback
glutPassiveMotionFunc( myMousePMotion );
§ Almost as same function as the glutMotionFunc();
§ The (active) motion callback is called when the mouse moves
within the window while one or more mouse buttons are
pressed.
§ The passive motion callback is called when the mouse moves
within the window while no mouse buttons are pressed.
21. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 21
Example 2
• Change color with the arrow keys
• Move the triangles with the mouse (left click)
• Move and shake with the mouse (right click)
22. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 22
Reading
OpenGL command syntax
§ Red Book(pdf): ch1 p17 – p18
Understand OpenGL’s state machine model
§ Red Book(pdf):ch1 p18
Understand OpenGL’s client server model
§ An example, glFlush, Red Book(pdf): ch2 p32
§ Think about the differences between glFlush, glFinish, glutSwapBuffers. To better understand glFinish,
think if you want to measure the exact rendering time of one frame on GPU.
Animation & Double buffering
§ Red Book(pdf): ch1 p24, explains double buffering and glutSwapBuffers
GLUT (important!!!)
§ Red Book(pdf): ch1 p21 - p28
§ Hearn Baker ch6 p307 – p34, similar as above but in more details
§ Red Book Appendix D
§ Example 1-2, Example 1-3 (Animation)
§ Glut.h will show you the technical details
23. Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 23
Homework
Programming, Programming, and Programming
24. SER332 Introduction to Graphics
Javier Gonzalez-Sanchez
javiergs@asu.edu
Spring 2018
Disclaimer. These slides can only be used as study material for the class SER332 at ASU. They cannot be distributed or used for another purpose.