3D Underwater World (using OpenGL and SDL)

Copyright Tristan Aubrey-Jones January 2008.

This is an example OpenGL SDL application which creates an animated 3D underwater world (screenshot), with "Thunderbird 4" with headlights moving on a spline path, a randomly generated sand terrain, sunken ship/submarine/treasure chest models, and swaying fish and seaweed. It is designed to demonstrate basic OpenGL features, and the structure is as follows:

readme.txt

home Home   up Up   ( Download )


COMP3004 CWK 3
Tristan Aubrey-Jones (taj105)
------------------------------------

Operating the program:
----------------------------
Keys:
    ,  turns left and right
    ,  increases and decreases velocity
    ,  increases and decreases elevation
     stops motion

    Q or  Quits to program
    H raises the help screen
    P goes to screenshot position
    T starts the tour
    E ends the tour
    R resets all animation (sets world time to 00)

Source files
--------------
global.h - global includes and settings

game.h, game.cpp - Game class which handles all key presses, holds the render/simulate event loop
                   and which holds the World object.

world.h, world.cpp - contains simulated enviroment with lighting setup, world initialization, 
                     simulation functions and rendering code. 

clipping.h, clipping.cpp - contains the CameraView class which hold the current camera position
                           and orientation, and the FrustrumClipper class which uses hyperplanes
                           to calculate whether a point is in view or not, so only objects inview
                           are drawn.

primitives.h, primitives.cpp - primitive functions for drawing simple geometric shapes
                             - like quadrangles and texturing them.

regulargrid.h, regulargrid.cpp - contains a textured grid of elevations for use in the terrain
terrain.h, terrain.cpp - generates a random fractal landscape using the diamond square function

splines.h, splines.cpp - contains SplineCurve class and MotionPath class for holding a 3D path
                         for an object to move along. The camera used two, one for its position
                         and one for its viewing object

textures.h, textures.cpp - contains texture loading function, courtesy for John Carter and a Texture
                           class to wrap common functionality.

vectors.h, vectors.cpp - contains my own bespoke 3D vector class Vec3, 4D matrix class Mat4 (with 
                         transformation functions, and hyperplane class.

worldobjects.h, worldobjects.cpp, seaweed.cpp, staticobjects.cpp, vehicleobject.cpp, fish.cpp
                - contains class definitions and implementation of objects that are drawn and 
                  the animation functionality
                  - worldobjects.cpp - holds base classes for world objects
                  - vehicleobject.cpp - holds Thunderbird 4
                  - staticobjects.cpp - holds the submarine and the ship and the treausure chest
                  - seaweed.cpp - holds dynamic seaweed.
                  - fish.cpp - holds fish objects

fish[0-4].jpg - fish textures
sand02.jpg - sand texture

screenshot.jpg - sample screenshot

help.txt - helpfile


How to build
----------------------
Compile using GCC (MingW) on Windows XP, using these options 

-D_GNU_SOURCE=1
-Dmain=SDL_main
-DNO_SDL_GLEXT

linked with 

-L/usr/local/cross-tools/i386-mingw32msvc/lib
-lm
-lmingw32
-lSDLmain
-lSDL
-lSDL_Image
-lopengl32
-lglu32
-mwindows

Or build the project in devcpp using DevCpp, and the above options in the
project settings.

How it works
---------------------
After initiaializing OpenGL, the main function creates a Game object and runs it. 
The Game function creates a World (world.cpp) which is the simulated enviroment being rendered. 
The World contains the static objects (the terrain, wrecked Submarine and Sunken ship and treasure chest), 
and the dynamic ones (Thunderbird4, the seaweed, and the fish).

The landscape is generated randomly by the Terrain object using the DiamondSquare fracal algorithm
in a 256x256 regular grid. The average normals are then calculated for each vertex so that the 
lighting is correct, and it is rendered triangle strip (where only visible squares are drawn).

Thunderbird 4 is made using the primitives (predominately the Box with modified vertices), and runs on
a MotionPath around the scene. It always points at the next place on the line. LIGHT1 is a spot light
and always points infront of it.

The seaweed is randomly generated at startup by producing blades of random length, at random angles to the
central upward vector, and then sways as it is simulated according to a sine wave (like the fish) so that
it looks as if it is moved in the currents. This fish are also randomly generated at startup with a random
size and startup texture, trajectory and velocity. They also sway as they are simulated in the current.

The Game objects run function (game.cpp) contains the rendering loop, which repeatedly
simulates the world (updating its time), and the world simulates all of its dynamic objects (
the Thunderbird4 vehicle, the fish, the seaweed). 

Then the camera position is updated according, doing collision detection on static objects,
to the current velocities in the game, and the scene is rendered for the current viewpoint. A 
CameraView object is passed to the World->draw function which contains the current viewing Frustrum 
(clipping.cpp) so that an object can decidide whether or not it should draw itself based on whether it
it viewable. All of the objects are drawn, and the loop continues.


Help
--------

Texture load function taken from texture.c in example on shaders COMP3004 websit, in textures.cpp
initgl function in main.cpp from https://secure.ecs.soton.ac.uk/notes/comp3004/lectures/code.html