CS 446: Real-Time Rendering
Project #1
Synopsis: Build the basic underpinnings of a 3D scene-graph engine.
Your program should be able to import 3D models with hierarchical
transformations, place them into a scene graph, and render the scene. Your
scene graph should support multiple traversals (for example, to render the scene
from multiple interactively controlled cameras), along with basic view-frustum
culling and basic LOD. Finally, your group should decide on and propose
the game you will build.
Due: This assignment has multiple components, each quite challenging
in its own right. To help you organize your effort, we will check your
progress midway through:
Feb 12, 2004 Checkpoint: Load and
fly around multiple models (40%)
Feb 19, 2004 Final assignment:
Everything else (60%)
Details: This is where you start: in this assignment your group will build a
basic scene-graph renderer that will become the base of your game engine.
Your renderer should support:
- Importing 3D models: your program will support loading multiple 3D models
in one or more file formats. Suggested file formats include .obj (alias/wavefront
objects), .md2 (QuakeII), .md3 (QuakeIII), .flt (OpenFlight), .3ds (3D Studio Max), .ma (Maya ascii). These formats are listed roughly in order of complexity.
The .obj file format is quite simple, but it will be difficult to find or
create
interesting models. The .3ds format is fairly complex, but many, many
models are publicly available.
- Hierarchical transformations: your program should support hierarchical
transformations in the organization of objects within the scene; for example,
if a statue sits on a table and the table is moved, the statue should move
with it. Your program may optionally support hierarchical transforms
within a single model, i.e. for articulated characters. Note that only
some of the file formats above (.flt, .3ds, .ma) support hierarchical models. If you
choose not to implement such a file format, you must write your own scene
description file that describes the objects in the scene and their
organization (I suggest using XML for this, as it is powerful, flexible,
extensible, and human-readable, and since tools like libxml can
alleviate much of the pain and suffering of parsing). Note that you
don't (yet) need to support loading "levels", in the sense of maps, terrains,
or background objects like walls, ceilings, etc.
- Instancing: your program should support instancing, in which a single
model can be represented (instantiated) multiple times with different
transforms.
- Moving objects: your program should allow the user to pick an object and
translate or rotate it within the scene (of course, hierarchical
transformations should be respected, so that any children of the selected
object are also affected by the user's actions on the parent object). At
this point you will not be graded on the interface; for instance, using keystrokes to
select and move objects is fine.
- Simple texturing and lighting: You should be able to load and display
models with simple texturing and/or lighting. The user or scene file
should be able to specify the rendering state (texture on/off, lighting
on/off, wireframe on/off) for each object or instance. Again, the
interface is less important than the functionality here. Directional
lighting and simple texture modes are fine for now; point-light sources
(attached to nodes in your scene graph) are an obvious and easy extension.
- Simple distance-switched discrete LOD: Objects may be represented by
multiple LODs depending on the distance from the viewpoint to the object.
- Hierarchical view-frustum culling: Off-screen objects are not
drawn. Calculate and store bounding
volumes with subtrees in your scene graph, and avoid rendering off-screen
objects by testing those bounding volumes against the planes of the view
frustum. Bounding volumes should be correctly updated with object
transformations. To account for animated objects, you may either pick a
bounding volume large enough to contain the object at all steps of the
animation, or incrementally update the volume.
- Multiple viewpoints/traversals: The user should be able to switch
between multiple cameras, for instance first- and third-person perspectives.
One particular traversal you should support is a "top-down" view showing the
effects of culling (draw the view-frustum and show objects disappearing when
they leave it) and LOD (objects get simpler with increasing distance.
Note that in this kind of view, the camera used for LOD and visibility culling
is not the same one used in rendering. This top-down view is an
invaluable debugging tool that you will need throughout the class!
- Interactive camera control: Your program should provide interactive
mouse-based camera control (you may implement a keyboard interface in addition
if you wish).
- Propose your game concept: You should write a formal proposal
describing the game that your group intends to create over the course of the
semester: concept, gameplay, visuals, and core real-time rendering techniques.
Your proposal should detail the overall shape of your game, the technical
contributions that your engine will incorporate, and (where you know) who will
code what. You should include some hand-made "screenshots" to help
explain the intended gameplay and visuals. You should have a game plan for
staged development, so that if your full-fledged game proves beyond the scope
of the semester, you will still develop something fun and interesting.
In response I will provide feedback on your ideas, whether you're being too
ambitious or not ambitious enough, and perhaps some (hopefully) useful advice.
Resources: There are many places you can go to look for advice,
tutorials, details, and source code for games, from loading file formats to AI
and physics. This can be
frustrating, however, as many of the resources on the Web are the results of
enthusiastic amateurs rather than paid professionals. Some good places to
start are:
- http://www.gametutorials.com: a
soup-to-nuts series of source code "tutorials" on game programming, written
for beginning programmers but containing some useful information.
The tutorials are in the form of heavily-commented source code. In
particular there are fairly good tutorials on loading Quake .md2 and .md3
models.
- http://lib3ds.sourceforge.net:
a library for reading .3ds files, seems fairly complete.
-
www.planetquake.com/polycount: lots of models for various games.
- 3D Studio Max files: I have purchased a collection of over 5000 models in
3D Studio .max format (not the same as .3ds), available at
\\eirene.cs.virginia.edu\3dEnc2000 in Windows. You can export these
models (for example, to .3ds format...) and create new ones using 3D Studio
Max, which is available in 002a. Note that we also have Maya, another
modeling package; right now it does not appear to work in 002a. If you
want to use Maya we should be able to accommodate you.
- www.gamasutra.com: Lots of useful
information on game programming here, along with the usual chaff.
-
http://www.iseran.com/Win32/CodeForSpeed: More important and
useful info on how to write efficient code. I will post a handout
summarizing some of the lessons from this site, but it is worth your reading
in full. Note that this site is not graphics-oriented.
Also, don't forget about the optional texts for the course like the game
programming gems series!
Lab: We are sharing Olsson 002a this semester. Most of you will
need to get a key from Ginny Hilton at the CS front desk. There are 13
machines and 24 students in this class, plus many students in Operating Sytems using
the lab...so be courteous and don't assume you will always get a computer
exactly when you were planning to work. The machines in 002 have decent
processors and decent (NVIDIA GeForce3) graphics cards; I will be installing a
few GeForce FX-class cards (programmable graphics) later. If you would rather work
on a personal machine, that's fine too -- in fact it will take the pressure off
the lab machines. Let me know any issues you encounter -- this is a new
use of this lab and there will undoubtedly be software, hardware, and availability issues to
work out.
Policy on code reuse: In general you are welcome to use code that you
find elsewhere. For example, you are welcome to use the lib3ds library mentioned above,
and you are strongly encouraged to use the in-house software tools that Ben has
posted.
However, you will not get credit for what you didn't write. Therefore, it
is critically important that you describe in detail what code you wrote
yourself and what code you imported or adapted from elsewhere.
Furthermore, if you find a particularly helpful library, tutorial, loader, etc.,
you should post it on the forum. Obviously
if you reuse a significant amount of code, that raises the bar for the
assignment: you will be expected to do something beyond the basics mentioned
above. If you have any questions about
code reuse or attribution, please ask me.
Platform: I would prefer that your code compile and run under
Microsoft Visual Studio 7 (.NET). Please don't use VS.NET 2003. If your
group wants to develop under Linux or Macintosh,
go ahead. Any Linux projects should compile and run on the lab machines;
this may require intervention by root (to install libraries, etc) so don't put
off testing your code down there. If you go Mac, you will need to work
with me to make sure our one Mac can run your code. You are welcome to use GL extensions supported
by NVIDIA cards; if you want to use other extensions or
other hardware, talk to me first (we also have an ATI Radeon 9700 in the lab, so
that is a possibility...but you'd have to own your own card for development).
If you want to use a particular input device (joystick or whatever), talk to me first...you may have to
lend it to me so I can grade your assignment.
Turning in the assignment: Checkpoint: Demo to the instructor
or TA that you can load and fly around multiple models. Final
assignment: Put all your code and models in a folder,
along with a detailed README.txt file that describes what your group did, who in
the group did what, what code you
wrote and what code you used from elsewhere, and how to run your assignment.
Zip up the folder and e-mail the .zip file (or a link) to me and the TA.
Be sure to include workspace and project files, along with any libraries/include
files/etc, so that we can compile your code.
We will read (and grade you on) your source code, so follow good programming
practices.
Advice: If this sounds like a lot for a two-week assignment, that's
because it is a lot. An awful lot. This will be the hardest assignment
in terms of the sheer amount of code you need to write. It is particularly
important to start early because you will be building on this code for the
remainder of the course; a careful and thoughtful design now will simplify
everything down the road, whereas a rush job will introduce bugs and design
flaws that will continue to bite you throughout the semester. Now is the
time to follow good careful software engineering practices: think carefully
about your design BEFORE you start, test your classes and functions early and
often, and use CVS to back up your work for disaster recovery and revision control.