Title: Input and Interaction
1Input and Interaction
2Objectives
- Introduce the basic input devices
-
- Event-driven input, and its programming with GLUT
- Smooth animations
- Build interactive programs using GLUT callbacks
- Picking, Rubberbanding, and Display Lists
3Physical Devices
mouse
trackball
light pen
data tablet
joy stick
space ball
4Incremental (Relative) Devices
- Devices (e.g. data tablet) return a position
directly to the operating system - Devices (e.g. mouse, trackball, and joy stick)
return incremental inputs (or velocities) to OS -
5Logical Devices
- Consider the C and C code
- C cin gtgt x
- C scanf (d, x)
- The physical input device
- The logical input
-
6Graphical Logical Devices
- Characterized by its high-level interface with
the user program -
7Request Mode
- A trigger (e.g. button on mouse) can be used to
send a signal to the operating system. -
- Typical of keyboard input
-
8Event 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
9Callbacks
- Programming interface for event-driven input
- Define a callback function for each type of event
the graphics system recognizes - Function is executed when the event occurs
- glutMouseFunc(mymouse)
- glutDisplayFunc
- glutReshapeFunc
- glutKeyboardFunc
- glutIdleFunc
- glutMotionFunc,
- glutPassiveMotionFunc
10Example The display callback
- The display callback is executed
-
- In main.c
- glutDisplayFunc(mydisplay) identifies the
function to be executed
11GLUT Event Loop
- In main.c, the instruction glutMainLoop() puts
the program in an infinite event loop - In each pass through the event loop, GLUT looks
at the events in the queue -
12Animating a Display
- When we redraw the display through the display
callback, we can see partially drawn display. -
- We use double buffers
-
13Double Buffering
- Requests a double buffer in main.c
- glutInitDisplayMode(GL_RGB GL_DOUBLE)
- At the end of the display callback buffers are
swapped
void mydisplay() glClear( GL_COLOR_BUFFER_BIT
. ) ... / draw
graphics here / .... glutSwapBuffer
s()
14Animating a Display
- The idle callback is executed whenever there are
no events in the event queue - glutIdleFunc(myidle)
- Useful for animations
void myidle() / change something / t
dt glutPostRedisplay() Void mydisplay()
glClear() / draw something that
depends on t / glutSwapBuffers()
15The mouse callback
- glutMouseFunc(mymouse)
- void mymouse(GLint button, GLint state, GLint x,
GLint y) - Returns
- which button (GLUT_LEFT_BUTTON,
GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON) caused
event - state of that button (GLUT_UP, GLUT_DOWN)
- Position in window
16Example Mouse Position
- Draw a small square at the location of the mouse
each time the left mouse button is clicked
void mymouse(int btn, int state, int x, int
y) if(btnGLUT_RIGHT_BUTTON
stateGLUT_DOWN) exit(0) if(btnGLUT_LEFT_BU
TTON stateGLUT_DOWN) drawSquare(x,
y) void drawSquare(int x, int y) yw-y /
invert y position / glColor3ub( (char)
rand()256, (char) rand()256, (char)
rand()256) / a random color / glBegin(GL_POLY
GON) glVertex2f(xsize, ysize)
glVertex2f(x-size, ysize)
glVertex2f(x-size, y-size)
glVertex2f(xsize, y-size) glEnd()
17Using the keyboard
- glutKeyboardFunc(mykey)
- void mykey(unsigned char key, int x, int y)
- Returns ASCII code of key depressed and mouse
location
void mykey() if(key Q key q)
exit(0)
18Reshaping the window
- Must redraw from application
-
19Example Reshape
- Refer to previous discussion about the mapping
from world window to viewport
void myReshape( int w, int h )
glViewport(0, 0, w, h) glMatrixMode(GL_PROJEC
TION) / switch matrix mode /
glLoadIdentity() if (w lt h)
gluOrtho2D(-2.0, 2.0, -2.0 (GLfloat) h /
(GLfloat) w, 2.0
(GLfloat) h / (GLfloat) w) else
gluOrtho2D(-2.0 (GLfloat) w / (GLfloat) h, 2.0
(GLfloat) w /
(GLfloat) h, -2.0, 2.0) glMatrixMode(GL_MODEL
VIEW) / return to modelview mode /
20Defining a simple menu
entries that appear when right button depressed
menu_id glutCreateMenu(mymenu) glutAddmenuEntry
(clear Screen, 1) gluAddMenuEntry(exit,
2) glutAttachMenu(GLUT_RIGHT_BUTTON)
identifiers
- Menu callback
- void mymenu(int id)
- if(id 1) glClear()
- if(id 2) exit(0)
21The use of stack in OpenGL
- A stack
- recover the previous status by popping them
- glPushAttrib( GL_ALL_ATTRIB_BITS )
- glPushMatrix( )
- ...
- glPopAttrib( )
- glPopMatrix( )
22Picking
- Identify a user-defined object on the display
- Practical difficulties
-
- OpenGL supports selection approach for picking
23Hit List is Not Enough
- The pipeline is feed forward
-
24Redraw it!
- Use selection mode to redraw, and save the IDs of
the objects in a Hit List. - The idea is to draw in a temporary buffer instead
of sending them to display. -
Temp. Buffer
Hit List
25Selection Mode
- Make a smaller region around the cursor.
Otherwise, every primitive in the view volume
will generate a hit. - gluPickMatrix (x, y, w, h, vp)
- A selection mode may be set with
- glRenderMode(GL_SELECTION)
26Implementation (picksqaues.cpp)
- Create a name stack for objects to be drawn,
glLoadName(), glPushName(), glPushName() - Register mouse callback function, then in
callback - Enter selection mode, glSelectBuffer(),
glrenderMode() - Initialize name stack for Hit List, glInitName(),
glPushName() - Set up a small region for pick, gluPickMatrix()
- Redraw the objects, when objects are drawn, the
IDs of each object is pushed to the name stack
(see Step1) - Enter the render mode, operation return of
hits. glRenderMode() - Process the hit list. Hit list has both IDs and
the depth information.