1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-10-31 00:07:39 +02:00

Quick fix for xbrz scaling artifacts on window borders

This commit is contained in:
Ivan Savenko
2024-12-10 14:20:55 +00:00
parent d7d60bf61b
commit 0842ada1c7
8 changed files with 41 additions and 11 deletions

View File

@@ -201,7 +201,7 @@ CBitmapFont::CBitmapFont(const std::string & filename):
static const std::map<std::string, EScalingAlgorithm> filterNameToEnum = {
{ "nearest", EScalingAlgorithm::NEAREST},
{ "bilinear", EScalingAlgorithm::BILINEAR},
{ "xbrz", EScalingAlgorithm::XBRZ}
{ "xbrz", EScalingAlgorithm::XBRZ_ALPHA}
};
auto filterName = settings["video"]["fontUpscalingFilter"].String();

View File

@@ -278,7 +278,7 @@ void SDLImageShared::optimizeSurface()
}
}
std::shared_ptr<const ISharedImage> SDLImageShared::scaleInteger(int factor, SDL_Palette * palette) const
std::shared_ptr<const ISharedImage> SDLImageShared::scaleInteger(int factor, SDL_Palette * palette, EImageBlitMode mode) const
{
if (factor <= 0)
throw std::runtime_error("Unable to scale by integer value of " + std::to_string(factor));
@@ -293,7 +293,13 @@ std::shared_ptr<const ISharedImage> SDLImageShared::scaleInteger(int factor, SDL
if(preScaleFactor == factor)
return shared_from_this();
else if(preScaleFactor == 1)
scaled = CSDL_Ext::scaleSurfaceIntegerFactor(surf, factor, EScalingAlgorithm::XBRZ);
{
// dump heuristics to differentiate tileable UI elements from map object / combat assets
if (mode == EImageBlitMode::OPAQUE || mode == EImageBlitMode::COLORKEY || mode == EImageBlitMode::SIMPLE)
scaled = CSDL_Ext::scaleSurfaceIntegerFactor(surf, factor, EScalingAlgorithm::XBRZ_OPAQUE);
else
scaled = CSDL_Ext::scaleSurfaceIntegerFactor(surf, factor, EScalingAlgorithm::XBRZ_ALPHA);
}
else
scaled = CSDL_Ext::scaleSurface(surf, (surf->w / preScaleFactor) * factor, (surf->h / preScaleFactor) * factor);
@@ -589,12 +595,12 @@ void SDLImageRGB::scaleTo(const Point & size)
void SDLImageIndexed::scaleInteger(int factor)
{
image = image->scaleInteger(factor, currentPalette);
image = image->scaleInteger(factor, currentPalette, blitMode);
}
void SDLImageRGB::scaleInteger(int factor)
{
image = image->scaleInteger(factor, nullptr);
image = image->scaleInteger(factor, nullptr, blitMode);
}
void SDLImageRGB::exportBitmap(const boost::filesystem::path & path) const

View File

@@ -60,7 +60,7 @@ public:
std::shared_ptr<IImage> createImageReference(EImageBlitMode mode) const override;
std::shared_ptr<const ISharedImage> horizontalFlip() const override;
std::shared_ptr<const ISharedImage> verticalFlip() const override;
std::shared_ptr<const ISharedImage> scaleInteger(int factor, SDL_Palette * palette) const override;
std::shared_ptr<const ISharedImage> scaleInteger(int factor, SDL_Palette * palette, EImageBlitMode blitMode) const override;
std::shared_ptr<const ISharedImage> scaleTo(const Point & size, SDL_Palette * palette) const override;
friend class SDLImageLoader;

View File

@@ -683,12 +683,17 @@ SDL_Surface * CSDL_Ext::scaleSurfaceIntegerFactor(SDL_Surface * surf, int factor
case EScalingAlgorithm::BILINEAR:
xbrz::bilinearScale(srcPixels, intermediate->w, intermediate->h, dstPixels, ret->w, ret->h);
break;
case EScalingAlgorithm::XBRZ:
tbb::parallel_for(tbb::blocked_range<size_t>(0, intermediate->h, granulation), [factor, srcPixels, dstPixels, intermediate](const tbb::blocked_range<size_t> & r)
case EScalingAlgorithm::XBRZ_ALPHA:
case EScalingAlgorithm::XBRZ_OPAQUE:
{
auto format = algorithm == EScalingAlgorithm::XBRZ_OPAQUE ? xbrz::ColorFormat::ARGB_CLAMPED : xbrz::ColorFormat::ARGB;
tbb::parallel_for(tbb::blocked_range<size_t>(0, intermediate->h, granulation), [factor, srcPixels, dstPixels, intermediate, format](const tbb::blocked_range<size_t> & r)
{
xbrz::scale(factor, srcPixels, dstPixels, intermediate->w, intermediate->h, xbrz::ColorFormat::ARGB, {}, r.begin(), r.end());
xbrz::scale(factor, srcPixels, dstPixels, intermediate->w, intermediate->h, format, {}, r.begin(), r.end());
});
break;
}
default:
throw std::runtime_error("invalid scaling algorithm!");
}

View File

@@ -31,7 +31,8 @@ enum class EScalingAlgorithm : int8_t
{
NEAREST,
BILINEAR,
XBRZ
XBRZ_OPAQUE, // xbrz, image edges are considered to have same color as pixel inside image
XBRZ_ALPHA // xbrz, image edges are considered to be transparent
};
namespace CSDL_Ext