X-Git-Url: https://git.jsancho.org/?a=blobdiff_plain;f=Source%2FTexture.cpp;h=a9c69cfe048646720fccdbe61ffdc5c3934647ad;hb=cd043e3f9e26c2b3406b40a354c2840941e9db7f;hp=37d4073b0a862e2f8488e816e00618572070b1f4;hpb=01a48eb9a98fa8c7d407077aa69d493e74eb86cd;p=lugaru.git diff --git a/Source/Texture.cpp b/Source/Texture.cpp index 37d4073..a9c69cf 100644 --- a/Source/Texture.cpp +++ b/Source/Texture.cpp @@ -1,92 +1,185 @@ +/* +Copyright (C) 2003, 2010 - Wolfire Games + +This file is part of Lugaru. + +Lugaru 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. + +Lugaru is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Lugaru. If not, see . +*/ + #include "gamegl.h" #include "Texture.h" #include "TGALoader.h" using namespace std; -map Texture::textures; - extern TGAImageRec texture; extern bool trilinear; -void Texture::load() { - GLuint type; - - LOGFUNC; - - LOG(std::string("Loading texture...") + fileName); - - unsigned char fileNamep[256]; - CopyCStringToPascal(ConvertFileName(fileName.c_str()), fileNamep); - //Load Image - upload_image( fileNamep ,hasalpha); - - //Alpha channel? - if ( texture.bpp == 24 ) - type = GL_RGB; - else - type = GL_RGBA; - - glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - - if(!id) - glGenTextures( 1, &id ); - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - - glBindTexture( GL_TEXTURE_2D, id); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - if(mipmap) - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (trilinear?GL_LINEAR_MIPMAP_LINEAR:GL_LINEAR_MIPMAP_NEAREST) ); - else - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - - skinsize=texture.sizeX; - - if(isSkin) { - int tempnum=0; - int nb = (texture.sizeY*texture.sizeX*(texture.bpp/8)); - array = (GLubyte*)malloc(nb*sizeof(GLubyte)); - for(int i=0;i list; + + GLuint id; + string filename; + bool hasMipmap; + bool hasAlpha; + bool isSkin; + int skinsize; + GLubyte* data; + int datalen; + GLubyte* skindata; + + void load(); + +public: + TextureRes(const string& filename, bool hasMipmap, bool hasAlpha); + TextureRes(const string& filename, bool hasMipmap, GLubyte* array, int* skinsize); + ~TextureRes(); + void bind(); + + static void reloadAll(); +}; + + +vector TextureRes::list; + +void TextureRes::load() +{ + //load image into 'texture' global var + if (!skindata) { + unsigned char filenamep[256]; + CopyCStringToPascal(ConvertFileName(filename.c_str()), filenamep); + upload_image(filenamep, hasAlpha); + } + + skinsize = texture.sizeX; + GLuint type = GL_RGBA; + if (texture.bpp == 24) + type = GL_RGB; + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glDeleteTextures(1, &id); + glGenTextures(1, &id); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glBindTexture(GL_TEXTURE_2D, id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (hasMipmap) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (trilinear ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST)); + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + + if (isSkin) { + if (skindata) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, skinsize, skinsize, 0, GL_RGB, GL_UNSIGNED_BYTE, skindata); + } else { + free(data); + const int nb = texture.sizeY * texture.sizeX * (texture.bpp / 8); + data = (GLubyte*)malloc(nb * sizeof(GLubyte)); + datalen = 0; + for (int i = 0; i < nb; i++) + if ((i + 1) % 4 || type == GL_RGB) + data[datalen++] = texture.data[i]; + glTexImage2D(GL_TEXTURE_2D, 0, type, texture.sizeX, texture.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + } + } else { + glTexImage2D(GL_TEXTURE_2D, 0, type, texture.sizeX, texture.sizeY, 0, type, GL_UNSIGNED_BYTE, texture.data); + } +} + +void TextureRes::bind() +{ + glBindTexture(GL_TEXTURE_2D, id); +} + +TextureRes::TextureRes(const string& _filename, bool _hasMipmap, bool _hasAlpha): + id(0), filename(_filename), hasMipmap(_hasMipmap), hasAlpha(_hasAlpha), isSkin(false), + skinsize(0), data(NULL), datalen(0), skindata(NULL) +{ + load(); + list.push_back(this); +} + +TextureRes::TextureRes(const string& _filename, bool _hasMipmap, GLubyte* array, int* skinsizep): + id(0), filename(_filename), hasMipmap(_hasMipmap), hasAlpha(false), isSkin(true), + skinsize(0), data(NULL), datalen(0), skindata(NULL) +{ + load(); + *skinsizep = skinsize; + for (int i = 0; i < datalen; i++) + array[i] = data[i]; + skindata = array; + list.push_back(this); +} + +TextureRes::~TextureRes() +{ + free(data); + glDeleteTextures(1, &id); + for (vector::iterator it = list.begin(); it != list.end(); it++) + if (*it == this) { + list.erase(it); + break; + } +} + +void TextureRes::reloadAll() +{ + for (vector::iterator it = list.begin(); it != list.end(); it++) { + (*it)->id = 0; + (*it)->load(); + } +} + + + + +void Texture::load(const string& filename, bool hasMipmap, bool hasAlpha) +{ + destroy(); + tex = new TextureRes(filename, hasMipmap, hasAlpha); +} + +void Texture::load(const string& filename, bool hasMipmap, GLubyte* array, int* skinsizep) +{ + destroy(); + tex = new TextureRes(filename, hasMipmap, array, skinsizep); +} + +void Texture::destroy() +{ + if (tex) { + delete tex; + tex = NULL; + } } -GLuint Texture::Load(const string& fileName, bool mipmap, bool hasalpha) { - map::iterator it = textures.find(fileName); - if(it==textures.end()) { - textures.insert(make_pair(fileName,Texture(fileName,mipmap,hasalpha))); - textures[fileName].load(); - return textures[fileName].getId(); - } else { - return it->second.getId(); - } +void Texture::bind() +{ + if (tex) + tex->bind(); + else + glBindTexture(GL_TEXTURE_2D, 0); } -GLuint Texture::Load(const string& fileName, bool mipmap, bool hasalpha, GLubyte* array, int* skinsize) { - map::iterator it = textures.find(fileName); - if(it==textures.end()) { - textures.insert(make_pair(fileName,Texture(fileName,mipmap,hasalpha,true))); - textures[fileName].load(); - *skinsize = textures[fileName].skinsize; - for(int i=0;isecond.skinsize; - for(int i=0;isecond.arraySize;i++) { - array[i] = it->second.array[i]; - } - return it->second.getId(); - } +void Texture::reloadAll() +{ + TextureRes::reloadAll(); }