unique_ptr based management for SDL_Surfaces
This commit is contained in:
2
Makefile
2
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
|
CXXOPTS=-O2 -ggdb -Wall -Wextra -pedantic -Wno-unused-function -Wno-unused-parameter -Wno-sign-compare -std=c++14 -flto
|
||||||
LDOPTS=
|
LDOPTS=
|
||||||
LIBS=-lglbinding -lSDL2 -lSDL2_image -lobj -lSDL2_ttf -lprotobuf
|
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
|
BINIFY_SRCS=binifyObj.cc objectParser.cc object.pb.cc
|
||||||
OBJS=$(addprefix objs/,$(CXXSRCS:.cc=.o))
|
OBJS=$(addprefix objs/,$(CXXSRCS:.cc=.o))
|
||||||
BINIFY_OBJS=$(addprefix objs/,$(BINIFY_SRCS:.cc=.o))
|
BINIFY_OBJS=$(addprefix objs/,$(BINIFY_SRCS:.cc=.o))
|
||||||
|
|||||||
10
common.hh
10
common.hh
@@ -5,6 +5,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <glbinding/gl/gl.h>
|
#include <glbinding/gl/gl.h>
|
||||||
|
|
||||||
@@ -136,4 +137,13 @@ enum class VAFormats {
|
|||||||
VertexNormalTexcoord
|
VertexNormalTexcoord
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SDLSurfaceDeleter {
|
||||||
|
void operator()(SDL_Surface* ptr) const
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(ptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using SDLSurfaceUPtr = std::unique_ptr<SDL_Surface, SDLSurfaceDeleter>;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
37
font.cc
37
font.cc
@@ -14,28 +14,45 @@ Font::Font(std::string const& filename, unsigned ptsize)
|
|||||||
throw TTFException{};
|
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()
|
Font::~Font()
|
||||||
{
|
{
|
||||||
if (font_)
|
if (font_)
|
||||||
TTF_CloseFont(font_);
|
TTF_CloseFont(font_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D Font::render(std::string const& text, bool fast) const {
|
Texture2D Font::render(std::string const& text, bool fast) const
|
||||||
SDL_Surface *surf;
|
{
|
||||||
|
SDLSurfaceUPtr surf;
|
||||||
if (fast)
|
if (fast)
|
||||||
surf = TTF_RenderUTF8_Solid(font_, text.c_str(), SDL_Color{255, 255, 255, 255});
|
surf.reset(TTF_RenderUTF8_Solid(font_, text.c_str(), SDL_Color{255, 255, 255, 255}));
|
||||||
else
|
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{};
|
throw TTFException{};
|
||||||
|
|
||||||
try {
|
Texture2D ret{surf.get()};
|
||||||
Texture2D ret{surf};
|
|
||||||
SDL_FreeSurface(surf);
|
|
||||||
return ret;
|
return ret;
|
||||||
} catch(...) {
|
|
||||||
SDL_FreeSurface(surf);
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TTF_Font* Font::getFont() const
|
||||||
|
{
|
||||||
|
return font_;
|
||||||
}
|
}
|
||||||
|
|||||||
3
font.hh
3
font.hh
@@ -10,14 +10,17 @@ class Texture2D;
|
|||||||
class Font {
|
class Font {
|
||||||
public:
|
public:
|
||||||
Font(std::string const& filename, unsigned ptsize);
|
Font(std::string const& filename, unsigned ptsize);
|
||||||
|
Font(Font&& move);
|
||||||
Font(Font const& copy) = delete;
|
Font(Font const& copy) = delete;
|
||||||
|
|
||||||
|
Font& operator=(Font&& move);
|
||||||
Font& operator=(Font const& copy) = delete;
|
Font& operator=(Font const& copy) = delete;
|
||||||
|
|
||||||
~Font();
|
~Font();
|
||||||
|
|
||||||
Texture2D render(std::string const& text, bool fast = false) const;
|
Texture2D render(std::string const& text, bool fast = false) const;
|
||||||
|
|
||||||
|
TTF_Font* getFont() const;
|
||||||
private:
|
private:
|
||||||
TTF_Font* font_;
|
TTF_Font* font_;
|
||||||
};
|
};
|
||||||
|
|||||||
43
texture.cc
43
texture.cc
@@ -101,6 +101,10 @@ void TextureCubeMap::bind() const
|
|||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _texID);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, _texID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture2D::Texture2D()
|
||||||
|
: texID_(0), width_(0), height_(0), alpha_(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Texture2D::Texture2D(unsigned width, unsigned height, bool alpha)
|
Texture2D::Texture2D(unsigned width, unsigned height, bool alpha)
|
||||||
: texID_(0), width_(width), height_(height), alpha_(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)
|
Texture2D::Texture2D(std::string const& file)
|
||||||
: texID_(0), width_(0), height_(0), alpha_(false)
|
: 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)
|
if (!surf)
|
||||||
throw SDLException();
|
throw SDLException();
|
||||||
|
|
||||||
@@ -122,14 +127,11 @@ Texture2D::Texture2D(std::string const& file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
copyFromSurface(surf);
|
copyFromSurface(surf.get());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
glDeleteTextures(1, &texID_);
|
glDeleteTextures(1, &texID_);
|
||||||
SDL_FreeSurface(surf);
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_FreeSurface(surf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D::Texture2D(SDL_Surface *surface)
|
Texture2D::Texture2D(SDL_Surface *surface)
|
||||||
@@ -174,11 +176,13 @@ Texture2D::~Texture2D()
|
|||||||
|
|
||||||
void Texture2D::bind() const
|
void Texture2D::bind() const
|
||||||
{
|
{
|
||||||
|
assert(texID_ != 0);
|
||||||
glBindTexture(GL_TEXTURE_2D, texID_);
|
glBindTexture(GL_TEXTURE_2D, texID_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture2D::copyFromSurface(SDL_Surface *src)
|
void Texture2D::copyFromSurface(SDL_Surface *src)
|
||||||
{
|
{
|
||||||
|
SDLSurfaceUPtr tmpSurf;
|
||||||
SDL_Surface *surf;
|
SDL_Surface *surf;
|
||||||
if ((src->w > width_) || src->h > height_)
|
if ((src->w > width_) || src->h > height_)
|
||||||
throw Exception("Cannot replace texture image with larger image");
|
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_)
|
if ((src->format->Amask != 0) != alpha_)
|
||||||
throw Exception("Cannot replace texture image with mismatched alpha");
|
throw Exception("Cannot replace texture image with mismatched alpha");
|
||||||
if (src->format->Amask == 0) {
|
if (src->format->Amask == 0) {
|
||||||
surf = SDL_ConvertSurfaceFormat(src, SDL_PIXELFORMAT_RGB24, 0);
|
tmpSurf.reset(SDL_ConvertSurfaceFormat(src, SDL_PIXELFORMAT_RGB24, 0));
|
||||||
} else {
|
} else {
|
||||||
surf = SDL_ConvertSurfaceFormat(src, SDL_PIXELFORMAT_ABGR8888, 0);
|
tmpSurf.reset(SDL_ConvertSurfaceFormat(src, SDL_PIXELFORMAT_ABGR8888, 0));
|
||||||
}
|
}
|
||||||
if (!surf)
|
if (!tmpSurf)
|
||||||
throw SDLException{};
|
throw SDLException{};
|
||||||
|
surf = tmpSurf.get();
|
||||||
} else {
|
} else {
|
||||||
surf = src;
|
surf = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_MUSTLOCK(surf))
|
if (SDL_MUSTLOCK(surf))
|
||||||
SDL_LockSurface(surf);
|
SDL_LockSurface(surf);
|
||||||
try {
|
|
||||||
bind();
|
bind();
|
||||||
if(surf->format->Amask == 0)
|
if(surf->format->Amask == 0)
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf->w, surf->h, GL_RGB, GL_UNSIGNED_BYTE, surf->pixels);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf->w, surf->h, GL_RGB, GL_UNSIGNED_BYTE, surf->pixels);
|
||||||
else
|
else
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf->w, surf->h, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf->w, surf->h, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels);
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
} catch(...) {
|
|
||||||
if (surf != src)
|
|
||||||
SDL_FreeSurface(surf);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
if(surf != src)
|
|
||||||
SDL_FreeSurface(surf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Surface* Texture2D::copyToSurface()
|
SDLSurfaceUPtr Texture2D::copyToSurface()
|
||||||
{
|
{
|
||||||
bind();
|
bind();
|
||||||
uint32_t rmask, gmask, bmask, amask;
|
uint32_t rmask, gmask, bmask, amask;
|
||||||
@@ -223,16 +221,13 @@ SDL_Surface* Texture2D::copyToSurface()
|
|||||||
if (!SDL_PixelFormatEnumToMasks(alpha_?SDL_PIXELFORMAT_ABGR8888:SDL_PIXELFORMAT_RGB24,
|
if (!SDL_PixelFormatEnumToMasks(alpha_?SDL_PIXELFORMAT_ABGR8888:SDL_PIXELFORMAT_RGB24,
|
||||||
&bpp, &rmask, &gmask, &bmask, &amask))
|
&bpp, &rmask, &gmask, &bmask, &amask))
|
||||||
throw SDLException{};
|
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)
|
if(!dst)
|
||||||
throw SDLException{};
|
throw SDLException{};
|
||||||
try {
|
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, alpha_?GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, dst->pixels);
|
glGetTexImage(GL_TEXTURE_2D, 0, alpha_?GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, dst->pixels);
|
||||||
} catch(...) {
|
|
||||||
SDL_FreeSurface(dst);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ private:
|
|||||||
|
|
||||||
class Texture2D {
|
class Texture2D {
|
||||||
public:
|
public:
|
||||||
|
Texture2D();
|
||||||
Texture2D(unsigned width, unsigned height, bool alpha = false);
|
Texture2D(unsigned width, unsigned height, bool alpha = false);
|
||||||
Texture2D(std::string const& file);
|
Texture2D(std::string const& file);
|
||||||
Texture2D(SDL_Surface *surface);
|
Texture2D(SDL_Surface *surface);
|
||||||
@@ -76,7 +77,11 @@ public:
|
|||||||
void bind() const;
|
void bind() const;
|
||||||
|
|
||||||
void copyFromSurface(SDL_Surface *src);
|
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:
|
private:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user