| Checkpoint 1 | Tuesday, Aug 1, 2000 |
| Checkpoint 2 | Tuesday, Aug 7, 2000 |
| Due: | Friday, Aug 11, 2000 |
| On Friday, at the scheduled final time, there will be a demo in Sweet
Hall of your game.
All team members are requested to be at the demo. You will get a chance to show off what you did, and play other people's games. There are absolutly NO LATE DAYS on this assignment. |
|
Throughout the quarter we explored different algorithms that are used in modeling, rendering and displaying. You will be asked to put your knowledge to the test while writing a simple 3D video game in openGL. As in some previous assignments, this result will be an interactive program: you will need to process different input events from the user (this includes BOTH mouse and keyboard input) while simultaneously simulating the events occurring in the game. This assignment will also give you a chance to show us how much you've learned about basic raster graphics techniques. You are required to use the OpenGL system for this assignment.
For purposes of this project, we consider a 3D video game to be an interactive 3D computer graphics application which has some goal and incorporates some concept of scoring or winning and losing. It is not required that your game idea be original. Definitely prioritize functionality over originality. If you have any questions about whether your idea meets the criteria for a 3D video game, please email cs48-help@cs.stanford.edu.
You are permitted (and encouraged) to form teams of 2-3 people and partition the work among the team members. The work expected from each team will be proportional to the size of the team. You can use the class newsgroup su.class.cs148 to find prospective team members.
Requirements
The bare basics (that everyone MUST implement) are as follows:
Groups of three must implement all of the above plus:Texture mapping. You must implement texture mapping for at least one of the 3D objects in your video game. In its most common form, texture mapping applies a detailed 2D image or pattern to 3D geometric primitives. Texture mapping is used extensively in modern 3D video games to improve graphic realism. Chapter 9 of the OpenGL Programming Guide describes how to implement a variety of texturing techniques. There's a caveat to this: texture mapping takes a long time to render, so be careful what object you choose to have texture mapped, and use the information in the book to optimize this rendering. one of the following: Procedural and physically-based modeling. In addition to using scanned or hand-modeled objects to populate the 3D worlds, some video games use procedurally computed models. In class on 7/27 we discussed one such example (the sierpinski pyramid). Chapter 20 of the textbook describes examples of procedural modeling, including fractally-generated mountainous terrains and L-grammars for generating models of plants. Procedurally generated textures may be used to simulate effects such as fire, smoke, and clouds. Parametric curved surfaces. OpenGL can directly display only simple convex polygons; however, you might create a 3D model for your video game which includes smoothly curved surfaces represented mathematically by a small number of parameters. This was also discussed (not in great detail, though) on 7/27. Chapter 12 of the OpenGL Programming Guide describes how to represent and manage the display of smooth surfaces such as NURBS. Be wary about performance if you use NURBS in OpenGL; use them judiciously. one of these two culling methodologies: View frustum culling. In video games with complex 3D environments, it is necessary to limit the number of 3D primitives drawn each frame in order to maintain interactive rendering rates. One way to do this is to avoid drawing any 3D objects which are outside of the viewing frustum of the camera. You can pre-compute rough bounding volumes for hierarchical objects or parts of your 3D world, and then test each bounding volume to verify that some part of it intersects the view frustum before drawing its contained objects each frame. Occlusion culling. Yet another way to maintain good game performance with complex environments is by performing occlusion culling. Similar to view frustum culling, this technique involves using a conservative computation to avoid drawing any parts of the 3D scene which won't be seen by the viewer because they are hidden behind other objects. For static environments such as buildings, you might pre-compute which regions of space (such as rooms) are impossible to see from other regions (due to occluding walls, for example). (Don't confuse occlusion culling with simple hidden-surface removal, which is required for your video game.) Implement a PAUSE using the keyboard.
Beyond this, there are extras for which you can get extra credit:On-screen control panel. Many 3D video games reserve part of the display area for an on-screen control panel, which may include text or 2D graphical elements for user controls, scoreboards, etc. Flight simulator games often use 2D graphical overlays on the 3D world for "Heads Up Displays (HUDs)." You can implement a control panel for your game using a variety of techniques in OpenGL, such as orthographic projection and the stencil buffer. Text primitives are not explicitly supported with OpenGL, but GLUT provides commands to help render text strings. Level of detail control. Another way to limit the number of 3D primitives drawn each frame is to implement level of detail (LOD) control in your game. One simple method of LOD control involves creating multiple versions of some of your 3D objects, varying in geometric complexity (such as 10, 100, and 1000 polygons). Then, before drawing the objects each frame, you can pick the most appropriate version of the object to render, depending on such metrics as the distance of the object from the viewer, the complexity of the current scene, or a user-selectable detail level. Multipass rendering effects. OpenGL makes it possible to easily implement a wide variety of realistic rendering effects. Many of these effects can be achieved by drawing the scene multiple times for each frame, varying one or more parameters each pass through the scene. Examples of such effects include soft shadows, full scene antialiasing, motion blur, depth of field, bump-mapping, reflections, refractions, and compositing. Good sources of information on implementing these and other effects are in Chapters 10 and 14 of the OpenGL Programming Guide, and in the OpenGL tutorials available on the Web.
Game DesignHierarchical Scene Graph. Many 3D graphics applications maintain their constituent objects and sub-objects in a tree-like data structure called a hierarchical scene graph. The scene graph provides a logical organization for the objects in the 3D world, and allows for efficient constructs and operations such as instancing, hierarchical transforms, nested bounding volumes, and traversals of the scene graph for rendering or collision detection. Simulated dynamics. Your video game implementation might include modeling dynamic behaviors and physics for objects in the 3D world. For example, the wheels of a vehicle might react realistically as they move over rough terrain, or a door might swing open differently depending on the force exerted by the player. Advanced image-based techniques. In an effort to increase graphical realism and maintain fast performance, many video games mix traditional 3D graphics rendering with 2D image-based graphics. Although 2D texture mapping is an example of a basic image-based technique, more advanced techniques such as environment mapping, billboarding, and projective textures are possible. Other ideas for image-based techniques include precomputing multiple 2D images ("sprites") of a object from different orientations, and then choosing the most appropriate sprite to warp and render in the 3D scene. Sound.- I do not recommend trying this. I did include some pointers to relevant documentation and sample sound effects- only for the hardy. AI. Some video games include computer-controlled agents that require a significant degree of artificial intelligence. Many of the techniques taught in a basic AI course are applicable to video game development, and some links to more detailed information on game AI are included on the course Web page for the assignment. If you have any doubts about whether a technique you are using qualifies as "AI" for this assignment, ask us.
The first thing I'd like to say is: Don't overdo it on the game idea!
Unless you'd really like to, you do NOT have to come up with a whole
new game idea. Though Tetris is not allowed (no collision detection, not
3D), you are free to reproduce an existing video game. You have just two
weeks to complete this assignment, so you must be realistic and set yourself
some realistic goals. We do not expect to see Dune. We're looking for functionality
and reasonable speed. I would recommend taking a known 2D game and making
it 3D. To get some ideas, you might want to think along the lines of some
of the following:
<suggestions came from Pat Hanrahan>
Your game should be highly interactive; that is, your program should be constantly redrawing to generate moving objects, and requiring continuous input by the user or game player. By these criteria you should avoid card and board games. If you're at a total loss as to what to do, implement Astroids. It's a good starter game, and it is not difficult to get the basic functionality to work out. You can always add functionality and glitz.3D Space Invaders - In the 2D version, the player moves a rocket launcher horizontally along the bottom of the screen, shooting missiles at rows of enemy ships that descend from above. When a missile hits an alien ship, both disintegrate. The ship rows move back and forth, and each time they switch direction they move downward. If a ship lands, the game is over. The ships also drop bombs periodically that fall towards the ground. If a bomb hits the rocket launcher, that round of the game is over. (This is similar to the game Missile Command.) The 3D versions would have the player's view from below (as the launcher) with the alien ships approaching you straight ahead. Shooting at them would have the same effect as before, only you'll have to show them exploding in 3D. Asteroid - Asteroids is a simple game where you pilot a spaceship in an asteroid field, shooting asteroids to destroy them before they collide with you. Larger asteroids break into smaller asteroids as you shoot them. The smallest asteroids are simply destroyed when shot. You have a limited amount of sheild power to protect you from asteroids. If you are in a real fix, you can jump into "hyperspace" to get you out of a tight spot. In 3D, the ships are coming at you, and are shooting spherical objects at you. Brickles- The player controls a rectangular paddle which can be moved in any direction on the screen to catch a ball that is reflected off the paddle and the wall (made of bricks). You can make the objective to get the ball to go into a certain goal on the wall, or to get the ball to hit every brick (you can either make the bricks disappear, or color them in a new color). The ball bounces off of the paddle and the walls and has a constant speed. You may want to have multiple goals and balls (maybe of different speeds and sizes) to make it more interesting.
The last thing I'd like to say is: Don't overdo it on the game idea!
Helpful Hints
(1)
(3)
Most successful video games include richly detailed 3D models, textures,
sounds, and other content for representing the game world and characters.
You have several options available in creating the 3D models for your video
game:
(4)
In the course of designing and implementing your video game, keep in
mind that CS148 is a computer graphics course. Focus your efforts on the
computer graphics techniques underlying the game; don't spend the majority
of your time on game design or object modeling if the graphics engine will
suffer as a result! I'm not penalizing here for lack of originality- and
functionality, at the end, is what counts (note that functionality does
include efficiency in this case)
(5)
You are free to develop your video game on any computer platform that
supports OpenGL, provided that you will be able to demonstrate your program
at the required demonstration periods at Sweet Hall. If your program cannot
run on the Sweet Hall elaine machines, you will be responsible for bringing
a system on which to run your video game. You can collaborate with other
groups in different demo time slots to bring a PC. Versions of OpenGL for
most common computing platforms are available for download at sites pointed
at from the links Web page, and the code Web page.
To keep things simple, our recommendation is to develop your video game on the Sweet Hall Sun or SGI system. As you know by now, OpenGL is window system independent, so an additional toolkit is necessary to provide the necessary windowing and input event management; for this we recommend using the GLUT package. GLUT is used for all the examples in recent editions of the OpenGL Programming Guide, and is available for most all common computing platforms.
Due Dates
The first checkpoint will be on Tuesday, Aug 1st. On that date, before 5pm, please email us (cs148-help@cs.stanford.edu) a short HTML file in which you tell us your group name, who is in your group, division of labor (who's in charge of what), and a description of the game plan. In the description, please include the game objectives, the player's interaction (what actions cause what to happen in the game), a description of the 3D scene in which the game will take place, and a description of what objects move in the game.
The second checkpoint will be on Tuesday, Aug 7th. On that date, you are asked to submit, or demo for me in person (at my office hours 8-11pm in Sweet Hall), the preliminary scene rednering with viewpoint change. Though you should already have some interaction working in this environment by this time, I just want to make sure that you aren't straggling. You should aim to have your entire scene draw, and animate any of the motion that will take place in the scene. This means that an Astroid-like game should have the enemy ships flying by. I do not expect to interact with your environment at this time, but some sort of motion about the scene is expected. I.e., I would like to change the viewpoint (to see that your 3D objects are rendering properly).
Submission and demonstration will take place on Friday, Aug 11th. We will have a project demo in Sweet Hall. You will present what you did (3-5 min. talk of the features and the ideas), and demonstrate your game. The class will go from station to station to see the different projects. If things go according to plan, we will have two people from the gaming industry come to see your game, and give you their input (if you'd like).
We will recompile your program and then attempt to play the game. Your
grade will be based on the following criteria: 80% for implementing the
functionality that we request, and 20% for the quality of the ``game play.''
Game play covers such factors as the overall refresh rate and interactivity,
the aesthetics of the game (aliasing, etc), no annoying flickering, etc.
Be forewarned, we will dock up to 10%, if your submission cannot be recompiled
and executed. Please make sure that the instructions are clear on how to
play the game. When you submit, call this program 4 (when you are prompted
for it), and include the README just as you have in the past. In the
README you must also specify who did what. You need only make one
submission per group (it doesn't matter from whose account).
QA: (some questions
from past students):
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 this 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 have also traditionally been available in
/usr/class/cs248/netpbm
We provide no support whatsoever for the NETPBM image libraries: they're just copied from 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.
First, find (a) project partner(s) that you can work with (this means
that your schedules match, you generally work at similar hours, can physically
see eachother once in a while, and may also have some complementary skills).
Second, discuss what you would like to implement, and write up the
document for checkpoint 1.
Third, choose a language you are all comfortable with.
Forth, design the scene in details. For the second checkpoint, I want
to see the fully integrated scene. You do not have to have the user interactions
working completely by that point, but I should be able to move about the
scene (or have some alien spaceships whizz past me).
A5. Yes - even if it means that one of them does something simple or silly. It's useful, though to have the mouse take care of the continuous input (like moving about the scene) where keyoard can control the discrete interactions (shoot, jump, throw, release, whatever single-point action you can think of).
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. 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.
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.
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).