Skip to content

Commit

Permalink
Clean scaling pre-filter for formspec/HUD.
Browse files Browse the repository at this point in the history
  • Loading branch information
Warr1024 authored and kwolekr committed Apr 1, 2015
1 parent b4247df commit 6d61375
Show file tree
Hide file tree
Showing 20 changed files with 524 additions and 102 deletions.
2 changes: 2 additions & 0 deletions build/android/jni/Android.mk
Expand Up @@ -143,9 +143,11 @@ LOCAL_SRC_FILES := \
jni/src/guiKeyChangeMenu.cpp \
jni/src/guiPasswordChange.cpp \
jni/src/guiTable.cpp \
jni/src/guiscalingfilter.cpp \
jni/src/guiVolumeChange.cpp \
jni/src/httpfetch.cpp \
jni/src/hud.cpp \
jni/src/imagefilters.cpp \
jni/src/inventory.cpp \
jni/src/inventorymanager.cpp \
jni/src/itemdef.cpp \
Expand Down
13 changes: 13 additions & 0 deletions minetest.conf.example
Expand Up @@ -172,6 +172,19 @@
#crosshair_alpha = 255
# Scale gui by a user specified value
#gui_scaling = 1.0
# Use a nearest-neighbor-anti-alias filter to scale the GUI.
# This will smooth over some of the rough edges, and blend
# pixels when scaling down, at the cost of blurring some
# edge pixels when images are scaled by non-integer sizes.
#gui_scaling_filter = false
# When gui_scaling_filter = true, all GUI images need to be
# filtered in software, but some images are generated directly
# to hardare (e.g. render-to-texture for nodes in inventory).
# When gui_scaling_filter_txr2img is true, copy those images
# from hardware to software for scaling. When false, fall back
# to the old scaling method, for video drivers that don't
# propery support downloading textures back from hardware.
#gui_scaling_filter_txr2img = true
# Sensitivity multiplier
#mouse_sensitivity = 0.2
# Sound settings
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Expand Up @@ -405,9 +405,11 @@ set(client_SRCS
guiFormSpecMenu.cpp
guiKeyChangeMenu.cpp
guiPasswordChange.cpp
guiscalingfilter.cpp
guiTable.cpp
guiVolumeChange.cpp
hud.cpp
imagefilters.cpp
keycode.cpp
localplayer.cpp
main.cpp
Expand Down
6 changes: 6 additions & 0 deletions src/client.cpp
Expand Up @@ -49,6 +49,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "drawscene.h"
#include "database-sqlite3.h"
#include "serialization.h"
#include "guiscalingfilter.h"

extern gui::IGUIEnvironment* guienv;

Expand Down Expand Up @@ -1607,6 +1608,11 @@ void Client::afterContentReceived(IrrlichtDevice *device)

const wchar_t* text = wgettext("Loading textures...");

// Clear cached pre-scaled 2D GUI images, as this cache
// might have images with the same name but different
// content from previous sessions.
guiScalingCacheClear(device->getVideoDriver());

// Rebuild inherited images and recreate textures
infostream<<"- Rebuilding images and textures"<<std::endl;
draw_load_screen(text,device, guienv, 0, 70);
Expand Down
61 changes: 9 additions & 52 deletions src/client/tile.cpp
Expand Up @@ -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>
Expand Down Expand Up @@ -223,58 +225,9 @@ class SourceImageCache
}
}

/* 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();
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand Down
16 changes: 1 addition & 15 deletions src/client/tile.h
Expand Up @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "threads.h"
#include <string>
#include <vector>
#include "util/numeric.h"

class IGameDef;

Expand Down Expand Up @@ -135,21 +136,6 @@ class IWritableTextureSource : public ITextureSource
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);

#ifdef __ANDROID__
/**
* @param size get next npot2 value
* @return npot2 value
*/
inline unsigned int npot2(unsigned int size)
{
if (size == 0) return 0;
unsigned int npot = 1;

while ((size >>= 1) > 0) {
npot <<= 1;
}
return npot;
}

video::IImage * Align2Npot2(video::IImage * image, video::IVideoDriver* driver);
#endif

Expand Down
2 changes: 2 additions & 0 deletions src/defaultsettings.cpp
Expand Up @@ -137,6 +137,8 @@ void set_default_settings(Settings *settings)
settings->setDefault("crosshair_alpha", "255");
settings->setDefault("hud_scaling", "1.0");
settings->setDefault("gui_scaling", "1.0");
settings->setDefault("gui_scaling_filter", "false");
settings->setDefault("gui_scaling_filter_txr2img", "true");
settings->setDefault("mouse_sensitivity", "0.2");
settings->setDefault("enable_sound", "true");
settings->setDefault("sound_volume", "0.8");
Expand Down
17 changes: 9 additions & 8 deletions src/drawscene.cpp
Expand Up @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clientmap.h"
#include "util/timetaker.h"
#include "fontengine.h"
#include "guiscalingfilter.h"

typedef enum {
LEFT = -1,
Expand Down Expand Up @@ -324,19 +325,19 @@ void draw_sidebyside_3d_mode(Camera& camera, bool show_hud,
//makeColorKeyTexture mirrors texture so we do it twice to get it right again
driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));

