diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-08-04 19:53:35 +0200 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-08-04 21:23:12 +0200 |
commit | ff32ef8aa7c4ef8ab3865a0b274f72b1bc134204 (patch) | |
tree | 8c9e77af219c47bba535dec6275e182dca0e387c | |
parent | bc29cbb38913abf66c794a134afe62ab8acf70b4 (diff) | |
download | mana-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.cpp | 8 | ||||
-rw-r--r-- | src/map.cpp | 7 | ||||
-rw-r--r-- | src/resources/image.cpp | 15 | ||||
-rw-r--r-- | src/sdlgraphics.cpp | 56 | ||||
-rw-r--r-- | src/sdlgraphics.h | 2 |
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; }; |