Bladeren bron

Fix handling of transparency in xbrz and in images with non-cyan
transparent color in unscaled mode

Ivan Savenko 1 jaar geleden
bovenliggende
commit
0bbc2bce33

+ 2 - 6
client/render/ImageLocator.cpp

@@ -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;
 }

+ 12 - 4
client/render/ImageLocator.h

@@ -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);

+ 7 - 9
client/renderSDL/ImageScaled.cpp

@@ -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();
 	}

+ 5 - 7
client/renderSDL/RenderHandler.cpp

@@ -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);

+ 4 - 3
client/renderSDL/SDLImage.cpp

@@ -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;
 }