0% found this document useful (0 votes)
7 views

Module 3 Part 1

Uploaded by

SantoshMeharwade
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Module 3 Part 1

Uploaded by

SantoshMeharwade
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

Interactive Input Methods and

Graphical User Interfaces

1 Graphical Input Data


2 Logical Classification of Input Devices
3 Input Functions for Graphical Data
4 Interactive Picture-Construction
Techniques
5 Virtual-Reality Environments
6 OpenGL Interactive Input-Device
Functions
7 OpenGL Menu Functions
8 Designing a Graphical User Interface
9 Summary

A lthough we can construct programs and provide input data


using the methods and program commands discussed in the
previous chapters, it is often useful to be able to specify
graphical input interactively. During the execution of a program, for
example, we might want to change the position of the camera or the
location of an object in a scene by pointing to a screen position, or
we might want to change animation parameters using menu selec-
tions. In design applications, control-point coordinates for spline con-
structions are chosen interactively, and pictures are often constructed
using interactive painting or drawing methods. There are several
kinds of data that are used by a graphics program, and a variety
of interactive input methods have been devised for processing these
data values. In addition, interfaces for systems now involve extensive
interactive graphics, including display windows, icons, menus, and a
mouse or other cursor-control devices.

From Chapter 20 of Computer Graphics with OpenGL®, Fourth Edition, Donald Hearn, M. Pauline Baker, Warren R. Carithers.
Copyright © 2011 by Pearson Education, Inc. Published by Pearson Prentice Hall. All rights reserved.
591
Interactive Input Methods and Graphical User Interfaces

1 Graphical Input Data


Graphics programs use several kinds of input data, such as coordinate positions,
attribute values, character-string specifications, geometric-transformation val-
ues, viewing conditions, and illumination parameters. Many graphics packages,
including the International Standards Organization (ISO) and American
National Standards Institute (ANSI) standards, provide an extensive set of
input functions for processing such data. But input procedures require interaction
with display-window managers and specific hardware devices. Therefore, some
graphics systems, particularly those that provide mainly device-independent
functions, often include relatively few interactive procedures for dealing with
input data.
A standard organization for input procedures in a graphics package is to
classify the functions according to the type of data that is to be processed by each
function. This scheme allows any physical device, such as a keyboard or a mouse,
to input any data class, although most input devices can handle some data types
better than others.

2 Logical Classification of Input Devices


When input functions are classified according to data type, any device that is used
to provide the specified data is referred to as a logical input device for that data
type. The standard logical input-data classifications are
LOCATOR A device for specifying one coordinate position.
STROKE A device for specifying a set of coordinate positions.
STRING A device for specifying text input.
VALUATOR A device for specifying a scalar value.
CHOICE A device for selecting a menu option.
PICK A device for selecting a component of a picture.

Locator Devices
Interactive selection of a coordinate point is usually accomplished by positioning
the screen cursor at some location in a displayed scene, although other meth-
ods, such as menu options, could be used in certain applications. We can use
a mouse, touchpad, joystick, trackball, spaceball, thumbwheel, dial, hand cur-
sor, or digitizer stylus for screen-cursor positioning. In addition, various but-
tons, keys, or switches can be used to indicate processing options for the selected
location.
Keyboards are used for locator input in several ways. A general-purpose
keyboard usually has four cursor-control keys that move the screen cursor up,
down, left, and right. With an additional four keys, we can move the cursor
diagonally as well. Rapid cursor movement is accomplished by holding down
the selected cursor key. Sometimes a keyboard includes a touchpad, joystick,
trackball, or other device for positioning the screen cursor. For some applications,
it may also be convenient to use a keyboard to type in numerical values or other
codes to indicate coordinate positions.
Other devices, such as a light pen, have also been used for interactive
input of coordinate positions. But light pens record screen positions by detect-
ing light from the screen phosphors, and this requires special implementation
procedures.

592
Interactive Input Methods and Graphical User Interfaces

Stroke Devices
This class of logical devices is used to input a sequence of coordinate positions,
and the physical devices used for generating locator input are also used as stroke
devices. Continuous movement of a mouse, trackball, joystick, or hand cursor
is translated into a series of input coordinate values. The graphics tablet is one
of the more common stroke devices. Button activation can be used to place the
tablet into “continuous” mode. As the cursor is moved across the tablet surface,
a stream of coordinate values is generated. This procedure is used in paintbrush
systems to generate drawings using various brush strokes. Engineering systems
also use this process to trace and digitize layouts.

String Devices
The primary physical device used for string input is the keyboard. Character
strings in computer-graphics applications are typically used for picture or graph
labeling.
Other physical devices can be used for generating character patterns for spe-
cial applications. Individual characters can be sketched on the screen using a
stroke or locator-type device. A pattern recognition program then interprets the
characters using a stored dictionary of predefined patterns.

Valuator Devices
We can employ valuator input in a graphics program to set scalar values for
geometric transformations, viewing parameters, and illumination parameters. In
some applications, scalar input is also used for setting physical parameters such
as temperature, voltage, or stress-strain factors.
A typical physical device used to provide valuator input is a panel of control
dials. Dial settings are calibrated to produce numerical values within some pre-
defined range. Rotary potentiometers convert dial rotation into a corresponding
voltage, which is then translated into a number within a defined scalar range,
such as −10.5 to 25.5. Instead of dials, slide potentiometers are sometimes used
to convert linear movements into scalar values.
Any keyboard with a set of numeric keys can be used as a valuator device.
Although dials and slide potentiometers are more efficient for fast input.
Joysticks, trackballs, tablets, and other interactive devices can be adapted for
valuator input by interpreting pressure or movement of the device relative to a
scalar range. For one direction of movement, say left to right, increasing scalar
values can be input. Movement in the opposite direction decreases the scalar input
value. Selected values are usually echoed on the screen for verification.
Another technique for providing valuator input is to display graphical rep-
resentations of sliders, buttons, rotating scales, and menus on the video monitor.
Cursor positioning, using a mouse, joystick, spaceball, or other device, can be
used to select a value on one of these valuators. As a feedback mechanism for the
user, selected values are usually displayed in text or color fields elsewhere within
the graphical display belonging to the application.

