mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Fix handling of transparency in xbrz and in images with non-cyan
transparent color in unscaled mode
This commit is contained in:
		| @@ -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,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); | ||||
|   | ||||
| @@ -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(); | ||||
| 	} | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user