TextureCache/TextureCache.cc
josh 93490cb3d1 not setting texture environment mode when loading a texture
git-svn-id: svn://anubis/misc/TextureCache@216 bd8a9e45-a331-0410-811e-c64571078777
2009-11-20 04:50:41 +00:00

144 lines
3.7 KiB
C++

#include <SDL.h>
#include <SDL_image.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <iostream>
#include "TextureCache.h"
#include "TextureLoader/TextureLoader.h"
#include "FileLoader/FileLoader.h"
using namespace std;
//#define DEBUG_GL_ERROR
#ifdef DEBUG_GL_ERROR
#define checkGLError() checkGLErrorLine(__FUNCTION__, __LINE__)
static void checkGLErrorLine(const char * function, int line)
{
GLenum err = glGetError();
if (err != 0)
{
cerr << "gl error in " << function
<< ": " << err << " (0x" << hex << err << ") at line "
<< dec << line << endl;
}
}
#else
#define checkGLError()
#endif
TextureCache::~TextureCache()
{
}
GLuint TextureCache::load(const FileLoader::Path & path,
FileLoader & fileLoader, bool mipmaps,
int mode, int quality)
{
string filename = path.shortPath;
if (filename == "")
filename = path.fullPath;
if (filename == "")
return 0;
map<string,GLuint>::iterator it = m_cache.find(filename);
if (it != m_cache.end())
{
return it->second;
}
GLuint tex = loadTexture(path, fileLoader, mipmaps, mode, quality);
if (tex > 0)
{
m_cache[filename] = tex;
}
return tex;
}
GLuint TextureCache::loadTexture(const FileLoader::Path & path,
FileLoader & fileLoader, bool mipmaps,
int mode, int quality)
{
checkGLError();
GLuint texture;
FileLoader::Buffer buff = fileLoader.load(path);
if (buff.size <= 0)
return 0;
SDL_RWops * ops = SDL_RWFromMem(buff.data, buff.size);
SDL_Surface * temp = IMG_Load_RW(ops, true);
if (!temp)
{
cerr << "Failed to load image ('" << path.fullPath << "', '"
<< path.shortPath << "'): " << IMG_GetError() << 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 << "Image 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);
checkGLError();
glBindTexture(GL_TEXTURE_2D, texture);
checkGLError();
glTexImage2D(GL_TEXTURE_2D, 0, 4, texsurf->w, texsurf->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, pixels);
if (quality > 0)
{
checkGLError();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
checkGLError();
}
else
{
checkGLError();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
mipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
checkGLError();
}
checkGLError();
if (mipmaps)
{
checkGLError();
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA,
texsurf->w, texsurf->h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
checkGLError();
}
SDL_FreeSurface(texsurf);
delete[] pixels;
checkGLError();
return texture;
}