Choice Devices
Menus are typically used in graphics programs to select processing options,
parameter values, and object shapes that are to be used in constructing a picture.
Commonly used choice devices for selecting a menu option are cursor-positioning
devices such as a mouse, trackball, keyboard, touch panel, or button box.
Keyboard function keys or separate button boxes are often used to enter
menu selections. Each button or function key is programmed to select a particular

593
Interactive Input Methods and Graphical User Interfaces

operation or value, although preset buttons or keys are sometimes included on


an input device.
For screen selection of listed menu options, we use a cursor-positioning
device. When a screen-cursor position (x, y) is selected, it is compared to the
coordinate extents of each listed menu item. A menu item with vertical and hori-
zontal boundaries at the coordinate values xmin , xmax , ymin , and ymax is selected if
the input coordinates satisfy the inequalities
xmin ≤ x ≤ xmax , ymin ≤ y ≤ ymax (1)
For larger menus with relatively few options displayed, a touch panel is com-
monly used. A selected screen position is compared to the coordinate extents of
the individual menu options to determine what process is to be performed.
Alternate methods for choice input include keyboard and voice entry. A stan-
dard keyboard can be used to type in commands or menu options. For this method
of choice input, some abbreviated format is useful. Menu listings can be numbered
or given short identifying names. A similar encoding scheme can be used with
voice input systems. Voice input is particularly useful when the number of options
is small (20 or fewer).

Pick Devices
We use a pick device to select a part of a scene that is to be transformed or edited
in some way. Several different methods can be used to select a component of a
displayed scene, and any input mechanism used for this purpose is classified as a
pick device. Most often, pick operations are performed by positioning the screen
cursor. Using a mouse, joystick, or keyboard, for example, we can perform picking
by positioning the screen cursor and pressing a button or key to record the pixel
coordinates. This screen position can then be used to select an entire object, a facet
of a tessellated surface, a polygon edge, or a vertex. Other pick methods include
highlighting schemes, selecting objects by name, or a combination of methods.
Using the cursor-positioning approach, a pick procedure could map a selected
screen position to a world-coordinate location using the inverse viewing and
geometric transformations that were specified for the scene. Then, the world-
coordinate position can be compared to the coordinate extents of objects. If the
pick position is within the coordinate extents of a single object, the pick object
has been identified. The object name, coordinates, or other information about the
object can then be used to apply the desired transformation or editing operations.
But if the pick position is within the coordinate extents of two or more objects,
further testing is necessary. Depending on the type of object to be selected and the
complexity of a scene, several levels of search may be required to identify the pick
object. For example, if we are attempting to pick a sphere whose coordinate extents
overlap the coordinate extents of some other three-dimensional object, the pick
position could be compared to the coordinate extents of the individual surface
facets of the two objects. If this test fails, the coordinate extents of individual line
d1 segments can be tested.
d2 When coordinate-extent tests do not uniquely identify a pick object, the
(x, y) distances from the pick position to individual line segments could be computed.
Figure 1 illustrates a pick position that is within the coordinate extents of
FIGURE 1 two line segments. For a two-dimensional line segment with pixel endpoint
Distances to line segments from a pick coordinates (x1 , y1 ) and (x2 , y2 ), the perpendicular distance squared from a pick
position. position (x, y) to the line is calculated as
[x(y − y1 ) − y(x − x1 )]2
d2 = (2)
x 2 + y2

594
Interactive Input Methods and Graphical User Interfaces

where x = x2 −x1 and y = y2 − y1 . Other methods, such as comparing distances


to endpoint positions, have been proposed to simplify the line-picking operations.
Pick procedures can be simplified if coordinate-extent testing is not carried
out for the surface facets and line segments of an object. When the pick position h
is within the coordinate extents of two or more objects, the pick procedures can (xp, yp)
simply return a list of all candidate pick objects.
Another picking technique is to associate a pick window with a selected
cursor position. The pick window is centered on the cursor position, as shown in
w
Figure 2, and clipping procedures are used to determine which objects intersect
the pick window. For line picking, we can set the pick-window dimensions w and FIGURE 2
h to very small values, so that only one line segment intersects the pick window. A pick window with center coordinates
( x p , y p ) , width w, and height h .
Some graphics packages implement three-dimensional picking by reconstructing
a scene using the viewing and projection transformations with the pick window
as the clipping window. Nothing is displayed from this reconstruction, but clip-
ping procedures are applied to determine which objects are within the pick view
volume. A list of information for each object in the pick view volume can then
be returned for processing. This list can contain information such as object name
and depth range, where the depth range could be used to select the nearest object
in the pick view volume.
Highlighting can also be used to facilitate picking. One way to do this is to
successively highlight those objects whose coordinate extents overlap a pick posi-
tion (or pick window). As each object is highlighted, a user could issue a “reject”
or “accept” action using keyboard keys. The sequence stops when the user accepts
a highlighted object as the pick object. Picking could also be accomplished simply
by successively highlighting all objects in the scene without selecting a cursor
position. The highlighting sequence can be initiated with a button or function
key, and a second button can be used to stop the process when the desired object
is highlighted. If very many objects are to be searched in this way, additional
buttons can be used to speed up the highlighting process. One button initiates a
rapid successive highlighting of structures. A second button is activated to stop
the process, and a third button is used to back up slowly through the highlighting
process. Finally, a stop button could be pressed to complete the pick procedure.
If picture components can be selected by name, keyboard input can be used
to pick an object. This is a straightforward, but less interactive, pick-selection
method. Some graphics packages allow picture components to be named at var-
ious levels down to the individual primitives. Descriptive names can be used
to help a user in the pick process, but this approach has drawbacks. It is gener-
ally slower than interactive picking on the screen, and a user will probably need
prompts to remember the various structure names.

3 Input Functions for Graphical Data


