unique_ptr based management for SDL_Surfaces

This commit is contained in:
2015-03-08 13:59:08 +01:00
parent 31e3a307b5
commit ffbc59140a
6 changed files with 80 additions and 50 deletions

View File

@@ -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;
}