From e479e1826cdc1eb2e3474e738b8e4313ac6a94c1 Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke 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) SVN-Revision: 6186 --- 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