03 OpenGL2
03 OpenGL2
03 OpenGL2
OpenGL/GLUT
Configure and open window Initialize OpenGL state Display callback function Register input callback functions
Render Resize Input user interface
Event Mode
Most systems have more than one input device, each of which can be triggered at an arbitrary time by a user Each trigger generates an event whose measure is put in an event queue which can be examined by the user program
Event Types
Window: resize, expose, iconify Mouse: click one or more buttons Motion: move mouse Keyboard: press or release a key Idle: nonevent
Define what should be done if no other event is in queue
Event Loop
Note that the program defines a display callback function named mydisplay
Every glut program must have a display callback The display callback is executed whenever OpenGL decides the display must be refreshed, for example when the window is opened The main function ends with the program entering an event loop
Program Structure
Most OpenGL programs have a similar structure that consists of the following functions
main():
defines the callback functions opens one or more windows with the required properties enters event loop (last executable statement)
callbacks
Display function Input and window functions
Callbacks
Programming interface for event-driven input Define a callback function for each type of event the graphics system recognizes This user-supplied function is executed when the event occurs GLUT example: glutMouseFunc(mymouse)
Posting redisplays
Many events may invoke the display callback function
Can lead to multiple executions of the display callback on a single pass through the event loop
In main.c
glutDisplayFunc(mydisplay) identifies the function to be executed Every GLUT program must have a display callback
which sets a flag. GLUT checks to see if the flag is set at the end of the event loop If set then the display callback function is executed
GLUT 3D primitives
glutWireSphere(GLdouble radious, GLint slices, GLint stacks) glutSolidSphere( ) glutWireCube(GLdouble size) glutSolidCube(GLdouble size) glutWireTeapot(GLdouble size) glutSolidTeapot(GLdouble size)
Reshape possiblities
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
original reshaped
Viewports
Do not have use the entire window for the image: glViewport(x,y,w,h) Values in pixels (screen coordinates)
The reshape callback is good place to put viewing functions because it is invoked when the window is first opened
Reshape Callback
void reshape(int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); }
Keyboard callback
glutKeyboardFunc sets the keyboard callback for the current window. When a user types into the window, each key press generating an ASCII character will generate a keyboard callback. The key callback parameter is the generated ASCII character.
Keyboard callback
void keyboard (unsigned char key, int x, int y) { switch(key) { case 'a' : Rotate_Cube() ; glutPostRedisplay() ; break ; case 's' : Rotate_Cube3D() ; glutPostRedisplay() ; break ; default : glutIdleFunc(NULL) ; break ; }}
Mouse Callback
glutMouseFunc sets the mouse callback for the current window. When a user presses and releases mouse buttons in the window, each press and each release generates a mouse callback. The button parameter is one of GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, or GLUT_RIGHT_BUTTON.
Positioning
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;
(0,0)
Mouse callback
void mouse(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(spinDisplay); break; case GLUT_MIDDLE_BUTTON: case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(NULL); break; default: break; }}
Motion Callback
glutMotionFunc and glutPassiveMotionFunc set the motion and passive motion callback respectively for the current window. The motion callback for a window is called when the mouse moves within the window while one or more mouse buttons are pressed. The passive motion callback for a window is called when the mouse moves within the window while no mouse buttons are pressed.
XOR write
Usual (default) mode: source replaces destination (d = s)
Cannot write temporary lines this way because we cannot recover what was under the line in a fast simple way
Rubberbanding
Switch to XOR write mode Draw object
For line can use first mouse click to fix one endpoint and then use motion callback to continuously update the second endpoint Each time mouse is moved, redraw line which erases it and then draw line from fixed first position to to new second position At end, switch back to normal drawing mode and draw line Works for other objects: rectangles, circles
Rubberband Lines
second point first point initial display draw line with mouse in XOR mode
XOR in OpenGL
There are 16 possible logical operations between two bits All are supported by OpenGL
Must first enable logical operations
glEnable(GL_COLOR_LOGIC_OP)
Motion Callback
void OnMouseMove(int mouse_x, int mouse_y){ if (g_bDragging) { int x = mouse_x; int y = WINDOW_HEIGHT - mouse_y; glColor3f(1.0, 1.0, 1.0); glEnable(GL_COLOR_LOGIC_OP); glBegin(GL_LINES); // redraw to erase the old line glVertex2i(g_LastLine[0].x, g_LastLine[0].y); glVertex2i(g_LastLine[1].x, g_LastLine[1].y); // draw the new line glVertex2i(g_LastLine[0].x, g_LastLine[0].y); glVertex2i(x, y); glEnd(); glFlush(); glDisable(GL_COLOR_LOGIC_OP); // update the last line g_LastLine[1].x = x; g_LastLine[1].y = y; } }
Animating a Display
When we redraw the display through the display callback, we usually start by clearing the window
glClear()
then draw the altered display Problem: the drawing of information in the frame buffer is decoupled from the display of its contents
Graphics systems use dual ported memory
Double buffering
Technique for tricking the eye into seeing smooth animation of rendered scenes Two equal halves, front and back buffer The front is displayed while the application renders into the back buffer Avoids displaying partially rendered frame buffer glutSwapBuffers (void)
Double Buffering