#include #include #include #include #include #include "TextureCache.h" using namespace std; GLuint TextureCache::load(const string & filename) { map::iterator it = m_cache.find(filename); if (it != m_cache.end()) return it->second; GLuint tex = loadTexture(filename.c_str()); m_cache[filename] = tex; return tex; } GLuint TextureCache::loadTexture(const char * filename, bool mipmaps, int mode, int quality) { GLuint texture; SDL_Surface * temp = IMG_Load(filename); if (!temp) { cerr << "Failed to load image '" << filename << "'!" << endl; return 0; } SDL_PixelFormat fmt; fmt.palette = NULL; fmt.BitsPerPixel = 32; fmt.BytesPerPixel = 4; fmt.Rmask = 0x000000FF; fmt.Gmask = 0x0000FF00; fmt.Bmask = 0x00FF0000; fmt.Amask = 0xFF000000; fmt.Rshift = 0; fmt.Gshift = 8; fmt.Bshift = 16; fmt.Ashift = 24; SDL_Surface * texsurf = SDL_ConvertSurface(temp, &fmt, SDL_SWSURFACE); SDL_FreeSurface(temp); if (!texsurf) { cerr << '\'' << filename << "' was not converted properly!" << endl; return 0; } unsigned int * pixels = new unsigned int[texsurf->w * texsurf->h]; int y; unsigned int dstOffset = texsurf->w * (texsurf->h - 1); unsigned int srcOffset = 0; for (y = 0; y < texsurf->h; y++) { memcpy(pixels + dstOffset, ((unsigned int *)texsurf->pixels) + srcOffset, texsurf->w << 2); dstOffset -= texsurf->w; srcOffset += texsurf->w; } glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, 4, texsurf->w, texsurf->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); if (quality > 0) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); } else { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST); } glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode); if (mipmaps) gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, texsurf->w, texsurf->h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); SDL_FreeSurface(texsurf); delete[] pixels; return texture; }