summaryrefslogtreecommitdiff
path: root/src/resources
diff options
context:
space:
mode:
Diffstat (limited to 'src/resources')
-rw-r--r--src/resources/ambientlayer.cpp22
-rw-r--r--src/resources/image.cpp291
-rw-r--r--src/resources/image.h58
3 files changed, 37 insertions, 334 deletions
diff --git a/src/resources/ambientlayer.cpp b/src/resources/ambientlayer.cpp
index c31afbac..301927f8 100644
--- a/src/resources/ambientlayer.cpp
+++ b/src/resources/ambientlayer.cpp
@@ -33,25 +33,6 @@ AmbientLayer::AmbientLayer(Image *img, float parallax,
mKeepRatio(keepRatio)
{
mImage->incRef();
-
- if (keepRatio && !mImage->useOpenGL()
- && defaultScreenWidth != 0
- && defaultScreenHeight != 0
- && graphics->getWidth() != defaultScreenWidth
- && graphics->getHeight() != defaultScreenHeight)
- {
- // Rescale the overlay to keep the ratio as if we were on
- // the default resolution...
- Image *rescaledOverlay = mImage->SDLgetScaledImage(
- (int) mImage->getWidth() / defaultScreenWidth * graphics->getWidth(),
- (int) mImage->getHeight() / defaultScreenHeight * graphics->getHeight());
-
- if (rescaledOverlay)
- {
- mImage->decRef();
- mImage = rescaledOverlay;
- }
- }
}
AmbientLayer::~AmbientLayer()
@@ -86,7 +67,7 @@ void AmbientLayer::update(int timePassed, float dx, float dy)
void AmbientLayer::draw(Graphics *graphics, int x, int y)
{
- if (!mImage->useOpenGL() || !mKeepRatio)
+ if (!mKeepRatio)
graphics->drawImagePattern(mImage,
(int) -mPosX, (int) -mPosY, x + (int) mPosX, y + (int) mPosY);
else
@@ -94,5 +75,4 @@ void AmbientLayer::draw(Graphics *graphics, int x, int y)
(int) -mPosX, (int) -mPosY, x + (int) mPosX, y + (int) mPosY,
(int) mImage->getWidth() / defaultScreenWidth * graphics->getWidth(),
(int) mImage->getHeight() / defaultScreenHeight * graphics->getHeight());
-
}
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 7e592198..6f2609b0 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -29,10 +29,8 @@
#endif
#include "log.h"
-#include "configuration.h"
#include <SDL_image.h>
-#include <SDL_rotozoom.h>
#ifdef USE_OPENGL
bool Image::mUseOpenGL = false;
@@ -40,47 +38,38 @@ bool Image::mPowerOfTwoTextures = true;
int Image::mTextureType = 0;
int Image::mTextureSize = 0;
#endif
-bool Image::mEnableAlphaCache = false;
// The low CPU mode is disabled per default
bool Image::mDisableTransparency = false;
-Image::Image(SDL_Surface *image, bool hasAlphaChannel, Uint8 *alphaChannel):
+SDL_Renderer *Image::mRenderer;
+
+Image::Image(SDL_Texture *texture, int width, int height):
mAlpha(1.0f),
- mSDLSurface(image),
- mAlphaChannel(alphaChannel),
- mHasAlphaChannel(hasAlphaChannel)
+ mTexture(texture)
{
#ifdef USE_OPENGL
mGLImage = 0;
#endif
- mUseAlphaCache = Image::mEnableAlphaCache;
-
mBounds.x = 0;
mBounds.y = 0;
+ mBounds.w = width;
+ mBounds.h = height;
- mLoaded = false;
+ mLoaded = mTexture != nullptr;
- if (mSDLSurface)
+ if (!mLoaded)
{
- mBounds.w = mSDLSurface->w;
- mBounds.h = mSDLSurface->h;
-
- mLoaded = true;
- }
- else
logger->log(
"Image::Image(SDL_Surface*): Couldn't load invalid Surface!");
+ }
}
#ifdef USE_OPENGL
Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight):
mAlpha(1.0f),
- mSDLSurface(0),
- mAlphaChannel(0),
- mHasAlphaChannel(true),
- mUseAlphaCache(false),
+ mTexture(0),
mGLImage(glimage),
mTexWidth(texWidth),
mTexHeight(texHeight)
@@ -140,10 +129,8 @@ Resource *Image::load(SDL_RWops *rw, Dye const &dye)
rgba.Gmask = 0x00FF0000; rgba.Gloss = 0; rgba.Gshift = 16;
rgba.Bmask = 0x0000FF00; rgba.Bloss = 0; rgba.Bshift = 8;
rgba.Amask = 0x000000FF; rgba.Aloss = 0; rgba.Ashift = 0;
- rgba.colorkey = 0;
- rgba.alpha = 255;
- SDL_Surface *surf = SDL_ConvertSurface(tmpImage, &rgba, SDL_SWSURFACE);
+ SDL_Surface *surf = SDL_ConvertSurface(tmpImage, &rgba, 0);
SDL_FreeSurface(tmpImage);
Uint32 *pixels = static_cast< Uint32 * >(surf->pixels);
@@ -173,34 +160,14 @@ Image *Image::load(SDL_Surface *tmpImage)
return _SDLload(tmpImage);
}
-void Image::SDLcleanCache()
-{
- ResourceManager *resman = ResourceManager::getInstance();
-
- for (std::map<float, SDL_Surface*>::iterator
- i = mAlphaCache.begin(), i_end = mAlphaCache.end();
- i != i_end; ++i)
- {
- if (mSDLSurface != i->second)
- resman->scheduleDelete(i->second);
- i->second = 0;
- }
- mAlphaCache.clear();
-}
-
void Image::unload()
{
mLoaded = false;
- if (mSDLSurface)
+ if (mTexture)
{
- SDLcleanCache();
- // Free the image surface.
- SDL_FreeSurface(mSDLSurface);
- mSDLSurface = NULL;
-
- delete[] mAlphaChannel;
- mAlphaChannel = NULL;
+ SDL_DestroyTexture(mTexture);
+ mTexture = NULL;
}
#ifdef USE_OPENGL
@@ -221,27 +188,6 @@ bool Image::useOpenGL()
#endif
}
-bool Image::hasAlphaChannel()
-{
- if (!mLoaded)
- return false;
-
-#ifdef USE_OPENGL
- if (mUseOpenGL)
- return true;
-#endif
-
- return mHasAlphaChannel;
-}
-
-SDL_Surface *Image::getByAlpha(float alpha)
-{
- std::map<float, SDL_Surface*>::iterator it = mAlphaCache.find(alpha);
- if (it != mAlphaCache.end())
- return (*it).second;
- return 0;
-}
-
void Image::setAlpha(float alpha)
{
if (!useOpenGL() && mDisableTransparency)
@@ -253,188 +199,26 @@ void Image::setAlpha(float alpha)
if (alpha < 0.0f || alpha > 1.0f)
return;
- if (mSDLSurface)
- {
- if (mUseAlphaCache)
- {
- SDL_Surface *surface = getByAlpha(mAlpha);
- if (!surface)
- {
- if (mAlphaCache.size() > 100)
- SDLcleanCache();
-
- mAlphaCache[mAlpha] = mSDLSurface;
- }
- surface = getByAlpha(alpha);
- if (surface)
- {
- mAlphaCache.erase(alpha);
- mSDLSurface = surface;
- mAlpha = alpha;
- return;
- }
- else
- {
- mSDLSurface = Image::SDLduplicateSurface(mSDLSurface);
- }
- }
-
- mAlpha = alpha;
-
- if (!hasAlphaChannel())
- {
- // Set the alpha value this image is drawn at
- SDL_SetAlpha(mSDLSurface, SDL_SRCALPHA, (int) (255 * mAlpha));
- }
- else
- {
- if (SDL_MUSTLOCK(mSDLSurface))
- SDL_LockSurface(mSDLSurface);
-
- // Precompute as much as possible
- int maxHeight = std::min((mBounds.y + mBounds.h), mSDLSurface->h);
- int maxWidth = std::min((mBounds.x + mBounds.w), mSDLSurface->w);
- int i = 0;
-
- for (int y = mBounds.y; y < maxHeight; y++)
- for (int x = mBounds.x; x < maxWidth; x++)
- {
- i = y * mSDLSurface->w + x;
- // Only change the pixel if it was visible at load time...
- Uint8 sourceAlpha = mAlphaChannel[i];
- if (sourceAlpha > 0)
- {
- Uint8 r, g, b, a;
- SDL_GetRGBA(((Uint32*) mSDLSurface->pixels)[i],
- mSDLSurface->format,
- &r, &g, &b, &a);
-
- a = (Uint8) (sourceAlpha * mAlpha);
-
- // Here is the pixel we want to set
- ((Uint32 *)(mSDLSurface->pixels))[i] =
- SDL_MapRGBA(mSDLSurface->format, r, g, b, a);
- }
- }
-
- if (SDL_MUSTLOCK(mSDLSurface))
- SDL_UnlockSurface(mSDLSurface);
- }
- }
- else
- {
- mAlpha = alpha;
- }
-}
-
-Image *Image::SDLgetScaledImage(int width, int height)
-{
- if (width == 0 || height == 0)
- return 0;
+ mAlpha = alpha;
- // Increase our reference count and return ourselves in case of same size
- if (width == getWidth() && height == getHeight())
+ if (mTexture)
{
- incRef();
- return this;
- }
-
- if (!mSDLSurface)
- return 0;
-
- ResourceManager *resman = ResourceManager::getInstance();
-
- // Generate a unique ID path for storing the scaled version in the
- // resource manager.
- std::string idPath = getIdPath();
- idPath += ":scaled:";
- idPath += toString(width);
- idPath += "x";
- idPath += toString(height);
-
- // Try whether a scaled version is already available
- Image *scaledImage = static_cast<Image*>(resman->get(idPath));
-
- if (!scaledImage)
- {
- // No scaled version with this size exists already, so create one
- SDL_Surface *scaledSurface = zoomSurface(mSDLSurface,
- (double) width / getWidth(),
- (double) height / getHeight(),
- 1);
-
- if (scaledSurface)
- {
- scaledImage = load(scaledSurface);
- SDL_FreeSurface(scaledSurface);
-
- // Place the scaled image in the resource manager
- resman->addResource(idPath, scaledImage);
- }
+ SDL_SetTextureAlphaMod(mTexture, (Uint8) (255 * mAlpha));
}
-
- return scaledImage;
}
-SDL_Surface* Image::SDLduplicateSurface(SDL_Surface* tmpImage)
+Image *Image::_SDLload(SDL_Surface *image)
{
- if (!tmpImage || !tmpImage->format)
+ if (!image || !mRenderer)
return NULL;
- return SDL_ConvertSurface(tmpImage, tmpImage->format, SDL_SWSURFACE);
+ SDL_Texture *texture = SDL_CreateTextureFromSurface(mRenderer, image);
+ return new Image(texture, image->w, image->h);
}
-Image *Image::_SDLload(SDL_Surface *tmpImage)
+void Image::setRenderer(SDL_Renderer *renderer)
{
- if (!tmpImage)
- return NULL;
-
- bool hasAlpha = false;
-
- // The alpha channel to be filled with alpha values
- Uint8 *alphaChannel = new Uint8[tmpImage->w * tmpImage->h];
-
- if (tmpImage->format->BitsPerPixel == 32)
- {
- // Figure out whether the image uses its alpha layer
- for (int i = 0; i < tmpImage->w * tmpImage->h; ++i)
- {
- Uint8 r, g, b, a;
- SDL_GetRGBA(
- ((Uint32*) tmpImage->pixels)[i],
- tmpImage->format,
- &r, &g, &b, &a);
-
- 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 = NULL;
- }
-
- if (!image)
- {
- logger->log("Error: Image convert failed.");
- delete[] alphaChannel;
- return NULL;
- }
-
- return new Image(image, hasAlpha, alphaChannel);
+ mRenderer = renderer;
}
#ifdef USE_OPENGL
@@ -489,7 +273,7 @@ Image *Image::_GLload(SDL_Surface *image)
}
// Make sure the alpha channel is not used, but copied to destination
- SDL_SetAlpha(oldImage, 0, SDL_ALPHA_OPAQUE);
+ SDL_SetSurfaceBlendMode(oldImage, SDL_BLENDMODE_NONE);
SDL_BlitSurface(oldImage, NULL, image, NULL);
}
@@ -583,38 +367,24 @@ Image *Image::getSubImage(int x, int y, int width, int height)
mTexWidth, mTexHeight);
#endif
- return new SubImage(this, mSDLSurface,
+ return new SubImage(this, mTexture,
mBounds.x + x,
mBounds.y + y,
width, height);
}
-void Image::SDLterminateAlphaCache()
-{
- SDLcleanCache();
- mUseAlphaCache = false;
-}
-
//============================================================================
// SubImage Class
//============================================================================
-SubImage::SubImage(Image *parent, SDL_Surface *image,
+SubImage::SubImage(Image *parent, SDL_Texture *texture,
int x, int y, int width, int height):
- Image(image),
+ Image(texture, width, height),
mParent(parent)
{
if (mParent)
{
mParent->incRef();
- mParent->SDLterminateAlphaCache();
- mHasAlphaChannel = mParent->hasAlphaChannel();
- mAlphaChannel = mParent->SDLgetAlphaChannel();
- }
- else
- {
- mHasAlphaChannel = false;
- mAlphaChannel = 0;
}
// Set up the rectangle.
@@ -622,7 +392,6 @@ SubImage::SubImage(Image *parent, SDL_Surface *image,
mBounds.y = y;
mBounds.w = width;
mBounds.h = height;
- mUseAlphaCache = false;
}
#ifdef USE_OPENGL
@@ -644,10 +413,8 @@ SubImage::SubImage(Image *parent, GLuint image,
SubImage::~SubImage()
{
- // Avoid destruction of the image
- mSDLSurface = 0;
- // Avoid possible destruction of its alpha channel
- mAlphaChannel = 0;
+ // Avoid destruction of the texture
+ mTexture = nullptr;
#ifdef USE_OPENGL
mGLImage = 0;
#endif
diff --git a/src/resources/image.h b/src/resources/image.h
index b762bf2a..efe2262e 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -37,8 +37,6 @@
#include <SDL_opengl.h>
#endif
-#include <map>
-
class Dye;
class Position;
@@ -129,12 +127,6 @@ class Image : public Resource
*/
Image *getSubImage(int x, int y, int width, int height);
- /**
- * Tells if the image has got an alpha channel
- * @return true if it's true, false otherwise.
- */
- bool hasAlphaChannel();
-
// SDL only public functions
/**
@@ -146,31 +138,7 @@ class Image : public Resource
static bool SDLisTransparencyDisabled()
{ return mDisableTransparency; }
- /**
- * Gets an scaled instance of an image. The returned image is managed
- * by the ResourceManager.
- *
- * @param width The desired width of the scaled image.
- * @param height The desired height of the scaled image.
- *
- * @return An Image resource, or 0 on failure.
- */
- Image *SDLgetScaledImage(int width, int height);
-
- /**
- * Get the alpha Channel of a SDL surface.
- */
- Uint8 *SDLgetAlphaChannel() const
- { return mAlphaChannel; }
-
- SDL_Surface* SDLduplicateSurface(SDL_Surface* tmpImage);
-
- void SDLcleanCache();
-
- void SDLterminateAlphaCache();
-
- static void SDLsetEnableAlphaCache(bool n)
- { mEnableAlphaCache = n; }
+ static void setRenderer(SDL_Renderer *renderer);
#ifdef USE_OPENGL
@@ -204,30 +172,18 @@ class Image : public Resource
// -----------------------
/** SDL Constructor */
- Image(SDL_Surface *image, bool hasAlphaChannel = false,
- Uint8 *alphaChannel = NULL);
+ Image(SDL_Texture *texture, int width, int height);
- /** SDL_Surface to SDL_Surface Image loader */
+ /** SDL_Surface to SDL_Texture Image loader */
static Image *_SDLload(SDL_Surface *tmpImage);
- SDL_Surface *getByAlpha(float alpha);
-
- SDL_Surface *mSDLSurface;
-
- /** Alpha Channel pointer used for 32bit based SDL surfaces */
- Uint8 *mAlphaChannel;
- bool mHasAlphaChannel;
-
- /** Alpha cache: The cache stores a copy of the image
- for specific requested opacities, hence, increasing
- the image disply speed */
- std::map<float, SDL_Surface*> mAlphaCache;
- bool mUseAlphaCache;
- static bool mEnableAlphaCache;
+ SDL_Texture *mTexture;
/** Stores whether the transparency is disabled */
static bool mDisableTransparency;
+ static SDL_Renderer *mRenderer;
+
// -----------------------
// OpenGL protected members
// -----------------------
@@ -261,7 +217,7 @@ class Image : public Resource
class SubImage : public Image
{
public:
- SubImage(Image *parent, SDL_Surface *image,
+ SubImage(Image *parent, SDL_Texture *texture,
int x, int y, int width, int height);
#ifdef USE_OPENGL
SubImage(Image *parent, GLuint image, int x, int y,