From: grumbel Date: Sun, 6 Dec 2009 12:44:11 +0000 (+0000) Subject: Use a new Texture for each Surface, this should fix blending artifacts caused by... X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=a3d7403438f3a5caf84bbcecde6001729b093529;p=supertux.git 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 --- 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();