Graphics packages that use the logical classification for input devices provide
several functions for selecting devices and data classes. These functions allow a
user to specify the following options:
• The input interaction mode for the graphics program and the input devices.
Either the program or the devices can initiate data entry, or both can operate
simultaneously.
• Selection of a physical device that is to provide input within a particular
logical classification (for example, a tablet used as a stroke device).
• Selection of the input time and device for a particular set of data values.

595
Interactive Input Methods and Graphical User Interfaces

Input Modes
Some input functions in an interactive graphics system are used to specify how
the program and input devices should interact. A program could request input
at a particular time in the processing (request mode), or an input device could
independently provide updated input (sample mode), or the device could inde-
pendently store all collected data (event mode).
In request mode, the application program initiates data entry. When
input values are requested, processing is suspended until the required values are
received. This input mode corresponds to the typical input operation in a general
programming language. The program and the input devices operate alternately.
Devices are put into a wait state until an input request is made; then the program
waits until the data are delivered.
In sample mode, the application program and input devices operate inde-
pendently. Input devices may be operating at the same time that the program is
processing other data. New values obtained from the input devices replace pre-
viously input data values. When the program requires new data, it samples the
current values that have been stored from the device input.
In event mode, the input devices initiate data input to the application pro-
gram. The program and the input devices again operate concurrently, but now
the input devices deliver data to an input queue, also called an event queue. All
input data is saved. When the program requires new data, it goes to the data
queue.
Typically, any number of devices can be operating at the same time in sample
and event modes. Some can be operating in sample mode, while others are operat-
ing in event mode. But only one device at a time can deliver input in request mode.
Other functions in the input library are used to specify physical devices
for the logical data classes. The input procedures in an interactive package can
involve complicated processing for some kinds of input. For instance, to obtain a
world-coordinate position, the input procedures must process an input screen
location back through the viewing and other transformations to the original
world-coordinate description of a scene. This processing also involves informa-
tion from the display-window routines.

Echo Feedback
Requests can usually be made in an interactive input program for an echo of input
data and associated parameters. When an echo of the input data is requested, it is
displayed within a specified screen area. Echo feedback can include, for example,
the size of the pick window, the minimum pick distance, the type and size of
a cursor, the type of highlighting to be employed during pick operations, the
range (mininum and maximum) for valuator input, and the resolution (scale) for
valuator input.

Callback Functions
For device-independent graphics packages, a limited set of input functions can be
provided in an auxiliary library. Input procedures can then be handled as callback
functions that interact with the system software. These functions specify what
actions are to be taken by a program when an input event occurs. Typical input
events are moving a mouse, pressing a mouse button, or pressing a key on the
keyboard.

596
Interactive Input Methods and Graphical User Interfaces

previous sections. Curve-drawing options can be provided using standard curve


shapes, such as circular arcs and splines, or with freehand sketching procedures.
Splines are interactively constructed by specifying a set of control points or a
freehand sketch that gives the general shape of the curve. Then the system fits
the set of points with a polynomial curve. In freehand drawing, curves are gen-
erated by following the path of a stylus on a graphics tablet or the path of the
screen cursor on a video monitor. Once a curve is displayed, the designer can
alter the curve shape by adjusting the positions of selected points along the
curve path.
Line widths, line styles, and other attribute options are also commonly found
in painting and drawing packages. Various brush styles, brush patterns, color
combinations, object shapes, and surface texture patterns are also available on
many systems, particularly those designed as artists’ workstations. Some paint
systems vary the line width and brush strokes according to the pressure of the
artist’s hand on the stylus. Color Plate 23 shows a window and menu system
used with a painting package that allows an artist to select variations of a spe-
cified object shape, different surface textures, and a variety of lighting conditions
for a scene.

5 Virtual-Reality Environments
A typical virtual-reality environment is illustrated in Color Plate 24. Interac-
tive input is accomplished in this environment with a data glove, which is capable
of grasping and moving objects displayed in a virtual scene. The computer-gener-
ated scene is displayed through a head-mounted viewing system as a stereographic
projection. Tracking devices compute the position and orientation of the headset
and data glove relative to the object positions in the scene. With this system, a user
can move through the scene and rearrange object positions with the data glove.
Another method for generating virtual scenes is to display stereographic
projections on a raster monitor, with the two stereographic views displayed on
alternate refresh cycles. The scene is then viewed through stereographic glasses.
Interactive object manipulations can again be accomplished with a data glove
and a tracking device to monitor the glove position and orientation relative to the
position of objects in the scene.

6 OpenGL Interactive Input-Device


Functions
Interactive device input in an OpenGL program is handled with routines in the
OpenGL Utility Toolkit (GLUT), because these routines need to interface with
a window system. In GLUT, we have functions to accept input from standard
devices, such as a mouse or a keyboard, as well as from tablets, space balls,
button boxes, and dials. For each device, we specify a procedure (the call back
function) that is to be invoked when an input event from that device occurs. These
GLUT commands are placed in the main procedure along with the other GLUT
statements. In addition, a combination of functions from the basic library and the
GLU library can be used with the GLUT mouse function for pick input.

600
Interactive Input Methods and Graphical User Interfaces

GLUT Mouse Functions


We use the following function to specify (“register”) a procedure that is to be
called when the mouse pointer is in a display window and a mouse button is
pressed or released:

glutMouseFunc (mouseFcn);

This mouse callback procedure, which we named mouseFcn, has four arguments:

void mouseFcn (GLint button, GLint action, GLint xMouse,


GLint yMouse)

Parameter button is assigned a GLUT symbolic constant that denotes one


