Warning: Attempt to call OpenGL function prior to calling
glXMakeCurrent()
A1. Here's a checklist to follow. For this checklist, I will assume that you are logged on raptor13.stanford.edu from the machine jitter.stanford.edu, and you want to have your display shown on jitter.stanford.edu.
A2. You may not implement TETRIS for the first assignment: Implementing TETRIS has been an assignment for CS193D, a very popular Stanford class, and thus there is the possibility of encouraging honor code violations (code reuse for different classes).
A3. To avoid writing code to read/write GIF files, use the public domain PBMPLUS (NETPBM) image libraries for I/O. These are now available in
/usr/class/cs248/netpbm
We provide no support whatsoever for the NETPBM image libraries: we only copied them to the leland file system for your convenience (and to save you disk space).
Once the image is in memory, you can write the image directly to the framebuffer using the routines discussed on page 237ff of the openGL programming guide. You could also paste the image onto some geometry using the texture mapping facilities of openGL; see chapter 9.
A4.If you are in the directory that the games are installed in
(ie. /usr/class/cs248/assignments/assignment1
), then the current
directory ".
" is probably not in your path. You can either:
./asteroids
or
./spacewar
, or
set path = ($path
.)
. Then simply run either asteroids
or
spacewar
.
A5. Yes - even if it means that one of them does something simple or silly. For example, in the asteroids sample game, most of the controls are via the keyboard. The mouse is used to influence the motion of the asteroids.
A6. The auxilliary library won't do this. If you want to get objects
to move at a constant rate, regardless of the speed of the underlying
processor or the complexity of the scene you are drawing, then base the
motions of your objects on gettimeofday()
. See its man page for
details on how to use it.
A7. The auxilliary library has code in /usr/class/cs248/support/src/libaux/font_tk.c that will do vector, outline, and filled fonts. This means that you can manipulate these fonts with scales, rotations, translations, etc. But you have to look at the code yourself and figure it out. The shabby bitmap font provided in the CS248 documentation is for you to be able to show the score with ease, and is the only one for which we will provide support. But if you feel gutsy, by all means go for it.
glOrtho()
and
glViewport()
do?
A8. glOrtho(left, right, bottom, top, back, front)
define the clipping frustum. Let us ignore back and front right for this
assignment, since they refer to the Z value. By doing this call, first
you specify that anything outside of the rectangle defined by left, right,
bottom, and top is clipped because it is outside the drawing region.
Furthermore, you define a scale for your coordinate system.
If you have glOrtho(0, width, 0, height, -1, 1)
, then you are
saying that your drawing area goes from (0, 0)
to (width,
height)
. To get the point in the middle of your drawing area, you
should specify it with glVertex(w/2, h/2)
.
Let's say, however, that you specify glOrtho(-1, 1, -1, 1, -1,
1)
. This means that the left side of your drawing region
corresponds to -1, the right side of your drawing region corresponds to 1,
the bottom of your drawing region corresponds to -1, and the top of your
drawing region corresponds to 1. Now if you want a point in the middle of
your drawing area, you should specify it with glVertex(0,0)
.
glViewport(x, y, w, h)
specifies the area of the window that
the drawing region should be put into. It says that the bottom left
corner of the drawing region corresponds to the window's (x,
y)
pixel, and (w, h)
represent the number of pixels
the drawing region should go in each direction. So if you wanted your
drawing to go only into the bottom right quarter of your window, you would
call glViewport(winWidth/2, 0, winWidth/2, winHeight/2)
. But
typically, you want glViewport(0, 0, winWidth, winHeight)
in
order to cover the whole window.
glFlush()
and
glFinish()
? (a.k.a.: Why is my program so slow?)
A9. glFlush()
guarantees that all the GL calls
made up to that point will complete execution in a finite amount of
time after glFlush()
returns, but doesn't specify exactly
how soon after. glFinish()
guarantees that all GL calls
made up to that point will complete execution before
glFinish()
returns.
So why do you care? If inside your redraw function you draw and then
call glFlush()
, then GL can queue up any number of
drawing commands. What can happen is that your redraw function gets
called 100 times (via your idle fuction, which in turn is called
repeatedly when no events are pending), each time returning before the
drawing is complete. Thus, you have 100 frames that have been
submitted to GL, but not finished, and then you receive a
keyboard/mouse event. Once you process that event, you will probably
want to change your drawing. So you send the next frame, which is
frame 101, and you have to wait for GL to do 100 frames before you get
the frame resulting from your event. Hence, there is a big lag between
the occurence of an event and drawing of it.
To avoid this, you should use glFinish()
so that the
redraw function does not return until the drawing has finished.
A10. To simply play audio files from the command line, use playaiff, playaifc, or sfplay. To convert audio files between different formats, use sox. To play audio from your code, without using fork() and exec() to invoke one of the executables above, you have to suffer a bit...
None of the raptors running IRIX 5.2 have the digital media development environment dmedia installed on them; dmedia includes man pages, such as the ones above, libraries, include files, sample code, etc. that allow your code to play sound. Hence, incorporating audio in your code is virtually impossible if you are developping on a raptor running IRIX 5.2. By contrast, the new machines, as well as those raptors upgraded to IRIX 5.3, will have dmedia installed on them.
But even if you have access to a platform with dmedia, we still advise against putting time into adding audio to your game; instead, experiment more with the graphics. Finally, if you do decide to go ahead, type insight, and read part two of the IRIS Digital Media Programming Guide.
Nothing, really. C++ and OpenGL are fully compatible. However, pay attention to the following:
A12. This is not possible using the auxiliary library. Calling
auxKeyDownFunc()
repeatedly simply adds additional
handlers for that event. When that event occurs, all of the handlers
will get called. Attempting to disable the handler by calling
auxKeyDownFunc()
with a 0 or NULL second parameter will
cause a segmentation fault (it simply adds this 0 to the table, and
tries to call the function located at address 0).
A13. Use double buffering. Simply calling auxSwapBuffers()
is not enough to make your program use double buffering. You must also ensure
that you are calling auxInitDisplayMode()
with
AUX_DOUBLE
as an argument, rather than
AUX_SINGLE
.