aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Suen <warr1024@gmail.com>2015-03-21 09:59:06 -0400
committerCraig Robbins <kde.psych@gmail.com>2015-03-22 01:31:01 +1000
commit837a2e1e5fef788cf108e036c27d092cedb3982f (patch)
tree6edec8f7b282bf709772928c954a92de9c4bdff8
parent709f4a50f73fd6c61412cf77516ed767893486ab (diff)
downloadminetest-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.
-rw-r--r--src/client/tile.cpp76
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