Fix composite textures with texture_min_size. Moved upscaling of textures to later...
authorAaron Suen <warr1024@gmail.com>
Sat, 21 Mar 2015 13:59:06 +0000 (09:59 -0400)
committerCraig Robbins <kde.psych@gmail.com>
Sat, 21 Mar 2015 15:31:01 +0000 (01:31 +1000)
src/client/tile.cpp

index 078e62741ab3036a053cfdfb2005817f3403958d..7b326c15221d33e71ed0f96f5488b85b8f43c71d 100644 (file)
@@ -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