summaryrefslogtreecommitdiff
path: root/src/client/tile.cpp
diff options
context:
space:
mode:
authorAaron Suen <warr1024@gmail.com>2015-03-30 20:04:19 -0400
committerCraig Robbins <kde.psych@gmail.com>2015-03-31 16:56:33 +1000
commitdb32e6c5aa3bf79c23fa51f9297440fcaf09215d (patch)
tree7d840ddc94da602c8fda5009feedbec06f91ac1a /src/client/tile.cpp
parent862d4ea328ed30d79f4e28eb9119e21e275295d9 (diff)
downloadminetest-db32e6c5aa3bf79c23fa51f9297440fcaf09215d.tar.gz
minetest-db32e6c5aa3bf79c23fa51f9297440fcaf09215d.tar.bz2
minetest-db32e6c5aa3bf79c23fa51f9297440fcaf09215d.zip
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.
Diffstat (limited to 'src/client/tile.cpp')
-rw-r--r--src/client/tile.cpp96
1 files changed, 47 insertions, 49 deletions
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<u32> 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<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.
*/
@@ -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; i<m_textureinfo_cache.size(); i++){
TextureInfo *ti = &m_textureinfo_cache[i];
- video::IImage *origimg = generateImage(ti->name);
- 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<u32> 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<u32> newdim = core::dimension2d<u32>(w, h);
+ video::IImage *newimg = driver->createImage(
+ baseimg->getColorFormat(), newdim);
+ baseimg->copyToScaling(newimg);
+ baseimg->drop();
+ baseimg = newimg;
+ }
+ }
+ }
else
{
errorstream << "generateImagePart(): Invalid "