diff options
author | Andrei Karas <akaras@inbox.ru> | 2011-07-20 02:57:47 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2011-07-20 03:41:35 +0300 |
commit | e645959d2dc85ee6a50d9927df3d9f6e374c8317 (patch) | |
tree | 6e5c348a7c89c4c864bab299fc9989fc0b0a5791 /src/resources/image.cpp | |
parent | ca945c9bd62318109246443c6d43091885e817b1 (diff) | |
download | mv-e645959d2dc85ee6a50d9927df3d9f6e374c8317.tar.gz mv-e645959d2dc85ee6a50d9927df3d9f6e374c8317.tar.bz2 mv-e645959d2dc85ee6a50d9927df3d9f6e374c8317.tar.xz mv-e645959d2dc85ee6a50d9927df3d9f6e374c8317.zip |
Improve perfomance in creation SDL font surfaces.
Diffstat (limited to 'src/resources/image.cpp')
-rw-r--r-- | src/resources/image.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 29e89d26e..583cf7343 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -189,6 +189,83 @@ Image *Image::load(SDL_Surface *tmpImage) return _SDLload(tmpImage); } +Image *Image::createTextSurface(SDL_Surface *tmpImage, float alpha) +{ + if (!tmpImage) + return NULL; + + Image *img; +#ifdef USE_OPENGL + if (mUseOpenGL) + { + img = _GLload(tmpImage); + img->setAlpha(alpha); + return img; + } +#endif + + bool hasAlpha = false; + bool converted = false; + + // The alpha channel to be filled with alpha values + Uint8 *alphaChannel = new Uint8[tmpImage->w * tmpImage->h]; + + const int sz = tmpImage->w * tmpImage->h; + const SDL_PixelFormat * const fmt = tmpImage->format; + if (fmt->Amask) + { + for (int i = 0; i < sz; ++ i) + { + unsigned v = ((static_cast<Uint32*>(tmpImage->pixels))[i] + & fmt->Amask) >> fmt->Ashift; + Uint8 a = (v << fmt->Aloss) + (v >> (8 - (fmt->Aloss << 1))); + + Uint8 a2 = static_cast<Uint8>(static_cast<float>(a) * alpha); + + (static_cast<Uint32*>(tmpImage->pixels))[i] &= ~fmt->Amask; + (static_cast<Uint32*>(tmpImage->pixels))[i] |= + ((a2 >> fmt->Aloss) << fmt->Ashift & fmt->Amask); + + if (a != 255) + hasAlpha = true; + + alphaChannel[i] = a; + + } + } + + SDL_Surface *image; + + // Convert the surface to the current display format + if (hasAlpha) + { + image = SDL_DisplayFormatAlpha(tmpImage); + } + else + { + image = SDL_DisplayFormat(tmpImage); + + // We also delete the alpha channel since + // it's not used. + delete[] alphaChannel; + alphaChannel = 0; + } + + if (!image) + { + logger->log1("Error: Image convert failed."); + delete[] alphaChannel; + return 0; + } + + if (converted) + SDL_FreeSurface(tmpImage); + + img = new Image(image, hasAlpha, alphaChannel); + img->mAlpha = alpha; + return img; +} + void Image::SDLCleanCache() { ResourceManager *resman = ResourceManager::getInstance(); |