From 9dcbb5222c77cd853490552bb636a9b89e59f51d Mon Sep 17 00:00:00 2001 From: josh Date: Tue, 29 Jan 2008 04:52:55 +0000 Subject: [PATCH] initial import git-svn-id: svn://anubis/misc/TextureCache@27 bd8a9e45-a331-0410-811e-c64571078777 --- Makefile | 12 +++++++ TextureCache.cc | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ TextureCache.hh | 20 +++++++++++ 3 files changed, 126 insertions(+) create mode 100644 Makefile create mode 100644 TextureCache.cc create mode 100644 TextureCache.hh diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..19fec6d --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ + +CXX := g++ +CXXFLAGS := -O2 +OBJS := TextureCache.o + +all: $(OBJS) + +%.o: %.cc %.hh + $(CXX) -c -o $@ $< $(CXXFLAGS) + +clean: + -rm -f *~ *.o diff --git a/TextureCache.cc b/TextureCache.cc new file mode 100644 index 0000000..8a8ab29 --- /dev/null +++ b/TextureCache.cc @@ -0,0 +1,94 @@ + +#include +#include +#include +#include +#include +#include "TextureCache.hh" +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; +} diff --git a/TextureCache.hh b/TextureCache.hh new file mode 100644 index 0000000..25a9d06 --- /dev/null +++ b/TextureCache.hh @@ -0,0 +1,20 @@ + +#include +#include +#include + +class TextureCache +{ +public: + GLuint load(const std::string & filename); + +private: + /* methods */ + GLuint loadTexture(const char * filename, + bool mipmaps = false, + int mode = GL_DECAL, + int quality = 1); + + /* data */ + std::map< std::string, GLuint > m_cache; +};