of the three mouse buttons, and parameter action is assigned a symbolic
constant that specifies which button action we want to use to trigger the
mouse activation event. Allowable values for button are GLUT LEFT BUTTON,
GLUT MIDDLE BUTTON, and GLUT RIGHT BUTTON. (If we have only a two-
button mouse, then we use just the left-button and right-button designations;
with a one-button mouse, we can assign parameter button only the value
GLUT LEFT BUTTON.) Parameter action can be assigned either GLUT DOWN or
GLUT UP, depending on whether we want to initiate an action when we press a
mouse button or when we release it. When procedure mouseFcn is invoked, the
display-window location of the mouse cursor is returned as the coordinate posi-
tion (xMouse, yMouse). This location is relative to the top-left corner of the display
window, so that xMouse is the pixel distance from the left edge of the display win-
dow and yMouse is the pixel distance down from the top of the display window.
By activating a mouse button while the screen cursor is within the display
window, we can select a position for displaying a primitive such as a single point,
a line segment, or a fill area. We could also use the mouse as a pick device by
comparing the returned screen position with the coordinate extents of displayed
objects in a scene. However, OpenGL does provide routines for using the mouse
as a pick device, and we discuss these routines in a later section.
As a simple example of the use of the glutMouseFunc routine, the following
program plots a red point, with a point size equal to 3, at the position of the mouse
cursor in the display window, each time that we press the left mouse button.
Because the coordinate origin for the OpenGL primitive functions is the lower-
left corner of the display window, we need to flip the returned yMouse value in
the procedure mousePtPlot.

#include <GL/glut.h>

GLsizei winWidth = 400, winHeight = 300; // Initial display-window size.

void init (void)


{
glClearColor (0.0, 0.0, 1.0, 1.0) // Set display-window color to blue.

glMatrixMode (GL_PROJECTION);
gluOrtho2D (0.0, 200.0, 0.0, 150.0);
}

601
Interactive Input Methods and Graphical User Interfaces

void displayFcn (void)


{
glClear (GL_COLOR_BUFFER_BIT); // Clear display window.

glColor3f (1.0, 0.0, 0.0); // Set point color to red.


glPointSize (3.0); // Set point size to 3.0.
}

void winReshapeFcn (GLint newWidth, GLint newHeight)


{
/* Reset viewport and projection parameters */
glViewport (0, 0, newWidth, newHeight);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ( );
gluOrtho2D (0.0, GLdouble (newWidth), 0.0, GLdouble (newHeight));

/* Reset display-window size parameters. */


winWidth = newWidth;
winHeight = newHeight;
}

void plotPoint (GLint x, GLint y)


{
glBegin (GL_POINTS);
glVertex2i (x, y);
glEnd ( );
}

void mousePtPlot (GLint button, GLint action, GLint xMouse, GLint yMouse)
{
if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN)
plotPoint (xMouse, winHeight - yMouse);

glFlush ( );
}

void main (int argc, char** argv)


{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition (100, 100);
glutInitWindowSize (winWidth, winHeight);
glutCreateWindow ("Mouse Plot Points");

init ( );
glutDisplayFunc (displayFcn);
glutReshapeFunc (winReshapeFcn);
glutMouseFunc (mousePtPlot);

glutMainLoop ( );
}

602
Interactive Input Methods and Graphical User Interfaces

where (xMouse, yMouse) is the mouse location in the display window relative to
the top-left corner, when the mouse is moved with a button pressed.
Similarly, we can perform some action when we move the mouse within the
display window without pressing a button:

glutPassiveMotionFunc (fcnDoSomethingElse);

Again, the mouse location is returned to fcnDoSomethingElse as coordi-


nate position (xMouse, yMouse), relative to the top-left corner of the display
window.

GLUT Keyboard Functions


With keyboard input, we use the following function to specify a procedure that
is to be invoked when a key is pressed:

glutKeyboardFunc (keyFcn);

The specified procedure has three arguments:

void keyFcn (GLubyte key, GLint xMouse, GLint yMouse)

Parameter key is assigned a character value or the corresponding ASCII code.


The display-window mouse location is returned as position (xMouse, yMouse)
relative to the top-left corner of the display window. When a designated key is
pressed, we can use the mouse location to initiate some action, independently of
whether any mouse buttons are pressed.
In the following code, we present a simple curve-drawing procedure
using keyboard input. A freehand curve is generated by moving the mouse
within the display window while holding down the “c” key. This displays a
sequence of red dots at each recorded mouse position. By slowly moving the
mouse, we can obtain a solid curved line. Mouse buttons have no effect in this
example.

#include <GL/glut.h>

GLsizei winWidth = 400, winHeight = 300; // Initial display-window size.

void init (void)


{
glClearColor (0.0, 0.0, 1.0, 1.0); // Set display-window color to blue.

glMatrixMode (GL_PROJECTION);
gluOrtho2D (0.0, 200.0, 0.0, 150.0);
}

void displayFcn (void)


{
glClear (GL_COLOR_BUFFER_BIT); // Clear display window.

glColor3f (1.0, 0.0, 0.0); // Set point color to red.


glPointSize (3.0); // Set point size to 3.0.
}

605
Interactive Input Methods and Graphical User Interfaces

void winReshapeFcn (GLint newWidth, GLint newHeight)


{
/* Reset viewport and projection parameters */
glViewport (0, 0, newWidth, newHeight);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ( );
gluOrtho2D (0.0, GLdouble (newWidth), 0.0, GLdouble (newHeight));

/* Reset display-window size parameters. */


winWidth = newWidth;
winHeight = newHeight;
}

void plotPoint (GLint x, GLint y)


{
glBegin (GL_POINTS);
glVertex2i (x, y);
glEnd ( );
}

/* Move cursor while pressing c key enables freehand curve drawing. */


void curveDrawing (GLubyte curvePlotKey, GLint xMouse, GLint yMouse)
{
GLint x = xMouse;
GLint y = winHeight - yMouse;
switch (curvePlotKey)
{
case 'c':
plotPoint (x, y);
break;
default:
break;
}
glFlush ( );
}

void main (int argc, char** argv)


{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition (100, 100);
glutInitWindowSize (winWidth, winHeight);
glutCreateWindow ("Keyboard Curve-Drawing Example");

init ( );
glutDisplayFunc (displayFcn);
glutReshapeFunc (winReshapeFcn);
glutKeyboardFunc (curveDrawing);

glutMainLoop ( );
}

