248 Mile has been the evolution of a game idea that we have been toying with for a long time due to one of our drawmates who really loves cars. We created it as a final project for the CS248 class at Stanford - Introduction to Computer Graphics. It is a game in which you, the stunt car driver, drive around on a terrain inhabited by evil patrol units. To win the game, you shoot them down with one of two possible weapons - a missile or a projectile. The name is of course, spun off from the movie, 8-mile, starring Eminem. It represents the long journey we took to the completion of this game over 3 weeks.
As of all ambitious projects hampered by stingy time constraints, we found that we were able to succeed in some of our goals, but we were forced to sacrifice others. We were glad to have this chance to get to know OpenGL.
Here are some really early screenshots from when we started to experiment with OpenGL. Observe the nifty rotating capability and texture mapping!
2d "radar" map of the world where enemies can be tracked.
View Frustum culling
We implemented a quadtree data structure to cull parts of the map that we were not currently viewing. This turned out to be kind of challenging since the tutorials that we downloaded from the web were very bad. Essentially, it divides the terrain into patches of 16x16 meter square patches, then recursively selects which patches intersectthe view frustum. Then the algorithm makes triangles given the heightfield information from those patches and sends them down the graphics pipeline along with texture coordinates.
The normals for the heightmap are precalculated during initialization by computing gradients of the scalar field.
As we found out, quadtrees made a huge difference in our program. Turning it off, we could not achieve real time framerates.
Procedural and physically-based modeling
We implemented a robust particle engine used to model all sorts of special effects, including exhaust from the back of the car, missiles/projectiles, and various types of explosions. The particles are just textured quads, that have been billboarded, and are blended into the scene after everything else has been rendered. We have a particle manager that controls several particle systems, each of which has a position, velocity and acceleration. This system serves as an emitter, where the actual individual particles appear. Each particle starts off at some velocity and acceleration and fade away at some rate depending on its lifetime. Different particle systems can follow different physical laws. For most systems, particles are subjected to gravitational forces and various air resistance models according to what looked the best.
For this game, we needed to collide the car with the terrain and rotate it about all three coordinate axes such that the tires would line up with the terrain. To do this, we linearly interpolated between sampled points in the heightmap and set each tire to the right height. Then we used dot products and cross products to figure out how much of an angle we needed to rotate about what axis. Finally, We also had to collide missiles and projectiles with enemies.
There were various things that we needed for physics. First, there were projectiles and missiles, which follow very simple newtonian kinematics equations. Furthermore, we had the particle systems, which were described above. The hardest part was by far modeling the car physics. Unfortunately at the end, we were not successful in many things we wanted to do. Car physics is a very hard problem involving finding all the forces and torques acting on a rigid body. Then translating the body in an appropriate way.
The best sources for this that we found online were:
We tried to take into account several effects like air resistance and rolling friction. We did not get around to accounting for gravity (inclined plane). Our goal was for the car to be able to spin out of control and drift if it was taking a turn too fast.
Throughout the game, we have background music, and when driving the car, the user has the ability to change the radio statio at the press of a button. We also have sounds for explosions, and whenever the user fires a weapon. We used the BASS library for sound routines, and so this feature was quite easy to implement, and worked very well.
The awesome cs248 staff!
The Red Book - with which we learned opengl
Real-Time Rendering (Akenine-Moller and Haines) - We got fast intersection tests and information about texturing
Special Effects Game Programming with DirectX (LaMothe) - we got many of our ideas for special effects here.