X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fvideo%2Ftexture_manager.cpp;h=b64fcee3ac67a24eea4f90eacd8f3d1aff7ce327;hb=c2624ec9162122f2e625b57eac798ee37912c3e0;hp=3831132bb511dafc4edd94b267a61fba1c4690c9;hpb=fbbf4e7e6f3f9251826f0c68169d3f04bb67efa8;p=supertux.git diff --git a/src/video/texture_manager.cpp b/src/video/texture_manager.cpp index 3831132bb..b64fcee3a 100644 --- a/src/video/texture_manager.cpp +++ b/src/video/texture_manager.cpp @@ -19,17 +19,24 @@ #include #include #include +#include +#include #include "math/rect.hpp" #include "physfs/physfs_sdl.hpp" #include "util/file_system.hpp" #include "util/log.hpp" -#include "video/gl/gl_texture.hpp" #include "video/sdl_surface_ptr.hpp" +#include "video/texture.hpp" #include "video/video_systems.hpp" +#ifdef HAVE_OPENGL +#include "video/gl/gl_texture.hpp" +#endif + TextureManager::TextureManager() : image_textures() + ,surfaces() #ifdef HAVE_OPENGL ,textures(), saved_textures() @@ -39,45 +46,50 @@ TextureManager::TextureManager() : TextureManager::~TextureManager() { - for(ImageTextures::iterator i = image_textures.begin(); - i != image_textures.end(); ++i) { - if(i->second == NULL) - continue; - log_warning << "Texture '" << i->first << "' not freed" << std::endl; - delete i->second; + for(ImageTextures::iterator i = image_textures.begin(); i != image_textures.end(); ++i) + { + if(!i->second.expired()) + { + log_warning << "Texture '" << i->first << "' not freed" << std::endl; + } } + image_textures.clear(); } -Texture* +TexturePtr TextureManager::get(const std::string& _filename) { std::string filename = FileSystem::normalize(_filename); ImageTextures::iterator i = image_textures.find(filename); - Texture* texture = NULL; + TexturePtr texture; if(i != image_textures.end()) - texture = i->second; + texture = i->second.lock(); - if(texture == NULL) { + if(!texture) { texture = create_image_texture(filename); + texture->cache_filename = filename; image_textures[filename] = texture; } return texture; } -Texture* -TextureManager::get(const std::string& filename, const Rect& rect) +TexturePtr +TextureManager::get(const std::string& _filename, const Rect& rect) { + std::string filename = FileSystem::normalize(_filename); // FIXME: implement caching return create_image_texture(filename, rect); } void -TextureManager::release(Texture* texture) +TextureManager::reap_cache_entry(const std::string& filename) { - image_textures.erase(texture->get_filename()); - delete texture; + ImageTextures::iterator i = image_textures.find(filename); + assert(i != image_textures.end()); + assert(i->second.expired()); + image_textures.erase(i); } #ifdef HAVE_OPENGL @@ -94,7 +106,7 @@ TextureManager::remove_texture(GLTexture* texture) } #endif -Texture* +TexturePtr TextureManager::create_image_texture(const std::string& filename, const Rect& rect) { try @@ -104,53 +116,57 @@ TextureManager::create_image_texture(const std::string& filename, const Rect& re catch(const std::exception& err) { log_warning << "Couldn't load texture '" << filename << "' (now using dummy texture): " << err.what() << std::endl; - Texture* texture = create_dummy_texture(); - return texture; + return create_dummy_texture(); } } -Texture* +TexturePtr TextureManager::create_image_texture_raw(const std::string& filename, const Rect& rect) { - SDLSurfacePtr image(IMG_Load_RW(get_physfs_SDLRWops(filename), 1)); + SDL_Surface *image = NULL; + + Surfaces::iterator i = surfaces.find(filename); + if (i != surfaces.end()) + image = i->second; + + if (!image) { + image = IMG_Load_RW(get_physfs_SDLRWops(filename), 1); + } + if (!image) { std::ostringstream msg; msg << "Couldn't load image '" << filename << "' :" << SDL_GetError(); throw std::runtime_error(msg.str()); } - else + + surfaces[filename] = image; + + SDLSurfacePtr subimage(SDL_CreateRGBSurfaceFrom(static_cast(image->pixels) + + rect.top * image->pitch + + rect.left * image->format->BytesPerPixel, + + rect.get_width(), rect.get_height(), + image->format->BitsPerPixel, + image->pitch, + image->format->Rmask, + image->format->Gmask, + image->format->Bmask, + image->format->Amask)); + if (!subimage) { - SDLSurfacePtr subimage(SDL_CreateRGBSurfaceFrom(static_cast(image->pixels) + - rect.top * image->pitch + - rect.left * image->format->BytesPerPixel, - - rect.get_width(), rect.get_height(), - image->format->BitsPerPixel, - image->pitch, - image->format->Rmask, - image->format->Gmask, - image->format->Bmask, - image->format->Amask)); - if (!subimage) - { - throw std::runtime_error("SDL_CreateRGBSurfaceFrom() call failed"); - } - else - { - if (image->format->palette) - { // copy the image palette to subimage if present - SDL_SetColors(subimage.get(), image->format->palette->colors, 0, image->format->palette->ncolors); - } - - Texture* result = VideoSystem::new_texture(subimage.get()); - result->set_filename(filename); - return result; - } + throw std::runtime_error("SDL_CreateRGBSurfaceFrom() call failed"); } + + /* if (image->format->palette) + { // copy the image palette to subimage if present + SDL_SetSurfacePalette(subimage.get(), image->format->palette->colors); //edited by giby + } */ + + return VideoSystem::new_texture(subimage.get()); } -Texture* +TexturePtr TextureManager::create_image_texture(const std::string& filename) { try @@ -160,12 +176,11 @@ TextureManager::create_image_texture(const std::string& filename) catch (const std::exception& err) { log_warning << "Couldn't load texture '" << filename << "' (now using dummy texture): " << err.what() << std::endl; - Texture* texture = create_dummy_texture(); - return texture; + return create_dummy_texture(); } } -Texture* +TexturePtr TextureManager::create_image_texture_raw(const std::string& filename) { SDLSurfacePtr image(IMG_Load_RW(get_physfs_SDLRWops(filename), 1)); @@ -177,13 +192,11 @@ TextureManager::create_image_texture_raw(const std::string& filename) } else { - Texture* result = VideoSystem::new_texture(image.get()); - result->set_filename(filename); - return result; + return VideoSystem::new_texture(image.get()); } } -Texture* +TexturePtr TextureManager::create_dummy_texture() { const std::string dummy_texture_fname = "images/engine/missing.png"; @@ -191,7 +204,7 @@ TextureManager::create_dummy_texture() // on error, try loading placeholder file try { - Texture* tex = create_image_texture_raw(dummy_texture_fname); + TexturePtr tex = create_image_texture_raw(dummy_texture_fname); return tex; } catch (const std::exception& err) @@ -205,10 +218,8 @@ TextureManager::create_dummy_texture() } else { - Texture* result = VideoSystem::new_texture(image.get()); - result->set_filename("-dummy-texture-.png"); log_warning << "Couldn't load texture '" << dummy_texture_fname << "' (now using empty one): " << err.what() << std::endl; - return result; + return VideoSystem::new_texture(image.get()); } } } @@ -232,7 +243,7 @@ TextureManager::save_textures() } for(ImageTextures::iterator i = image_textures.begin(); i != image_textures.end(); ++i) { - save_texture(dynamic_cast(i->second)); + save_texture(dynamic_cast(i->second.lock().get())); } }