diff --git a/common.hh b/common.hh index 6313e9c..db9afe9 100644 --- a/common.hh +++ b/common.hh @@ -12,15 +12,23 @@ #include using namespace gl; +using namespace std::string_literals; class Exception { public: - Exception() { + Exception() : msg_() { } + Exception(std::string msg) : msg_(msg) { + } + virtual ~Exception() {} - virtual std::string toString() const = 0; + virtual std::string toString() const { + return "Exception: "s + msg_; + } +protected: + std::string msg_; }; class POSIXException : public Exception { @@ -31,7 +39,7 @@ public: int getErr() const {return err_;} std::string toString() const override { - return std::string("POSIXException: ") + std::strerror(err_); + return "POSIXException: "s + std::strerror(err_); } private: @@ -66,7 +74,7 @@ public: } std::string toString() const override { - return "GLException: " + errToString() + "(" + std::to_string(static_cast(err_)) + ")"; + return "GLException: "s + errToString() + "(" + std::to_string(static_cast(err_)) + ")"; } private: @@ -75,28 +83,22 @@ private: class SDLException : public Exception { public: - SDLException() : Exception(), msg_(SDL_GetError()) { + SDLException() : Exception(SDL_GetError()) { } std::string toString() const override { - return "SDLException: " + msg_; + return "SDLException: "s + msg_; } - -private: - std::string msg_; }; class TTFException : public Exception { public: - TTFException() : Exception(), msg_(TTF_GetError()) { + TTFException() : Exception(TTF_GetError()) { } std::string toString() const override { - return "TTFException: " + msg_; + return "TTFException: "s + msg_; } - -private: - std::string msg_; }; static void checkGlError() { diff --git a/main.cc b/main.cc index 2418c57..6245ac7 100644 --- a/main.cc +++ b/main.cc @@ -334,7 +334,7 @@ int main(int argc, char *argv[]) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); fpsTex.bind(); - //redTex.bind(); + ovl.draw(); glDisable(GL_BLEND); diff --git a/shaders/textured.fs b/shaders/textured.fs index c1ccfcc..3dff33c 100644 --- a/shaders/textured.fs +++ b/shaders/textured.fs @@ -8,8 +8,8 @@ uniform samplerCubeShadow texShadowMaps[lights]; float VectorToDepth (vec3 Vec) { vec3 AbsVec = abs(Vec); - //float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z)); - float LocalZcomp = length(AbsVec); + float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z)); + //float LocalZcomp = length(AbsVec); // Replace f and n with the far and near plane values you used when // you drew your cube map. diff --git a/texture.cc b/texture.cc index a92401c..e07580a 100644 --- a/texture.cc +++ b/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_); } } diff --git a/texture.hh b/texture.hh index 2fd4a15..46224ae 100644 --- a/texture.hh +++ b/texture.hh @@ -74,12 +74,17 @@ public: ~Texture2D(); void bind() const; + + void copyFromSurface(SDL_Surface *src); + SDL_Surface* copyToSurface(); private: void _glCreate(unsigned width, unsigned height, bool alpha = false); - gl::GLuint _texID; + gl::GLuint texID_; + unsigned width_, height_; + bool alpha_; };