From 62e2ccbb158f146e2c3ceab14ff5581d3f3975ef Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Tue, 1 Jul 2014 21:57:46 +0300 Subject: Add to image helper function to copy surface into part of image. --- src/resources/imagehelper.h | 15 ++++++++--- src/resources/openglimagehelper.cpp | 54 ++++++++++++++++++++++++++++++------- src/resources/openglimagehelper.h | 7 +++++ src/resources/sdl2imagehelper.cpp | 18 +++++++++++++ src/resources/sdl2imagehelper.h | 5 ++++ src/resources/sdlimagehelper.cpp | 17 ++++++++++++ src/resources/sdlimagehelper.h | 5 ++++ 7 files changed, 107 insertions(+), 14 deletions(-) diff --git a/src/resources/imagehelper.h b/src/resources/imagehelper.h index 6752f3eae..b7080ee4b 100644 --- a/src/resources/imagehelper.h +++ b/src/resources/imagehelper.h @@ -75,15 +75,22 @@ class ImageHelper notfinal { return nullptr; } #endif + virtual SDL_Surface *create32BitSurface(int width, + int height) + const A_WARN_UNUSED; + + virtual void copySurfaceToImage(Image *const image A_UNUSED, + const int x A_UNUSED, + const int y A_UNUSED, + SDL_Surface *const surface A_UNUSED) + const + { } + static SDL_Surface *convertTo32Bit(SDL_Surface *const tmpImage) A_WARN_UNUSED; static void dumpSurfaceFormat(const SDL_Surface *const image); - virtual SDL_Surface *create32BitSurface(int width, - int height) - const A_WARN_UNUSED; - static void setEnableAlpha(const bool n) { mEnableAlpha = n; } diff --git a/src/resources/openglimagehelper.cpp b/src/resources/openglimagehelper.cpp index d083b22b5..5f1ec643c 100644 --- a/src/resources/openglimagehelper.cpp +++ b/src/resources/openglimagehelper.cpp @@ -133,19 +133,12 @@ int OpenGLImageHelper::powerOfTwo(const int input) return value >= mTextureSize ? mTextureSize : value; } -Image *OpenGLImageHelper::glLoad(SDL_Surface *tmpImage, - int width, int height) +SDL_Surface *OpenGLImageHelper::convertSurface(SDL_Surface *tmpImage, + int width, int height) { if (!tmpImage) return nullptr; - // Flush current error flag. - graphicsManager.getLastError(); - - if (!width) - width = tmpImage->w; - if (!height) - height = tmpImage->h; int realWidth = powerOfTwo(width); int realHeight = powerOfTwo(height); @@ -197,6 +190,28 @@ Image *OpenGLImageHelper::glLoad(SDL_Surface *tmpImage, } SDL_BlitSurface(oldImage, nullptr, tmpImage, nullptr); } + return tmpImage; +} + +Image *OpenGLImageHelper::glLoad(SDL_Surface *tmpImage, + int width, int height) +{ + if (!tmpImage) + return nullptr; + + // Flush current error flag. + graphicsManager.getLastError(); + + if (!width) + width = tmpImage->w; + if (!height) + height = tmpImage->h; + + SDL_Surface *oldImage = tmpImage; + tmpImage = convertSurface(tmpImage, width, height); + + const int realWidth = tmpImage->w; + const int realHeight = tmpImage->h; const GLuint texture = getNewTexture(); switch (mUseOpenGL) @@ -281,7 +296,7 @@ Image *OpenGLImageHelper::glLoad(SDL_Surface *tmpImage, if (SDL_MUSTLOCK(tmpImage)) SDL_UnlockSurface(tmpImage); - if (oldImage) + if (oldImage != tmpImage) MSDL_FreeSurface(tmpImage); GLenum error = graphicsManager.getLastError(); @@ -358,4 +373,23 @@ void OpenGLImageHelper::invalidate(const GLuint textureId) } } +void OpenGLImageHelper::copySurfaceToImage(Image *const image, + const int x, const int y, + SDL_Surface *surface) const +{ + if (!surface) + return; + + SDL_Surface *const oldSurface = surface; + surface = convertSurface(surface, surface->w, surface->h); + + glTexSubImage2D(mTextureType, 0, + x, y, + surface->w, surface->h, + GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels); + + if (surface != oldSurface) + MSDL_FreeSurface(surface); +} + #endif diff --git a/src/resources/openglimagehelper.h b/src/resources/openglimagehelper.h index 2a91689d9..b413e21ae 100644 --- a/src/resources/openglimagehelper.h +++ b/src/resources/openglimagehelper.h @@ -123,12 +123,19 @@ class OpenGLImageHelper final : public ImageHelper void postInit() override final; + void copySurfaceToImage(Image *const image, + const int x, const int y, + SDL_Surface *surface) const; + protected: /** * Returns the first power of two equal or bigger than the input. */ static int powerOfTwo(const int input) A_WARN_UNUSED; + static SDL_Surface *convertSurface(SDL_Surface *tmpImage, + int width, int height); + Image *glLoad(SDL_Surface *tmpImage, int width = 0, int height = 0) A_WARN_UNUSED; diff --git a/src/resources/sdl2imagehelper.cpp b/src/resources/sdl2imagehelper.cpp index c671a60c1..12e975ae6 100644 --- a/src/resources/sdl2imagehelper.cpp +++ b/src/resources/sdl2imagehelper.cpp @@ -94,4 +94,22 @@ int SDLImageHelper::combineSurface(SDL_Surface *restrict const src, return 1; } +void SDLImageHelper::copySurfaceToImage(Image *const image, + const int x, const int y, + SDL_Surface *const surface) const +{ + if (!image || !surface) + return; + + SDL_SetSurfaceAlphaMod(surface, SDL_ALPHA_OPAQUE); + SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); + + SDL_Rect rect = + { + x, y, + surface->w, surface->h + }; + + SDL_BlitSurface(surface, nullptr, image->mSDLSurface, &rect); +} #endif // USE_SDL2 diff --git a/src/resources/sdl2imagehelper.h b/src/resources/sdl2imagehelper.h index e7ddc2987..f59a6bee1 100644 --- a/src/resources/sdl2imagehelper.h +++ b/src/resources/sdl2imagehelper.h @@ -62,6 +62,11 @@ class SDLImageHelper final : public ImageHelper const float alpha) override final A_WARN_UNUSED; + void copySurfaceToImage(Image *const image, + const int x, const int y, + SDL_Surface *const surface) + const override final; + static void SDLSetEnableAlphaCache(const bool n) { mEnableAlphaCache = n; } diff --git a/src/resources/sdlimagehelper.cpp b/src/resources/sdlimagehelper.cpp index 7d4090deb..baf1125fa 100644 --- a/src/resources/sdlimagehelper.cpp +++ b/src/resources/sdlimagehelper.cpp @@ -284,4 +284,21 @@ int SDLImageHelper::combineSurface(SDL_Surface *restrict const src, return SDL_gfxBlitRGBA(src, srcrect, dst, dstrect); } +void SDLImageHelper::copySurfaceToImage(Image *const image, + const int x, const int y, + SDL_Surface *const surface) const +{ + if (!image || !surface) + return; + + SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE); + SDL_Rect rect = + { + x, y, + surface->w, surface->h + }; + + SDL_BlitSurface(surface, nullptr, image->mSDLSurface, &rect); +} + #endif // USE_SDL2 diff --git a/src/resources/sdlimagehelper.h b/src/resources/sdlimagehelper.h index c80a7ba2b..9ab12368f 100644 --- a/src/resources/sdlimagehelper.h +++ b/src/resources/sdlimagehelper.h @@ -74,6 +74,11 @@ class SDLImageHelper final : public ImageHelper const float alpha) override final A_WARN_UNUSED; + void copySurfaceToImage(Image *const image, + const int x, const int y, + SDL_Surface *const surface) + const override final; + static void SDLSetEnableAlphaCache(const bool n) { mEnableAlphaCache = n; } -- cgit v1.2.3-60-g2f50