Chapter 3: Input and Interaction
Most interesting graphical systems provide for user input. The two standard input devices are a pointing device, usually implemented as a mouse, and a keyboard for input of ASCII characters. The author of the book posits two uses of such input devices: measure (I call it “data”) and trigger. The trigger device sends a signal to the computer and the measure device sends data, such as a string of characters, to the computer.
There a number of classes of devices worth a quick mention. These include:
String allows for
input of a string of characters
perhaps these characters are converted to numbers for later processing
Locator provides a position in logical coordinates to the graphical program
Pick returns the
identity of the o
Input devices work in two basic modes. In computer architecture, we refer to these modes as program-controlled input and interrupt-driven input.
corresponds to what the book calls request-mode
sample-mode input. The characteristic feature of these modes is that input is requested by a program in a standard manner, such as calls to standard input functions.
Interrupt-driven input corresponds to what the book calls event-mode input. In this mode, the program responds to external events, such as clicks of the mouse. A program written to respond to external events must have a mechanism for associating user-written methods with these events; i.e., what method should be invoked when a mouse button is clicked. The approach used by OpenGL is called callback functions. We shall say a lot more about callbacks when we discuss programming event-driven input.
Clients and Servers
The modern world of computer graphics is based on some sort of client-server model. The reality is that there may be a number of users displaying and editing graphical data stored on a single database server. Large systems are developed on the Microsoft three-tier model: client (display), middle (business rules), and server.
In this model, programs in the server layer are used only to store data. In a graphics system the stored data is used to “persist” the graphical information so that it can be saved between editing sessions. The business rule layer contains validity rules for the data. Consider a design of a ship. Some of the typical business rules would be:
1) Two independent pipes
may not be so close that their outer walls overlap.
2) If a pump is placed on a deck, there must be a minimum clearance between that
deck and the deck above to allow the pump to fit.
3) If a pump is placed
on a deck, the deck may not be removed without providing
another support for the pump. Just because we can draw a pump hanging in the
air with no supports does not make it possible in a real design.
In the three-tier model, software on the display (client) layer is used only to produce graphical images from the data as presented from the server layer and validated by the middle layer. The client software might often include simple edit checks on the user input to avoid sending spurious or erroneous data to the middle layer. For example, the client-layer software might specify a minimum distance for movement of a mouse before passing the mouse move to the middle layer. This benefits users with hand tremors.
We also shall mention display lists only in passing. The book describes a number of methods used to access the display lists directly. Our studies will not focus on these methods, so we just mention the concept. The origin of the display list is the desire to offload the task of displaying data from the computer that generates the data.
One essential feature of the display list is that it is not just a static picture but a set of descriptions from which number of pictures can be generated. In any industrial graphic system, we demand the ability to display the view from a number of directions. For example, we consider the following scene to be depicted graphically.
We have a cube 1 unit on
a side centered one the X-axis at
X = 1, Y = 0, and Z = 0.
We also have a sphere
with radius 0.7 centered on the
X-axis at X = 3, Y = 0, Z = 0.
The display list must contain all of this information. Any two-dimensional representation of this scene must necessarily lose some of the information required for a full three-dimensional rendering. For example, consider three possible views of this configuration.
As seen along the X axis, looking from the –X direction, the cube will obscure the sphere. In this view, all information about the sphere is lost. The main point here is that the display list must contain all the information required to generate any view.
Programming Event-Driven Input
The trick to developing event-driven software is the association of functions and procedures with the events so that the language run-time system can invoke the proper method whenever the event is detected. In the early days of Windows programming, this was done by a Message Loop, essentially a case statement inside a loop forever statement.
OpenGL uses a set of functions to associate user-written functions with events. In modern windowing systems, a display event is raised whenever a window opens or is resized. User code that is to display to that window must use a predefined GLUT function to associate its display code with the display event.
In our sample code, the
display function is
void display ()
To cause the code in
this function to be executed when a display event is raised, we use a standard
GLUT function to associate the display function with the event. Thus, the code
The specification of this function in the header GLUT.H is probably
Void glutDisplayFunc (void (*func) (void))
Where func is the name of a function taking no arguments that will be called whenever the OpenGL window must be redisplayed. Our function void display () fits the bill.
We associate a function
with the mouse by use of the function glutMouseFunc, called as
glutMouseFunc(mouse), where mouse is a user written function of the form
void mouse (int button, int state, int x, int y)
Keyboard input is
attached to the user program by the function glutKeyboardFunc, called as
glutKeyboardFunc(keyboard), where keyboard is a user written function of the form
void keyboard (unsigned char key, int x, int y)
The chapter has a number of other interesting topics, including animation. We close our discussion of the chapter with a mention of double buffering. In double buffering, we have two frame buffers, a front buffer (the one being displayed) and a back buffer (the one into which the program is drawing). This allows a continuous display while not showing the sometimes time-consuming construction of the view. A typical scenario involves two buffers, here called B1 and B2. Note the start up period. Nothing can be done until one buffer has been computed, in the first step of this example buffer B1 is being computed while buffer B2 remains empty. Then B1 is displayed and the program begins filling B2. At this point we have the true double buffering in effect.