/* 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 "render/gl.h" #include "render/textures.h" #include "render/tga.h" #include "sys/sys.h" #include "core/application.h" namespace render { std::map Textures::registry; size_t Textures::index = 0; GLuint Textures::textures[MAXTEXTURES]; void Textures::init() { clear(); con_print << "^BLoading textures..." << std::endl; // "no texture" bitmap load("textures/common/notex"); // console characters if (!load("bitmaps/fonts/console", false)) { con_error << "Essential file bitmaps/fonts/console missing" << std::endl; core::application()->shutdown(); } // console characters 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/crosshairs/aim"); load("bitmaps/crosshairs/control"); load("bitmaps/crosshairs/target"); // light flares load("bitmaps/fx/flare00"); load("bitmaps/fx/flare01"); } void Textures::shutdown() { clear(); } void Textures::clear() { if (index) glDeleteTextures(index, textures); registry.clear(); memset(textures,0, sizeof(textures)); index = 0; } 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; // try the tga version std::string filename(name); filename.append(".tga"); Image *image = TGA::load(filename.c_str()); if (!image) { // add to the registry with id 0 (texture not found) registry[name] = 0; return 0; } if (index == MAXTEXTURES) { con_error << "Texture limit " << MAXTEXTURES << " exceeded!" << std::endl; delete image; registry[name] = 0; return 0; } size_t id = index; 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; index++; // 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 (texture >= index) 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); } } }