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:

fish.cpp

home Home   up Up   ( Download )


#include "worldobjects.h" #include "vectors.h" #define MIN_X 0.0 #define MIN_Y 3.0 #define MIN_Z 0.0 #define MAX_X 100.0 #define MAX_Y 30.0 #define MAX_Z 100.0 #define TEX_COUNT 4 // calculate a random float between // 0.0 and ran. inline GLfloat randf(GLfloat min, GLfloat max) { // calculate between 0 and 1 int ir = rand() % 1000; GLfloat v = ((float)(ir) / 1000.0f); // change to range return (v * (max - min)) + min; } // init textures Texture** FishObject::textures; void FishObject::initTextures() { FishObject::textures = new Texture*[TEX_COUNT]; for (int i = 0; i < TEX_COUNT; i++) { char txt[] = "fish0.jpg"; sprintf(txt, "fish%i.jpg", i); FishObject::textures[i] = new Texture(txt); } } // constructor FishObject::FishObject() { // random location on map loc.x = randf(MIN_X, MAX_X); loc.y = randf(MIN_Y, MAX_Y); loc.z = randf(MIN_Z, MAX_Z); pos.x = loc.x; pos.y = loc.y; pos.z = loc.z; // random bearing bearing = randf(0, 360); // random texture tex = rand() % TEX_COUNT; if (tex == 4 && rand()%4 != 0) tex = rand() % TEX_COUNT; // random size if (tex == 4) { // shark w = randf(3.5,4); h = randf(1,1.5); s = randf(1, 3); moving = true; v = randf(0.2, 10); } else { // other fish w = randf(2, 3); h = randf(0.5, 1); s = randf(0.1, 0.8); // moving? if (randf(0, 1) < 0.5) moving = true; else moving = false; v = randf(0.05, 10); } } // draw void FishObject::drawMesh() { glColor3f(1, 1, 1); glDisable(GL_LIGHTING); Texture* t = FishObject::textures[tex]; t->Begin(); //GLfloat cl[] = {1.0, 0, 0, 0, 0}; //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); //glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cl); //glColor3f(0.2, 0.2, 1); glPushMatrix(); glRotatef(bearing, 0, 1, 0); glScalef(1, h, w); glScalef(s, s, s); //Primitives::drawSphere(); glBegin(GL_QUADS); glTexCoord2f(t->minX(), t->maxY()); glVertex3f(0, 0, 0); glTexCoord2f(t->maxX(), t->maxY()); glVertex3f(0, 0, 1); glTexCoord2f(t->maxX(), t->minY()); glVertex3f(0, 1, 1); glTexCoord2f(t->minX(), t->minY()); glVertex3f(0, 1, 0); glEnd(); glPopMatrix(); //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); t->End(); glEnable(GL_LIGHTING); } // simulate void FishObject::simulate(GLfloat dT) { time += dT; // wave in the current pos.x = loc.x + sin(time); // move along vector if (moving) { Vec3 dir; dir.z += v * dT; Mat4 m; m.rotate(bearing + 90, 0, 1, 0); m.transform(&dir); pos.add(&dir); } // check if out of bounds if (pos.x > MAX_X) pos.x = MIN_X; else if (pos.x < MIN_X) pos.x = MAX_X; if (pos.y > MAX_Y) pos.y = MIN_Y; else if (pos.y < MIN_Y) pos.y = MAX_Y; if (pos.z > MAX_Z) pos.z = MIN_Z; else if (pos.z < MIN_Z) pos.z = MAX_Z; }