Idempotent changes to PixelAttribute class (preparing for next patch)

master
Rogier 2014-06-19 10:59:39 +02:00
parent a065e68eac
commit e27d181d9f
2 changed files with 68 additions and 54 deletions

View File

@ -48,7 +48,7 @@ void PixelAttributes::setParameters(int width, int lines)
}
for (int i=0; i<m_lineCount; i++)
for (int j=0; j<m_width; j++) {
m_pixelAttributes[i][j].a=0;
m_pixelAttributes[i][j].m_a=0;
m_pixelAttributes[i][j].next16Empty = (j - 1) % 16 == 0;
}
}
@ -119,11 +119,11 @@ void PixelAttributes::renderShading(bool drawAlpha)
}
if (!m_pixelAttributes[y][x - 1].is_valid())
continue;
if (!m_pixelAttributes[y][x].a)
if (!m_pixelAttributes[y][x].m_a)
continue;
double h = m_pixelAttributes[y][x].h;
double h1 = m_pixelAttributes[y][x - 1].a ? m_pixelAttributes[y][x - 1].h : h;
double h2 = m_pixelAttributes[y - 1][x].a ? m_pixelAttributes[y - 1][x].h : h;
double h = m_pixelAttributes[y][x].m_h;
double h1 = m_pixelAttributes[y][x - 1].m_a ? m_pixelAttributes[y][x - 1].m_h : h;
double h2 = m_pixelAttributes[y - 1][x].m_a ? m_pixelAttributes[y - 1][x].m_h : h;
double d = (h - h1) + (h - h2);
if (d > 3) {
d = 3;
@ -132,10 +132,10 @@ void PixelAttributes::renderShading(bool drawAlpha)
#define pixel (m_pixelAttributes[y][x])
//PixelAttribute &pixel = m_pixelAttributes[y][x];
if (drawAlpha)
d = d * (1 - pixel.t);
pixel.r = colorSafeBounds(pixel.r + d);
pixel.g = colorSafeBounds(pixel.g + d);
pixel.b = colorSafeBounds(pixel.b + d);
d = d * (1 - pixel.m_t);
pixel.m_r = colorSafeBounds(pixel.m_r + d);
pixel.m_g = colorSafeBounds(pixel.m_g + d);
pixel.m_b = colorSafeBounds(pixel.m_b + d);
#undef pixel
}
}
@ -144,33 +144,35 @@ void PixelAttributes::renderShading(bool drawAlpha)
void PixelAttribute::mixUnder(const PixelAttribute &p, bool darkenHighAlpha)
{
if (!is_valid() || a == 0) {
if (!is_valid() || p.a != 0) {
r = p.r;
g = p.g;
b = p.b;
a = p.a;
t = 0;
if (!is_valid() || m_a == 0) {
if (!is_valid() || p.m_a != 0) {
m_n = p.m_n;
m_r = p.m_r;
m_g = p.m_g;
m_b = p.m_b;
m_a = p.m_a;
m_t = 0;
}
h = p.h;
m_h = p.m_h;
}
else {
int prev_alpha = alpha();
r = (a * r + p.a * (1 - a) * p.r);
g = (a * g + p.a * (1 - a) * p.g);
b = (a * b + p.a * (1 - a) * p.b);
a = (a + (1 - a) * p.a);
if (p.a != 1)
t = (t + p.t) / 2;
h = p.h;
m_r = (m_a * m_r + p.m_a * (1 - m_a) * p.m_r);
m_g = (m_a * m_g + p.m_a * (1 - m_a) * p.m_g);
m_b = (m_a * m_b + p.m_a * (1 - m_a) * p.m_b);
m_a = (m_a + (1 - m_a) * p.m_a);
if (p.m_a != 1)
m_t = (m_t + p.m_t) / 2;
m_h = p.m_h;
if (prev_alpha >= 254 && p.alpha() < 255 && darkenHighAlpha) {
// Darken
// Parameters make deep water look good :-)
r = r * 0.95;
g = g * 0.95;
b = b * 0.95;
if (p.a != 1)
t = (t + p.t) / 2;
// (maybe this setting should be per-node-type, and obtained from the colors file ?)
m_r = m_r * 0.95;
m_g = m_g * 0.95;
m_b = m_b * 0.95;
if (p.m_a != 1)
m_t = (m_t + p.m_t) / 2;
}
}

View File

@ -18,28 +18,39 @@
#include "config.h"
#include "Color.h"
struct PixelAttribute {
PixelAttribute(): next16Empty(true), h(NAN), t(0), a(0), r(0), g(0), b(0) {};
class PixelAttribute {
public:
PixelAttribute(): next16Empty(true), m_n(0), m_h(NAN), m_t(0), m_a(0), m_r(0), m_g(0), m_b(0) {};
PixelAttribute(const Color &color, double height);
PixelAttribute(const ColorEntry &entry, double height);
bool next16Empty;
double h;
double t;
double a;
double r;
double g;
double b;
uint8_t red(void) const { return int(r*255+0.5); }
uint8_t green(void) const { return int(g*255+0.5); }
uint8_t blue(void) const { return int(b*255+0.5); }
uint8_t alpha(void) const { return int(a*255+0.5); }
uint8_t thicken(void) const { return int(t*255+0.5); }
unsigned height(void) const { return unsigned(h+0.5); }
double h(void) const { return m_h / (m_n ? m_n : 1); }
double t(void) const { return m_t / (m_n ? m_n : 1); }
double a(void) const { return m_a / (m_n ? m_n : 1); }
double r(void) const { return m_r / (m_n ? m_a : 1); }
double g(void) const { return m_g / (m_n ? m_a : 1); }
double b(void) const { return m_b / (m_n ? m_a : 1); }
uint8_t red(void) const { return int(r() * 255 + 0.5); }
uint8_t green(void) const { return int(g() * 255 + 0.5); }
uint8_t blue(void) const { return int(b() * 255 + 0.5); }
uint8_t alpha(void) const { return int(a() * 255 + 0.5); }
uint8_t thicken(void) const { return int(t() * 255 + 0.5); }
unsigned height(void) const { return unsigned(h() + 0.5); }
Color color(void) const { return Color(red(), green(), blue(), alpha()); }
inline bool is_valid() const { return !isnan(h); }
inline bool is_valid() const { return !isnan(m_h); }
PixelAttribute &operator=(const PixelAttribute &p);
void mixUnder(const PixelAttribute &p, bool darkenHighAlpha);
private:
double m_n;
double m_h;
double m_t;
double m_a;
double m_r;
double m_g;
double m_b;
friend class PixelAttributes;
};
class PixelAttributes
@ -96,25 +107,26 @@ inline PixelAttribute &PixelAttributes::attribute(int y, int x)
}
inline PixelAttribute::PixelAttribute(const Color &color, double height) :
next16Empty(false), h(height), t(0), a(color.a/255.0),
r(color.r/255.0), g(color.g/255.0), b(color.b/255.0)
next16Empty(false), m_n(0), m_h(height), m_t(0), m_a(color.a/255.0),
m_r(color.r/255.0), m_g(color.g/255.0), m_b(color.b/255.0)
{
}
inline PixelAttribute::PixelAttribute(const ColorEntry &entry, double height) :
next16Empty(false), h(height), t(entry.t/255.0), a(entry.a/255.0),
r(entry.r/255.0), g(entry.g/255.0), b(entry.b/255.0)
next16Empty(false), m_n(0), m_h(height), m_t(entry.t/255.0), m_a(entry.a/255.0),
m_r(entry.r/255.0), m_g(entry.g/255.0), m_b(entry.b/255.0)
{
}
inline PixelAttribute &PixelAttribute::operator=(const PixelAttribute &p)
{
h = p.h;
t = p.t;
a = p.a;
r = p.r;
g = p.g;
b = p.b;
m_n = p.m_n;
m_h = p.m_h;
m_t = p.m_t;
m_a = p.m_a;
m_r = p.m_r;
m_g = p.m_g;
m_b = p.m_b;
return *this;
}