1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
// textureloader.cpp
// TextureLoader
// by Joe Flint
// OpenGL Texture loading with the help of SDL_Image
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "textureloader.h"
#include "SDL_image.h"
vector<string> TextureLoader::names;
vector<GLuint> TextureLoader::textures;
vector<string> TextureLoader::filenames;
bool TextureLoader::loadTexture( const string & filename, const string & name )
{
glEnable( GL_TEXTURE_2D );
// First look for a duplicate name and error out
for( unsigned int i = 0; i < names.size(); i++ )
if( names.at( i ) == name )
return false;
// Name is ok, now try to load the image data from the file
SDL_Surface *img = IMG_Load( filename.c_str() );
if( img == NULL )
// Image file failed to load for some reason
return false;
// Make sure the size is a power of two
if( nearestPow2( img->w ) != img->w || nearestPow2( img->h ) != img->h )
return false;
// Loaded ok, store it in an OpenGL texture
GLuint newtext = loadSurface( img );
// All went well
names.push_back( name );
textures.push_back( newtext );
filenames.push_back( filename );
// Free the image data
SDL_FreeSurface( img );
return true;
}
bool TextureLoader::setTexture( const string & name )
{
for( unsigned int i = 0; i < names.size(); i++ ) {
if( names.at( i ) == name ) {
glBindTexture( GL_TEXTURE_2D, textures.at( i ) );
return true;
}
}
// No texture by that name
return false;
}
bool TextureLoader::setTexture( unsigned int index )
{
if( index < textures.size() ) {
glBindTexture( GL_TEXTURE_2D, textures.at( index ) );
return true;
}
return false;
}
void TextureLoader::reload()
{
SDL_Surface *img;
for( unsigned int i = 0; i < filenames.size(); i++ ) {
img = IMG_Load( filenames.at( i ).c_str() );
textures.at( i ) = loadSurface( img );
}
}
void TextureLoader::unload()
{
unloadGL();
textures.clear();
names.clear();
filenames.clear();
}
void TextureLoader::unloadGL()
{
for( unsigned int i = 0; i < textures.size(); i++ )
glDeleteTextures( 1, &textures.at( i ) );
}
GLuint TextureLoader::loadSurface( SDL_Surface * surf )
{
GLuint newtext;
// Create a new texture handle
glGenTextures( 1, &newtext );
// Bind to the new handle
glBindTexture( GL_TEXTURE_2D, newtext );
// Load the actual data
glTexImage2D( GL_TEXTURE_2D, 0, surf->format->BytesPerPixel, surf->w,
surf->h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
surf->pixels );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
return newtext;
}
unsigned int TextureLoader::nearestPow2( unsigned int n )
{
unsigned int pow2;
for( pow2 = 2; pow2 < n; pow2 *= 2 ) {}
return pow2;
}
|