From fbbf87a36f5f27851a2e2d17b95a0f17dd82624b Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 17 May 2015 19:48:30 +0300 Subject: Fix possible issues in texture atlas creation with non power of two image sizes. --- src/resources/openglimagehelper.cpp | 55 +++++++++++++++++++++++++++++++++++-- src/resources/openglimagehelper.h | 3 ++ 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/resources/openglimagehelper.cpp b/src/resources/openglimagehelper.cpp index 4c7095ec8..ca553a180 100644 --- a/src/resources/openglimagehelper.cpp +++ b/src/resources/openglimagehelper.cpp @@ -134,8 +134,8 @@ int OpenGLImageHelper::powerOfTwo(const int input) return value >= mTextureSize ? mTextureSize : value; } -SDL_Surface *OpenGLImageHelper::convertSurface(SDL_Surface *tmpImage, - int width, int height) +SDL_Surface *OpenGLImageHelper::convertSurfaceNormalize(SDL_Surface *tmpImage, + int width, int height) { if (!tmpImage) return nullptr; @@ -193,6 +193,55 @@ SDL_Surface *OpenGLImageHelper::convertSurface(SDL_Surface *tmpImage, return tmpImage; } +SDL_Surface *OpenGLImageHelper::convertSurface(SDL_Surface *tmpImage, + int width, int height) +{ + if (!tmpImage) + return nullptr; + +#ifdef USE_SDL2 + SDL_SetSurfaceAlphaMod(tmpImage, SDL_ALPHA_OPAQUE); +#else + // Make sure the alpha channel is not used, but copied to destination + SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); +#endif + + // Determine 32-bit masks based on byte order + uint32_t rmask, gmask, bmask, amask; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif + + if (tmpImage->format->BitsPerPixel != 32 + || rmask != tmpImage->format->Rmask + || gmask != tmpImage->format->Gmask + || amask != tmpImage->format->Amask) + { + SDL_Surface *oldImage = tmpImage; +#ifdef USE_SDL2 + SDL_SetSurfaceBlendMode(oldImage, SDL_BLENDMODE_NONE); +#endif + tmpImage = MSDL_CreateRGBSurface(SDL_SWSURFACE, width, height, + 32, rmask, gmask, bmask, amask); + + if (!tmpImage) + { + logger->log("Error, image convert failed: out of memory"); + return nullptr; + } + SDL_BlitSurface(oldImage, nullptr, tmpImage, nullptr); + } + return tmpImage; +} + void OpenGLImageHelper::bindTexture(const GLuint texture) { switch (mUseOpenGL) @@ -241,7 +290,7 @@ Image *OpenGLImageHelper::glLoad(SDL_Surface *tmpImage, height = tmpImage->h; SDL_Surface *oldImage = tmpImage; - tmpImage = convertSurface(tmpImage, width, height); + tmpImage = convertSurfaceNormalize(tmpImage, width, height); const int realWidth = tmpImage->w; const int realHeight = tmpImage->h; diff --git a/src/resources/openglimagehelper.h b/src/resources/openglimagehelper.h index 1afebb736..758817684 100644 --- a/src/resources/openglimagehelper.h +++ b/src/resources/openglimagehelper.h @@ -135,6 +135,9 @@ class OpenGLImageHelper final : public ImageHelper */ static int powerOfTwo(const int input) A_WARN_UNUSED; + static SDL_Surface *convertSurfaceNormalize(SDL_Surface *tmpImage, + int width, int height); + static SDL_Surface *convertSurface(SDL_Surface *tmpImage, int width, int height); -- cgit v1.2.3-60-g2f50