From 837a2e1e5fef788cf108e036c27d092cedb3982f Mon Sep 17 00:00:00 2001 From: Aaron Suen Date: Sat, 21 Mar 2015 09:59:06 -0400 Subject: Fix composite textures with texture_min_size. Moved upscaling of textures to later in the process, when images are converted to textures, instead of right after image load, so the original image is unmodified for generateImagePart. --- src/client/tile.cpp | 76 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 078e62741..7b326c152 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -182,6 +182,42 @@ struct TextureInfo } }; +/* Upscale textures to user's requested minimum size. This is a trick to make + * filters look as good on low-res textures as on high-res ones, by making + * low-res textures BECOME high-res ones. This is helpful for worlds that + * mix high- and low-res textures, or for mods with least-common-denominator + * textures that don't have the resources to offer high-res alternatives. + */ +video::IImage *textureMinSizeUpscale(video::IVideoDriver *driver, video::IImage *orig) { + if(orig == NULL) + return orig; + s32 scaleto = g_settings->getS32("texture_min_size"); + if (scaleto > 0) { + + /* Calculate scaling needed to make the shortest texture dimension + * equal to the target minimum. If e.g. this is a vertical frames + * animation, the short dimension will be the real size. + */ + const core::dimension2d dim = orig->getDimension(); + u32 xscale = scaleto / dim.Width; + u32 yscale = scaleto / dim.Height; + u32 scale = (xscale > yscale) ? xscale : yscale; + + // Never downscale; only scale up by 2x or more. + if (scale > 1) { + u32 w = scale * dim.Width; + u32 h = scale * dim.Height; + const core::dimension2d newdim = core::dimension2d(w, h); + video::IImage *newimg = driver->createImage( + orig->getColorFormat(), newdim); + orig->copyToScaling(newimg); + return newimg; + } + } + + return orig; +} + /* SourceImageCache: A cache used for storing source images. */ @@ -276,36 +312,6 @@ public: } } - /* Upscale textures to user's requested minimum size. This is a trick to make - * filters look as good on low-res textures as on high-res ones, by making - * low-res textures BECOME high-res ones. This is helpful for worlds that - * mix high- and low-res textures, or for mods with least-common-denominator - * textures that don't have the resources to offer high-res alternatives. - */ - s32 scaleto = g_settings->getS32("texture_min_size"); - if (scaleto > 0) { - - /* Calculate scaling needed to make the shortest texture dimension - * equal to the target minimum. If e.g. this is a vertical frames - * animation, the short dimension will be the real size. - */ - const core::dimension2d dim = toadd->getDimension(); - u32 xscale = scaleto / dim.Width; - u32 yscale = scaleto / dim.Height; - u32 scale = (xscale > yscale) ? xscale : yscale; - - // Never downscale; only scale up by 2x or more. - if (scale > 1) { - u32 w = scale * dim.Width; - u32 h = scale * dim.Height; - const core::dimension2d newdim = core::dimension2d(w, h); - video::IImage *newimg = driver->createImage( - toadd->getColorFormat(), newdim); - toadd->copyToScaling(newimg); - toadd = newimg; - } - } - if (need_to_grab) toadd->grab(); m_images[name] = toadd; @@ -682,7 +688,8 @@ u32 TextureSource::generateTexture(const std::string &name) video::IVideoDriver *driver = m_device->getVideoDriver(); sanity_check(driver); - video::IImage *img = generateImage(name); + video::IImage *origimg = generateImage(name); + video::IImage *img = textureMinSizeUpscale(driver, origimg); video::ITexture *tex = NULL; @@ -693,6 +700,8 @@ u32 TextureSource::generateTexture(const std::string &name) // Create texture from resulting image tex = driver->addTexture(name.c_str(), img); img->drop(); + if((origimg != NULL) && (img != origimg)) + origimg->drop(); } /* @@ -783,7 +792,8 @@ void TextureSource::rebuildImagesAndTextures() // Recreate textures for (u32 i=0; iname); + video::IImage *origimg = generateImage(ti->name); + video::IImage *img = textureMinSizeUpscale(driver, origimg); #ifdef __ANDROID__ img = Align2Npot2(img, driver); sanity_check(img->getDimension().Height == npot2(img->getDimension().Height)); @@ -794,6 +804,8 @@ void TextureSource::rebuildImagesAndTextures() if (img) { t = driver->addTexture(ti->name.c_str(), img); img->drop(); + if(origimg && (origimg != img)) + origimg->drop(); } video::ITexture *t_old = ti->texture; // Replace texture -- cgit v1.2.3