Use a new Texture for each Surface, this should fix blending artifacts caused by...
authorgrumbel <grumbel@837edb03-e0f3-0310-88ca-d4d4e8b29345>
Sun, 6 Dec 2009 12:44:11 +0000 (12:44 +0000)
committergrumbel <grumbel@837edb03-e0f3-0310-88ca-d4d4e8b29345>
Sun, 6 Dec 2009 12:44:11 +0000 (12:44 +0000)
git-svn-id: http://supertux.lethargik.org/svn/supertux/trunk/supertux@6186 837edb03-e0f3-0310-88ca-d4d4e8b29345

src/video/sdl_surface_ptr.hpp
src/video/surface.cpp
src/video/texture_manager.cpp
src/video/texture_manager.hpp

index 2fffc95..4311e70 100644 (file)
@@ -36,6 +36,11 @@ public:
     SDL_FreeSurface(m_surface);
   }
 
+  SDL_Surface* operator->()
+  {
+    return m_surface;
+  }
+
   SDL_Surface* get()
   {
     return m_surface;
index 5f1caf0..4d8582b 100644 (file)
@@ -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();
index 4073639..6caf485 100644 (file)
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include <iostream>
 
+#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<uint8_t*>(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*
index a9a1fac..cf7f940 100644 (file)
@@ -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();