summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-08-04 19:53:35 +0200
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-08-04 21:23:12 +0200
commitff32ef8aa7c4ef8ab3865a0b274f72b1bc134204 (patch)
tree8c9e77af219c47bba535dec6275e182dca0e387c
parentbc29cbb38913abf66c794a134afe62ab8acf70b4 (diff)
downloadmana-ff32ef8aa7c4ef8ab3865a0b274f72b1bc134204.tar.gz
mana-ff32ef8aa7c4ef8ab3865a0b274f72b1bc134204.tar.bz2
mana-ff32ef8aa7c4ef8ab3865a0b274f72b1bc134204.tar.xz
mana-ff32ef8aa7c4ef8ab3865a0b274f72b1bc134204.zip
Fixed issues related to wrong alpha mod set on textures
Due to the use of SubImage, there can be multiple images pointing to the same SDL_Texture with different alpha values. However, since the alpha mod set on the texture was only set from Image::setAlpha, images were not always rendered with the correct alpha value. Now the alpha mod is always set right before rendering each image. Most of the time the alpha will remain the same, but I don't expect this to become a performance issue so I've not added extra variables and checks to suppress such calls when they aren't needed. On the upside, this simplifies the "use color" option, which previously had to restore the previously set alpha mod. Closes #117
-rw-r--r--src/gui/truetypefont.cpp8
-rw-r--r--src/map.cpp7
-rw-r--r--src/resources/image.cpp15
-rw-r--r--src/sdlgraphics.cpp56
-rw-r--r--src/sdlgraphics.h2
5 files changed, 29 insertions, 59 deletions
diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp
index c85d08c0..2dd7b817 100644
--- a/src/gui/truetypefont.cpp
+++ b/src/gui/truetypefont.cpp
@@ -45,14 +45,6 @@ static const char *getSafeUtf8String(const std::string &text)
return buf;
}
-bool operator==(SDL_Color lhs, SDL_Color rhs)
-{
- return (lhs.r == rhs.r &&
- lhs.g == rhs.g &&
- lhs.b == rhs.b &&
- lhs.a == rhs.a);
-}
-
class TextChunk
{
diff --git a/src/map.cpp b/src/map.cpp
index 8dbc7c28..5b89cd69 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -151,14 +151,13 @@ void MapLayer::draw(Graphics *graphics,
for (int x = startX; x < endX; x++)
{
- Image *img = getTile(x, y);
- if (img)
+ if (Image *img = getTile(x, y))
{
- const int px = (x * mMap->getTileWidth()) + dx;
- const int py = py0 - img->getHeight();
if (!(debugFlags & (Map::DEBUG_SPECIAL1 | Map::DEBUG_SPECIAL2))
|| img->getHeight() <= mMap->getTileHeight())
{
+ const int px = (x * mMap->getTileWidth()) + dx;
+ const int py = py0 - img->getHeight();
int width = 0;
int c = getTileDrawWidth(x, y, endX, width);
if (!c)
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 11d5c275..6e6f1187 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -32,6 +32,8 @@
#include <SDL_image.h>
+#include <algorithm>
+
#ifdef USE_OPENGL
bool Image::mUseOpenGL = false;
bool Image::mPowerOfTwoTextures = true;
@@ -176,18 +178,7 @@ void Image::setAlpha(float alpha)
if (!useOpenGL() && mDisableTransparency)
return;
- if (mAlpha == alpha)
- return;
-
- if (alpha < 0.0f || alpha > 1.0f)
- return;
-
- mAlpha = alpha;
-
- if (mTexture)
- {
- SDL_SetTextureAlphaMod(mTexture, (Uint8) (255 * mAlpha));
- }
+ mAlpha = std::clamp(alpha, 0.0f, 1.0f);
}
Image *Image::_SDLload(SDL_Surface *image)
diff --git a/src/sdlgraphics.cpp b/src/sdlgraphics.cpp
index 7d75e7f2..371288e1 100644
--- a/src/sdlgraphics.cpp
+++ b/src/sdlgraphics.cpp
@@ -30,39 +30,6 @@
#include <cmath>
-class SetColorAlphaMod
-{
-public:
- SetColorAlphaMod(SDL_Texture *texture, gcn::Color color, bool enabled)
- : mTexture(texture)
- , mEnabled(texture != nullptr && enabled)
- {
- if (mEnabled)
- {
- SDL_GetTextureColorMod(texture, &mOriginal.r, &mOriginal.g, &mOriginal.b);
- SDL_GetTextureAlphaMod(texture, &mOriginal.a);
-
- SDL_SetTextureColorMod(texture, color.r, color.g, color.b);
- SDL_SetTextureAlphaMod(texture, color.a * mOriginal.a / 255);
- }
- }
-
- ~SetColorAlphaMod()
- {
- if (mEnabled)
- {
- SDL_SetTextureAlphaMod(mTexture, mOriginal.a);
- SDL_SetTextureColorMod(mTexture, mOriginal.r, mOriginal.g, mOriginal.b);
- }
- }
-
-private:
- SDL_Texture *mTexture = nullptr;
- SDL_Color mOriginal;
- const bool mEnabled;
-};
-
-
std::unique_ptr<Graphics> SDLGraphics::create(SDL_Window *window, const VideoSettings &settings)
{
int rendererFlags = 0;
@@ -168,7 +135,7 @@ bool SDLGraphics::drawRescaledImage(const Image *image,
dstRect.w = desiredWidth;
dstRect.h = desiredHeight;
- SetColorAlphaMod mod(image->mTexture, mColor, useColor);
+ setColorAlphaMod(image, useColor);
return SDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect) != 0;
}
@@ -199,7 +166,7 @@ bool SDLGraphics::drawRescaledImageF(const Image *image,
dstRect.w = desiredWidth;
dstRect.h = desiredHeight;
- SetColorAlphaMod mod(image->mTexture, mColor, useColor);
+ setColorAlphaMod(image, useColor);
return SDL_RenderCopyF(mRenderer, image->mTexture, &srcRect, &dstRect) == 0;
}
#endif
@@ -219,6 +186,8 @@ void SDLGraphics::drawRescaledImagePattern(const Image *image,
if (scaledHeight <= 0 || scaledWidth <= 0)
return;
+ setColorAlphaMod(image, false);
+
SDL_Rect srcRect;
srcRect.x = image->mBounds.x + srcX;
srcRect.y = image->mBounds.y + srcY;
@@ -413,3 +382,20 @@ void SDLGraphics::fillRectangle(const gcn::Rectangle &rectangle)
(Uint8)(mColor.a));
SDL_RenderFillRect(mRenderer, &rect);
}
+
+void SDLGraphics::setColorAlphaMod(const Image *image, bool useColor) const
+{
+ SDL_Color color = { 255, 255, 255, 255 };
+ if (useColor)
+ {
+ color.r = static_cast<uint8_t>(mColor.r);
+ color.g = static_cast<uint8_t>(mColor.g);
+ color.b = static_cast<uint8_t>(mColor.b);
+ color.a = static_cast<uint8_t>(mColor.a);
+ }
+ color.a *= image->getAlpha();
+
+ SDL_Texture *texture = image->mTexture;
+ SDL_SetTextureColorMod(texture, color.r, color.g, color.b);
+ SDL_SetTextureAlphaMod(texture, color.a);
+}
diff --git a/src/sdlgraphics.h b/src/sdlgraphics.h
index 057fcdc3..a27deb4c 100644
--- a/src/sdlgraphics.h
+++ b/src/sdlgraphics.h
@@ -83,6 +83,8 @@ protected:
void updateClipRect() override;
private:
+ void setColorAlphaMod(const Image *image, bool useColor) const;
+
SDL_Window *mWindow = nullptr;
SDL_Renderer *mRenderer = nullptr;
};