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.

This commit is contained in:
Aaron Suen 2015-03-21 09:59:06 -04:00 committed by Craig Robbins
parent 709f4a50f7
commit 837a2e1e5f
1 changed files with 44 additions and 32 deletions

View 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