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<float>(lightmap_width) / static_cast<float>(width);
lightmap_uv_bottom = static_cast<float>(lightmap_height) / static_cast<float>(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
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,
GLLightmap::draw_surface(const DrawingRequest& request)
{
const Surface* surface = (const Surface*) request.request_data;
- GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+ boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
const SurfacePartRequest* surfacepartrequest
= (SurfacePartRequest*) request.request_data;
const Surface* surface = surfacepartrequest->surface;
- GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+ boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
static const int LIGHTMAP_DIV = 5;
SDL_Surface* screen;
- GLTexture* lightmap;
+ boost::shared_ptr<GLTexture> lightmap;
int lightmap_width;
int lightmap_height;
float lightmap_uv_right;
GLRenderer::draw_surface(const DrawingRequest& request)
{
const Surface* surface = (const Surface*) request.request_data;
- GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+ boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
const SurfacePartRequest* surfacepartrequest
= (SurfacePartRequest*) request.request_data;
const Surface* surface = surfacepartrequest->surface;
- GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+ boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
//FIXME: support parameters request.alpha, request.angle, request.blend
const Surface* surface = (const Surface*) request.request_data;
- SDLTexture *sdltexture = dynamic_cast<SDLTexture *>(surface->get_texture());
+ boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->get_texture());
SDLSurfaceData *surface_data = reinterpret_cast<SDLSurfaceData *>(surface->get_surface_data());
DrawingEffect effect = request.drawing_effect;
= (SurfacePartRequest*) request.request_data;
const Surface* surface = surfacepartrequest->surface;
- SDLTexture *sdltexture = dynamic_cast<SDLTexture *>(surface->get_texture());
+ boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->get_texture());
DrawingEffect effect = request.drawing_effect;
if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
{
//FIXME: support parameters request.alpha, request.angle, request.blend
const Surface* surface = (const Surface*) request.request_data;
- SDLTexture *sdltexture = dynamic_cast<SDLTexture *>(surface->get_texture());
+ boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->get_texture());
SDLSurfaceData *surface_data = reinterpret_cast<SDLSurfaceData *>(surface->get_surface_data());
DrawingEffect effect = request.drawing_effect;
= (SurfacePartRequest*) request.request_data;
const Surface* surface = surfacepartrequest->surface;
- SDLTexture *sdltexture = dynamic_cast<SDLTexture*>(surface->get_texture());
+ boost::shared_ptr<SDLTexture> sdltexture = boost::dynamic_pointer_cast<SDLTexture>(surface->get_texture());
DrawingEffect effect = request.drawing_effect;
if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
texture->get_image_height())),
flipx(false)
{
- texture->ref();
surface_data = VideoSystem::new_surface_data(*this);
}
rect(0, 0, Size(rect_.get_width(), rect_.get_height())),
flipx(false)
{
- texture->ref();
surface_data = VideoSystem::new_surface_data(*this);
}
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
return flipx;
}
-Texture*
+TexturePtr
Surface::get_texture() const
{
return texture;
#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
static SurfacePtr create(const std::string& file, const Rect& rect);
private:
- Texture* texture;
+ TexturePtr texture;
SurfaceData* surface_data;
Rect rect;
bool flipx;
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;
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;
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&);
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;
}
return texture;
}
-Texture*
+TexturePtr
TextureManager::get(const std::string& filename, const Rect& rect)
{
// FIXME: implement caching
TextureManager::release(Texture* texture)
{
image_textures.erase(texture->get_filename());
- delete texture;
}
#ifdef HAVE_OPENGL
}
#endif
-Texture*
+TexturePtr
TextureManager::create_image_texture(const std::string& filename, const Rect& rect)
{
try
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));
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
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));
}
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";
// 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)
}
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;
}
for(ImageTextures::iterator i = image_textures.begin();
i != image_textures.end(); ++i) {
- save_texture(dynamic_cast<GLTexture *>(i->second));
+ save_texture(dynamic_cast<GLTexture*>(i->second.lock().get()));
}
}
#include <set>
#include <string>
#include <vector>
+#include <boost/weak_ptr.hpp>
#include "video/glutil.hpp"
+#include "video/texture_ptr.hpp"
class Texture;
class GLTexture;
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);
friend class Texture;
void release(Texture* texture);
- typedef std::map<std::string, Texture*> ImageTextures;
+ typedef std::map<std::string, boost::weak_ptr<Texture> > 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<GLTexture*> Textures;
--- /dev/null
+// SuperTux
+// Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_TEXTURE_PTR_HPP
+#define HEADER_SUPERTUX_VIDEO_TEXTURE_PTR_HPP
+
+#include <boost/shared_ptr.hpp>
+
+class Texture;
+typedef boost::shared_ptr<Texture> TexturePtr;
+
+#endif
+
+/* EOF */
}
}
-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
}
}
#include <SDL.h>
#include <string>
+#include "video/texture_ptr.hpp"
+
class Renderer;
class Lightmap;
-class Texture;
class Surface;
class SurfaceData;
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);