driver->draw2DImage(left_image,
draw2DImageFilterScaled(driver, left_image,
irr::core::rect<s32>(0, 0, screensize.X/2, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);

driver->draw2DImage(hudtexture,
draw2DImageFilterScaled(driver, hudtexture,
irr::core::rect<s32>(0, 0, screensize.X/2, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);

driver->draw2DImage(right_image,
draw2DImageFilterScaled(driver, right_image,
irr::core::rect<s32>(screensize.X/2, 0, screensize.X, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);

driver->draw2DImage(hudtexture,
draw2DImageFilterScaled(driver, hudtexture,
irr::core::rect<s32>(screensize.X/2, 0, screensize.X, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);

Expand Down Expand Up @@ -380,19 +381,19 @@ void draw_top_bottom_3d_mode(Camera& camera, bool show_hud,
//makeColorKeyTexture mirrors texture so we do it twice to get it right again
driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));

driver->draw2DImage(left_image,
draw2DImageFilterScaled(driver, left_image,
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y/2),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);

driver->draw2DImage(hudtexture,
draw2DImageFilterScaled(driver, hudtexture,
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y/2),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);

driver->draw2DImage(right_image,
draw2DImageFilterScaled(driver, right_image,
irr::core::rect<s32>(0, screensize.Y/2, screensize.X, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);

driver->draw2DImage(hudtexture,
draw2DImageFilterScaled(driver, hudtexture,
irr::core::rect<s32>(0, screensize.Y/2, screensize.X, screensize.Y),
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);

Expand Down
11 changes: 6 additions & 5 deletions src/guiEngine.cpp
Expand Up @@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "httpfetch.h"
#include "log.h"
#include "fontengine.h"
#include "guiscalingfilter.h"

#ifdef __ANDROID__
#include "client/tile.h"
Expand Down Expand Up @@ -409,7 +410,7 @@ void GUIEngine::drawBackground(video::IVideoDriver* driver)
{
for (unsigned int y = 0; y < screensize.Y; y += tilesize.Y )
{
driver->draw2DImage(texture,
draw2DImageFilterScaled(driver, texture,
core::rect<s32>(x, y, x+tilesize.X, y+tilesize.Y),
core::rect<s32>(0, 0, sourcesize.X, sourcesize.Y),
NULL, NULL, true);
Expand All @@ -419,7 +420,7 @@ void GUIEngine::drawBackground(video::IVideoDriver* driver)
}

/* Draw background texture */
driver->draw2DImage(texture,
draw2DImageFilterScaled(driver, texture,
core::rect<s32>(0, 0, screensize.X, screensize.Y),
core::rect<s32>(0, 0, sourcesize.X, sourcesize.Y),
NULL, NULL, true);
Expand All @@ -438,7 +439,7 @@ void GUIEngine::drawOverlay(video::IVideoDriver* driver)

/* Draw background texture */
v2u32 sourcesize = texture->getOriginalSize();
driver->draw2DImage(texture,
draw2DImageFilterScaled(driver, texture,
core::rect<s32>(0, 0, screensize.X, screensize.Y),
core::rect<s32>(0, 0, sourcesize.X, sourcesize.Y),
NULL, NULL, true);
Expand Down Expand Up @@ -471,7 +472,7 @@ void GUIEngine::drawHeader(video::IVideoDriver* driver)

video::SColor bgcolor(255,50,50,50);

driver->draw2DImage(texture, splashrect,
draw2DImageFilterScaled(driver, texture, splashrect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
NULL, NULL, true);
Expand Down Expand Up @@ -503,7 +504,7 @@ void GUIEngine::drawFooter(video::IVideoDriver* driver)
rect += v2s32(screensize.Width/2,screensize.Height-footersize.Y);
rect -= v2s32(footersize.X/2, 0);

driver->draw2DImage(texture, rect,
draw2DImageFilterScaled(driver, texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
NULL, NULL, true);
Expand Down
15 changes: 8 additions & 7 deletions src/guiFormSpecMenu.cpp
Expand Up @@ -51,6 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/hex.h"
#include "util/numeric.h"
#include "util/string.h" // for parseColorString()
#include "guiscalingfilter.h"

#define MY_CHECKPOS(a,b) \
if (v_pos.size() != 2) { \
Expand Down Expand Up @@ -1307,8 +1308,8 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element,
}

e->setUseAlphaChannel(true);
e->setImage(texture);
e->setPressedImage(pressed_texture);
e->setImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), pressed_texture, geom.X, geom.Y));
e->setScaleImage(true);
e->setNotClipped(noclip);
e->setDrawBorder(drawborder);
Expand Down Expand Up @@ -1452,8 +1453,8 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
}

e->setUseAlphaChannel(true);
e->setImage(texture);
e->setPressedImage(texture);
e->setImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
e->setScaleImage(true);
spec.ftype = f_Button;
rect+=data->basepos-padding;
Expand Down Expand Up @@ -2283,7 +2284,7 @@ void GUIFormSpecMenu::drawMenu()

const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
driver->draw2DImage(texture, rect,
draw2DImageFilterScaled(driver, texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
NULL/*&AbsoluteClippingRect*/, colors, true);
Expand Down Expand Up @@ -2333,7 +2334,7 @@ void GUIFormSpecMenu::drawMenu()
core::rect<s32> rect = imgrect + spec.pos;
const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
driver->draw2DImage(texture, rect,
draw2DImageFilterScaled(driver, texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),img_origsize),
NULL/*&AbsoluteClippingRect*/, colors, true);
}
Expand Down Expand Up @@ -2362,7 +2363,7 @@ void GUIFormSpecMenu::drawMenu()
core::rect<s32> rect = imgrect + spec.pos;
const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
driver->draw2DImage(texture, rect,
draw2DImageFilterScaled(driver, texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
NULL/*&AbsoluteClippingRect*/, colors, true);
Expand Down
1 change: 1 addition & 0 deletions src/guiTable.cpp
Expand Up @@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "main.h"
#include "settings.h" // for settings
#include "porting.h" // for dpi
#include "guiscalingfilter.h"

/*
GUITable
Expand Down

0 comments on commit 6d61375

Please sign in to comment.