1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

Fix handling of transparency in xbrz and in images with non-cyan

transparent color in unscaled mode
This commit is contained in:
Ivan Savenko
2024-08-27 19:44:11 +00:00
parent 5da00799c4
commit 0bbc2bce33
5 changed files with 30 additions and 29 deletions

View File

@@ -56,12 +56,8 @@ bool ImageLocator::operator<(const ImageLocator & other) const
return scalingFactor < other.scalingFactor;
if(playerColored != other.playerColored)
return playerColored < other.playerColored;
if(layerShadow != other.layerShadow)
return layerShadow < other.layerShadow;
if(layerBody != other.layerBody)
return layerBody < other.layerBody;
if (layerOverlay != other.layerOverlay)
return layerOverlay < other.layerOverlay;
if(layer != other.layer)
return layer < other.layer;
return false;
}

View File

@@ -12,6 +12,15 @@
#include "../../lib/filesystem/ResourcePath.h"
#include "../../lib/constants/EntityIdentifiers.h"
enum class EImageLayer
{
ALL,
BODY,
SHADOW,
OVERLAY,
};
struct ImageLocator
{
std::optional<ImagePath> image;
@@ -19,13 +28,12 @@ struct ImageLocator
int defFrame = -1;
int defGroup = -1;
PlayerColor playerColored = PlayerColor::CANNOT_DETERMINE;
bool verticalFlip = false;
bool horizontalFlip = false;
int8_t scalingFactor = 1;
PlayerColor playerColored = PlayerColor::CANNOT_DETERMINE;
bool layerShadow = false;
bool layerBody = true;
bool layerOverlay = false;
EImageLayer layer = EImageLayer::ALL;
ImageLocator() = default;
ImageLocator(const AnimationPath & path, int frame, int group);

View File

@@ -30,6 +30,8 @@ ImageScaled::ImageScaled(const ImageLocator & inputLocator, const std::shared_pt
{
locator.scalingFactor = GH.screenHandler().getScalingFactor();
setBodyEnabled(true);
if (mode == EImageBlitMode::ALPHA)
setShadowEnabled(true);
}
std::shared_ptr<ISharedImage> ImageScaled::getSharedImage() const
@@ -107,11 +109,10 @@ void ImageScaled::adjustPalette(const ColorFilter &shifter, uint32_t colorsToSki
void ImageScaled::setShadowEnabled(bool on)
{
assert(blitMode == EImageBlitMode::ALPHA);
if (on)
{
locator.layerBody = false;
locator.layerShadow = true;
locator.layerOverlay = false;
locator.layer = EImageLayer::SHADOW;
locator.playerColored = PlayerColor::CANNOT_DETERMINE;
shadow = GH.renderHandler().loadImage(locator, blitMode)->getSharedImage();
}
@@ -123,9 +124,7 @@ void ImageScaled::setBodyEnabled(bool on)
{
if (on)
{
locator.layerBody = true;
locator.layerShadow = false;
locator.layerOverlay = false;
locator.layer = blitMode == EImageBlitMode::ALPHA ? EImageLayer::BODY : EImageLayer::ALL;
locator.playerColored = playerColor;
body = GH.renderHandler().loadImage(locator, blitMode)->getSharedImage();
}
@@ -136,11 +135,10 @@ void ImageScaled::setBodyEnabled(bool on)
void ImageScaled::setOverlayEnabled(bool on)
{
assert(blitMode == EImageBlitMode::ALPHA);
if (on)
{
locator.layerBody = false;
locator.layerShadow = false;
locator.layerOverlay = true;
locator.layer = EImageLayer::OVERLAY;
locator.playerColored = PlayerColor::CANNOT_DETERMINE;
overlay = GH.renderHandler().loadImage(locator, blitMode)->getSharedImage();
}

View File

@@ -228,16 +228,14 @@ std::shared_ptr<ISharedImage> RenderHandler::scaleImage(const ImageLocator & loc
if (imageFiles.count(locator))
return imageFiles.at(locator);
auto handle = image->createImageReference(EImageBlitMode::OPAQUE);
auto handle = image->createImageReference(locator.layer == EImageLayer::ALL ? EImageBlitMode::OPAQUE : EImageBlitMode::ALPHA);
assert(locator.scalingFactor != 1); // should be filtered-out before
handle->setOverlayEnabled(locator.layerOverlay);
handle->setBodyEnabled(locator.layerBody);
handle->setShadowEnabled(locator.layerShadow);
if (locator.layerBody && locator.playerColored != PlayerColor::CANNOT_DETERMINE)
handle->setOverlayEnabled(locator.layer == EImageLayer::ALL || locator.layer == EImageLayer::OVERLAY);
handle->setBodyEnabled(locator.layer == EImageLayer::ALL || locator.layer == EImageLayer::BODY);
handle->setShadowEnabled(locator.layer == EImageLayer::ALL || locator.layer == EImageLayer::SHADOW);
if (locator.layer == EImageLayer::ALL && locator.playerColored != PlayerColor::CANNOT_DETERMINE)
handle->playerColored(locator.playerColored);
handle->scaleInteger(locator.scalingFactor);

View File

@@ -472,13 +472,11 @@ void SDLImageIndexed::setShadowTransparency(float factor)
};
// seems to be used unconditionally
colorsSDL[0] = CSDL_Ext::toSDL(Colors::TRANSPARENCY);
colorsSDL[1] = CSDL_Ext::toSDL(shadow25);
colorsSDL[4] = CSDL_Ext::toSDL(shadow50);
// seems to be used only if color matches
if (colorsSimilar(originalPalette->colors[0], sourcePalette[0]))
colorsSDL[0] = CSDL_Ext::toSDL(Colors::TRANSPARENCY);
if (colorsSimilar(originalPalette->colors[2], sourcePalette[2]))
colorsSDL[2] = CSDL_Ext::toSDL(shadow25);
@@ -502,6 +500,9 @@ void SDLImageIndexed::setShadowEnabled(bool on)
if (on)
setShadowTransparency(1.0);
if (!on && blitMode == EImageBlitMode::ALPHA)
setShadowTransparency(0.0);
shadowEnabled = on;
}