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

Module 2 ppt

This document discusses the use of display lists in interactive graphics, explaining how they improve performance by offloading tasks to a display processor or graphics server. It covers the differences between immediate mode and retained mode for sending graphical entities, as well as how to handle text and keyboard events in graphical applications using GLUT. Additionally, it outlines window management, event handling, and the creation of pop-up menus for user interaction.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Module 2 ppt

This document discusses the use of display lists in interactive graphics, explaining how they improve performance by offloading tasks to a display processor or graphics server. It covers the differences between immediate mode and retained mode for sending graphical entities, as well as how to handle text and keyboard events in graphical applications using GLUT. Additionally, it outlines window management, event handling, and the creation of pop-up menus for user interaction.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

Module 2

Chapter 3
INPUT AND INTERACTION
3.4 Display List
• Display lists illustrate how we can use clients and servers on a network to
improve interactive graphics performance.
• A special-purpose computer, called a display processor, with an organization
like that illustrated in Figure 3.13.
• The user program was processed in the host computer, resulting in a compiled
list of instructions that was then sent to the display processor, where the
instructions were stored in a display memory as a display file, or display list.
• For a simple noninteractive application, once the display list was sent to the
display processor, the host was free for other tasks, and the display processor
would execute its display list repeatedly at a rate sufficient to avoid flicker.
• The display processor of old has become a graphics
server, and the application program on the host computer
has become a client.
• The display list is stored in the server and redisplayed by a
simple function call issued from the client to the server.
• We can send graphical entities to a display in one of two
ways.
• Immediate Mode
• Retain Mode
• We can send the complete description of our objects to
the graphics server.
Immediate Mode
• As soon as the program executes a statement that defines a
primitive, that primitive is sent to the server for possible display
and no memory of it is retained in the system.
• To redisplay the primitive after a clearing of the screen, or in a
new position after an interaction, the program must specify the
primitive and then must resend the information through the
display process.
Retained-mode
• We define the object once, and then put its description in a
display list.
• The display list is stored in the server and redisplayed by a simple
function call issued from the client to the server.
Disadvantages to the use of display lists.
• Display lists require memory on the server, and
there is the overhead of creating a display list.
• Although this overhead is often offset by the
efficiency of the execution of the display list, it
might not be if the data are changing.
3.4.1 Definition and Execution of Display Lists
• Display lists have much in common with ordinary files.
• Display lists are defined similarly to geometric primitives.
• There is a glNewList at the beginning and a glEndList at the end, with the
contents in between.
• For example, the following code defines a red box as an output.
• Each display list must have a unique identifier—an integer that is
usually macro defined in the C program by means of a #define
directive to an appropriate name for the object in the list.
• The flag GL_COMPILE tells the system to send the list to the server
but not to display its contents.
• If we want an immediate display of the contents while the list is
being constructed, we can use the GL_COMPILE_AND_EXECUTE
flag instead.
• Each time that we wish to draw the box on the server, we execute
the function as follows:
glCallList(BOX);
3.4.2 Text and Display Lists
• We introduced both stroke and raster text.
• Regardless of which type we choose to use, we need a reasonable amount of
code to describe a set of characters.
• For example, suppose that we use a raster font in which each character is
stored as an 8 × 13 pattern of bits.
• It takes 13 bytes to store each character.
• If we want to display a string by the most straightforward method, we can
send each character to the server each time that we want it displayed.
• This transfer requires the movement of at least 13 bytes per character.
• If we define a stroke font using only line segments, each character can require
a different number of lines.
• If we use filled polygons for characters, as shown in Figure 3.14, we see
that an “I” is fairly simple to define, but we may need many line segments
to get a sufficiently smooth “O.”
• On the average, we need many more than 13 bytes per character to
represent a stroke font.
• For applications that display large quantities of text, sending each character
to the display every time that it is needed can place a significant burden on
our graphics systems.
3.4.3 Fonts in GLUT
• Prefer to use an existing font rather than to define our own.
• GLUT provides a few raster and stroke fonts.
• We can access a single character from a monotype, or evenly spaced,
font by the following function call:

glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, int character)

• Each invocation of glutStrokeCharacter includes a translation to the


bottom right of the character’s box, to prepare for the next character.
• Scaling and translation affect the OpenGL state, so here we should be
careful to use glPushMatrix and glPopMatrix as necessary to prevent
undesirable positioning of objects defined later in the program.
• Raster and bitmap characters are produced in a similar manner.
• For example, a single 8 × 13 character is obtained using the following:

glutBitmapCharacter(GLUT_BITMAP_8_BY_13, int character)

• Positioning of bitmap characters is considerably simpler than the positioning of


