From a3d7403438f3a5caf84bbcecde6001729b093529 Mon Sep 17 00:00:00 2001 From: grumbel Date: Sun, 6 Dec 2009 12:44:11 +0000 Subject: [PATCH] Use a new Texture for each Surface, this should fix blending artifacts caused by shared Textures (code is not bug free right now, the ship path on the Worldmap doesn't show up) git-svn-id: http://supertux.lethargik.org/svn/supertux/trunk/supertux@6186 837edb03-e0f3-0310-88ca-d4d4e8b29345 --- src/video/sdl_surface_ptr.hpp | 5 +++++ src/video/surface.cpp | 4 ++-- src/video/texture_manager.cpp | 49 ++++++++++++++++++++++++++++++++++++++++--- src/video/texture_manager.hpp | 1 + 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/video/sdl_surface_ptr.hpp b/src/video/sdl_surface_ptr.hpp index 2fffc95fd..4311e7019 100644 --- a/src/video/sdl_surface_ptr.hpp +++ b/src/video/sdl_surface_ptr.hpp @@ -36,6 +36,11 @@ public: SDL_FreeSurface(m_surface); } + SDL_Surface* operator->() + { + return m_surface; + } + SDL_Surface* get() { return m_surface; diff --git a/src/video/surface.cpp b/src/video/surface.cpp index 5f1caf00c..4d8582baf 100644 --- a/src/video/surface.cpp +++ b/src/video/surface.cpp @@ -48,9 +48,9 @@ Surface::Surface(const std::string& file) : } Surface::Surface(const std::string& file, const Rect& rect_) : - texture(texture_manager->get(file)), + texture(texture_manager->get(file, rect_)), surface_data(), - rect(rect_), + rect(0, 0, Size(rect_.get_width(), rect_.get_height())), flipx(false) { texture->ref(); diff --git a/src/video/texture_manager.cpp b/src/video/texture_manager.cpp index 40736397f..6caf48595 100644 --- a/src/video/texture_manager.cpp +++ b/src/video/texture_manager.cpp @@ -20,6 +20,7 @@ #include #include +#include "math/rect.hpp" #include "physfs/physfs_sdl.hpp" #include "util/file_system.hpp" #include "util/log.hpp" @@ -68,7 +69,8 @@ TextureManager::get(const std::string& _filename) Texture* TextureManager::get(const std::string& filename, const Rect& rect) { - return 0; + // FIXME: implement caching + return create_image_texture(filename, rect); } void @@ -95,8 +97,49 @@ TextureManager::remove_texture(GLTexture* texture) Texture* TextureManager::create_image_texture(const std::string& filename, const Rect& rect) { - assert(!"not implemented"); - return 0; + try + { + return create_image_texture_raw(filename, rect); + } + 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; + } +} + +Texture* +TextureManager::create_image_texture_raw(const std::string& filename, const Rect& rect) +{ + SDLSurfacePtr 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 + { + 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 + { + Texture* result = VideoSystem::new_texture(subimage.get()); + result->set_filename(filename); + return result; + } + } } Texture* diff --git a/src/video/texture_manager.hpp b/src/video/texture_manager.hpp index a9a1fac3c..cf7f9400c 100644 --- a/src/video/texture_manager.hpp +++ b/src/video/texture_manager.hpp @@ -61,6 +61,7 @@ private: /** throw an exception on error */ Texture* create_image_texture_raw(const std::string& filename); + Texture* create_image_texture_raw(const std::string& filename, const Rect& rect); Texture* create_dummy_texture(); -- 2.11.0