1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Clean scaling pre-filter for formspec/HUD.

This commit is contained in:
Aaron Suen 2015-03-09 09:32:11 -04:00 committed by kwolekr
parent b4247dff2e
commit 6d61375cc7
20 changed files with 524 additions and 102 deletions

View file

@ -34,6 +34,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gamedef.h"
#include "strfnd.h"
#include "util/string.h" // for parseColorString()
#include "imagefilters.h"
#include "guiscalingfilter.h"
#ifdef __ANDROID__
#include <GLES/gl.h>
@ -223,58 +225,9 @@ public:
}
}
/* Apply the "clean transparent" filter to textures, removing borders on transparent textures.
* PNG optimizers discard RGB values of fully-transparent pixels, but filters may expose the
* replacement colors at borders by blending to them; this filter compensates for that by
* filling in those RGB values from nearby pixels.
*/
if (g_settings->getBool("texture_clean_transparent")) {
const core::dimension2d<u32> dim = toadd->getDimension();
// Walk each pixel looking for ones that will show as transparent.
for (u32 ctrx = 0; ctrx < dim.Width; ctrx++)
for (u32 ctry = 0; ctry < dim.Height; ctry++) {
irr::video::SColor c = toadd->getPixel(ctrx, ctry);
if (c.getAlpha() > 127)
continue;
// Sample size and total weighted r, g, b values.
u32 ss = 0, sr = 0, sg = 0, sb = 0;
// Walk each neighbor pixel (clipped to image bounds).
for (u32 sx = (ctrx < 1) ? 0 : (ctrx - 1);
sx <= (ctrx + 1) && sx < dim.Width; sx++)
for (u32 sy = (ctry < 1) ? 0 : (ctry - 1);
sy <= (ctry + 1) && sy < dim.Height; sy++) {
// Ignore the center pixel (its RGB is already
// presumed meaningless).
if ((sx == ctrx) && (sy == ctry))
continue;
// Ignore other nearby pixels that would be
// transparent upon display.
irr::video::SColor d = toadd->getPixel(sx, sy);
if(d.getAlpha() < 128)
continue;
// Add one weighted sample.
ss++;
sr += d.getRed();
sg += d.getGreen();
sb += d.getBlue();
}
// If we found any neighbor RGB data, set pixel to average
// weighted by alpha.
if (ss > 0) {
c.setRed(sr / ss);
c.setGreen(sg / ss);
c.setBlue(sb / ss);
toadd->setPixel(ctrx, ctry, c);
}
}
}
// Apply the "clean transparent" filter, if configured.
if (g_settings->getBool("texture_clean_transparent"))
imageCleanTransparent(toadd, 127);
if (need_to_grab)
toadd->grab();
@ -670,6 +623,7 @@ u32 TextureSource::generateTexture(const std::string &name)
#endif
// Create texture from resulting image
tex = driver->addTexture(name.c_str(), img);
guiScalingCache(io::path(name.c_str()), driver, img);
img->drop();
}
@ -776,6 +730,7 @@ void TextureSource::rebuildImagesAndTextures()
video::ITexture *t = NULL;
if (img) {
t = driver->addTexture(ti->name.c_str(), img);
guiScalingCache(io::path(ti->name.c_str()), driver, img);
img->drop();
}
video::ITexture *t_old = ti->texture;
@ -896,6 +851,8 @@ video::ITexture* TextureSource::generateTextureFromMesh(
rawImage->copyToScaling(inventory_image);
rawImage->drop();
guiScalingCache(io::path(params.rtt_texture_name.c_str()), driver, inventory_image);
video::ITexture *rtt = driver->addTexture(params.rtt_texture_name.c_str(), inventory_image);
inventory_image->drop();