Introduction

I wanted to write a program to shoot rockets; A mini-game with simple or no game logic, just a sand-box like environment to shoot rockets.

Goals

Design

I modeled the trail and explotion as particles. To implement a particle system, I decided to use a Transform Feedback Buffer, which updates the particles on the GPU using a vertex shader.

I created a particle class (TFBParticles and Sparks) to handle updating and rendering the particles, and Rocket and Rockets class to manage the rockets. For the smoke trail I used alpha-blended textured points.

Multiple Shaders

Since this project uses multiple shaders, I created a class to encapsulate the phong lighting shader.

For drawing meshes, I noticed the only information needed to draw the mesh was the Opengl Vertex Buffer Object handles for the position and normal vertex attributes (assuming they have been created.) I defined those to be 0 and 1, respectavely. This way drawing meshes is independent of the shader only if the shader also uses location 0 and 1 contain position and vertex attributes.

The Particle System

A particle system is a method to render effects (such as fire, rain, dust, etc.) that are hard to render using meshes. Usually it made of a large number of points, or small planes with a texture.

A particle can have attributes, just like a vertex.

For smoke and sparks, each particle has a position, velocity, and age. On each frame, the veretx shader updates the position using euler integration:

x = v * dt;
v = a * dt;

I also increase the particle's "age":

age += dt;

When a particle reaches a certain age, it's position and velocity are reset to initial values. This way, if the ages of particles are initialized in an incremental order, the particles appear to be continually generated from the initial position.

Transform Feedback Buffer

One way to implement a particle system is to do all the computations on the CPU then send the data for rendering. Another way is to update the particles on the GPU using Transform Buffer Object.

A Transform Buffer was introduced in Opengl 3.0 to allow the output of a vertex shader to be used as input again. Normally a vertex shader has read-only access to a VBO.

The main "good thing" of using Transform Feedback Buffer is performance imporovements, since data doesn't need to be copied each frame, and computations are done on the highly parallel GPU.

One drawback is we're limited by what computations can be performed on a vertex shader.

Alpha Blending

Alpha Blending is mostly used to create transparancy, by using the 4th color component. It's more complicated than that though.

When a new fragment is drawn on the frame buffer, we can specify the way the new color (called source) is blended with what is already there (destination.)

A common way to make objects appear transparant based on their alpha value is using the blending function

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

A problem arises when drawing multiple transparant over on top of each other. If a new fragment is behind one already in the fragment buffer, the fragment would not be drawn because of depth testing.

One way to fix that is drawing the transparant objects last, and drawing from the furthest to the closest.

Unfortunately, I couldn't depth-sort the points in the VBO, so there are some rendering artifacts for the smoke.

Disabling depth testing for just the particles looks better, but the depth-testing for objects nearer than the particles is broken.

Rockets

I created a rocket manager to handle the rockets. When the player clicks the left mouse button, the rocket manage adds a rocket object to a list of rockets in the air.

The rocket manager handles instantiating, updating, rendering, rocket collision detection, and deleting rockets.

A rocket is modeled as simple a state machine. It is either flying, exploding, or done (in which case the rocket manager deletes it).

A rocket contains two particle systems. One for the smoke trail and one for the sparks.

If rockets reach a certain distance, or hit the ground, they're deleted or explode.

Planes

Shooting rockets on the ground is boring. In the last few hours I added objects to shoot, so I created the Plane and Planes classes, which were surprisingly similar to Rockets and Rocket, with the addition of a new state.

I added simple bounding-shpere collision detection between rockets and planes.

The smoke trail from planes should be bigger.

Controls

W A S D - Move

Space - move up

z - move down

b - explode all rockets (has some lag if there's more than few)

p - pause (locks mouse. needs fixing)

q - quit

Screenshots

(The mouse appears after taking a screenshot. The mouse is invisible while the program is running)

Multiple rockets exploding on the ground

Many rockets being fired

Plane flying.

Plane hit the ground after being shot.

Code

The source code

References