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:

textures.cpp

home Home   up Up   ( Download )


#include "textures.h" // load an SDL surface into an OpenGL texture. GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord); // constructor // opens an image file and stores it in memory Texture::Texture(const char *file) { // load image file SDL_Surface *surface = IMG_Load(file); // create opengl texture GLfloat texcoord[4]; tex = SDL_GL_LoadTexture(surface, texcoord); minx = texcoord[0]; miny = texcoord[1]; maxx = texcoord[2]; maxy = texcoord[3]; // delete sdl image SDL_FreeSurface(surface); } // destructor Texture::~Texture() { GLuint ts[] = { tex }; glDeleteTextures( 1, &tex ); } /* Taken from texture.c in example on shaders COMP3004 website * ------------------------------------------------------------------- * QUOTE STARTS * ------------------------------------------------------------------/ /* Return power of 2 greater than input. */ static int power_of_two(int input) { int value = 1; while ( value < input ) { value <<= 1; } return value; } /* Load an SDL surface into an OpenGL texture. */ GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord) { GLuint texture; int w, h; SDL_Surface *image; SDL_Rect area; Uint32 saved_flags; Uint8 saved_alpha; static GLint texture_base = 0; w = power_of_two(surface->w);/* Use the surface width and height expanded to powers of 2 */ h = power_of_two(surface->h); texcoord[0] = 0.0f; /* Min X */ texcoord[1] = 0.0f; /* Min Y */ texcoord[2] = (GLfloat)surface->w / w; /* Max X */ texcoord[3] = (GLfloat)surface->h / h; /* Max Y */ image = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #else 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF #endif ); if ( image == NULL ) { return 0; } /* Save the alpha blending attributes */ saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK); saved_alpha = surface->format->alpha; if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { SDL_SetAlpha(surface, 0, 0); } /* Copy the surface into the GL texture image */ area.x = 0; area.y = 0; area.w = surface->w; area.h = surface->h; SDL_BlitSurface(surface, &area, image, &area); /* Restore the alpha blending attributes */ if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { SDL_SetAlpha(surface, saved_flags, saved_alpha); } //SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 0, 186, 171)); //SDL_SetAlpha(image, SDL_RLEACCEL|SDL_SRCALPHA, 50); /* Create an OpenGL texture for the image */ // glGenTextures(1, &texture); // generate a texture number texture = texture_base; texture_base++; glBindTexture(GL_TEXTURE_2D, texture); //Map specific texture to the 2D texture glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); return texture; } /* * ------------------------------------------------------------------ * QUOTE ENDS * ------------------------------------------------------------------ */