/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program 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, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER #include "texture_sequence.h" #include "debug.h" #include "graphics_engine.h" #include #ifdef HAVE_SDL_IMAGE_H #include #else #include #endif ObjectListDefinition(TextureSequence); /** * @brief Constructor for a Texture */ TextureSequence::TextureSequence(unsigned int count, ...) { this->registerObject(this, TextureSequence::_objectList); va_list textureNameList; va_start(textureNameList, count); for (unsigned int i = 0; i < count; i++) { this->addFrame(va_arg(textureNameList, char*)); } va_end(textureNameList); this->loadImageSeries(count, textureNameList); } /** * @brief Creates an ImageSeries out of TextureNames. * @param textureNames The Names of the Textures * @param prependFolder Optional you can prepend a Folder of Textures. */ TextureSequence::TextureSequence(const std::vector& textureNames, const std::string& prependFolder) { this->registerObject(this, TextureSequence::_objectList); this->loadImageSeries(textureNames, prependFolder); } /** * @brief Destructor of a TextureSequence * * Frees Data, and deletes the textures from GL */ TextureSequence::~TextureSequence() { this->clearLists(); } void TextureSequence::clearLists() { // delete all images while(!this->images.empty()) { SDL_FreeSurface(this->images.back()); this->images.pop_back(); } // delete all textures. while(!this->textures.empty()) { if (glIsTexture(this->textures.back())) glDeleteTextures(1, &this->textures.back()); this->textures.pop_back(); } } /** * @brief loads an image Sequence * @param count how many images to load to the TextureSequence * @param ... the names of the Images to load * @returns true on success, false otherwise */ bool TextureSequence::loadImageSeries(unsigned int count, ...) { bool retVal = true; va_list textureNameList; va_start(textureNameList, count); for (unsigned int i = 0; i < count; i++) { if( !this->addFrame(va_arg(textureNameList, char*))) retVal = false; } va_end(textureNameList); return retVal; } /** * @brief Load an TextureSeries from TextureNames * @param textureNames The Names of the Textures. * @param prependFolder (optional) the Folder to prepend * @return true on success. */ bool TextureSequence::loadImageSeries(const std::vector& textureNames, const std::string& prependFolder) { bool retVal = true; for (unsigned int i = 0; i < textureNames.size(); i++) { if( !this->addFrame(prependFolder + textureNames[i])) retVal = false; } return retVal; } /** * @brief Loads an Image-Series into the TextureSequence. * @param imageNameSubstitue The Prefix of the Image * @param from From which image * @param to To which image * @return true on success. * * @example to load the Files image_001.jpg, image_002.jpg, ... image_099.jpg * use loadImageSeries("image_###.jpg", 0, 99); * @note important is, that the count of ###'s is correct. */ bool TextureSequence::loadImageSeries(const std::string& imageNameSubstitue, unsigned int from, unsigned int to) { unsigned int index = 0; unsigned int frameSize = 0; // search for the special character # in the LoadParam if ((index = imageNameSubstitue.find("_#")) != std::string::npos) { std::string _imageNameSubstitue = imageNameSubstitue; index++; // start at # while(imageNameSubstitue[index+frameSize] == '#') { _imageNameSubstitue[index+frameSize] = '0'; frameSize++; } PRINTF(4)("Found %d '#'s in %s... searching for LOD's\n", frameSize, imageNameSubstitue.c_str()); char tmpString[32]; for (unsigned int i = from; i < to; i++) { sprintf(tmpString, "%d", i); _imageNameSubstitue.replace(index+frameSize -strlen(tmpString), strlen(tmpString), tmpString); this->addFrame(_imageNameSubstitue); } return true; } return false; } /** * @brief adds a new Frame to this Sequence (at the end) * @param imageName the Name of the Image to add * @returns true on success */ bool TextureSequence::addFrame(const std::string& imageName) { SDL_Surface* addSurface = IMG_Load(imageName.c_str()); if (addSurface == NULL) { PRINTF(2)("Unable to load Image %s\n", imageName.c_str()); return false; } bool success = this->addFrame(addSurface); SDL_FreeSurface(addSurface); return success; } /** * @brief adds a new Frame at the end of the Sequence. * @param surface the Surface to add at the end of the Sequence. */ bool TextureSequence::addFrame(SDL_Surface* surface) { if (surface == NULL) return false; bool hasAlpha; SDL_Surface* newSurf = this->prepareSurface(surface, hasAlpha); if (newSurf != NULL) { this->images.push_back(newSurf); this->textures.push_back(Texture::loadTexToGL(newSurf)); } this->setAlpha(hasAlpha); return true; } /** * @brief adds a new Frame at the end of the Sequence. * @param texture the texture to add at the end of the Sequence. */ bool TextureSequence::addFrame(GLuint texture) { if (texture == 0) return false; this->textures.push_back(texture); return true; } /** * @brief rebuilds all the textures from the Images stored in this FrameSequence */ bool TextureSequence::rebuild() { PRINTF(3)("Reloading TextureSequence of %s '%s'\n", this->getClassCName(), this->getCName()); for (unsigned int i = 0; i < this->textures.size(); i++) { if (glIsTexture(this->textures[i])) { glDeleteTextures(1, &this->textures[i]); this->textures[i] = 0; } if (this->images[i] != NULL) this->textures[i] = loadTexToGL(this->images[i]); } return true; }