From ffbc59140a5a5ae7b6e22da7df6cafd96315881c Mon Sep 17 00:00:00 2001 From: Matthias Blankertz Date: Sun, 8 Mar 2015 13:59:08 +0100 Subject: [PATCH] unique_ptr based management for SDL_Surfaces --- Makefile | 2 +- common.hh | 10 ++++++++++ font.cc | 49 +++++++++++++++++++++++++++++++--------------- font.hh | 5 ++++- texture.cc | 57 +++++++++++++++++++++++++----------------------------- texture.hh | 7 ++++++- 6 files changed, 80 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index 422d986..95e6661 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CXX=g++ CXXOPTS=-O2 -ggdb -Wall -Wextra -pedantic -Wno-unused-function -Wno-unused-parameter -Wno-sign-compare -std=c++14 -flto LDOPTS= LIBS=-lglbinding -lSDL2 -lSDL2_image -lobj -lSDL2_ttf -lprotobuf -CXXSRCS=main.cc objectParser.cc shaders.cc Object.cc VBOManager.cc texture.cc font.cc Overlay.cc +CXXSRCS=main.cc objectParser.cc shaders.cc Object.cc VBOManager.cc texture.cc font.cc Overlay.cc TextWidget.cc BINIFY_SRCS=binifyObj.cc objectParser.cc object.pb.cc OBJS=$(addprefix objs/,$(CXXSRCS:.cc=.o)) BINIFY_OBJS=$(addprefix objs/,$(BINIFY_SRCS:.cc=.o)) diff --git a/common.hh b/common.hh index db9afe9..d75db5e 100644 --- a/common.hh +++ b/common.hh @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -136,4 +137,13 @@ enum class VAFormats { VertexNormalTexcoord }; +struct SDLSurfaceDeleter { + void operator()(SDL_Surface* ptr) const + { + SDL_FreeSurface(ptr); + } +}; + +using SDLSurfaceUPtr = std::unique_ptr; + #endif diff --git a/font.cc b/font.cc index e85dad8..6151c9e 100644 --- a/font.cc +++ b/font.cc @@ -10,32 +10,49 @@ Font::Font(std::string const& filename, unsigned ptsize) { assert(TTF_WasInit()); font_ = TTF_OpenFont(filename.c_str(), ptsize); - if(!font_) + if (!font_) throw TTFException{}; } +Font::Font(Font&& move) + : font_(move.font_) +{ + move.font_ = nullptr; +} + +Font& Font::operator=(Font&& move) +{ + if (font_) + TTF_CloseFont(font_); + font_ = move.font_; + move.font_ = nullptr; + + return *this; +} + Font::~Font() { - if(font_) + if (font_) TTF_CloseFont(font_); } -Texture2D Font::render(std::string const& text, bool fast) const { - SDL_Surface *surf; - if(fast) - surf = TTF_RenderUTF8_Solid(font_, text.c_str(), SDL_Color{255, 255, 255, 255}); +Texture2D Font::render(std::string const& text, bool fast) const +{ + SDLSurfaceUPtr surf; + if (fast) + surf.reset(TTF_RenderUTF8_Solid(font_, text.c_str(), SDL_Color{255, 255, 255, 255})); else - surf = TTF_RenderUTF8_Blended(font_, text.c_str(), SDL_Color{255, 255, 255, 255}); + surf.reset(TTF_RenderUTF8_Blended(font_, text.c_str(), SDL_Color{255, 255, 255, 255})); - if(!surf) + if (!surf) throw TTFException{}; - try { - Texture2D ret{surf}; - SDL_FreeSurface(surf); - return ret; - } catch(...) { - SDL_FreeSurface(surf); - throw; - } + Texture2D ret{surf.get()}; + + return ret; +} + +TTF_Font* Font::getFont() const +{ + return font_; } diff --git a/font.hh b/font.hh index 319a034..bd73c50 100644 --- a/font.hh +++ b/font.hh @@ -10,14 +10,17 @@ class Texture2D; class Font { public: Font(std::string const& filename, unsigned ptsize); + Font(Font&& move); Font(Font const& copy) = delete; + Font& operator=(Font&& move); Font& operator=(Font const& copy) = delete; ~Font(); Texture2D render(std::string const& text, bool fast = false) const; - + + TTF_Font* getFont() const; private: TTF_Font* font_; }; diff --git a/texture.cc b/texture.cc index f09af40..2cd75c4 100644 --- a/texture.cc +++ b/texture.cc @@ -101,6 +101,10 @@ void TextureCubeMap::bind() const glBindTexture(GL_TEXTURE_CUBE_MAP, _texID); } +Texture2D::Texture2D() + : texID_(0), width_(0), height_(0), alpha_(false) +{ +} Texture2D::Texture2D(unsigned width, unsigned height, bool alpha) : texID_(0), width_(width), height_(height), alpha_(alpha) @@ -111,7 +115,8 @@ Texture2D::Texture2D(unsigned width, unsigned height, bool alpha) Texture2D::Texture2D(std::string const& file) : texID_(0), width_(0), height_(0), alpha_(false) { - SDL_Surface *surf = IMG_Load(file.c_str()); + SDLSurfaceUPtr surf(IMG_Load(file.c_str())); + if (!surf) throw SDLException(); @@ -122,14 +127,11 @@ Texture2D::Texture2D(std::string const& file) } try { - copyFromSurface(surf); + copyFromSurface(surf.get()); } catch (...) { glDeleteTextures(1, &texID_); - SDL_FreeSurface(surf); throw; } - - SDL_FreeSurface(surf); } Texture2D::Texture2D(SDL_Surface *surface) @@ -174,11 +176,13 @@ Texture2D::~Texture2D() void Texture2D::bind() const { + assert(texID_ != 0); glBindTexture(GL_TEXTURE_2D, texID_); } void Texture2D::copyFromSurface(SDL_Surface *src) { + SDLSurfaceUPtr tmpSurf; SDL_Surface *surf; if ((src->w > width_) || src->h > height_) throw Exception("Cannot replace texture image with larger image"); @@ -187,35 +191,29 @@ void Texture2D::copyFromSurface(SDL_Surface *src) if ((src->format->Amask != 0) != alpha_) throw Exception("Cannot replace texture image with mismatched alpha"); if (src->format->Amask == 0) { - surf = SDL_ConvertSurfaceFormat(src, SDL_PIXELFORMAT_RGB24, 0); + tmpSurf.reset(SDL_ConvertSurfaceFormat(src, SDL_PIXELFORMAT_RGB24, 0)); } else { - surf = SDL_ConvertSurfaceFormat(src, SDL_PIXELFORMAT_ABGR8888, 0); + tmpSurf.reset(SDL_ConvertSurfaceFormat(src, SDL_PIXELFORMAT_ABGR8888, 0)); } - if (!surf) + if (!tmpSurf) throw SDLException{}; + surf = tmpSurf.get(); } else { surf = src; } if (SDL_MUSTLOCK(surf)) SDL_LockSurface(surf); - try { - bind(); - if(surf->format->Amask == 0) - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf->w, surf->h, GL_RGB, GL_UNSIGNED_BYTE, surf->pixels); - else - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf->w, surf->h, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels); - glGenerateMipmap(GL_TEXTURE_2D); - } catch(...) { - if (surf != src) - SDL_FreeSurface(surf); - throw; - } - if(surf != src) - SDL_FreeSurface(surf); + + bind(); + if(surf->format->Amask == 0) + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf->w, surf->h, GL_RGB, GL_UNSIGNED_BYTE, surf->pixels); + else + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf->w, surf->h, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels); + glGenerateMipmap(GL_TEXTURE_2D); } -SDL_Surface* Texture2D::copyToSurface() +SDLSurfaceUPtr Texture2D::copyToSurface() { bind(); uint32_t rmask, gmask, bmask, amask; @@ -223,17 +221,14 @@ SDL_Surface* Texture2D::copyToSurface() if (!SDL_PixelFormatEnumToMasks(alpha_?SDL_PIXELFORMAT_ABGR8888:SDL_PIXELFORMAT_RGB24, &bpp, &rmask, &gmask, &bmask, &amask)) throw SDLException{}; - SDL_Surface *dst = SDL_CreateRGBSurface(0, width_, height_, bpp, - rmask, gmask, bmask, amask); + + SDLSurfaceUPtr dst(SDL_CreateRGBSurface(0, width_, height_, bpp, + rmask, gmask, bmask, amask)); if(!dst) throw SDLException{}; - try { - glGetTexImage(GL_TEXTURE_2D, 0, alpha_?GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, dst->pixels); - } catch(...) { - SDL_FreeSurface(dst); - throw; - } + glGetTexImage(GL_TEXTURE_2D, 0, alpha_?GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, dst->pixels); + return dst; } diff --git a/texture.hh b/texture.hh index 16bcd87..880ff4e 100644 --- a/texture.hh +++ b/texture.hh @@ -61,6 +61,7 @@ private: class Texture2D { public: + Texture2D(); Texture2D(unsigned width, unsigned height, bool alpha = false); Texture2D(std::string const& file); Texture2D(SDL_Surface *surface); @@ -76,7 +77,11 @@ public: void bind() const; void copyFromSurface(SDL_Surface *src); - SDL_Surface* copyToSurface(); + SDLSurfaceUPtr copyToSurface(); + + unsigned getWidth() const { return width_; } + unsigned getHeight() const { return height_; } + bool getAlpha() const { return alpha_; } private: