490 likes | 740 Views
Input and Interaction. Input Devices Physical Input Devices and Logical Devices Input Modes Request Mode, Sample Mode, Event Mode Clients and Servers Concepts Display Lists; Matrix and Attribute Stacks Programming Event-Driven Input Mouse, Window and Keyboard events; Picking Menus
E N D
Input and Interaction • Input Devices • Physical Input Devices and Logical Devices • Input Modes • Request Mode, Sample Mode, Event Mode • Clients and Servers Concepts • Display Lists; Matrix and Attribute Stacks • Programming Event-Driven Input • Mouse, Window and Keyboard events; Picking • Menus • Animation and Double Buffering
Input Devices • Physical Input Devices • Pointing devices • Indicates a position on the screen • Mouse trackball data tablet light pen • Joystick Spaceball
Physical Input Devices • Pointingdevices • Mechanical: Encoders measure motion in tow orthogonal directions • Optical: Measures distance traveled by counting points on a special pad • Pressure-sensitive • Converted by the system to two dimensional location • Sometimes, velocities are integrated to obtain the position • Relative and absolute position • Keyboard devices: returns character codes to the program
Logical Devices • String: Provides a string • Locator: Pointing device • Pick: Pointing device • Choice: Widgets (menus, buttons, etc.) • Dial (Valuator): Widgets (slidebars, etc.) • Stroke: Returns an array of locations (drag)
Input Modes • Request Mode • Sample Mode • Event Mode
Request Mode • request_locator(device_id, &measure);
Sample Mode • sample_locator(device_id, &measure);
Event Mode • Event queue • Callback functions: e.g. display()
Graphics Architectures Simple graphics architecture Display-processor architecture
Definition of Display Lists #define BOX 1 /* or some other unused integer */ glNewList (BOX, GL_COMPLILE); glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex3f(-1.0, -1.0); glVertex3f( 1.0, -1.0); glVertex3f( 1.0, 1.0); glVertex3f(-1.0, 1.0); glEnd(): glEndList();
Execution of Display Lists • GL_COMPLILE sends the list to the server, but not to display its contents. For immediate display we use: • glNewList (BOX, GL_COMPLILE_AND_EXECUTE); • To draw a BOX we use: • glCallList (BOX);
Example of Display Lists Execution glMatrixMode(GL_PROJECTION); for(I= 1; I<5; I++) { glLoadIdentity(); gluOrtho2D(-2.0*i, 2.0 *i, -2.0 *i, 2.0 *i); glCallList (BOX); }
Matrix and Attribute Stacks • Saving the present values of attributes and matrices: • glPushAttrib(); • glPushAttrib(); • Recover the previous values of attributes and matrices: • glPopAttrib(); • glPophAttrib();
Example of stroke characters Using Text in Display Lists
Drawing Character ‘O’ case ‘O' : glTranslatef ( 0.5, 0.5, 0.0); /* move to center */ glBegin{GL_QUAD_STRIP}; for (i=0; i<=12; i++) /* 12 vertices { angle = 3.14159 /6.0 * i; /* 30 degrees in radians glVertex2f (0.4 * cos (angle), 0.4 * sin(angle)); glVertex2f (0.5 * cos (angle), 0.5 * sin(angle)); } glEnd( ); glTranslatef(0.5, -0.5, 0.0); /* move to lower right */ break;
Generating 256-Character Set base = glGenLists(256); /* return index of first of 256 consecutive available ids */ for (i=0; i<256; i++) { glNewList(base + i, GL_COMPILE); OurFont(i); glEndList(); }
Using Display Lists • Setting an offset: glListBase(base) • Drawing: char *text_string; glCallLists ( (GLint) strlen (text_string), GL_BYTE, text_string);
Fonts in GLUT • Monotype (evenly spaced) stroke character: glutStrokeCharacter (GLUT_STROKE_MONO_ROMAN, int character); • Raster character: glutBitmapCharacter (GLUT_BITMAP_8_BY_13, int character); • Positionning: glRasterPos2i(rx, ry); glutBitmapCharacter (GLUT_BITMAP_8_BY_13, k); rx+=glutBitmapWidth (GLUT_BITMAP_8_BY_13, k);
Programming Event-Driven Input • Mouse (pointing device) events • Window events • Keyboard events
Mouse Events • Move events and passive move event • Registering the mouse callback function: glutMouseFunc(mouse) void mouse (int button, int state, int x, int y)
Example: Using mouse events void mouse (int button, int state, int x, int y) { if(button==GLUT_LEFT_BUTTON & state==GLUT_DOWN) drawSquare(x, y); if(button==GLUT_RIGHT_BUTTON & state==GLUT_DOWN) exit(0); }
Example: Using mouse events (cont.) void drawSquare(int x, int y) { y = wh - y; glColor3ub( (char) rand()%256, (char) rand()%256, (char) rand()%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(); }
Window Events • Window resizing • Registering the callback function: glutReshapeFunc(myReshape) void myReshape (GLsizei w, GLsizei h)
Example void myReshape(GLsizei w, GLsizei h) { /* adjust clipping box glMatrixMode(GL-PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h); glMatrixMode(GL-MODELVIEW); glLoadIdentityo; /* adjust viewport and clear glViewport(0,0,w,h); glClearColor (0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glFlush(); }
Keybord Events • Key pressing events • Registering the callback function: glutKeyboardFunc(keyboard); • Example void keyboard(unsigned char key, int x, int y) { if(key==’q’ || key == ’Q’) exit(0); }
Display and Idle Callbacks • Display callbacks glutDisplayFunc(display) glutPostRedisplayFunc() • Idle callback • Invoked when there is no other events • Defaults to the null function
Window Management • Creating a new window id = glutCreateWindow(“Second Window”); • Setting the current window glutSetWindow(id);
Menus: Pop-Up Menus • Define the entries in the menu • Link the menu to a mouse button • Define the callback function for each entry
Examples of Menu glutCreateMenu (demo_menu); glutAddMenuEntry ("quit",1); glutAddMenuEntry ("increase square size", 2); glutAddMenuEntry ("decrease square size", 3) glutAttachMenu (GLUT_RIGHT_BUTTON);
Examples of Menu • Creating a menu and sub-menu
Defining Menu Callback Function void demo-menu(int id) { if(id == 1) exit( ) ; else if (id == 2) size = 2 * size; else if (size > 1) size = size/2; glutPostRedisplay( ); }
Picking • Selection: by adjusting the clipping region and viewport near the cursor • Use bounding rectangles • Difficult if objects are grouped together
Application Example: Paint Program • Drawing geometric objects and characters • Manipulate pixels • Provide control of attributes • Includes menus for interaction • Able to process window events
Animating Interactive Programs Example: • Drawing rotating square • Control the rotation by using the idle function • Control the idle function by using a menu
Display Function void display(){ glclear(); glBegin(GL_POLYGON), thetar = theta/((2*3.14159)/360.0); /* convert degrees to radians glVertex2f (cos(thetar), sin(thetar)); glVertex2f (-sin(thetar), cos(thetar)); glVertex2f (-cos(thetar), -sin(thetar)); glVertex2f (sin(thetar), -cos(thetar)); glEnd(); }
Idle Function glutIdleFunc(idle); vold ldle() { theta += 2 /* or some other amount */ lf (theta >= 360.0) theta = 0.0; glutPostRedisplay( ); }
Mouse Callback Function glutMouseFunc(mouse); void mouse(int button, int state, int x, int y) { if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN) glutIdleFunc(idle); if(button==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN) glutIdleFunc(NULL); }
Double Buffering • Hardware: refresh rate between 50 and 85 times per second. • Software: Depending on drawing speed, some objects may be displayed completely. • Double Buffering: use front buffer and back buffer • Draw into the back buffer • Swap the front buffer and back buffer when needed. Thus generating smooth display.
Double Buffering (cont.) • Using Double Buffering: • In the main function: glutInitDisplayMode(GLUT_RGB, GLUT_DOUBLE); • In the display function (after drawing): glutSwapBuffers();
Needs to Work in the Frame Buffer • Menu display • Rubberbanding
Design of Interactive Programs • Smooth Display, showing neither flicker nor any artifacts of the refresh process • Variety of interactive devices • Variety of methods for entering and displaying information • Easy to use interface • Feedback to the user • Tolerate user’s errors • Design should consider both the visual and motor properties of users.