From db32e6c5aa3bf79c23fa51f9297440fcaf09215d Mon Sep 17 00:00:00 2001 From: Aaron Suen Date: Mon, 30 Mar 2015 20:04:19 -0400 Subject: Move texture_min_size even further down the pipe. Now, textures are JIT-upscaled using an image transformation, right at the time they're added to a mesh or particle; images used in 2D elements are left unscaled. This should fix any remaining issues with HUD elements. --- src/client/tile.cpp | 96 ++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 49 deletions(-) (limited to 'src/client/tile.cpp') diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 1cf9f1506..b7f63502d 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -182,47 +182,6 @@ 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 > 1) { - const core::dimension2d dim = orig->getDimension(); - - // Don't upscale 1px images. They don't benefit from it anyway - // (wouldn't have been blurred) and MIGHT be sun/moon tonemaps. - if ((dim.Width <= 1) || (dim.Height <= 1)) - return orig; - - /* 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. - */ - 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. */ @@ -425,6 +384,14 @@ public: video::ITexture* getTexture(const std::string &name, u32 *id); + /* + Get a texture specifically intended for mesh + application, i.e. not HUD, compositing, or other 2D + use. This texture may be a different size and may + have had additional filters applied. + */ + video::ITexture* getTextureForMesh(const std::string &name, u32 *id); + // Returns a pointer to the irrlicht device virtual IrrlichtDevice* getDevice() { @@ -693,8 +660,7 @@ u32 TextureSource::generateTexture(const std::string &name) video::IVideoDriver *driver = m_device->getVideoDriver(); sanity_check(driver); - video::IImage *origimg = generateImage(name); - video::IImage *img = textureMinSizeUpscale(driver, origimg); + video::IImage *img = generateImage(name); video::ITexture *tex = NULL; @@ -705,8 +671,6 @@ 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(); } /* @@ -757,6 +721,11 @@ video::ITexture* TextureSource::getTexture(const std::string &name, u32 *id) return getTexture(actual_id); } +video::ITexture* TextureSource::getTextureForMesh(const std::string &name, u32 *id) +{ + return getTexture(name + "^[autoupscaleformesh", id); +} + void TextureSource::processQueue() { /* @@ -797,8 +766,7 @@ void TextureSource::rebuildImagesAndTextures() // Recreate textures for (u32 i=0; iname); - video::IImage *img = textureMinSizeUpscale(driver, origimg); + video::IImage *img = generateImage(ti->name); #ifdef __ANDROID__ img = Align2Npot2(img, driver); sanity_check(img->getDimension().Height == npot2(img->getDimension().Height)); @@ -809,8 +777,6 @@ 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 @@ -1735,6 +1701,38 @@ bool TextureSource::generateImagePart(std::string part_of_name, blit_with_interpolate_overlay(img, baseimg, v2s32(0,0), v2s32(0,0), dim, ratio); img->drop(); } + else if (part_of_name.substr(0,19) == "[autoupscaleformesh") { + /* 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 > 1) { + const core::dimension2d dim = baseimg->getDimension(); + + /* 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. + */ + 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( + baseimg->getColorFormat(), newdim); + baseimg->copyToScaling(newimg); + baseimg->drop(); + baseimg = newimg; + } + } + } else { errorstream << "generateImagePart(): Invalid " -- cgit v1.2.3