Urge to Merge

Ross Light
CSC 471: Introduction to Computer Graphics
Zoë Wood

Project Description

Urge to Merge is a simple arcade game rendered in 3D. The player drives a racecar down a freeway at speeds of questionable legality, obtaining points for successfully dodging cars.

Project Goals

Controls

Keyboard Gamepad Meaning
WAnalog Stick UpAccelerate
SAnalog Stick DownBrake
AAnalog Stick LeftTurn Left
DAnalog Stick RightTurn Right
SpaceA (Button 1)Start Game
EscapeStart (Button 8)Pause
Shift-QQuit

Technical Details

Modeling

Raytraced cars

I created the car models and UV maps using Blender. The cars were modeled using subdivision surfaces, which were baked into polygons and manually edited to reduce the triangle count. While I was creating the textures, I realized that photorealistic images I had in mind didn't fit the arcade feel of the game, so I opted for a simple cartoon appearance.

The tires are modeled separately from the cars so that I can apply hierarchical modeling. This has two benefits: the same tire model can be instanced to reduce GPU memory and the tires can be transformed separately from the car body. This reduced modeling time and allows the player car to turn its tires when rotating.

Each object was exported out as an OBJ file. Because I intend to try to port this program to multiple platforms and languages (possibly Android and iOS), I chose to write a single program that reads in OBJ files and generates source code. This has a negligible effect on executable size (roughly 100KiB for the two car models and the tires) and speeds up model loading because the data is already in a usable VBO format.

Shading

All shading is being done on a per-pixel basis in GLSL. The cars use Phong shading with a texture map bound to the diffuse color. The scene uses a single point light. Blender precomputes per-vertex normals; I do not perform normal mapping. The road is a procedurally generated texture that can overlay simple radial shadows that are passed to the shader.

There is only one texture map for the enemy car. However, a tint can be passed to the car shader. Any grayish pixels in the texture are multipled by the tint color. This allows a variety of enemy car colors without altering the color of the tail lights or head lights.

Collision Detection

Cars with collision boxes

All collisions are calculated using axis-aligned bounding boxes (AABBs) for simplicity. The enemy cars are represented using one box per car. To handle the player car, I split the object into three discrete AABBs that are translated with respect to the car's rotation.

No scene partitioning is being done because the number of objects at a time being considered is so small (<10).

Antialiasing

All in-game 3D graphics are rendered to an off-screen buffer before being displayed to the screen. I use this to provide multisample antialiasing using OpenGL's framebuffer objects.

Heads-Up Display

Urge to Merge, Press Space to Start

The 2D overlays in the game and in the UI are rendering using the SDL surface API. The surface is copied to a texture map in OpenGL. I use alpha blending on a rectangle that covers the screen to finally render the HUD. Multiple passes can be used to produce a layering effect (demonstrated with the text outline in the splash screen).

Sound

I used SDL_mixer to load Ogg Vorbis files for sound effects and music (I composed the music with GarageBand, the sound effects are from a stock sound effects library). The program plays three songs in a loop.

Libraries Used

See the README file for the licenses on included components.