mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
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.
This commit is contained in:
parent
862d4ea328
commit
db32e6c5aa
11 changed files with 78 additions and 78 deletions
|
@ -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 "
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue