diff options
author | Aaron Suen <warr1024@gmail.com> | 2015-03-21 09:59:06 -0400 |
---|---|---|
committer | Craig Robbins <kde.psych@gmail.com> | 2015-03-22 01:31:01 +1000 |
commit | 837a2e1e5fef788cf108e036c27d092cedb3982f (patch) | |
tree | 6edec8f7b282bf709772928c954a92de9c4bdff8 /src/client | |
parent | 709f4a50f73fd6c61412cf77516ed767893486ab (diff) | |
download | minetest-837a2e1e5fef788cf108e036c27d092cedb3982f.tar.gz minetest-837a2e1e5fef788cf108e036c27d092cedb3982f.tar.bz2 minetest-837a2e1e5fef788cf108e036c27d092cedb3982f.zip |
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.
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/tile.cpp | 76 |
1 files changed, 44 insertions, 32 deletions
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<u32> 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<u32> newdim = core::dimension2d<u32>(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<u32> 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<u32> newdim = core::dimension2d<u32>(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; i<m_textureinfo_cache.size(); i++){ TextureInfo *ti = &m_textureinfo_cache[i]; - video::IImage *img = generateImage(ti->name); + 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 |