606
Interactive Input Methods and Graphical User Interfaces

For function keys, arrow keys, and other special-purpose keys, we can use
the command

glutSpecialFunc (specialKeyFcn);

The specified procedure has the same three arguments:

void specialKeyFcn (GLint specialKey, GLint xMouse,


GLint yMouse)

but now parameter specialKey is assigned an integer-valued GLUT symbolic


constant. To select a function key, we use one of the constants GLUT KEY F1
through GLUT KEY F12. For the arrow keys, we use constants such as
GLUT KEY UP and GLUT KEY RIGHT. Other keys can be designated using
GLUT KEY PAGE DOWN, GLUT KEY HOME, and similar constants for the page
up, end, and insert keys. The backspace, delete, and escape keys can be designated
with the glutKeyboardFunc routine using their ASCII codes, which are 8, 127,
and 27, respectively.
An interactive program using the mouse, keyboard, and function keys is
demonstrated in the following code. Mouse input is used to select a location for
the lower-left corner of a red square. Keyboard input is used to scale the size of
the square, and a new square is obtained with each click of the left mouse button.

#include <GL/glut.h>
#inclue <stdlib.h>

GLsizei winWidth = 400, winHeight = 300; // Initial display-window size.


GLint edgeLength = 10; // Initial edge length for square.

void init (void)


{
glClearColor (0.0, 0.0, 1.0, 1.0) // Set display-window color to blue.

glMatrixMode (GL_PROJECTION);
gluOrtho2D (0.0, 200.0, 0.0, 150.0);
}

void displayFcn (void)


{
glClear (GL_COLOR_BUFFER_BIT); // Clear display window.

glColor3f (1.0, 0.0, 0.0); // Set fill color to red.


}

void winReshapeFcn (GLint newWidth, GLint newHeight)


{
/* Reset viewport and projection parameters */
glViewport (0, 0, newWidth, newHeight);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ( );
gluOrtho2D (0.0, GLdouble (newWidth), 0.0, GLdouble (newHeight));

607
Interactive Input Methods and Graphical User Interfaces

case GLUT_KEY_F3:
edgeLength /= 4;
break;
default:
break;
}
}

void main (int argc, char** argv)


{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition (100, 100);
glutInitWindowSize (winWidth, winHeight);
glutCreateWindow ("Display Squares of Various Sizes");

init ( );
glutDisplayFunc (displayFcn);
glutReshapeFunc (winReshapeFcn);
glutMouseFunc (fillSquare);
glutKeyboardFunc (enlargeSquare);
glutSpecialFunc (reduceSquare);

glutMainLoop ( );
}

GLUT Tablet Functions


Usually, tablet activation occurs only when the mouse cursor is in the display
window. A button event for tablet input is then recorded with

glutTabletButtonFunc (tabletFcn);

and the arguments for the invoked function are similar to those for a mouse:

void tabletFcn (GLint tabletButton, GLint action,


GLint xTablet, GLint yTablet)

We designate a tablet button with an integer identifier such as 1, 2, 3, and so on,


and the button action is again specified with either GLUT UP or GLUT DOWN.
The returned values xTablet and yTablet are the tablet coordinates. We can
determine the number of available tablet buttons with the command

glutDeviceGet (GLUT_NUM_TABLET_BUTTONS);

Motion of a tablet stylus or cursor is processed with the following function:

glutTabletMotionFunc (tabletMotionFcn);

where the invoked function has the form

void tabletMotionFcn (GLint xTablet, GLint yTablet)

The returned values xTablet and yTablet give the coordinates on the tablet
surface.

609
Interactive Input Methods and Graphical User Interfaces

GLUT Spaceball Functions


We use the following function to specify an operation when a spaceball button is
activated for a selected display window:
glutSpaceballButtonFunc (spaceballFcn);

The callback function has two parameters:


void spaceballFcn (GLint spaceballButton, GLint action)

Spaceball buttons are identified with the same integer values as a tablet, and
parameter action is assigned either the value GLUT UP or the value
GLUT DOWN. We can determine the number of available spaceball buttons with a
call to glutDeviceGet using the argument GLUT NUM SPACEBALL BUTTONS.
Translational motion of a spaceball, when the mouse is in the display window,
is recorded with the function call
glutSpaceballMotionFunc (spaceballTranlFcn);

The three-dimensional translation distances are passed to the invoked function


as, for example:
void spaceballTranslFcn (GLint tx, GLint ty, GLint tz)

These translation distances are normalized within the range from −1000 to 1000.
Similarly, a spaceball rotation is recorded with
glutSpaceballRotateFunc (spaceballRotFcn);

The three-dimensional rotation angles are then available to the callback


function, as follows:
void spaceballRotFcn (GLint thetaX, GLint thetaY, GLint thetaZ)

GLUT Button-Box Function


Input from a button box is obtained with the following statement:
glutButtonBoxFunc (buttonBoxFcn);

Button activation is then passed to the invoked function:


void buttonBoxFcn (GLint button, GLint action);

The buttons are identified with integer values, and the button action is specified
as GLUT UP or GLUT DOWN.

GLUT Dials Function


A dial rotation can be recorded with the following routine:
glutDialsFunc (dialsFcn);

In this case, we use the callback function to identify the dial and obtain the angular
amount of rotation:
void dialsFcn (GLint dial, GLint degreeValue);

Dials are designated with integer values, and the dial rotation is returned as an
integer degree value.

610
Interactive Input Methods and Graphical User Interfaces

OpenGL Picking Operations


