Slide 1

Slide 1 text

jgs SER332 Introduction to Graphics and Game Development Lecture 04: Callback Functions Javier Gonzalez-Sanchez [email protected] PERALTA 230U Office Hours: By appointment

Slide 2

Slide 2 text

jgs GLUT OpenGL Utility Toolkit

Slide 3

Slide 3 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 3 jgs Example 1 /** https://github.com/javiergs/SER332/blob/master/Lecture03/main.c */ // main void main(int argc, char** argv){ glutInit(&argc, argv); // glut init glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(500,500); // actual window size glutInitWindowPosition(0,0); // window location glutCreateWindow("simple"); myInit(); glutDisplayFunc(myDisplay); glutMainLoop(); //event loop }

Slide 4

Slide 4 text

jgs Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 4 // myInit void myInit() { glClearColor(0.764f, 0.129f, 0.282f, 1.0); // maroon glColor3f(1.0f, 0.843f, 0.0f); // gold // projection transformations glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-1.0, 1.0, -1.0, 1.0); // units inside }

Slide 5

Slide 5 text

jgs Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 5 // myDisplay void myDisplay() { glClear(GL_COLOR_BUFFER_BIT); // clear the window glBegin(GL_POLYGON); // fill connected polygon glVertex2f(-0.7, 0.7); // vertices of the square glVertex2f( 0.6, 0.7); glVertex2f(-0.7, -0.6); glEnd(); glBegin(GL_POLYGON); // fill connected polygon glVertex2f( 0.7, 0.6); // vertices of the square glVertex2f(-0.6, -0.7); glVertex2f( 0.7, -0.7); glEnd(); glFlush(); //forces issued commands to execute }

Slide 6

Slide 6 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 6 jgs Example 1 500 500 (0.7,0.7) (-0.7,-0.7)

Slide 7

Slide 7 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 7 jgs 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()

Slide 8

Slide 8 text

jgs Callback Functions

Slide 9

Slide 9 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 9 jgs Callback Functions § What is this? void (*func)(void) § GLUT uses callbacks to handle events Windows system invokes a particular procedure when an event of particular type occurs. MOST IMPORTANT: display event. It is signaled when window first displays and whenever portions of the window reveals from blocking window glutDisplayFunc(void (*func)(void)) registers the display callback function

Slide 10

Slide 10 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 10 jgs Callbacks Functions § glutDisaplyFunc(void (*func)(void)) whenever GLUT decides to redisplay the window, the registered 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.

Slide 11

Slide 11 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 11 jgs Callbacks Functions § 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

Slide 12

Slide 12 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 12 jgs Example 2 /** * https://github.com/javiergs/SER332/blob/master/Lecture04/main.c */ #include "glut.h" // main void main(int argc, char** argv) { glutInit(&argc, argv); // glut init glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(500, 500); glutInitWindowPosition(0, 0); glutCreateWindow("simple"); myInit(); glutDisplayFunc(myDisplay); glutKeyboardFunc(myKeyboard); glutSpecialFunc(mySpecialKeys); glutMouseFunc(myMouseClick); glutMotionFunc(myMouseMotion); glutMainLoop(); }

Slide 13

Slide 13 text

jgs Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 13 // 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 }

Slide 14

Slide 14 text

jgs Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 14 // 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 }

Slide 15

Slide 15 text

jgs Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 15 // 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; } }

Slide 16

Slide 16 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 16 jgs 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

Slide 17

Slide 17 text

jgs Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 17 //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(); }

Slide 18

Slide 18 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 18 jgs 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

Slide 19

Slide 19 text

jgs Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 19 // 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(); }

Slide 20

Slide 20 text

jgs Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 20 // mouse motion callback void myMouseMotion(int x, int y) { if (mouse_button == GLUT_LEFT_BUTTON && mouse_button_state== GLUT_DOWN) { corner_x = (x / 250.0)-1; // from 0 : 500 to -1 : 1 corner_y = -((y / 250.0)-1); } else { shake=-shake; // shaking triangles corner_x=((x-shake)/250.0)-1; //from 0 : 500 to -1 : 1 corner_y = -(((y-shake) / 250.0) - 1); } glutPostRedisplay(); }

Slide 21

Slide 21 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 21 jgs 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.

Slide 22

Slide 22 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 22 jgs Example 2 § Change color with the arrow keys § Move the triangles with the mouse (left click) § Move and shake with the mouse (right click)

Slide 23

Slide 23 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 23 jgs 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.

Slide 24

Slide 24 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 24 jgs Reading 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

Slide 25

Slide 25 text

Javier Gonzalez-Sanchez | SER332 | Spring 2018 | 25 jgs Homework Programming, Programming, and Programming

Slide 26

Slide 26 text

jgs SER332 Introduction to Graphics Javier Gonzalez-Sanchez [email protected] 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.