|
|
2fb9fd |
#ifndef COLOR_H
|
|
|
2fb9fd |
#define COLOR_H
|
|
|
2fb9fd |
|
|
|
2fb9fd |
|
|
|
2fb9fd |
#include "real.h"
|
|
|
2fb9fd |
|
|
|
2fb9fd |
|
|
|
2fb9fd |
typedef Real ColorReal;
|
|
|
2fb9fd |
|
|
|
2fb9fd |
|
|
|
2fb9fd |
class Color {
|
|
|
2fb9fd |
public:
|
|
|
2fb9fd |
union {
|
|
|
2fb9fd |
struct { ColorReal channels[4]; };
|
|
|
2fb9fd |
struct { ColorReal r, g, b, a; };
|
|
|
2fb9fd |
};
|
|
|
2fb9fd |
|
|
|
2fb9fd |
Color(): r(), g(), b(), a() { }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
explicit Color(
|
|
|
2fb9fd |
const ColorReal r,
|
|
|
2fb9fd |
const ColorReal g,
|
|
|
2fb9fd |
const ColorReal b,
|
|
|
2fb9fd |
const ColorReal a = 1
|
|
|
2fb9fd |
):
|
|
|
2fb9fd |
r(r), g(g), b(b), a(a) { }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
const Real& operator[] (int i) const { return channels[i]; }
|
|
|
2fb9fd |
Real& operator[] (int i) { return channels[i]; }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
bool operator< (const Color &c) const {
|
|
|
2fb9fd |
return less(r, c.r) ? true : less(c.r, r) ? false
|
|
|
2fb9fd |
: less(g, c.g) ? true : less(c.g, g) ? false
|
|
|
2fb9fd |
: less(b, c.b) ? true : less(c.b, b) ? false
|
|
|
2fb9fd |
: less(a, c.a);
|
|
|
2fb9fd |
}
|
|
|
2fb9fd |
bool operator== (const Color &c) const { return equal(r, c.r) && equal(g, c.g) && equal(b, c.b) && equal(a, c.a); }
|
|
|
2fb9fd |
bool operator!= (const Color &c) const { return !(*this == c); }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
bool istransparent() const { return *this == Color(); }
|
|
|
2fb9fd |
void reset() { *this = Color(); }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
Color withalpha(const ColorReal &a) const { return Color(r, g, b, a); }
|
|
|
2fb9fd |
Color mulalpha(const ColorReal &a = 0.5) const { return Color(r, g, b, this->a*a); }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
Color blend(const Color &c, const ColorReal &value = 1) const {
|
|
|
2fb9fd |
ColorReal asrc = c.a*value;
|
|
|
2fb9fd |
ColorReal adst = a*(1 - asrc);
|
|
|
2fb9fd |
ColorReal ares = asrc + adst;
|
|
|
2fb9fd |
|
|
|
2fb9fd |
if (lesseq(ares, 0))
|
|
|
2fb9fd |
return Color();
|
|
|
2fb9fd |
|
|
|
2fb9fd |
ColorReal k = 1/ares;
|
|
|
2fb9fd |
return Color(
|
|
|
2fb9fd |
(r*asrc + c.r*adst)*k,
|
|
|
2fb9fd |
(g*asrc + c.g*adst)*k,
|
|
|
2fb9fd |
(b*asrc + c.b*adst)*k,
|
|
|
2fb9fd |
ares );
|
|
|
2fb9fd |
}
|
|
|
2fb9fd |
|
|
|
2fb9fd |
Color mergecolor(const Color &c, const ColorReal &value = 0.5) const {
|
|
|
2fb9fd |
ColorReal v = 1 - value;
|
|
|
2fb9fd |
return Color(
|
|
|
2fb9fd |
r*v + c.r*value,
|
|
|
2fb9fd |
g*v + c.g*value,
|
|
|
2fb9fd |
b*v + c.b*value,
|
|
|
2fb9fd |
a );
|
|
|
2fb9fd |
}
|
|
|
2fb9fd |
|
|
|
2fb9fd |
Color merge(const Color &c, const ColorReal &value = 0.5) const
|
|
|
2fb9fd |
{ return mergecolor(c, value).withalpha(a*(1 - value) + c.a*value); }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
static Color transparent() { return Color(); }
|
|
|
2fb9fd |
static Color black() { return Color(0, 0, 0); }
|
|
|
2fb9fd |
static Color white() { return Color(1, 1, 1); }
|
|
|
2fb9fd |
static Color red() { return Color(1, 0, 0); }
|
|
|
2fb9fd |
static Color green() { return Color(0, 1, 0); }
|
|
|
2fb9fd |
static Color blue() { return Color(0, 0, 1); }
|
|
|
2fb9fd |
static Color yellow() { return Color(1, 1, 0); }
|
|
|
2fb9fd |
static Color cyan() { return Color(0, 1, 1); }
|
|
|
2fb9fd |
static Color magenta() { return Color(1, 0, 1); }
|
|
|
2fb9fd |
|
|
|
2fb9fd |
static Color gray(const ColorReal &value = 0.5) { return Color(value, value, value); }
|
|
|
2fb9fd |
};
|
|
|
2fb9fd |
|
|
|
2fb9fd |
|
|
|
2fb9fd |
#endif
|