Make darkening of thick transparent stacks (e.g. deep water) configurable.

In order to reduce rendering surprises, this darkening is off by default
(it was on previously).
This commit is contained in:
Rogier 2014-06-18 21:13:33 +02:00
parent 9285bc586c
commit a065e68eac
6 changed files with 38 additions and 11 deletions

View File

@ -142,7 +142,7 @@ void PixelAttributes::renderShading(bool drawAlpha)
m_firstUnshadedY = y - yCoord2Line(0); m_firstUnshadedY = y - yCoord2Line(0);
} }
void PixelAttribute::mixUnder(const PixelAttribute &p) void PixelAttribute::mixUnder(const PixelAttribute &p, bool darkenHighAlpha)
{ {
if (!is_valid() || a == 0) { if (!is_valid() || a == 0) {
if (!is_valid() || p.a != 0) { if (!is_valid() || p.a != 0) {
@ -163,7 +163,7 @@ void PixelAttribute::mixUnder(const PixelAttribute &p)
if (p.a != 1) if (p.a != 1)
t = (t + p.t) / 2; t = (t + p.t) / 2;
h = p.h; h = p.h;
if (prev_alpha >= 254 && p.alpha() < 255) { if (prev_alpha >= 254 && p.alpha() < 255 && darkenHighAlpha) {
// Darken // Darken
// Parameters make deep water look good :-) // Parameters make deep water look good :-)
r = r * 0.95; r = r * 0.95;

View File

@ -39,7 +39,7 @@ struct PixelAttribute {
inline bool is_valid() const { return !isnan(h); } inline bool is_valid() const { return !isnan(h); }
PixelAttribute &operator=(const PixelAttribute &p); PixelAttribute &operator=(const PixelAttribute &p);
void mixUnder(const PixelAttribute &p); void mixUnder(const PixelAttribute &p, bool darkenHighAlpha);
}; };
class PixelAttributes class PixelAttributes

View File

@ -176,8 +176,22 @@ drawplayers:
draworigin: draworigin:
Draw origin indicator, `--draworigin` Draw origin indicator, `--draworigin`
drawalpha: drawalpha[=darken|nodarken]:
Allow blocks to be drawn with transparency, `--drawalpha` Allow blocks to be drawn with transparency, `--drawalpha=darken`
Even with drawalpha, transparency decreases with depth. After a certain
number of transparent blocks (e.g. water depth), the color will become opaque,
and the underlying colors will no longer shine through. The height differences
*will* still be visible though.
With 'darken', after the color becomes opaque, it will gradually be darkened
to visually simulate the bigger thickness of transparent blocks. The downside
is that eventually, the color becomes black.
Darken mode makes deeper, but not too deep water look much better. Very deep water
will become black though.
With nodarken (default), after it becomes opaque, the color will not be darkened.
drawair: drawair:
Draw air blocks. `--drawair` Draw air blocks. `--drawair`

View File

@ -134,6 +134,7 @@ TileGenerator::TileGenerator():
m_drawPlayers(false), m_drawPlayers(false),
m_drawScale(false), m_drawScale(false),
m_drawAlpha(false), m_drawAlpha(false),
m_darkenHighAlpha(false),
m_drawAir(false), m_drawAir(false),
m_shading(true), m_shading(true),
m_border(0), m_border(0),
@ -267,9 +268,10 @@ void TileGenerator::setDrawScale(bool drawScale)
} }
} }
void TileGenerator::setDrawAlpha(bool drawAlpha) void TileGenerator::setDrawAlpha(bool drawAlpha, bool darkenHighAlpha)
{ {
m_drawAlpha = drawAlpha; m_drawAlpha = drawAlpha;
m_darkenHighAlpha = darkenHighAlpha;
} }
void TileGenerator::setDrawAir(bool drawAir) void TileGenerator::setDrawAir(bool drawAir)
@ -1235,7 +1237,7 @@ inline void TileGenerator::renderMapBlock(const ustring &mapBlock, const BlockPo
rowIsEmpty = false; rowIsEmpty = false;
#define nodeColor (*m_nodeIDColor[content]) #define nodeColor (*m_nodeIDColor[content])
//const ColorEntry &nodeColor = *m_nodeIDColor[content]; //const ColorEntry &nodeColor = *m_nodeIDColor[content];
pixel.mixUnder(PixelAttribute(nodeColor, pos.y * 16 + y)); pixel.mixUnder(PixelAttribute(nodeColor, pos.y * 16 + y), m_darkenHighAlpha);
if ((m_drawAlpha && nodeColor.a == 0xff) || (!m_drawAlpha && nodeColor.a != 0)) { if ((m_drawAlpha && nodeColor.a == 0xff) || (!m_drawAlpha && nodeColor.a != 0)) {
m_readedPixels[z] |= (1 << x); m_readedPixels[z] |= (1 << x);
break; break;

View File

@ -91,7 +91,7 @@ public:
void setDrawOrigin(bool drawOrigin); void setDrawOrigin(bool drawOrigin);
void setDrawPlayers(bool drawPlayers); void setDrawPlayers(bool drawPlayers);
void setDrawScale(bool drawScale); void setDrawScale(bool drawScale);
void setDrawAlpha(bool drawAlpha); void setDrawAlpha(bool drawAlpha, bool darkenHighAlpha = false);
void setDrawAir(bool drawAir); void setDrawAir(bool drawAir);
void drawObject(const DrawObject &object) { m_drawObjects.push_back(object); } void drawObject(const DrawObject &object) { m_drawObjects.push_back(object); }
void setShading(bool shading); void setShading(bool shading);
@ -169,6 +169,7 @@ private:
bool m_drawPlayers; bool m_drawPlayers;
bool m_drawScale; bool m_drawScale;
bool m_drawAlpha; bool m_drawAlpha;
bool m_darkenHighAlpha;
bool m_drawAir; bool m_drawAir;
bool m_shading; bool m_shading;
int m_border; int m_border;

View File

@ -71,7 +71,7 @@ void usage()
" --drawscale\n" " --drawscale\n"
" --drawplayers\n" " --drawplayers\n"
" --draworigin\n" " --draworigin\n"
" --drawalpha\n" " --drawalpha[=[no]darken]\n"
" --drawair\n" " --drawair\n"
" --draw[map]point \"<x>,<y> color\"\n" " --draw[map]point \"<x>,<y> color\"\n"
" --draw[map]line \"<geometry> color\"\n" " --draw[map]line \"<geometry> color\"\n"
@ -527,7 +527,7 @@ int main(int argc, char *argv[])
{"draworigin", no_argument, 0, 'R'}, {"draworigin", no_argument, 0, 'R'},
{"drawplayers", no_argument, 0, 'P'}, {"drawplayers", no_argument, 0, 'P'},
{"drawscale", no_argument, 0, 'S'}, {"drawscale", no_argument, 0, 'S'},
{"drawalpha", no_argument, 0, 'e'}, {"drawalpha", optional_argument, 0, 'e'},
{"drawair", no_argument, 0, OPT_DRAWAIR}, {"drawair", no_argument, 0, OPT_DRAWAIR},
{"drawpoint", required_argument, 0, OPT_DRAW_OBJECT}, {"drawpoint", required_argument, 0, OPT_DRAW_OBJECT},
{"drawline", required_argument, 0, OPT_DRAW_OBJECT}, {"drawline", required_argument, 0, OPT_DRAW_OBJECT},
@ -648,7 +648,17 @@ int main(int argc, char *argv[])
} }
break; break;
case 'e': case 'e':
generator.setDrawAlpha(true); if (optarg && string(optarg) == "darken")
generator.setDrawAlpha(true, true);
else if (optarg && string(optarg) == "nodarken")
generator.setDrawAlpha(true, false);
else if (!optarg)
generator.setDrawAlpha(true);
else {
std::cerr << "Invalid parameter to '" << long_options[option_index].name << "': '" << optarg << "'" << std::endl;
usage();
exit(1);
}
break; break;
case OPT_DRAWAIR: case OPT_DRAWAIR:
generator.setDrawAir(true); generator.setDrawAir(true);