minetest-mapper-cpp/PixelCacheEntry.h
2014-04-14 01:26:48 +02:00

102 lines
2.5 KiB
C

#ifndef PIXELCACHEINFO_H
#define PIXELCACHEINFO_H
#include<cmath>
#include"Color.h"
struct PixelCacheEntry {
PixelCacheEntry();
PixelCacheEntry(unsigned int color, double height=NAN);
PixelCacheEntry(const Color &color, double height=NAN);
PixelCacheEntry(const ColorEntry &entry, double height=NAN);
Color to_color(void) const;
ColorEntry to_colorEntry(void) const;
void reset(void);
void mixUnder(const PixelCacheEntry &p);
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); }
int height(void) const { return int(h+0.5); }
double r;
double g;
double b;
double a;
double t;
double h;
int n;
};
inline PixelCacheEntry::PixelCacheEntry() :
r(0), g(0), b(0), a(0), t(0), h(NAN), n(0)
{
}
inline PixelCacheEntry::PixelCacheEntry(unsigned int color, double height) :
r(((color>>16)&0xff)/255.0), g(((color>>8)&0xff)/255.0), b((color&0xff)/255.0),
a(((color>>24)&0xff)/255.0), t(0), h(height), n(1)
{
}
inline PixelCacheEntry::PixelCacheEntry(const Color &color, double height) :
r(color.r/255.0), g(color.g/255.0), b(color.b/255.0),
a(color.a/255.0), t(0), h(height), n(1)
{
}
inline PixelCacheEntry::PixelCacheEntry(const ColorEntry &entry, double height) :
r(entry.r/255.0), g(entry.g/255.0), b(entry.b/255.0),
a(entry.a/255.0), t(entry.t/255.0), h(height), n(1)
{
}
inline Color PixelCacheEntry::to_color(void) const
{
return Color(int(r*255+0.5),int(g*255+0.5),int(b*255+0.5),int(a*255+0.5));
}
inline ColorEntry PixelCacheEntry::to_colorEntry(void) const
{
return ColorEntry(int(r*255+0.5),int(g*255+0.5),int(b*255+0.5),int(a*255+0.5),int(t*255+0.5));
}
inline void PixelCacheEntry::reset(void)
{
r=0; g=0; b=0; a=0; t=0; h=NAN; n=0;
}
inline void PixelCacheEntry::mixUnder(const PixelCacheEntry &p)
{
int prev_alpha = alpha();
if (!n || a==0) {
r = p.r;
g = p.g;
b = p.b;
a = p.a;
t = p.t;
h = p.h;
n = p.n;
}
else {
// Regular mix
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);
t = (t + p.t) / 2;
h = p.h;
}
if (prev_alpha == 255 && p.alpha() < 255) {
// Darken
// Parameters make deep water look good :-)
r = r * (0.85 + 0.1 * (1 - p.a));
g = g * (0.85 + 0.1 * (1 - p.a));
b = b * (0.85 + 0.1 * (1 - p.a));
}
}
#endif // PIXELCACHEINFO_H