From b0bf549b4f85bc84429d2b09d16432aa4b2e7e5b Mon Sep 17 00:00:00 2001 From: grumbel Date: Mon, 14 Dec 2009 10:26:09 +0000 Subject: [PATCH] Added TexturePtr git-svn-id: http://supertux.lethargik.org/svn/supertux/trunk/supertux@6217 837edb03-e0f3-0310-88ca-d4d4e8b29345 --- src/video/gl/gl_lightmap.cpp | 16 +++++--------- src/video/gl/gl_lightmap.hpp | 2 +- src/video/gl/gl_renderer.cpp | 4 ++-- src/video/sdl/sdl_lightmap.cpp | 4 ++-- src/video/sdl/sdl_renderer.cpp | 4 ++-- src/video/surface.cpp | 6 +----- src/video/surface.hpp | 6 +++--- src/video/texture.hpp | 28 ++++++------------------ src/video/texture_manager.cpp | 48 +++++++++++++++++++++--------------------- src/video/texture_manager.hpp | 18 +++++++++------- src/video/texture_ptr.hpp | 27 ++++++++++++++++++++++++ src/video/video_systems.cpp | 14 ++++++------ src/video/video_systems.hpp | 5 +++-- 13 files changed, 93 insertions(+), 89 deletions(-) create mode 100644 src/video/texture_ptr.hpp diff --git a/src/video/gl/gl_lightmap.cpp b/src/video/gl/gl_lightmap.cpp index 08cfa99a8..57b9730a0 100644 --- a/src/video/gl/gl_lightmap.cpp +++ b/src/video/gl/gl_lightmap.cpp @@ -142,19 +142,15 @@ GLLightmap::GLLightmap() : unsigned int width = next_po2(lightmap_width); unsigned int height = next_po2(lightmap_height); - lightmap = new GLTexture(width, height); + lightmap.reset(new GLTexture(width, height)); lightmap_uv_right = static_cast(lightmap_width) / static_cast(width); lightmap_uv_bottom = static_cast(lightmap_height) / static_cast(height); - texture_manager->register_texture(lightmap); + texture_manager->register_texture(lightmap.get()); } GLLightmap::~GLLightmap() { - if(texture_manager){ - texture_manager->remove_texture(lightmap); - } - delete lightmap; } void @@ -199,12 +195,10 @@ GLLightmap::end_draw() void GLLightmap::do_draw() { - const GLTexture* texture = lightmap; - // multiple the lightmap with the framebuffer glBlendFunc(GL_DST_COLOR, GL_ZERO); - glBindTexture(GL_TEXTURE_2D, texture->get_handle()); + glBindTexture(GL_TEXTURE_2D, lightmap->get_handle()); float vertices[] = { 0, 0, @@ -231,7 +225,7 @@ void GLLightmap::draw_surface(const DrawingRequest& request) { const Surface* surface = (const Surface*) request.request_data; - GLTexture *gltexture = dynamic_cast(surface->get_texture()); + boost::shared_ptr gltexture = boost::dynamic_pointer_cast(surface->get_texture()); GLSurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); glBindTexture(GL_TEXTURE_2D, gltexture->get_handle()); @@ -255,7 +249,7 @@ GLLightmap::draw_surface_part(const DrawingRequest& request) const SurfacePartRequest* surfacepartrequest = (SurfacePartRequest*) request.request_data; const Surface* surface = surfacepartrequest->surface; - GLTexture *gltexture = dynamic_cast(surface->get_texture()); + boost::shared_ptr gltexture = boost::dynamic_pointer_cast(surface->get_texture()); GLSurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left(); diff --git a/src/video/gl/gl_lightmap.hpp b/src/video/gl/gl_lightmap.hpp index f6af11d21..10ee5465d 100644 --- a/src/video/gl/gl_lightmap.hpp +++ b/src/video/gl/gl_lightmap.hpp @@ -43,7 +43,7 @@ private: static const int LIGHTMAP_DIV = 5; SDL_Surface* screen; - GLTexture* lightmap; + boost::shared_ptr lightmap; int lightmap_width; int lightmap_height; float lightmap_uv_right; diff --git a/src/video/gl/gl_renderer.cpp b/src/video/gl/gl_renderer.cpp index 9c88cd34b..5b62d2dad 100644 --- a/src/video/gl/gl_renderer.cpp +++ b/src/video/gl/gl_renderer.cpp @@ -192,7 +192,7 @@ void GLRenderer::draw_surface(const DrawingRequest& request) { const Surface* surface = (const Surface*) request.request_data; - GLTexture *gltexture = dynamic_cast(surface->get_texture()); + boost::shared_ptr gltexture = boost::dynamic_pointer_cast(surface->get_texture()); GLSurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); glBindTexture(GL_TEXTURE_2D, gltexture->get_handle()); @@ -216,7 +216,7 @@ GLRenderer::draw_surface_part(const DrawingRequest& request) const SurfacePartRequest* surfacepartrequest = (SurfacePartRequest*) request.request_data; const Surface* surface = surfacepartrequest->surface; - GLTexture *gltexture = dynamic_cast(surface->get_texture()); + boost::shared_ptr gltexture = boost::dynamic_pointer_cast(surface->get_texture()); GLSurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left(); diff --git a/src/video/sdl/sdl_lightmap.cpp b/src/video/sdl/sdl_lightmap.cpp index 4c6234d7f..b523fbc36 100644 --- a/src/video/sdl/sdl_lightmap.cpp +++ b/src/video/sdl/sdl_lightmap.cpp @@ -451,7 +451,7 @@ SDLLightmap::draw_surface(const DrawingRequest& request) //FIXME: support parameters request.alpha, request.angle, request.blend const Surface* surface = (const Surface*) request.request_data; - SDLTexture *sdltexture = dynamic_cast(surface->get_texture()); + boost::shared_ptr sdltexture = boost::dynamic_pointer_cast(surface->get_texture()); SDLSurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); DrawingEffect effect = request.drawing_effect; @@ -478,7 +478,7 @@ SDLLightmap::draw_surface_part(const DrawingRequest& request) = (SurfacePartRequest*) request.request_data; const Surface* surface = surfacepartrequest->surface; - SDLTexture *sdltexture = dynamic_cast(surface->get_texture()); + boost::shared_ptr sdltexture = boost::dynamic_pointer_cast(surface->get_texture()); DrawingEffect effect = request.drawing_effect; if (surface->get_flipx()) effect = HORIZONTAL_FLIP; diff --git a/src/video/sdl/sdl_renderer.cpp b/src/video/sdl/sdl_renderer.cpp index dc4b73829..d769dc5f6 100644 --- a/src/video/sdl/sdl_renderer.cpp +++ b/src/video/sdl/sdl_renderer.cpp @@ -169,7 +169,7 @@ SDLRenderer::draw_surface(const DrawingRequest& request) { //FIXME: support parameters request.alpha, request.angle, request.blend const Surface* surface = (const Surface*) request.request_data; - SDLTexture *sdltexture = dynamic_cast(surface->get_texture()); + boost::shared_ptr sdltexture = boost::dynamic_pointer_cast(surface->get_texture()); SDLSurfaceData *surface_data = reinterpret_cast(surface->get_surface_data()); DrawingEffect effect = request.drawing_effect; @@ -238,7 +238,7 @@ SDLRenderer::draw_surface_part(const DrawingRequest& request) = (SurfacePartRequest*) request.request_data; const Surface* surface = surfacepartrequest->surface; - SDLTexture *sdltexture = dynamic_cast(surface->get_texture()); + boost::shared_ptr sdltexture = boost::dynamic_pointer_cast(surface->get_texture()); DrawingEffect effect = request.drawing_effect; if (surface->get_flipx()) effect = HORIZONTAL_FLIP; diff --git a/src/video/surface.cpp b/src/video/surface.cpp index 98bd86809..f9eb560e8 100644 --- a/src/video/surface.cpp +++ b/src/video/surface.cpp @@ -43,7 +43,6 @@ Surface::Surface(const std::string& file) : texture->get_image_height())), flipx(false) { - texture->ref(); surface_data = VideoSystem::new_surface_data(*this); } @@ -53,7 +52,6 @@ Surface::Surface(const std::string& file, const Rect& rect_) : rect(0, 0, Size(rect_.get_width(), rect_.get_height())), flipx(false) { - texture->ref(); surface_data = VideoSystem::new_surface_data(*this); } @@ -63,14 +61,12 @@ Surface::Surface(const Surface& rhs) : rect(rhs.rect), flipx(false) { - texture->ref(); surface_data = VideoSystem::new_surface_data(*this); } Surface::~Surface() { VideoSystem::free_surface_data(surface_data); - texture->unref(); } SurfacePtr @@ -91,7 +87,7 @@ bool Surface::get_flipx() const return flipx; } -Texture* +TexturePtr Surface::get_texture() const { return texture; diff --git a/src/video/surface.hpp b/src/video/surface.hpp index 9523efd7d..07280817b 100644 --- a/src/video/surface.hpp +++ b/src/video/surface.hpp @@ -23,8 +23,8 @@ #include "math/vector.hpp" #include "math/rect.hpp" #include "video/surface_ptr.hpp" +#include "video/texture_ptr.hpp" -class Texture; class SurfaceData; /** A rectangular image. The class basically holds a reference to a @@ -37,7 +37,7 @@ public: static SurfacePtr create(const std::string& file, const Rect& rect); private: - Texture* texture; + TexturePtr texture; SurfaceData* surface_data; Rect rect; bool flipx; @@ -56,7 +56,7 @@ public: void hflip(); bool get_flipx() const; - Texture *get_texture() const; + TexturePtr get_texture() const; SurfaceData* get_surface_data() const; int get_x() const; int get_y() const; diff --git a/src/video/texture.hpp b/src/video/texture.hpp index 74710bd60..a4beb86fe 100644 --- a/src/video/texture.hpp +++ b/src/video/texture.hpp @@ -44,12 +44,15 @@ enum DrawingEffect { class Texture { protected: - int refcount; std::string filename; public: - Texture() : refcount(0), filename() {} - virtual ~Texture() {} + Texture() : filename() {} + virtual ~Texture() + { + if (texture_manager) + texture_manager->release(this); + } virtual unsigned int get_texture_width() const = 0; virtual unsigned int get_texture_height() const = 0; @@ -66,25 +69,6 @@ public: this->filename = filename; } - void ref() - { - refcount++; - } - - void unref() - { - assert(refcount > 0); - refcount--; - if(refcount == 0) - release(); - } - -private: - void release() - { - texture_manager->release(this); - } - private: Texture(const Texture&); Texture& operator=(const Texture&); diff --git a/src/video/texture_manager.cpp b/src/video/texture_manager.cpp index 3831132bb..a7c32e4e9 100644 --- a/src/video/texture_manager.cpp +++ b/src/video/texture_manager.cpp @@ -39,26 +39,27 @@ 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.lock()) + { + 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); image_textures[filename] = texture; } @@ -66,7 +67,7 @@ TextureManager::get(const std::string& _filename) return texture; } -Texture* +TexturePtr TextureManager::get(const std::string& filename, const Rect& rect) { // FIXME: implement caching @@ -77,7 +78,6 @@ void TextureManager::release(Texture* texture) { image_textures.erase(texture->get_filename()); - delete texture; } #ifdef HAVE_OPENGL @@ -94,7 +94,7 @@ TextureManager::remove_texture(GLTexture* texture) } #endif -Texture* +TexturePtr TextureManager::create_image_texture(const std::string& filename, const Rect& rect) { try @@ -104,12 +104,12 @@ 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(); + TexturePtr texture = create_dummy_texture(); return 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)); @@ -143,14 +143,14 @@ TextureManager::create_image_texture_raw(const std::string& filename, const Rect SDL_SetColors(subimage.get(), image->format->palette->colors, 0, image->format->palette->ncolors); } - Texture* result = VideoSystem::new_texture(subimage.get()); + TexturePtr result = VideoSystem::new_texture(subimage.get()); result->set_filename(filename); return result; } } } -Texture* +TexturePtr TextureManager::create_image_texture(const std::string& filename) { try @@ -160,12 +160,12 @@ 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(); + TexturePtr texture = create_dummy_texture(); return texture; } } -Texture* +TexturePtr TextureManager::create_image_texture_raw(const std::string& filename) { SDLSurfacePtr image(IMG_Load_RW(get_physfs_SDLRWops(filename), 1)); @@ -177,13 +177,13 @@ TextureManager::create_image_texture_raw(const std::string& filename) } else { - Texture* result = VideoSystem::new_texture(image.get()); + TexturePtr result = VideoSystem::new_texture(image.get()); result->set_filename(filename); return result; } } -Texture* +TexturePtr TextureManager::create_dummy_texture() { const std::string dummy_texture_fname = "images/engine/missing.png"; @@ -191,7 +191,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,7 +205,7 @@ TextureManager::create_dummy_texture() } else { - Texture* result = VideoSystem::new_texture(image.get()); + TexturePtr 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; @@ -232,7 +232,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())); } } diff --git a/src/video/texture_manager.hpp b/src/video/texture_manager.hpp index cf7f9400c..e88223dd9 100644 --- a/src/video/texture_manager.hpp +++ b/src/video/texture_manager.hpp @@ -23,8 +23,10 @@ #include #include #include +#include #include "video/glutil.hpp" +#include "video/texture_ptr.hpp" class Texture; class GLTexture; @@ -36,8 +38,8 @@ public: TextureManager(); ~TextureManager(); - Texture* get(const std::string& filename); - Texture* get(const std::string& filename, const Rect& rect); + TexturePtr get(const std::string& filename); + TexturePtr get(const std::string& filename, const Rect& rect); #ifdef HAVE_OPENGL void register_texture(GLTexture* texture); @@ -51,19 +53,19 @@ private: friend class Texture; void release(Texture* texture); - typedef std::map ImageTextures; + typedef std::map > ImageTextures; ImageTextures image_textures; - Texture* create_image_texture(const std::string& filename, const Rect& rect); + TexturePtr create_image_texture(const std::string& filename, const Rect& rect); /** on failure a dummy texture is returned and no exception is thrown */ - Texture* create_image_texture(const std::string& filename); + TexturePtr create_image_texture(const std::string& filename); /** 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); + TexturePtr create_image_texture_raw(const std::string& filename); + TexturePtr create_image_texture_raw(const std::string& filename, const Rect& rect); - Texture* create_dummy_texture(); + TexturePtr create_dummy_texture(); #ifdef HAVE_OPENGL typedef std::set Textures; diff --git a/src/video/texture_ptr.hpp b/src/video/texture_ptr.hpp new file mode 100644 index 000000000..e590449d5 --- /dev/null +++ b/src/video/texture_ptr.hpp @@ -0,0 +1,27 @@ +// SuperTux +// Copyright (C) 2009 Ingo Ruhnke +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef HEADER_SUPERTUX_VIDEO_TEXTURE_PTR_HPP +#define HEADER_SUPERTUX_VIDEO_TEXTURE_PTR_HPP + +#include + +class Texture; +typedef boost::shared_ptr TexturePtr; + +#endif + +/* EOF */ diff --git a/src/video/video_systems.cpp b/src/video/video_systems.cpp index ca86eb1e2..b73996c3b 100644 --- a/src/video/video_systems.cpp +++ b/src/video/video_systems.cpp @@ -90,29 +90,29 @@ VideoSystem::new_lightmap() } } -Texture* +TexturePtr VideoSystem::new_texture(SDL_Surface *image) { switch(g_config->video) { case AUTO_VIDEO: #ifdef HAVE_OPENGL - return new GLTexture(image); + return TexturePtr(new GLTexture(image)); #else - return new SDLTexture(image); + return TexturePtr(new SDLTexture(image)); #endif #ifdef HAVE_OPENGL case OPENGL: - return new GLTexture(image); + return TexturePtr(new GLTexture(image)); #endif case PURE_SDL: - return new SDLTexture(image); + return TexturePtr(new SDLTexture(image)); default: assert(0 && "invalid video system in config"); #ifdef HAVE_OPENGL - return new GLTexture(image); + return TexturePtr(new GLTexture(image)); #else - return new SDLTexture(image); + return TexturePtr(new SDLTexture(image)); #endif } } diff --git a/src/video/video_systems.hpp b/src/video/video_systems.hpp index a09cd765b..e82ceda49 100644 --- a/src/video/video_systems.hpp +++ b/src/video/video_systems.hpp @@ -22,9 +22,10 @@ #include #include +#include "video/texture_ptr.hpp" + class Renderer; class Lightmap; -class Texture; class Surface; class SurfaceData; @@ -41,7 +42,7 @@ public: public: static Renderer* new_renderer(); static Lightmap* new_lightmap(); - static Texture* new_texture(SDL_Surface *image); + static TexturePtr new_texture(SDL_Surface *image); static SurfaceData* new_surface_data(const Surface &surface); static void free_surface_data(SurfaceData* surface_data); -- 2.11.0