43 PRAGMA48(GCC diagnostic ignored
"-Wshadow")
47 #include <SDL_rotozoom.h>
71 mHasAlphaChannel(false),
72 mUseAlphaCache(false),
73 mIsAlphaVisible(true),
74 mIsAlphaCalculated(false)
85 const int width,
const int height) :
99 mHasAlphaChannel(false),
100 mUseAlphaCache(false),
101 mIsAlphaVisible(true),
102 mIsAlphaCalculated(false)
106 static_cast<void*
>(
this));
128 uint8_t *
restrict const alphaChannel) :
141 mAlphaChannel(alphaChannel),
144 mHasAlphaChannel(hasAlphaChannel0),
146 mIsAlphaVisible(hasAlphaChannel0),
147 mIsAlphaCalculated(false)
150 logger->
log(
"created image: %p",
static_cast<void*
>(
this));
156 if (mSDLSurface !=
nullptr)
158 mBounds.w =
CAST_U16(mSDLSurface->w);
159 mBounds.h =
CAST_U16(mSDLSurface->h);
171 Image::Image(
const GLuint glimage,
const int width,
const int height,
172 const int texWidth,
const int texHeight) :
176 mTexHeight(texHeight),
186 mHasAlphaChannel(true),
187 mUseAlphaCache(false),
188 mIsAlphaVisible(true),
189 mIsAlphaCalculated(false)
192 logger->
log(
"created image: %p",
static_cast<void*
>(
this));
210 logger->
log(
"delete image: %p",
static_cast<void*
>(
this));
211 logger->
log(
" %s, %s", mIdPath.c_str(), mSource.c_str());
217 void Image::SDLCleanCache()
219 for (std::map<float, SDL_Surface*>::iterator
220 i = mAlphaCache.begin(), i_end = mAlphaCache.end();
223 if (mSDLSurface != i->second)
234 if (mSDLSurface !=
nullptr)
239 mSDLSurface =
nullptr;
241 delete [] mAlphaChannel;
242 mAlphaChannel =
nullptr;
247 SDL_DestroyTexture(mTexture);
255 glDeleteTextures(1, &mGLImage);
257 #ifdef DEBUG_OPENGL_LEAKS
265 bool Image::hasAlphaChannel()
const
268 return mHasAlphaChannel;
278 SDL_Surface *Image::getByAlpha(
const float alpha)
280 const std::map<float, SDL_Surface*>::const_iterator
281 it = mAlphaCache.find(alpha);
282 if (it != mAlphaCache.end())
287 void Image::setAlpha(
const float alpha)
292 if (alpha < 0.0F || alpha > 1.0F)
295 if (mSDLSurface !=
nullptr)
299 SDL_Surface *surface = getByAlpha(mAlpha);
300 if (surface ==
nullptr)
302 if (mAlphaCache.size() > 100)
304 #ifdef DEBUG_ALPHA_CACHE
306 for (std::map<float, SDL_Surface*>::const_iterator
307 i = mAlphaCache.begin(), i_end = mAlphaCache.end();
316 surface = mSDLSurface;
317 if (surface !=
nullptr)
318 mAlphaCache[mAlpha] = surface;
325 surface = getByAlpha(alpha);
326 if (surface !=
nullptr)
328 if (mSDLSurface == surface)
330 mAlphaCache.erase(alpha);
331 mSDLSurface = surface;
336 if (mSDLSurface ==
nullptr)
342 if (!mHasAlphaChannel)
345 SDL_SetSurfaceAlphaMod(mSDLSurface,
350 SDL_SetAlpha(mSDLSurface, SDL_SRCALPHA,
356 if (SDL_MUSTLOCK(mSDLSurface))
357 SDL_LockSurface(mSDLSurface);
359 const int bx = mBounds.x;
360 const int by = mBounds.y;
361 const int bw = mBounds.w;
362 const int bh = mBounds.h;
363 const int bxw = bx + bw;
364 const int sw = mSDLSurface->w;
365 const int maxHeight = std::min(by + bh, mSDLSurface->h);
366 const int maxWidth = std::min(bxw, sw);
367 const int i1 = by * sw + bx;
368 const SDL_PixelFormat *
const fmt = mSDLSurface->format;
369 const uint32_t amask = fmt->Amask;
370 const uint32_t invMask = ~fmt->Amask;
371 const uint8_t aloss = fmt->Aloss;
372 const uint8_t ashift = fmt->Ashift;
374 if ((bx == 0) && bxw == sw)
376 const int i2 = (maxHeight - 1) * sw + maxWidth - 1;
377 for (
int i = i1; i <= i2; i++)
379 const uint8_t sourceAlpha = mAlphaChannel[i];
383 static_cast<float>(sourceAlpha) * mAlpha);
385 uint32_t c = (
static_cast<uint32_t*
>(
386 mSDLSurface->pixels))[i];
388 c |= ((a >> aloss) << ashift & amask);
389 (
static_cast<uint32_t*
>(mSDLSurface->pixels))[i] = c;
395 for (
int y = by;
y < maxHeight;
y ++)
397 const int idx =
y * sw;
398 const int x1 = idx + bx;
399 const int x2 = idx + maxWidth;
400 for (
int i = x1; i < x2; i ++)
402 const uint8_t sourceAlpha = mAlphaChannel[i];
406 static_cast<float>(sourceAlpha) * mAlpha);
408 uint32_t c = (
static_cast<uint32_t*
>(
409 mSDLSurface->pixels))[i];
411 c |= ((a >> aloss) << ashift & amask);
412 (
static_cast<uint32_t*
>(
413 mSDLSurface->pixels))[i] = c;
419 if (SDL_MUSTLOCK(mSDLSurface))
420 SDL_UnlockSurface(mSDLSurface);
427 SDL_SetTextureAlphaMod(mTexture,
437 Image* Image::SDLgetScaledImage(
const int width,
const int height)
const
440 if (width == 0 || height == 0)
444 if (width == mBounds.w && height == mBounds.h)
447 Image* scaledImage =
nullptr;
449 if (mSDLSurface !=
nullptr)
451 SDL_Surface *
const scaledSurface =
zoomSurface(mSDLSurface,
452 static_cast<double>(width) / mBounds.w,
453 static_cast<double>(height) / mBounds.h,
458 if (scaledSurface !=
nullptr)
468 const int width,
const int height)
483 mTexWidth, mTexHeight);
493 return new SubImage(
this, mSDLSurface,
x,
y, width, height);
495 return new SubImage(
this, mTexture,
x,
y, width, height);
498 return new SubImage(
this, mSDLSurface,
x,
y, width, height);
502 void Image::SDLTerminateAlphaCache()
505 mUseAlphaCache =
false;
511 int sz =
static_cast<int>(
sizeof(
Image) +
512 sizeof(std::map<float, SDL_Surface*>)) +
514 if (mSDLSurface !=
nullptr)
516 sz +=
CAST_S32(mAlphaCache.size()) *
525 if ((mGLImage != 0U) && mRefCount <= 1)
SDL_Surface * zoomSurface(SDL_Surface *src, double zoomx, double zoomy, int smooth)
Zoom a surface by independent horizontal and vertical factors with optional smoothing.
static RenderType mUseOpenGL
virtual Image * loadSurface(SDL_Surface *const)
void log(const char *const log_text,...)
static int getSurfaceSize(const SDL_Surface *const surface)
static void invalidate(const GLuint textureId)
int calcMemoryLocal() const
static SDL_Surface * SDLDuplicateSurface(SDL_Surface *const tmpImage)
#define MSDL_FreeSurface(surface)
ImageHelper * imageHelper
std::string toString(T const &value)
converts any type to a string
Image * getSubImage(Image *const parent, const int x, const int y, const int width, const int height)
void scheduleDelete(SDL_Surface *const surface)