In an OpenGL program, we can interactively select objects by pointing to screen
positions. However, the picking operations in OpenGL are not straightforward.
Basically, we perform picking using a designated pick window to form a
revised view volume. We assign integer identifiers to objects in a scene, and the
identifiers for those objects that intersect the revised view volume are stored in a
pick-buffer array. Thus, to use the OpenGL pick features, we need to incorporate
the following procedures into a program:
• Create and display a scene.
• Pick a screen position and, within the mouse callback function, do the
following:
• Set up a pick buffer.
• Activate the picking operations (selection mode).
• Initialize an ID name stack for object identifiers.
• Save the current viewing and geometric-transformation matrix.
• Specify a pick window for the mouse input.
• Assign identifiers to objects and reprocess the scene using the revised
view volume. (Pick information is then stored in the pick buffer.)
• Restore the original viewing and geometric-transformation matrix.
• Determine the number of objects that have been picked, and return to
the normal rendering mode.
• Process the pick information.
We can also use a modification of these procedures to select objects without
interactive input from a mouse. This is accomplished by specifying the vertices
for the revised view volume, instead of designating a pick window.
A pick-buffer array is set up with the command

glSelectBuffer (pickBuffSize, pickBuffer);

Parameter pickBuffer designates an integer array with pickBuffSize


elements. The glSelectBuffer function must be invoked before the OpenGL
picking operations (selection mode) are activated. An integer information record
is stored in pick-buffer array for each object that is selected with a single pick
input. Several records of information can be stored in the pick buffer, depending
on the size and location of the pick window. Each record in the pick buffer contains
the following information:
1. The stack position of the object, which is the number of identifiers in the
name stack, up to and including the position of the picked object.
2. The minimum depth of the picked object.
3. The maximum depth of the picked object.
4. The list of the identifiers in the name stack from the first (bottom) identifier
to the identifier for the picked object.
The integer depth values stored in the pick buffer are the original values in the
range from 0 to 1.0, multiplied by 232 − 1.
The OpenGL picking operations are activated with

glRenderMode (GL_SELECT);

611
Interactive Input Methods and Graphical User Interfaces

This places us in selection mode, which means that a scene is processed through
the viewing pipeline but not stored in the frame buffer. A record of information
for each object that would have been displayed in the normal rendering mode is
placed in the pick buffer. In addition, this command returns the number of picked
objects, which is equal to the number of information records in the pick buffer. To
return to the normal rendering mode (the default), we invoke the glRenderMode
routine using the argument GL RENDER. A third option is the argument
GL FEEDBACK, which stores object coordinates and other information in a feed-
back buffer without displaying the objects. Feedback mode is used to obtain
information about primitive types, attributes, and other parameters associated
with the objects in a scene.
We use the following statement to activate the integer-ID name stack for the
picking operations:

glInitNames ( );

The ID stack is initially empty, and this stack can be used only in selection mode.
To place an unsigned integer value on the stack, we can invoke the following
function:

glPushName (ID);

This places the value for parameter ID on the top of the stack and pushes the
previous top name down to the next position in the stack. We can also simply
replace the top of the stack using

glLoadName (ID);

but we cannot use this command to place a value on an empty stack. To eliminate
the top of the ID stack, we issue the command

glPopName ( );

A pick window within a selected viewport is defined using the following


GLU function:

gluPickMatrix (xPick, yPick, widthPick, heightPick, vpArray);

Parameters xPick and yPick give the double-precision, screen-coordinate


location for the center of the pick window relative to the lower-left corner of
the viewport. When these coordinates are given with mouse input, the mouse
coordinates are relative to the upper-left corner, and thus we need to invert the
input yMouse value. The double-precision values for the width and height of
the pick window are specified with parameters widthPick and heightPick.
Parameter vpArray designates an integer array containing the coordinate posi-
tion and size parameters for the current viewport. We can obtain the viewport
parameters using the glGetIntegerv function. This pick window is then used
as a clipping window to construct a revised view volume for the viewing trans-
formations. Information for objects that intersect this revised view volume is
placed in the pick buffer.
We illustrate the OpenGL picking operations in the following program, which
displays three color rectangles with the colors red, blue, and green. For this picking
example, we use a 5 × 5 pick window, and the center of the pick window is given

612
Interactive Input Methods and Graphical User Interfaces

EXAMPLE 1 Sample Output from Procedure pickrects.

Number of objects picked = 2

Stack position = 1
Min depth = 0, Max depth = 0
Stack IDs are:
30

Stack position = 3
Min depth = 0, Max depth = 0
Stack IDs are:
30 10 20

7 OpenGL Menu Functions


In addition to the input-device routines, GLUT contains various functions for
adding simple pop-up menus to programs. With these functions, we can set up and
access a variety of menus and associated submenus. The GLUT menu commands
are placed in procedure main along with the other GLUT functions.

Creating a GLUT Menu


A pop-up menu is created with the statement

glutCreateMenu (menuFcn);

where parameter menuFcn is the name of a procedure that is to be invoked when


a menu entry is selected. This procedure has one argument, which is the integer
value corresponding to the position of a selected option.

void menuFcn (GLint menuItemNumber)

The integer value passed to parameter menuItemNumber is then used by


menuFcn to perform an operation. When a menu is created, it is associated with
the current display window.
Once we have designated the menu function that is to be invoked when a
menu item is selected, we must specify the options that are to be listed in the
menu. We do this with a series of statements that list the name and position for
each option. These statements have the general form

glutAddMenuEntry (charString, menuItemNumber);

Parameter charString specifies text that is to be displayed in the menu, and


parameter menuItemNumber gives the location for that entry in the menu. For
example, the following statements create a menu with two options:

glutCreateMenu (menuFcn);
glutAddMenuEntry ("First Menu Item", 1);
glutAddMenuEntry ("Second Menu Item", 2);

Next, we must specify a mouse button that is to be used to select a menu


option. This is accomplished with

glutAttachMenu (button);

616
Interactive Input Methods and Graphical User Interfaces

where parameter button is assigned one of the three GLUT symbolic constants
referencing the left, middle, or right mouse button.
To illustrate the creation and use of a GLUT menu, the following program
provides two options for displaying the interior fill of a triangle. Initially, the
triangle is defined with two white vertices, one red vertex, and a fill color
determined by an interpolation of the vertex colors. We use the glShadeModel
function to select a polygon fill that is either a solid color or an interpolation
(Gouraud rendering) of the vertex colors. A menu is created in this program that
allows us to choose between these two options using the right mouse button,
when the mouse cursor is inside the display window. This pop-up menu is dis-
played with the upper-left corner at the position of the mouse cursor. A menu
option is highlighted when we move the mouse cursor over that option. The
highlighted option is then selected by releasing the right button. If the
option “Solid-Color Fill” is selected, the triangle is filled with the color specified for
the last vertex (which is red). At the end of the menu-display procedure,
fillOption, we include a glutPostRedisplay command to indicate that
the triangle should be redrawn when the menu is displayed.

