OpenGL Interaction: Intro

blareweyrSoftware and s/w Development

Dec 13, 2013 (3 years and 8 months ago)

76 views

OpenGL Interaction:Intro
 Need to be able to handle interaction
 Well-designed interactive program should
1.Be easy to use
2.Be tolerant of user errors
3.Provide feedback to users
4.Use interaction devices appropriate to the task
5.Be ergonomic
6.Produce smooth animation,with no artifacts
1
OpenGL Interaction:Window Resizing
 When display window is resized,usually want to control eects programmati-
cally
 OpenGL allows control via reshape callback function
void glutReshapeFunc(void (*)(int width,int height));
void glutPostRedisplay(void);
 If no reshape function supplied,OpenGL uses a default viewport that lls the
resized window
 Typical reshape function has following format:
glViewport(...);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//projection call
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
...
 Variations in control based on viewport and projection specications
1.Want larger window to display proportionally more of world
{ Expand both viewport and view volume proportionately
2.Have static display
{ Neither viewport nor view volume change
3.Viewport changes with respect to window changes
(a) Changes in length and width are proportional to window's
(b) Changes are proportional to window's,but viewport length:width ratio
is xed
2
OpenGL Interaction:User Input
 Keyboard and mouse input handled using callback functions
void glutKeyboardFunc(void (*func)(unsigned char key,int x,int y));
void glutMouseFunc(void (*func)(int button,int state,int x,int y));
Button State
GLUT
LEFT
BUTTON GLUT
UP
GLUT
MIDDLE
BUTTON GLUT
DOWN
GLUT
RIGHT
BUTTON
void glutMotionFunc(void (*func)(int x,int y));
3
OpenGL Interaction:Menus
 Creating menus in OpenGL is a four-stage process:
1.Create a menu handler
{ The handler is a function that processes the users'choices
{ Choices are numerically id'd
{ For each menu option,your handler should provide appropriate process-
ing
2.Create the menu
int glutCreateMenu(void (*func)(int value));
{ Like many other things in OpenGL,there is a single menu"in focus"at
any one time
{ Creating a menu associates your handler with a menu,and makes this
menu the active one
{ A unique id for the menu is also returned
3.Specify menu options
void glutAddMenuEntry(char *name,int value);
{ This step associates numeric values with option text
{ The numeric values should be coordinated with the values you've spec-
ied in your menu handler
4.Associate the menu with a mouse button
void glutAttachMenu(int button);
4
OpenGL Interaction:Menus (2)
 Example:
void choice (int selection) {
if (selection == 1) {...}
if (selection == 2) {...}
...
glutPostRedisplay ();
}
glutCreateMenu (choice);
glutAddMenuEntry ("Do this:",1);
glutAddMenuEntry ("Do that:",2);
glutAttachMenu (GLUT_RIGHT_BUTTON);
 This will produce the following on a right-click.
 Many menus can exist at one time
{ To make a menu the active menu
void glutSetMenu(int menu);
{ To determine which menu is the active menu
int glutGetMenu(void);
 To delete a menu
void glutDestroyMenu(int menu);
5
OpenGL Interaction:SubMenus
 Menus can be nested
 To create a hierarchy of menus,one generally works from lowest to top level
 Each submenu is created using the rst 3 steps above:Create handler,create
menu,and specify options
 As each new menu is created,it becomes the active menu,so care must be
taken to store the id's for each submenu for future reference
 Submenus are added to a menu's options by specifying the id for the submenu
instead of a user-specied value
void glutAddSubMenu(char *name,int menu);
 Example:
void choiceSub (int selection) {
if (selection == 1) {}
if (selection == 2) {}
...
glutPostRedisplay ();
}
void choiceMain (int selection) {
if (selection == 1) {}
if (selection == 2) {}
...
glutPostRedisplay ();
}
submenu = glutCreateMenu (choiceSub);
glutAddMenuEntry ("Do this:",1);
glutAddMenuEntry ("Do that:",2);
glutCreateMenu (choiceMain);
glutAddMenuEntry ("Option 1:",1);
glutAddMenuEntry ("Option 2:",2);
glutAddSubMenu ("Option 3:",submenu);
glutAttachMenu (GLUT_RIGHT_BUTTON);
6
OpenGL Interaction:SubMenus (2)
 This will produce the following.
7
OpenGL Interaction:Double Buering
 Basic animation achieved by
1.Rendering a frame
2.Display frame
3.Modify frame
4.Repeat
 As complexity of image increases,animation becomes less uid
{ If all objects can be rendered within 1/60 second,can display entire scene
60 frames per second
{ If not,some objects will be displayed 60 frames per second,others at 30,
20,15,12,10,...
{ This causes ickering
 Solution is double buering
1.Requires at least 2 buers:one displayed,one hidden
2.Rendered image written to hidden buer
3.When complete,swap buers
void glutSwapBuers(void);
4.Only completely-rendered image is displayed
5.Must initialize glut for double buering (GLUT
DOUBLE)
 Problems:
{ Frame rates decrease as complexity of image increases:
60,30,20,15,12,10,...fps
{ Can cause non-smooth animation in games,etc.
{ Solution is to manually control frame rate,based on slowest rate in program
8
OpenGL Interaction:Animation and User Interaction
 In order to animate,we need to draw and redraw many times
 The naive way to do this would be to incorporate a loop in our drawing routine,
something like this:
void display ()
{
...
while ()
{
//update animation control
if (time-to-draw) {
//render scene
//update animation variables
glFlush();
}
}
}
 The problem with this is that the glut main loop gets stalled in the display
function
 This freezes out user interaction
 OpenGL provides idle function for this situation
void glutIdleFunc(void (*func)(void));
 Glut main loop:
while (true) {
if (need to redraw)
redraw
else if (event occurred)
handle event
else
call idle function
}
9
OpenGL Interaction:Animation and User Interaction (2)
 Strategy:
{ Since OpenGL has built-in loop,let it handle the iteration
{ Move all animation updates to idle function
 New program structure:
void display ()
{
...
//render scene
glFlush();
}
void idle ()
{
//update animation control
if (time to draw) {
//update animation variables
glutPostRedisplay();
}
}
10
OpenGL Interaction:Picking
 Picking is process of obtaining an object's id interactively
 Usually achieved by clicking on the object
 Approaches:
1.Explicit programmer handling
(a) Have 1:1 correspondence between projection plane and view port
{ Simply compare mouse coords with object extent
{ Impractical with window resizes
(b) Explicitly compare mouse coords with object extent
{ Requires reverse mapping
int gluUnProject(GLdouble winx,GLdouble winy,GLdouble winz,
const GLdouble modelMatrix[16],
const GLdouble projMatrix[16],
const GLint viewport[4],
GLdouble *objx,GLdouble *objy,GLdouble *objz);
glGetIntegerv(GLenum pname,GLint *params);
pname:GL
VIEWPORT,GL
MODELVIEW
MATRIX,GL
PROJECTION
MATRIX
11
OpenGL Interaction:Picking (2)
int gluUnProject4(GLdouble winx,GLdouble winy,GLdouble winz,
GLdouble clipw,const GLdouble modelMatrix[16],
const GLdouble projMatrix[16],
const GLint viewport[4],
GLclampd zNear,GLclampd zfar,
GLdouble *objx,GLdouble *objy,GLdouble *objz,
GLdouble *objw);
12
OpenGL Interaction:Picking (3)
(c) Use a second buer
{ Color each object uniquely
{ Draw to invisible (back )buer
void glDrawBuer(GLenum mode);
GL
FRONT GL
LEFT GL
BACK
LEFT
GL
BACK GL
RIGHT GL
BACK
RIGHT
GL
FRONT
AND
BACK GL
FRONT
LEFT GL
AUX
i
GL
NONE GL
FRONT
RIGHT
glGetBooleanv():GL
STEREO,GL
DOUBLE
BUFFER
glGetIntegerv():GL
AUX
BUFFERS
{ Read mouse coords
{ Get color at mouse position
void glReadBuer(GLenum mode);
void glReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,
GLenum format,GLenum type,GLvoid *pixels);
Format:GL
RGBA;type GL
FLOAT (complete list pp 315-316)
{ Requires every object drawn with unique color
13
OpenGL Interaction:Picking (4)
2.Selection
{ Selection mode draws objects invisibly,and determines if any fall within
a specied view volume
{ Objects of interest are placed on a name stack
{ Any object on the name stack that falls within the volume when drawn
is registered on a hit list
{ The hit list becomes available when exiting from selection mode
{ Steps required:
(a) Dene an area about the cursor
void glPushMatrix(void);
void gluPickmatrix(GLdouble x,GLdouble y,GLdouble w,
GLdouble h,GLint viewport[4]);
14
Interaction:Picking (5)
(b) Set up the hit list
void glSelectBuer(GLsizei n,GLuint *bu);
Contents of hit list when exit selection mode:
i.Number of names on stack when hit occurred
ii.Min z value of objects
iii.Max z value of objects
iv.Names on stack at time of hit
(c) Initialize the name stack
void glInitNames();
(d) Enter selection mode
GLint glRenderMode(GLenum mode);
GL
RENDER GL
SELECT GL
FEEDBACK
(e) Draw the scene using selection mode,moving objects on/o the stack
as they're drawn
void glPushName(GLuint name);
void glPopName();
void glLoadName(GLuint name);
(f) Exit selection mode
(g) Access hit list
15
OpenGL Interaction:Pixel Logic Operators
glEnable(GL
COLOR
LOGIC
OP);
void glLogicOp(GLenum mode);
mode op mode op
GL
CLEAR 0 GL
AND s ^d
GL
COPY s GL
OR s _d
GL
NOOP d GL
NAND:(s ^ d)
GL
SET 1 GL
NOR:(s _ d)
GL
COPY
INVERTED:s GL
XOR s d
GL
INVERT:d GL
EQUIV:(s d)
GL
AND
REVERSE s ^:d GL
AND
INVERTED:s ^d
GL
OR
REVERSE s _:d GL
OR
INVERTED:s _d
16