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:

staticobjects.cpp

home Home   up Up   ( Download )


#include "worldobjects.h" /* UBoatObject class Submarine model */ UBoatObject::UBoatObject() { width = 12; height = 20; depth = 62; org.x = -10; org.y = -8; org.z = -10; } // draw uboat at origin void UBoatObject::drawMesh() { // setup material and colour glMaterialf(GL_FRONT, GL_SHININESS, 11); GLfloat spec[] = {0.7, 0.7, 0.7, 1.0}; glMaterialfv(GL_FRONT, GL_SPECULAR, spec); GLfloat em[] = {0.1, 0.1, 0.1, 1.0}; glMaterialfv(GL_FRONT, GL_EMISSION, em); glColor3f(0.3, 0.3, 0.3); // draw cylinder glPushMatrix(); glScalef(5, 7, 50); Primitives::drawCylinder(); glPopMatrix(); // draw two spheres at each end glPushMatrix(); glScalef(5, 7, 5); Primitives::drawSphere(); glPopMatrix(); glPushMatrix(); glTranslatef(0, 0, 50); glScalef(5, 7, 5); Primitives::drawSphere(); glPopMatrix(); // draw bit on top glPushMatrix(); glTranslatef(0, 9, 20); glScalef(3, 6, 5); glRotatef(90, 1, 0, 0); Primitives::drawCylinder(); Primitives::drawDisk(); glPopMatrix(); // fins Vec3 box[8]; Vec3 na[8]; Mat4 m; Primitives::initBox(box); m.setI(); m.scale(0.5, 15, 5); m.translate(0.0, -7, -8); m.transform(box, 8); Primitives::boxNormals(box, na); Primitives::drawBox(box, na); Primitives::initBox(box); m.setI(); m.scale(0.5, 15, 5); m.translate(0.0, -7, -8); m.rotate(90, 0, 0, 1); m.transform(box, 8); Primitives::boxNormals(box, na); Primitives::drawBox(box, na); // revert material glMaterialf(GL_FRONT, GL_SHININESS, 0); spec[0] = 0.0; spec[1] = 0.0; spec[2] = 0.0; glMaterialfv(GL_FRONT, GL_SPECULAR, spec); em[0] = 0.0; em[1] = 0.0; em[2] = 0.0; glMaterialfv(GL_FRONT, GL_EMISSION, spec); } /* Ship class A sunken ship */ ShipObject::ShipObject() { width = 12; height = 14; depth = 32; } void ShipObject::drawMesh() { // init Vec3 box[8]; Vec3 na[8]; Mat4 m; // the ship base glColor3f(0.64, 0.32, 0); Primitives::initBox(box); m.setI(); m.scale(10.0, 10.0, 30.0); m.translate(0.0, 0.0, 0.0); m.transform(box, 8); box[0].add(2, 0, 4); box[3].add(-2, 0, 4); box[4].add(2, 0, -4); box[7].add(-2, 0, -4); Primitives::boxNormals(box, na); Primitives::drawBox(box, na); // the cabins Primitives::initBox(box); m.setI(); m.scale(10.0, 2.0, 10.0); m.translate(0.0, 10.0, 0.0); m.transform(box, 8); box[1].add(0, 1, 0); box[2].add(0, 1, 0); Primitives::boxNormals(box, na); Primitives::drawBox(box, na); // the main mast glPushMatrix(); glTranslatef(5, 30, 15); glScalef(0.5, 20, 0.5); glRotatef(90, 1, 0, 0); Primitives::drawCylinder(); glPopMatrix(); // cross beams // large glPushMatrix(); glRotatef(90, 0, 1, 0); glTranslatef(-15, 20, -2.5); glScalef(0.5, 0.5, 15); Primitives::drawCylinder(); glPopMatrix(); glPushMatrix(); glRotatef(90, 0, 1, 0); glTranslatef(-15, 27, 0); glScalef(0.5, 0.5, 10); Primitives::drawCylinder(); glPopMatrix(); } /* TreasureChest class A treasure chest */ TreasureChestObject::TreasureChestObject() { goldT = new Texture("gold00.jpg"); width = 3.5; height = 2.5; depth = 2.0; org.x = -0.3; org.y = -0.3; org.z = -0.3; } void TreasureChestObject::drawMesh() { // init Vec3 box[8]; Vec3 na[8]; Mat4 m; // the chest itself glColor3f(0.64, 0.32, 0); Primitives::initBox(box); m.setI(); m.scale(3.0, 1.0, 1.5); m.translate(0.0, 0.0, 0.0); m.transform(box, 8); Primitives::boxNormals(box, na); Primitives::drawBox(box, na); // the lid glPushMatrix(); glTranslatef(0, 1.2, 1.9); glRotatef(-120, 1, 0, 0); Primitives::initBox(box); m.setI(); m.scale(3.0, 0.5, 1.5); m.translate(0.0, 0.0, 0.0); m.transform(box, 8); box[0].add(0.2, 0, 0.4); box[3].add(-0.2, 0, 0.4); box[4].add(0.2, 0, -0.4); box[7].add(-0.2, 0, -0.4); Primitives::boxNormals(box, na); Primitives::drawBox(box, na); glPopMatrix(); // the treasure FaceInfo faces[6]; FaceInfo::initBox(faces, 1, 1, 0); //FaceInfo::initBox(faces, goldT); Primitives::initBox(box); m.setI(); m.scale(2.5, 0.9, 1.2); m.translate(0.2, 0.2, 0.2); m.transform(box, 8); Primitives::boxNormals(box, na); Primitives::drawBox(box, na, faces); /*Primitives::initBox(box); m.setI(); m.scale(5, 5, 5); m.translate(0.2, 20, 0.2); m.transform(box, 8); Primitives::boxNormals(box, na); Primitives::drawBox(box, na, faces);*/ }