#include <GL/glut.h>

GLsizei winWidth = 400, winHeight = 400; // Initial display-window size.

GLfloat red = 1.0, green = 1.0, blue = 1.0; // Initial triangle color: white.
GLenum fillMode = GL_SMOOTH; // Initial polygon fill: color interpolation.

void init (void)


{
glClearColor (0.6, 0.6, 0.6, 1.0); // Set display-window color to gray.

glMatrixMode (GL_PROJECTION);
gluOrtho2D (0.0, 300.0, 0.0, 300.0);
}

void fillOption (GLint selectedOption)


{
switch (selectedOption) {
case 1: fillMode = GL_FLAT; break; // Flat surface rendering.
case 2: fillMode = GL_SMOOTH; break; // Gouraud rendering.
}
glutPostRedisplay ( );
}

void displayTriangle (void)


{
glClear (GL_COLOR_BUFFER_BIT);

glShadeModel (fillMode); // Set fill method for triangle.


glColor3f (red, green, blue); // Set color for first two vertices.

glBegin (GL_TRIANGLES);
glVertex2i (280, 20);
glVertex2i (160, 280);

617
Interactive Input Methods and Graphical User Interfaces

glColor3f (red, 0.0, 0.0); // Set color of last vertex to red.


glVertex2i (20, 100);
glEnd ( );

glFlush ( );
}

void reshapeFcn (GLint newWidth, GLint newHeight)


{
glViewport (0, 0, newWidth, newHeight);

glMatrixMode (GL_PROJECTION);
glLoadIdentity ( );
gluOrtho2D (0.0, GLfloat (newWidth), 0.0, GLfloat (newHeight));
displayTriangle ( );
glFlush ( );
}

void main (int argc, char **argv)


{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition (200, 200);
glutInitWindowSize (winWidth, winHeight);
glutCreateWindow ("Menu Example");

init ( );
glutDisplayFunc (displayTriangle);

glutCreateMenu (fillOption); // Create pop-up menu.


glutAddMenuEntry ("Solid-Color Fill", 1);
glutAddMenuEntry ("Color-Interpolation Fill", 2);

/* Select a menu option using the right mouse button. */


glutAttachMenu (GLUT_RIGHT_BUTTON);

glutReshapeFunc (reshapeFcn);

glutMainLoop ( );
}

Creating and Managing Multiple GLUT Menus


When a menu is created, it is associated with the current display window.
We can create multiple menus for a single display window, and we can create
different menus for different windows. As each menu is created, it is assigned
an integer identifier, starting with the value 1 for the first menu created. The
integer identifier for a menu is returned by the glutCreateMenu routine, and
we can record this value with a statement such as

menuID = glutCreateMenu (menuFcn);

618
Interactive Input Methods and Graphical User Interfaces

A newly created menu becomes the current menu for the current dis-
play window. To activate a menu for the current display window, we use the
statement

glutSetMenu (menuID);

This menu then becomes the current menu, which will pop up in the display
window when the mouse button that has been attached to that menu is pressed.
We eliminate a menu with the command

glutDestroyMenu (menuID);

If the designated menu is the current menu for a display window, then that
window has no menu assigned as the current menu, even though other menus
may exist.
The following function is used to obtain the identifier for the current menu
in the current display window:

currentMenuID = glutGetMenu ( );

A value of 0 is returned if no menus exist for this display window or if the previous
current menu was eliminated with the glutDestroyMenu function.

Creating GLUT Submenus


A submenu can be associated with a menu by first creating the submenu using
glutCreateMenu, along with a list of suboptions, and then listing the submenu
as an additional option in the main menu. We can add the submenu to the option
list in a main menu (or other submenu) using a sequence of statements such as

submenuID = glutCreateMenu (submenuFcn);


glutAddMenuEntry ("First Submenu Item", 1);
.
.
.
glutCreateMenu (menuFcn);
glutAddMenuEntry ("First Menu Item", 1);
.
.
.
glutAddSubMenu ("Submenu Option", submenuID);

The glutAddSubMenu function can also be used to add the submenu to the
current menu.
In the following program, we illustrate the creation of a submenu. This
program, which is a modification of the previous menu program, displays
a submenu that provides three color choices (blue, green, and white) for
the first two vertices of the triangle. The main menu is now listed with three
options, and the third option is displayed with an arrow symbol to indicate
that a pop-up submenu will be displayed when that option is highlighted. A
glutPostRedisplay function is included at the end of both the main-menu
function and the submenu function.

619
Interactive Input Methods and Graphical User Interfaces

void reshapeFcn (GLint newWidth, GLint newHeight)


{
glViewport (0, 0, newWidth, newHeight);

glMatrixMode (GL_PROJECTION);
glLoadIdentity ( );
gluOrtho2D (0.0, GLfloat (newWidth), 0.0, GLfloat (newHeight));

displayTriangle ( );
glFlush ( );
}

void main (int argc, char **argv)


{
GLint subMenu; // Identifier for submenu.

glutInit (&argc, argv);


glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition (200, 200);
glutInitWindowSize (winWidth, winHeight);
glutCreateWindow ("Submenu Example");

init ( );
glutDisplayFunc (displayTriangle);

subMenu = glutCreateMenu (colorSubMenu);


glutAddMenuEntry ("Blue", 1);
glutAddMenuEntry ("Green", 2);
glutAddMenuEntry ("White", 3);

glutCreateMenu (mainMenu); // Create main pop-up menu.


glutAddMenuEntry ("Solid-Color Fill", 1);
glutAddMenuEntry ("Color-Interpolation Fill", 2);
glutAddSubMenu ("Color", subMenu);

/* Select menu option using right mouse button. */


glutAttachMenu (GLUT_RIGHT_BUTTON);

glutReshapeFunc (reshapeFcn);

glutMainLoop ( );
}

