CS 381
>
Week 2 Review Problems
CS 381, Fall 2003
Week 2 Review Problems
Below are some problems related to the material covered
in class recently.
Answers are in the
Answers section, below.
Do not turn these in.
We may certainly discuss any of these problems in class,
if you want.
You can expect Test 1 (on Friday, October 3)
to contain problems similar to some of these.
Problems
- Why is it generally convenient to implement a GLUT
keyboard function as a single, large switch statement?
- What is the primary use of the GLUT idle function?
- Suppose we are writing a GLUT program in C++.
We have already written and registered display and keyboard functions;
the keyboard function is implemented with a switch,
as recommended in class.
We wish to add a feature to the program:
When the user presses the “s” key,
the program should switch between drawing a square and drawing a pentagon.
Describe the code we will need to add to the program.
(You do not need to give the details of drawing the square and the pentagon; you do need to follow THE RULES.)
- What are two reasons why calling glutPostRedisplay in an event-handling callback
is better than calling the display function directly?
(Yes, doing the latter breaks The Rules, and will lower your homework grade.
Now give two more reasons.)
- What issue is a key tipoff that GLUT might not be intended for production-quality code?
(Hint: How do we tell the display function that the scene has changed?)
- We have seen how to pass x- and y-coordinates of a vertex
to OpenGL.
But in 3-D CG, we need to pass the z-coordinate as well.
How is this done?
- List three major issues that come up in 3-D CG, but which are either absent or much simpler
in 2-D CG.
- Briefly describe OpenGL’s built-in hidden-surface removal method.
(Do not tell me how to use it; tell me what it does.)
- Suppose we are writing an OpenGL/GLUT program, and we want to use OpenGL’s built-in
depth buffering to do hidden-surface removal.
How do we add this to the program?
- a. What is “double buffering”? b. What is double buffering good for?
c. What is one possible disadvantage of double buffering?
- Concisely describe how to convert a (properly written) singly-buffered GLUT program
into one that uses double buffering.
- What does “GUI” stand for?
- What assumptions are made by most modern GUI’s concerning available input devices?
- a. What is a “client-server” relationship?
b. Give an example of a common client-server relationship (not a CG example).
- a. How is OpenGL built around a client-server relationship?
b. Give one way in which this idea influenced the design of OpenGL.
- In what situation might the connection between application program
and graphics hardware be very slow?
- In the context of this course, what are “events”?
Answers
- We generally implement the GLUT keyboard function as a
switch with many cases, since such a function is given one primary parameter,
the ASCII value of the key that was pressed,
and we may do very different things depending on the value of this parameter.
This is what switch’s are for: testing a single parameter and performing
different, possibly unrelated actions depending on its value.
- The GLUT idle function is primarily used for making programs change in some
automatic way.
For example, the idle function may be used to advance to the next frame in
an animated sequence.
Note: Error checking is not the primary use of the idle function;
that is just something I like to stick in my programs.
- We will need to write the following:
- Declare and initialize a global variable of type bool to hold the current square/pentagon state.
(I will call the variable drawpent; false means draw a square, true means draw a pentagon.)
Something like this:
bool drawpent = false; // true: show pentagon in window, false: show square
- Add the following to the display function:
if (drawpent) // show pentagon
[Code to draw a pentagon goes here]
else // show square
[Code to draw a square goes here]
- Add the following to the switch in the keyboard function:
case 's':
case 'S': // upper & lower case are different!!
drawpent = !drawpent; // toggle shape
glutPostRedisplay(); // no drawing in kbd func, so tell GLUT to display
break;
- Calling glutPostRedisplay
is better than calling the display function directly because:
- It avoids multiple window redraws when only one would be enough.
- It improves and clarifies program organization.
(For example, when the display function begins,
you know that there is no other callback function that is in the middle of executing.)
- One rather problematic aspect of GLUT is that callbacks have fixed parameter lists.
Thus, any extra information must be passed in through global variables.
The resulting proliferation of globals tends to make GLUT
flow-of-control management inappropriate for large projects.
- We pass a 3-D vertex to OpenGL by using one of the 3-parameter (or more)
versions of the glVertex* command.
For example, glVertex3d.
- The three major issues that make 3-D CG trickier than 2-D CG are:
- Viewing and transformations: We generally allow ourselves to view a scene from any point within it, using perspective,
and we can rotate objects about any line.
- Hidden-surface removal: We need to be sure that opaque objects hide the things behind them
(and that transparency, if it is present, is handled as well).
- Lighting: We need to make objects look like they are lit.
- Built into OpenGL is a hidden-surface technique called “depth buffering”.
OpenGL allows the user to allocate a depth buffer, which is a 2-D array of data, one
piece for each pixel in the viewport, just like the color buffer, except that, instead of
holding color information, the buffer holds depth information.
The idea is that the “depth” for each pixel would be the distance from the viewer
of the closest thing drawn there so far.
Then, for each fragment, we perform the depth test: see if the fragment is closer than
the current depth. If so, the depth test passes,
and we put the fragment’s color in the color buffer and its depth in the depth buffer.
Otherwise, the depth test fails, and we toss out the fragment.
- To add OpenGL depth buffering to an OpenGL/GLUT program:
- Allocate a depth buffer by adding GLUT_DEPTH to the glutInitDisplayMode call.
- Clear the depth buffer by adding GL_DEPTH_BUFFER_BIT to the glClear call (where appropriate).
- Somewhere (probably in the initialization), enable the depth test by doing “glEnable(GL_DEPTH_TEST);”.
- Double buffering means allocating two frame buffers (in OpenGL-speak “color buffers”),
the front buffer and the back buffer.
We then render in the back buffer, which is invisible to the user, and then swap the buffers
when a frame is complete.
- Double buffering is good for producing smooth animation.
Since the user only sees completed frames, flickering is reduced or eliminated.
- Here are two possible disadvantages.
- Double buffering will sometimes slow down the program.
- If double buffering is done, the user cannot see frames being built.
Of course, this is usually a Good Thing, but if you want the user to see
the frame being built, then it is a disadvantage.
- To convert a singly buffered GLUT program to use double buffering:
- Change “GLUT_SINGLE” to “GLUT_DOUBLE” in the call to glutInitDisplayMode.
- Put “glutSwapBuffers();” at the end of the display function, replacing any glFlush
or glFinish call.
- GUI = Graphical User Interface.
- Most modern GUI’s assume the availability of a full-ASCII keyboard and a pointing device
(mouse, pen, trackball, etc.).
Notable exceptions are palm-top computers, which often do not have keyboards.
GUI’s also assume that output is immediately available to the user,
who can react and give input after very little delay
(interactivity).
- A client-server relationship is a relationship between
something (a computer, a program, etc.) that requires services (the client)
and the thing that provides the services (the server).
In typical situations, the client and server can process data independently
and are often joined by a relatively slow communications channel (for example, a network).
- One example of a client-server relationship is a web browser (client)
requesting web pages from a web server (server). (Many answers are possible.)
- OpenGL assumes a client-server relationship between the application program and the
graphics hardware (or low-level software).
- Here are two ways this client-server idea influenced the design of OpenGL:
- The glFlush and glFinish commands allow the application
program to manage the data flow between client and server;
they are very appropriate in the case that there is a slow, buffered connection
between the two.
- Call lists (or display lists) allow sequences of OpenGL commands to
be loaded on the server for repeated execution without being sent again and again from
the client.
- The connection between the application program and the graphics hardware
might be extremely slow if the two reside on different machines,
joined by a slow network.
As noted in class, this is not too common these days.
But in the past, when Unix-based systems were more common (at Universities anyway)
and security was less stringent,
it was not unusual at all to run a program on one machine and have its display occur on another.
- Events are a mechanism for dealing with input devices.
Events are generated when an action that generates input is performed by the user.
Examples of such events are: keypress, mouse-down, mouse-up.
The event mechanism has been generalized to handle non-user-based input devices
(network packet reception, etc.),
and windowing-related events (window moved to front, redisplay needed, etc.).
CS 381, Fall 2003: Week 2 Review Problems /
Last update: 25 Sep 2002 /
Glenn G. Chappell /
ffggc@uaf.edu