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:
#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);*/
}