/* render/textures.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include "render/gl.h" #include "render/textures.h" #include "render/tga.h" #include "render/pngfile.h" #include "render/jpgfile.h" #include "sys/sys.h" #include "core/application.h" namespace render { std::map Textures::registry; GLuint Textures::textures[MAXTEXTURES]; void Textures::init() { con_print << "^BLoading textures..." << std::endl; if (registry.size()) { clear(); } else { memset(textures,0, sizeof(textures)); } // "no texture" bitmap load("textures/common/notex"); // gui font if (!load("bitmaps/fonts/gui", false)) { con_error << "Essential file bitmaps/fonts/gui missing" << std::endl; core::application()->shutdown(); } // loading screen background load("bitmaps/loader"); // crosshairs load("bitmaps/pointers/pointer"); load("bitmaps/pointers/aim"); load("bitmaps/pointers/center"); load("bitmaps/pointers/control"); load("bitmaps/pointers/target"); } void Textures::shutdown() { clear(); } void Textures::list() { for (iterator it = registry.begin(); it != registry.end(); it++) { con_print << " " << (*it).first << " " << (*it).second << std::endl; } con_print << registry.size() << " loaded textures" << std::endl; } void Textures::clear() { for (size_t i=0; i < MAXTEXTURES; i++) { if (textures[i]) { glDeleteTextures(1, &textures[i]); } } registry.clear(); memset(textures,0, sizeof(textures)); } void Textures::unload(std::string name) { iterator it = registry.find(name); if (it != registry.end()) { con_debug << " unloading " << (*it).first << std::endl; size_t id = (*it).second; if (textures[id]) { glDeleteTextures(1, &textures[id]); } registry.erase(it); } } void Textures::unload(size_t id) { // find in map for (iterator it = registry.begin(); it != registry.end(); it++) { if ((*it).second == id) { con_debug << " unloading " << (*it).first << std::endl; size_t id = (*it).second; if (textures[id]) { glDeleteTextures(1, &textures[id]); } registry.erase(it); break; } } } size_t Textures::load(std::string name, bool filter) { // check if it is already loaded iterator it = registry.find(name); if (it != registry.end()) return (*it).second; // find first available texture size_t id = 0; while ((id < MAXTEXTURES) && (textures[id])) { id++; } if (id == MAXTEXTURES) { con_error << "Texture limit " << MAXTEXTURES << " exceeded!" << std::endl; registry[name] = 0; return 0; } std::string filename; Image *image = 0; if (!image) { // try the png version filename.assign(name); filename.append(".png"); image = PNG::load(filename.c_str()); } if (!image) { // try the tga version filename.assign(name); filename.append(".tga"); image = TGA::load(filename.c_str()); } if (!image) { // try the jpg version filename.assign(name); filename.append(".jpg"); image = JPG::load(filename.c_str()); } if (!image) { // add to the registry with id 0 (texture not found) con_warn << "Could not open " << filename << std::endl; registry[name] = 0; return 0; } glGenTextures(1, &textures[id]); glBindTexture(GL_TEXTURE_2D, textures[id]); int texture_type; if (image->channels() == 4) texture_type = GL_RGBA; else texture_type = GL_RGB; gluBuild2DMipmaps(GL_TEXTURE_2D, image->channels(), image->width(), image->height(), texture_type, GL_UNSIGNED_BYTE, image->data()); set_filter(filter); // add to the registry registry[name] = id; // delete image data delete image; return id; } size_t Textures::find(std::string name) { size_t id = 0; iterator it = registry.find(name); if (it != registry.end()) id = (*it).second; return id; } size_t Textures::bind(std::string name, bool filter) { size_t id = 0; iterator it = registry.find(name); if (it != registry.end()) id = (*it).second; else id = load(name); glBindTexture(GL_TEXTURE_2D, textures[id]); set_filter(filter); return id; } size_t Textures::bind(size_t texture, bool filter) { size_t id = texture; if (!textures[id]) id = 0; glBindTexture(GL_TEXTURE_2D, textures[id]); set_filter(filter); return id; } void Textures::set_filter(bool filter) { if (filter) { glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); } } }