WIP
This commit is contained in:
128
texture.cc
128
texture.cc
@@ -103,13 +103,13 @@ void TextureCubeMap::bind() const
|
||||
|
||||
|
||||
Texture2D::Texture2D(unsigned width, unsigned height)
|
||||
: _texID(0)
|
||||
: texID_(0), width_(width), height_(height), alpha_(false)
|
||||
{
|
||||
_glCreate(width, height);
|
||||
}
|
||||
|
||||
Texture2D::Texture2D(std::string const& file)
|
||||
: _texID(0)
|
||||
: texID_(0), width_(0), height_(0), alpha_(false)
|
||||
{
|
||||
SDL_Surface *surf = IMG_Load(file.c_str());
|
||||
if (!surf)
|
||||
@@ -124,7 +124,7 @@ Texture2D::Texture2D(std::string const& file)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf->w, surf->h, GL_RGB, GL_UNSIGNED_BYTE, surf->pixels);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
} catch(...) {
|
||||
glDeleteTextures(1, &_texID);
|
||||
glDeleteTextures(1, &texID_);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -136,78 +136,118 @@ Texture2D::Texture2D(std::string const& file)
|
||||
}
|
||||
|
||||
Texture2D::Texture2D(SDL_Surface *surface)
|
||||
: _texID(0)
|
||||
: texID_(0), width_(0), height_(0), alpha_(false)
|
||||
{
|
||||
if(surface->format->Amask == 0)
|
||||
_glCreate(surface->w, surface->h);
|
||||
else
|
||||
else {
|
||||
_glCreate(surface->w, surface->h, true);
|
||||
}
|
||||
|
||||
try {
|
||||
SDL_Surface *surf;
|
||||
if((surface->format->format != SDL_PIXELFORMAT_RGB24) &&
|
||||
(surface->format->format != SDL_PIXELFORMAT_RGBA8888)) {
|
||||
if(surface->format->Amask == 0) {
|
||||
surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGB24, 0);
|
||||
} else {
|
||||
surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0);
|
||||
}
|
||||
if(!surf)
|
||||
throw SDLException{};
|
||||
} else {
|
||||
surf = surface;
|
||||
}
|
||||
|
||||
if (SDL_MUSTLOCK(surf))
|
||||
SDL_LockSurface(surf);
|
||||
try {
|
||||
if(surface->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 != surface)
|
||||
SDL_FreeSurface(surf);
|
||||
throw;
|
||||
}
|
||||
SDL_FreeSurface(surf);
|
||||
copyFromSurface(surface);
|
||||
} catch(...) {
|
||||
glDeleteTextures(1, &_texID);
|
||||
glDeleteTextures(1, &texID_);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
Texture2D::Texture2D(Texture2D&& move)
|
||||
: _texID(move._texID)
|
||||
: texID_(move.texID_), width_(move.width_), height_(move.height_), alpha_(move.alpha_)
|
||||
{
|
||||
move._texID = 0;
|
||||
move.texID_ = 0;
|
||||
}
|
||||
|
||||
Texture2D& Texture2D::operator=(Texture2D&& move)
|
||||
{
|
||||
glDeleteTextures(1, &_texID);
|
||||
_texID = move._texID;
|
||||
move._texID = 0;
|
||||
glDeleteTextures(1, &texID_);
|
||||
texID_ = move.texID_;
|
||||
width_ = move.width_;
|
||||
height_ = move.height_;
|
||||
alpha_ = move.alpha_;
|
||||
move.texID_ = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
{
|
||||
glDeleteTextures(1, &_texID);
|
||||
glDeleteTextures(1, &texID_);
|
||||
}
|
||||
|
||||
void Texture2D::bind() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, _texID);
|
||||
glBindTexture(GL_TEXTURE_2D, texID_);
|
||||
}
|
||||
|
||||
void Texture2D::copyFromSurface(SDL_Surface *src)
|
||||
{
|
||||
SDL_Surface *surf;
|
||||
if ((src->w > width_) || src->h > height_)
|
||||
throw Exception("Cannot replace texture image with larger image");
|
||||
if ((src->format->format != SDL_PIXELFORMAT_RGB24) &&
|
||||
(src->format->format != SDL_PIXELFORMAT_RGBA8888)) {
|
||||
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);
|
||||
} else {
|
||||
surf = SDL_ConvertSurfaceFormat(src, SDL_PIXELFORMAT_ABGR8888, 0);
|
||||
}
|
||||
if (!surf)
|
||||
throw SDLException{};
|
||||
} 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);
|
||||
}
|
||||
|
||||
SDL_Surface* Texture2D::copyToSurface()
|
||||
{
|
||||
bind();
|
||||
uint32_t rmask, gmask, bmask, amask;
|
||||
int bpp;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void Texture2D::_glCreate(unsigned width, unsigned height, bool alpha)
|
||||
{
|
||||
glGenTextures(1, &_texID);
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
alpha_ = alpha;
|
||||
glGenTextures(1, &texID_);
|
||||
try {
|
||||
glBindTexture(GL_TEXTURE_2D, _texID);
|
||||
glBindTexture(GL_TEXTURE_2D, texID_);
|
||||
unsigned logWidth = ilog2(width), logHeight = ilog2(height);
|
||||
unsigned levels = std::max(logWidth,logHeight)+1u;
|
||||
if(SDL_GL_ExtensionSupported("GL_ARB_texture_storage"))
|
||||
@@ -223,6 +263,6 @@ void Texture2D::_glCreate(unsigned width, unsigned height, bool alpha)
|
||||
}
|
||||
}
|
||||
} catch(...) {
|
||||
glDeleteTextures(1, &_texID);
|
||||
glDeleteTextures(1, &texID_);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user