stroke characters is because bitmap characters are drawn directly in the frame
buffer and are not subject to geometric transformations, whereas stroke
characters are.
• OpenGL keeps, within its state, a raster position.
• This position identifies where the next raster primitive will be placed; it can be
set using the glRasterPos*() function.
• The user program typically moves the raster position to the desired location
before the first character in a string defined by glutBitmapCharacter is invoked.
3.6 Programming Event-Driven Input
3.6.1 Using the Pointing Device
• Two types of events are associated with the pointing device, which is
conventionally assumed to be a mouse but could be a trackball or a data
tablet.
• A mouse event occurs when one of the mouse buttons is either pressed or
released.
• A button being held down does not generate a mouse event until the button
is released.
• We register the mouse callback function, usually in the main function, by
means of the GLUT function as follows:
glutMouseFunc(myMouse);
• The mouse callback must have the form
void myMouse(int button, int state, int x, int y)
and is written by the application programmer.
• Within the callback function, we define the actions that we want to take place
if the specified event occurs.
• For our simple example, we want the pressing of the left mouse button to
terminate the program. The required callback is the following single-line
function:

void myMouse(int button, int state, int x, int y)


{
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
exit(0);
}
• If any other mouse event—such as the pressing of one of the other buttons—
occurs, no response action will occur, because no action corresponding to these
events has been defined in the callback function.
3.6.2 Window Events
• Most window systems allow a user to resize the window interactively, usually by
using the mouse to drag a corner of the window to a new location.
• This event is an example of a window event.
• If the window size changes, we have to consider three questions:
1. Do we redraw all the objects that were in the window before it was resized?
2. What do we do if the aspect ratio of the new window is different from that of the old
window?
3. Do we change the sizes or attributes of new primitives if the size of the new window is
different from that of the old?
• There is no single answer to any of these questions.
• If we are displaying the image of a real-world scene, our
reshape function probably should make sure that no shape
distortions occur.
• The reshape event returns in its measure the height and
width of the new window.
• We use these values to create a new OpenGL clipping
window using gluOrtho2D, as well as a new viewport with
the same aspect ratio.
• Thus, we have the following callback
glutReshapeFunc(myReshape)
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);
glLoadIdentity();

/* adjust viewport and clear */


glViewport(0,0,w,h);
/* save new window size in global variables */
}
3.6.3 Keyboard Events
• We can also use the keyboard as an input device.
• Keyboard events are generated when the mouse is in the
window and one of the keys is pressed or released.
• The GLUT function glutKeyboardFunc is the callback for
events generated by pressing a key.
• When a keyboard event occurs, the ASCII code for the key
that generated the event and the location of the mouse are
returned.
• All the keyboard callbacks are registered in a single callback
function, such as the following:
glutKeyboardFunc(myKey);

• For example, if we wish to use the keyboard only to exit the


program, we can use the following callback function:
void myKey(unsigned char key, int x, int y)
{
if(key==’q’ || key == ’Q’)
exit(0);
}
3.6.4 The Display and Idle Callbacks
• This callback is specified in GLUT by the following function call:
glutDisplayFunc(myDisplay);
• It is invoked when GLUT determines that the window should be
redisplayed.
• One such situation occurs when the window is opened initially;
another happens after a resize event.
• Because we know that a display event will be generated when the
window is first opened, the display callback is a good place to put
the code that generates most noninteractive output.
• Consequently, interactive and animation programs will contain
many calls for the reexecution of the display function.
• Rather than call it directly, we use the GLUT function as follows:
glutPostRedisplay();
• Using this function, rather than invoking the display callback
directly, avoids extra or unnecessary screen drawings by setting
a flag inside GLUT’s main loop indicating that the display needs
to be redrawn.
• Thus, using glutPostRedisplay ensures that the display will be
drawn only once each time the program goes through the event
loop.
• The idle callback is invoked when there are no
other events. Its default is the null function
pointer.
• A typical use of the idle callback is to continue to
generate graphical primitives through a display
function while nothing else is happening.
glutIdleFunc(NULL);
3.6.5 Window Management
• GLUT also supports multiple windows and subwindows of a given window.
• We can open a second top-level window (with the label “second window”) as
follows:
id=glutCreateWindow("second window");
• The returned integer value allows us to select this window as the current
window into which objects will be rendered as follows:
glutSetWindow(id);
• We can make this window have properties different from those of other
windows by invoking the glutInitDisplayMode before glutCreateWindow.
3.7 Menus
• We could use our graphics primitives and our mouse
callbacks to construct various graphical input devices.
• GLUT provides one additional feature, pop-up menus,
that we can use with the mouse to create sophisticated
interactive applications.
• We must define the actions corresponding to each entry
in the menu.
• We must link the menu to a particular mouse button.
Finally, we must register a callback function for each
menu.
• We name the menu callback demo_ menu.
• The function calls to set up the menu and to link it to the right mouse
button should be placed in our main function.
• They are as follows:
glutCreateMenu(demo_menu);
glutAddMenuEntry("quit",1);
glutAddMenuEntry("increase square size", 2);
glutAddMenuEntry("decrease square size", 3);
glutAttachMenu(GLUT_RIGHT_BUTTON)
• The function glutCreateMenu registers the callback function
demo_menu.
• The second argument in each entry’s definition is the identifier passed
to the callback when the entry is selected.
• Hence, our callback function is as follows:
void demo_menu(int id)
{
switch(id)
{
case 1: exit(0);
break;
case 2: size=2* size;
break;
case 3: if(size > 1) size = size/2;
break;
}
}

You might also like