From d5847d54a527c41006cb4cade15d0b6346490e77 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 25 Aug 2013 19:36:20 +0300 Subject: add partial support for software mode with SDL2. --- src/resources/image.cpp | 71 +++++++++++++++++++++++++++++++++++- src/resources/image.h | 7 ++++ src/resources/sdl2imagehelper.cpp | 21 ++++++----- src/resources/sdl2imagehelper.h | 8 ++++ src/resources/subimage.cpp | 53 +++++++++++++++++++++++++++ src/resources/subimage.h | 4 ++ src/resources/surfaceimagehelper.cpp | 2 +- 7 files changed, 155 insertions(+), 11 deletions(-) (limited to 'src/resources') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 49650fef3..759a3a055 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -46,6 +46,50 @@ #include "debug.h" +#ifdef USE_SDL2 +Image::Image(SDL_Texture *const image, const int width, const int height) : + Resource(), +#ifdef USE_OPENGL + mGLImage(0), + mTexWidth(0), + mTexHeight(0), +#endif + mBounds(), + mAlpha(1.0f), + mSDLSurface(nullptr), + mTexture(image), + mAlphaChannel(nullptr), + mAlphaCache(), + mLoaded(false), + mHasAlphaChannel(false), + mUseAlphaCache(false), + mIsAlphaVisible(true), + mIsAlphaCalculated(false) +{ +#ifdef DEBUG_IMAGES + logger->log("created: %p", this); +#endif + + mBounds.x = 0; + mBounds.y = 0; + + if (mTexture) + { + mBounds.w = static_cast(width); + mBounds.h = static_cast(height); + + mLoaded = true; + } + else + { + logger->log("Image::Image(SDL_Texture *const image):" + " Couldn't load invalid Surface!"); + mBounds.w = 0; + mBounds.h = 0; + } +} +#endif + Image::Image(SDL_Surface *const image, const bool hasAlphaChannel0, uint8_t *const alphaChannel) : Resource(), @@ -57,6 +101,9 @@ Image::Image(SDL_Surface *const image, const bool hasAlphaChannel0, mBounds(), mAlpha(1.0f), mSDLSurface(image), +#ifdef USE_SDL2 + mTexture(nullptr), +#endif mAlphaChannel(alphaChannel), mAlphaCache(), mLoaded(false), @@ -98,6 +145,9 @@ Image::Image(const GLuint glimage, const int width, const int height, mBounds(), mAlpha(1.0f), mSDLSurface(nullptr), +#ifdef USE_SDL2 + mTexture(nullptr), +#endif mAlphaChannel(nullptr), mAlphaCache(), mLoaded(false), @@ -164,6 +214,13 @@ void Image::unload() delete [] mAlphaChannel; mAlphaChannel = nullptr; } +#ifdef USE_SDL2 + if (mTexture) + { + SDL_DestroyTexture(mTexture); + mTexture = nullptr; + } +#endif #ifdef USE_OPENGL if (mGLImage) @@ -257,11 +314,11 @@ void Image::setAlpha(const float alpha) if (!mHasAlphaChannel) { - // Set the alpha value this image is drawn at #ifdef USE_SDL2 SDL_SetSurfaceAlphaMod(mSDLSurface, static_cast(255 * mAlpha)); #else + // Set the alpha value this image is drawn at SDL_SetAlpha(mSDLSurface, SDL_SRCALPHA, static_cast(255 * mAlpha)); #endif @@ -302,6 +359,14 @@ void Image::setAlpha(const float alpha) SDL_UnlockSurface(mSDLSurface); } } +#ifdef USE_SDL2 + else if (mTexture) + { + mAlpha = alpha; + SDL_SetTextureAlphaMod(mTexture, + static_cast(255 * mAlpha)); + } +#endif else { mAlpha = alpha; @@ -352,7 +417,11 @@ Image *Image::getSubImage(const int x, const int y, } #endif +#ifdef USE_SDL2 + return new SubImage(this, mTexture, x, y, width, height); +#else return new SubImage(this, mSDLSurface, x, y, width, height); +#endif } void Image::SDLTerminateAlphaCache() diff --git a/src/resources/image.h b/src/resources/image.h index ed42991bb..a40f62dee 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -199,9 +199,16 @@ class Image : public Resource Image(SDL_Surface *const image, const bool hasAlphaChannel = false, uint8_t *const alphaChannel = nullptr); +#ifdef USE_SDL2 + Image(SDL_Texture *const image, const int width, const int height); +#endif + SDL_Surface *getByAlpha(const float alpha) A_WARN_UNUSED; SDL_Surface *mSDLSurface; +#ifdef USE_SDL2 + SDL_Texture *mTexture; +#endif /** Alpha Channel pointer used for 32bit based SDL surfaces */ uint8_t *mAlphaChannel; diff --git a/src/resources/sdl2imagehelper.cpp b/src/resources/sdl2imagehelper.cpp index b131b4d69..ee342ee26 100644 --- a/src/resources/sdl2imagehelper.cpp +++ b/src/resources/sdl2imagehelper.cpp @@ -38,6 +38,9 @@ #include "debug.h" bool SDLImageHelper::mEnableAlphaCache = false; +#ifdef USE_SDL2 +SDL_Renderer *SDLImageHelper::mRenderer = nullptr; +#endif Image *SDLImageHelper::load(SDL_RWops *const rw, Dye const &dye) const { @@ -114,13 +117,9 @@ Image *SDLImageHelper::createTextSurface(SDL_Surface *const tmpImage, if (!tmpImage) return nullptr; - Image *img; - bool hasAlpha = false; - uint8_t *alphaChannel = nullptr; - SDL_Surface *image = SDLDuplicateSurface(tmpImage); - - img = new Image(image, hasAlpha, alphaChannel); - img->mAlpha = alpha; + Image *const img = _SDLload(tmpImage); + if (img) + img->setAlpha(alpha); return img; } @@ -137,8 +136,12 @@ Image *SDLImageHelper::_SDLload(SDL_Surface *tmpImage) const if (!tmpImage) return nullptr; - SDL_Surface *image = convertTo32Bit(tmpImage); - return new Image(image, false, nullptr); + SDL_Texture *const texture = SDL_CreateTextureFromSurface( + mRenderer, tmpImage); + if (!texture) + return nullptr; + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + return new Image(texture, tmpImage->w, tmpImage->h); } int SDLImageHelper::useOpenGL() const diff --git a/src/resources/sdl2imagehelper.h b/src/resources/sdl2imagehelper.h index 9edd48ebe..5c35f8026 100644 --- a/src/resources/sdl2imagehelper.h +++ b/src/resources/sdl2imagehelper.h @@ -94,11 +94,19 @@ class SDLImageHelper final : public ImageHelper SDL_Surface *const dst, SDL_Rect *const dstrect); +#ifdef USE_SDL2 + static void setRenderer(SDL_Renderer *const renderer) + { mRenderer = renderer; } +#endif + protected: /** SDL_Surface to SDL_Surface Image loader */ Image *_SDLload(SDL_Surface *tmpImage) const A_WARN_UNUSED; static bool mEnableAlphaCache; +#ifdef USE_SDL2 + static SDL_Renderer *mRenderer; +#endif }; #endif // USE_SDL2 diff --git a/src/resources/subimage.cpp b/src/resources/subimage.cpp index b2343c71c..d37eda91a 100644 --- a/src/resources/subimage.cpp +++ b/src/resources/subimage.cpp @@ -36,6 +36,59 @@ #include "debug.h" +#ifdef USE_SDL2 +SubImage::SubImage(Image *const parent, SDL_Texture *const image, + const int x, const int y, + const int width, const int height) : + Image(image, width, height), + mInternalBounds(), + mParent(parent) +{ + if (mParent) + { + mParent->incRef(); + mParent->SDLTerminateAlphaCache(); + mHasAlphaChannel = mParent->hasAlphaChannel(); + mIsAlphaVisible = mHasAlphaChannel; + mAlphaChannel = mParent->SDLgetAlphaChannel(); + mSource = parent->getIdPath(); +#ifdef DEBUG_IMAGES + logger->log("set name2 %p, %s", this, mSource.c_str()); +#endif +#ifdef DEBUG_BIND_TEXTURE + mIdPath = parent->getIdPath(); +#endif + } + else + { + mHasAlphaChannel = false; + mIsAlphaVisible = false; + mAlphaChannel = nullptr; + } + + // Set up the rectangle. + mBounds.x = static_cast(x); + mBounds.y = static_cast(y); + mBounds.w = static_cast(width); + mBounds.h = static_cast(height); + if (mParent) + { + mInternalBounds.x = mParent->mBounds.x; + mInternalBounds.y = mParent->mBounds.y; + mInternalBounds.w = mParent->mBounds.w; + mInternalBounds.h = mParent->mBounds.h; + } + else + { + mInternalBounds.x = 0; + mInternalBounds.y = 0; + mInternalBounds.w = 1; + mInternalBounds.h = 1; + } + mUseAlphaCache = false; +} +#endif + SubImage::SubImage(Image *const parent, SDL_Surface *const image, const int x, const int y, const int width, const int height) : diff --git a/src/resources/subimage.h b/src/resources/subimage.h index 8dae594f6..5322f9a71 100644 --- a/src/resources/subimage.h +++ b/src/resources/subimage.h @@ -50,6 +50,10 @@ class SubImage final : public Image /** * Constructor. */ +#ifdef USE_SDL2 + SubImage(Image *const parent, SDL_Texture *const image, + const int x, const int y, const int width, const int height); +#endif SubImage(Image *const parent, SDL_Surface *const image, const int x, const int y, const int width, const int height); #ifdef USE_OPENGL diff --git a/src/resources/surfaceimagehelper.cpp b/src/resources/surfaceimagehelper.cpp index 1b5997ce0..45a7d95fd 100644 --- a/src/resources/surfaceimagehelper.cpp +++ b/src/resources/surfaceimagehelper.cpp @@ -120,7 +120,7 @@ Image *SurfaceImageHelper::createTextSurface(SDL_Surface *const tmpImage, SDL_Surface *image = SDLDuplicateSurface(tmpImage); img = new Image(image, hasAlpha, alphaChannel); - img->mAlpha = alpha; + img->setAlpha(alpha); return img; } -- cgit v1.2.3-70-g09d2