input and interaction yuanfeng zhou shandong university software college 1
TRANSCRIPT
Input and Interaction
Yuanfeng Zhou
Shandong University Software College
1
Objectives
• Introduce the basic input devices Physical Devices
Logical Devices
Input Modes
•Event-driven input• Introduce double buffering for smooth animations
•Programming event input with GLUT
2
Project Sketchpad
• Ivan Sutherland (MIT 1963)
established the basic interactive
paradigm that characterizes
interactive computer graphics: User sees an object on the display
User points to (picks) the object with an
input device (light pen, mouse, trackball)
Object changes
(moves, rotates, morphs)
Repeat
3
Interaction with Graphics System
4
ChangeImage
Reactto
Change
Graphics System User
InputDevice
Display
Graphical Input
•Devices can be described either by Physical properties
• Mouse• Keyboard• Trackball (Thinkpad)
Logical properties• What is returned to program via API (Application
Programming Interface)– A position– An object identifier
•Modes How and when input is obtained
• Request or event5
Logical Properties
6
ApplicationModel
ApplicationProgram
GraphicsSystem
OutputDevices
InputDevices
API
Function Callsor Protocol
Data
WM_LBUTTONDOWN#define ON_BN_LBUTTONDOWN(id, memberFxn)void CMyProgram::OnLButtonDown(UINT nFlags, CPoint point) { processing code…
CButton::OnLButtonDown(nFlags, point); }
Physical Devices
7
mouse trackball light pen
data tablet joy stick space ball
Logical Devices
•Consider the C and C++ code C++: cin >> x; C: scanf (“%d”, &x);
•What is the input device? Can’t tell from the code Could be keyboard, file, output from another
program
•The code provides logical input A number (an int) is returned to the program
regardless of the physical device
8
Graphical Logical Devices
• Graphical input is more varied than input to standard programs which is usually numbers, characters, or bits
• Two older APIs (GKS77’, PHIGS90’) defined six types of logical input:
Locator: return a position
Pick: return ID of an object
Keyboard: return strings of characters
Stroke: return array of positions
Valuator: return floating point number
Choice: return one of n items
9
10
X Window Input
• The X Window System introduced a client-server model for a network of workstations
Client: OpenGL program
Graphics Server: bitmap display with a pointing device and a keyboard
Display List in OpenGL
•Matrix computation• Image display•Light, material•Texture•Polygonal objects display
11
Display List in OpenGL
• void glNewList(GLuint list, GLenum mode);• mode: GL_COMPILE and GL_COMPILE_AND_EXECUTE
• void glEndList(void);• NOT included in Display List:• glDeleteLists() glIsEnable()• glFeedbackBuffer() glIsList()• glFinish() glPixelStore()• glGenLists() glRenderMode()• glGet*() glSelectBuffer()
12
Display List in OpenGL
•Example:GLuint listName = 1;
void myinit (void)
{
glNewList (listName, GL_COMPILE);
glColor3f (1.0, 0.0, 0.0);
glBegin (GL_TRIANGLES);
glVertex2f (0.0, 0.0);
glVertex2f (1.0, 0.0);
glVertex2f (0.0, 1.0);
glEnd ();
glTranslatef (1.5, 0.0, 0.0);
glEndList ();
glShadeModel (GL_FLAT);
}
13
void CALLBACK display(void) { GLuint i; glClear(GL_COLOR_BUFFER_BIT); glColor3f (0.0, 1.0, 0.0); glPushMatrix(); for (i = 0; i <5; i++) glCallList (listName); drawLine (); glPopMatrix(); glFlush (); }
Input Mode
• Input devices contain a trigger which can be used to send a signal to the operating system
Button on mouse
Pressing or releasing a key
•When triggered, input devices return information (their measure) to the system
Mouse returns position information
Keyboard returns ASCII code
14
Request Mode
• Input provided to program only when user triggers the device
•Typical of keyboard input Can erase (backspace), edit, correct until enter
(return) key (the trigger) is depressed
15
1. Program requests measure of a device and blocks.2. Measure process maintains current measure.3. Trigger process signals measure process to return measure.request_locator(device_id, &measure);
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
16glutMainLoop();
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
17
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)
18
mouse callback function
19
GLUT callbacks
GLUT recognizes a subset of the events recognized by any particular window system (Windows, X, Macintosh) glutDisplayFunc glutMouseFunc glutReshapeFunc glutKeyboardFunc glutIdleFunc glutMotionFunc glutPassiveMotionFunc
GLUT Event Loop
• Recall that the last line in main.c for a program using GLUT must be
glutMainLoop();
which puts the program in an infinite event loop
• In each pass through the event loop, GLUT looks at the events in the queue
for each event in the queue, GLUT executes the appropriate callback function if one is defined
if no callback is defined for the event, the event is ignored
20
Using 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
21
float t; /*global */
void mydisplay(){/* draw something that depends on t}
GLUT Display Event
Trigger: GLUT determines that the window needs to be redisplayed. A display event is generated when the window is first drawn.Callback function form: void display();
Registration: glutDisplayFunc(display);
The display callback is executed whenever GLUT determines that the window should be refreshed, for example
When the window is first openedWhen the window is reshapedWhen a window is exposedWhen the user program decides it wants to change the display
23
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
• We can avoid this problem by instead usingglutPostRedisplay();
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
24
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
• Hence we can see partially drawn display See the program single_double.c for an example
with a rotating cube
GLUT Mouse Event
Trigger: Any mouse button is depressed or released.
Callback function form:
void mouse_callback_func(int button, int state, int x, int y);
Registration:
glutMouseFunc(mouse_callback_function);
GLUT Defined Mouse Constants
GLUT_LEFT_BUTTONGLUT_MIDDLE_BUTTONGLUT_RIGHT_BUTTON
GLUT_UPGLUT_DOWN
Systems with only one mouse button can only generatea GLUT_LEFT_BUTTON callback.
GLUT Reshape Event
Trigger: Active window is resized
Callback function form:
void reshape_func(GLsizei w, GLsizei h);
Registration:
glutReshapeFunc(reshape_func);
GLUT Move Event
Trigger: The mouse is moved while one or more mousebuttons are pressed.
Callback function form:
void motion_func(int x, int y);
Registration:
glutMotionFunc(motion_func);
GLUT Keyboard Event
Trigger: Any key is depressed.
Callback function form:
void keyboard_function(unsigned char key, int x, int y);
Registration:
glutKeyboardFunc(keyboard_function);
Other Defined Events in GLUT
glutPassiveMotionFuncglutVisibilityFuncglutEntryFuncglutSpecialFuncglutSpaceballMotionFuncglutSpaceballRotateFuncglutSpaceballButtonFuncglutButtonBoxFuncglutDialsFuncglutTabletMotionFuncglutTabletButtonFuncglutMenuStatusFunc
Example: Simple Square Drawing Program
• Open a window.• Clear it to black.• Draw a box at location of the mouse each time the left
button is clicked. Color of box should be randomly selected from RGB space.
• Clear window when resized.• Quit when right button is clicked.
Square Program Source Code Slide 1
/* This program illustrates the use of the glut library forinterfacing with a Window System */
/* The program opens a window, clears it to black,then draws a box at the location of the mouse each time theleft button is clicked. The right button exits the program
The program also reacts correctly when the window ismoved or resized by clearing the new window to black*/
#include <GL/gl.h>#include <GL/glut.h>
/* globals */
GLsizei wh = 500, ww = 500; /* initial window size */GLfloat size = 3.0; /* half side length of square */
Square Program Source Code Slide 2
void drawSquare(int x, int y){
y = wh-y; glColor3f( (char) random()%256, (char) random()%256, (char) random()%256); glBegin(GL_POLYGON); glVertex2f(x+size, y+size);
glVertex2f(x-size, y+size); glVertex2f(x-size, y-size); glVertex2f(x+size, y-size); glEnd(); glFlush();
}
Square Program Source Code Slide 3
void myReshape(GLsizei w, GLsizei h){/* adjust clipping box */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();
/* adjust viewport and clear */ glViewport(0,0,w,h); glClearColor (0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glFlush();
/* set global size for use by drawing routine */ww = w;
wh = h; }
Square Program Source Code Slide 4
void myinit(void){ glViewport(0,0,ww,wh);
/* Pick 2D clipping window to match size of screen window This choice avoids having to scale object coordinateseach time window is resized */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, (GLdouble) ww , 0.0, (GLdouble) wh , -1.0, 1.0);
/* set clear color to black and clear window */ glClearColor (0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);glFlush();
/* callback routine for reshape event */ glutReshapeFunc(myReshape);}
Square Program Source Code Slide 5
void mouse(int btn, int state, int x, int y){ if(btn==GLUT_RIGHT_BUTTON&state==GLUT_DOWN) exit();}
int main(int argc, char** argv){ glutInit(&argc,argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);glutCreateWindow("square");
myinit ();
glutReshapeFunc (myReshape); glutMouseFunc (mouse); glutMotionFunc(drawSquare);
glutMainLoop();}
Output of “Square” program
Implementing Choice:Menus in GLUT
•Four steps: Create menu: glutCreateMenu(menu); Define menu entries: glutAddMenuEntry Attach menu to a mouse button: gluAttachMenu
Define callback function: void menu(int id);
Creating a Menu in GLUT
int glutCreateMenu(void (*func)(int value));
Creates a new pop-up menu.
Returns a unique integer identifier for the menu.
Takes as argument a pointer to a single callback functionthat takes an integer argument. The integer argument of the callback is mapped to the menu choice.
Sets the current menu to the newly created menu.
Menu Identifier Callback Function Choice
Associating a Menu with a Mouse Key
void glutAttachMenu(int button);
Associates the selected button with the current menu.
button is selected from the GLUT defined button constants:
GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON
Adding Entries to the Menu
void glutAddMenuEntry(char *name, int value);
String to appearin menu entry.
Value to be passedto callback function.
Adds a menu entry to the bottom of the current menu.
Building a Sub-menu
void glutAddSubMenu(char *name, int menu);
String to display in the menuitem from which to cascade sub-menu.
Identifier of menu to cascadefrom this sub-menu item.
Double Buffering
• Instead of one color buffer, we use two Front Buffer: one that is displayed but not written to Back Buffer: one that is written to but not displayed
• Program then requests a double buffer in main.c glutInitDisplayMode(GL_RGB | GL_DOUBLE) At the end of the display callback buffers are swapped
43
void mydisplay(){
glClear(GL_COLOR_BUFFER_BIT|….)./* draw graphics here */.
glutSwapBuffers()}
44
Using 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 += dtglutPostRedisplay();
}
Void mydisplay() {glClear();
/* draw something that depends on t */glutSwapBuffers();
}
45
Using 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}