Screenshots:







Paper Plane 3D is a video game created for the final project of Stanford's CS 248 course (Introduction to Computer Graphics) by sophomores Rahul Agarwal, Justin Solomon, and Salik Syed. In the game, players steer a paper plane through a series of virtual worlds. To complete a level, they must fly through several rings distributed throughout the world while staying afloat—vents and strategic steering help provide lift to counteract gravity.

The game was developed in Visual C++ using OpenGL/GLUT for basic graphics routines, OpenAL for audio, and FTGL/FreeType for antialiased text. Basic technical features (as required in the Project 3 guidelines) of Paper Plane 3D include:

  • 3D Viewing and Objects: The game is entirely in three dimensions from the perspective of the paper plane. Occlusion and other basic rendering operations are handled correctly and efficiently by the game engine, allowing more than sufficient time for more advanced features and computations.

  • User input: The plane is controlled by the keyboard. The left and right arrows speed the plane. The back arrow increases air resistance, and the forward arrow slowly accelerates the plane. To help stabilize the plane after complicated maneuvers, the space bar can be pressed to move the plane to a horizontal orientation. The space bar is allowable because the key focus of the game is the "puzzle" component of planning a path from vent to vent through the rings rather than steering the plane.

  • Lighting and smooth shading: A general texture class allows for any number of different shading operations to be implemented. The plane is shaded using simple OpenGL routines. Most objects in the scene are rendered with per-pixel lighting and other shader effects for greater realism or effect.

  • Texture mapping: Most objects in the scene are texture-mapped; displacement shaders and other effects are used to produce higher realism than simple flat textures.

More advanced features of Paper Plane 3D include the following:

     Spatial Acceleration: An octree was implemented for use in collision detection, culling, or other purposes. Octree insertion is sufficiently general that any number of objects could be added to the tree, including scene objects and vents, in efficient time. Search routines are provided for boxes and general "Object" models.
 

Realistic game physics: A full rigid body simulation system is implemented for computing the motions of the paper plane. Orientation and position are generated using a forward Euler scheme. Steering is accomplished by adding fictitious forces to the nose of the plane and correcting its orientation; this can generate vertical drift, which can be used strategically to navegate the scene (in combination with the space bar function). The aerodynamics of the plane are simulated using a modification of the aerodynamic tensor algorithm (the original version of which is desribed in Game Physics Engine Development, by Ian Millington). Lift from the vents is generated using air resistance forces.

 

Vertex Displacement Shaders: An extension to the standard texture class allows us to generate complex motions by using a vertex shader to displace vertices as a function of position and time.

  Per Pixel Lighting: A combination vertex shader and fragment shader is used to interpolate the surface normal direction per fragment, allowing for more accurate lighting calculations. Multiple lights are supported.
  Normal Mapping: A normal mapping shader builds upon the per-pixel lighting algorithm to simulate small surface variations without increasing geometry. A special texture map encodes surface variation in its RGB values. The normal vector is used to compute the tangent and binormal vectors at each vertex and these are used to convert the normals retrieved from the texture from tangent space to object space.
  Volumetric Shadowing: Shadow volume edges are generated using a visble contour-finding algorithm. These edges are then extruded to infinity, creating a volume. The stencil buffer is used to count when a "ray" enters or leaves this shadow volume. Rays (pixels) which intersect a single the front of the volume but not the back are rendered. Furthermore shadow volumes can be optimized on the fly using our engines mesh-simplification tool (described below)
  In-Engine Mesh Simplification / LOD: Incoming .OBJ files can be simplified within the engine. Mesh geometry is iteratively refined using a triangle collapse method. Candidate triangles are ranked based on area, perimeter and the number of previously collapsed triangles within a certain distance from the triangle. This simplification is used when generating shadow volumes for complex geometry. Data is cached and modified between refinements, allowing for fairly quick load times.
    Built-in Math Libraries: The engine includes a comprehensive library of computational geometry routines including basic vector and matrix manipulation, Quaternions, and Triangle intersection.
  Particle Systems: A flexible particle engine can be used to generate complex effects such as water, fire and wind. The engine allows user control of gravity, force scaling, growth and color. Arbitrary geometry can be rendered using the engine. Most effects use hardware accelerated point sprites for speed.
    3D Sound: The OpenAL library allows us to support multiple sound sources, sources are attenuated based on the user's in-game position.
  2D Images and Anti-Aliased Text: The FTGL Library is used along with Freetype to generate anti-aliased text as texture maps. A 2D imaging class allows simple rendering of 2D control panels and user interface components.
  Heads-up Display: A heads-up display makes use of the 2D image routines to draw a map of the local vents. The display is always oriented in the direction of the plane's motion and updates in real time.
    Collision detection: The octree is queried to make collision detection more efficient. Once the plane and a scene object are discovered to be in the same octree bounding box, per-triangle intersection detection makes for accurate collision detection, important for tight paper airplaine "squeezes."