Modifying GLUT Menus


If we want to change the mouse button that is used to select a menu option, we first
cancel the current button attachment and then attach the new button. A button
attachment is cancelled for the current menu with

glutDetachMenu (mouseButton);

where parameter mouseButton is assigned the GLUT constant identifying the


button (left, middle, or right) that was previously attached to the menu. Once we

621
Interactive Input Methods and Graphical User Interfaces

have detached the menu from the button, we can use glutAttachMenu to attach
it to a different button.
Options within an existing menu can also be changed. For example, we can
delete an option in the current menu with the function

glutRemoveMenuItem (itemNumber);

where parameter itemNumber is assigned the integer value of the menu option
that is to be deleted.
Other GLUT routines allow us to modify the names or status of items within
an existing menu. For example, we can use these routines to change the displayed
name of a menu option, to change the item number of the option, or to change an
option into a submenu.

8 Designing a Graphical User Interface


A common feature of modern applications software is a graphical user interface
(GUI) composed of display windows, icons, menus, and other features to aid a user
in applying the software to a particular problem. Specialized interactive dialogues
are designed so that programming options are selected using familiar terms within
a particular field, such as architectural and engineering design, drafting, business
graphics, geology, economics, chemistry, or physics. Other considerations for a
user interface (whether graphical or not) are the accommodation of various skill
levels, consistency, error handling, and feedback.

The User Dialogue


For any application, the user’s model serves as the basis for the design of the
dialogue by describing what the system is designed to accomplish and what
operations are available. It states the type of objects that can be displayed and
how the objects can be manipulated. For example, if the system is to be used as a
tool for architectural design, the model describes how the package can be used to
construct and display views of buildings by positioning walls, doors, windows,
and other building components. A facility-layout package might include a set of
furniture items along with the operations for positioning and removing different
objects in a specified floor plan. A circuit-design program provides electrical or
logic symbols and the positioning operations for adding or deleting elements
within a layout.
All information in the user dialogue is presented in the language of the appli-
cation. In an architectural design package, this means that all interactions are
described only in architectural terms, without reference to particular data struc-
tures, computer-graphics terms, or other concepts that may be unfamiliar to an
architect.

Windows and Icons


Typical GUIs provide visual representations both for the objects that are to be
manipulated in an application and for the actions to be performed on the appli-
cation objects.
In addition to the standard display-window operations, such as opening, clos-
ing, positioning, and resizing, other operations are needed for working with the
sliders, buttons, icons, and menus. Some systems are capable of supporting mul-
tiple window managers so that different window styles can be accommodated,

622
Interactive Input Methods and Graphical User Interfaces

T A B L E 1
Summary of OpenGL Input Functions

Function Description

glutMouseFunc Specifies a mouse callback function that is to


be invoked when a mouse button is pressed.
glutMotionFunc Specifies a mouse callback function that
is to be invoked when the mouse cursor
is moved while a button is pressed.

glutPassiveMotionFunc Specifies a mouse callback function that


is to be invoked when the mouse cursor is
moved without pressing a button.
glutKeyboardFunc Specifies a keyboard callback function that is
to be invoked when a standard key is
pressed.

glutSpecialFunc Specifies a keyboard callback function that is


to be invoked when a special-purpose key
(e.g., a function key) is pressed.
glutTabletButtonFunc Specifies a tablet callback function that
is to be invoked when a tablet button
is pressed while the mouse cursor is in
a display window.

glutTabletMotionFunc Specifies a tablet callback function that


is to be invoked when a tablet stylus or
cursor is moved while the mouse cursor is
in a display window.

glutSpaceballButtonFunc Specifies a spaceball callback function


that is to be invoked when a spaceball
button is pressed while the mouse cursor
is in a display window, or using another
display-window activation method.
glutSpaceballMotionFunc Specifies a spaceball callback function
that is to be invoked when a spaceball
translational motion occurs for an activated
display window.
glutSpaceballRotateFunc Specifies a spaceball callback function that
is to be invoked when a spaceball
rotational motion occurs for an activated
display window.
glutButtonBoxFunc Specifies a button-box callback function that
is to be invoked when a button is pressed.
glutDialsFunc Specifies a dial callback function that is
to be invoked when a dial is rotated.

626
Interactive Input Methods and Graphical User Interfaces

T A B L E 1
(Continued)

Function Description

glSelectBuffer Specifies size and name for the pick buffer.


glRenderMode Activates pick operations using the
argument GL SELECT. This function is
also used to activate the normal rendering
mode or the feedback mode.
glInitNames Activates the object-ID name stack.
glPushName Pushes an object identifier onto the ID stack.

glLoadName Replaces the top identifier on the ID stack


with a specified value.
glPopName Eliminates the top item on the ID stack.

gluPickMatrix Defines a pick window and forms a revised


view volume for the picking operations.

T A B L E 2
Summary of OpenGL Menu Functions

Function Description

glutCreateMenu Creates a pop-up menu and specifies a procedure that is


to be invoked when a menu item is selected; an
integer identifier is assigned to the created menu.

glutAddMenuEntry Specifies an option that is to be listed in a pop-up menu.


glutAttachMenu Specifies the mouse button that is to used for selecting
menu options.
glutSetMenu Specifies the current menu for the current display window.

glutDestroyMenu Specifies an identifier for a menu that is to be eliminated.

glutGetMenu Returns the identifier for the current menu attached to


the current window.

glutAddSubMenu Specifies a submenu that is to be included in a menu


listing, where the indicated submenu has been set up
using the glutCreateMenu routine.

glutDetachMenu Cancels a specified mouse-button attachment for the


current menu.

glutRemoveMenuItem Deletes a specified option in the current menu.

627

You might also like