mirror of https://github.com/AxioDL/zeus.git
261 lines
7.3 KiB
C++
261 lines
7.3 KiB
C++
#ifndef CCOLOR_HPP
|
|
#define CCOLOR_HPP
|
|
|
|
#include "Global.hpp"
|
|
#include "Math.hpp"
|
|
#if ZE_ATHENA_TYPES
|
|
#include <Athena/IStreamReader.hpp>
|
|
#endif
|
|
|
|
#if BYTE_ORDER == __ORDER_LITTLE_ENDIAN__
|
|
#define COLOR(rgba) (unsigned long)( ( (rgba) & 0x000000FF ) << 24 | ( (rgba) & 0x0000FF00 ) << 8 \
|
|
| ( (rgba) & 0x00FF0000 ) >> 8 | ( (rgba) & 0xFF000000 ) >> 24 )
|
|
#else
|
|
#define COLOR(rgba) (unsigned long)rgba
|
|
#endif
|
|
|
|
namespace Zeus
|
|
{
|
|
typedef unsigned char Comp8;
|
|
typedef unsigned long Comp32;
|
|
|
|
class alignas(16) CColor
|
|
{
|
|
public:
|
|
ZE_DECLARE_ALIGNED_ALLOCATOR();
|
|
|
|
static const CColor skRed;
|
|
static const CColor skBlack;
|
|
static const CColor skBlue;
|
|
static const CColor skGreen;
|
|
static const CColor skGrey;
|
|
static const CColor skOrange;
|
|
static const CColor skPurple;
|
|
static const CColor skYellow;
|
|
static const CColor skWhite;
|
|
|
|
|
|
CColor() : rgba(~0u) {}
|
|
CColor(float rgb, float a = 1.0) { splat(rgb, a); }
|
|
CColor(float r, float g, float b, float a = 1.0f)
|
|
: r(Comp8(255*r)),
|
|
g(Comp8(255*g)),
|
|
b(Comp8(255*b)),
|
|
a(Comp8(255*a))
|
|
{}
|
|
|
|
#if ZE_ATHENA_TYPES
|
|
CColor(Athena::io::IStreamReader& reader) {readRGBA(reader);}
|
|
#endif
|
|
CColor(Comp32 rgba) { fromRGBA32(rgba); }
|
|
CColor(const Comp8 rgba[4]) : r(rgba[0]), g(rgba[1]), b(rgba[2]), a(rgba[3]) {}
|
|
CColor(Comp8 r, Comp8 g, Comp8 b, Comp8 a = 255)
|
|
: r(r), g(g), b(b), a(a) {}
|
|
|
|
#if ZE_ATHENA_TYPES
|
|
inline void readRGBA(Athena::io::IStreamReader& reader)
|
|
{
|
|
r = Comp8(255 * reader.readFloat());
|
|
g = Comp8(255 * reader.readFloat());
|
|
b = Comp8(255 * reader.readFloat());
|
|
a = Comp8(255 * reader.readFloat());
|
|
}
|
|
inline void readBGRA(Athena::io::IStreamReader& reader)
|
|
{
|
|
b = Comp8(255 * reader.readFloat());
|
|
g = Comp8(255 * reader.readFloat());
|
|
r = Comp8(255 * reader.readFloat());
|
|
a = Comp8(255 * reader.readFloat());
|
|
}
|
|
#endif
|
|
|
|
inline bool operator==(const CColor& rhs) const
|
|
{ return (rgba == rhs.rgba); }
|
|
inline bool operator!=(const CColor& rhs) const
|
|
{ return !(*this == rhs); }
|
|
inline CColor operator+(const CColor& rhs) const
|
|
{
|
|
CColor ret; ret.r = r + rhs.r; ret.g = g + rhs.g; ret.b = b + rhs.b; ret.a = a + rhs.a;
|
|
return ret;
|
|
}
|
|
inline CColor operator-(const CColor& rhs) const
|
|
{
|
|
CColor ret; ret.r = r - rhs.r; ret.g = g - rhs.g; ret.b = b - rhs.b; ret.a = a - rhs.a;
|
|
return ret;
|
|
}
|
|
|
|
inline CColor operator*(const CColor& rhs) const
|
|
{
|
|
CColor ret; ret.r = r * rhs.r; ret.g = g * rhs.g; ret.b = b * rhs.b; ret.a = a * rhs.a;
|
|
return ret;
|
|
}
|
|
inline CColor operator/(const CColor& rhs) const
|
|
{
|
|
CColor ret; ret.r = r / rhs.r; ret.g = g / rhs.g; ret.b = b / rhs.b; ret.a = a / rhs.a;
|
|
return ret;
|
|
}
|
|
inline CColor operator+(float val) const
|
|
{
|
|
CColor ret;
|
|
ret.r = r + Comp8(255 * val); ret.g = g + Comp8(255 * val); ret.b = b + Comp8(255 * val); ret.a = a + Comp8(255 * val);
|
|
return ret;
|
|
}
|
|
inline CColor operator-(float val) const
|
|
{
|
|
CColor ret;
|
|
ret.r = r - Comp8(255 * val); ret.g = g - Comp8(255 * val); ret.b = b - Comp8(255 * val); ret.a = a - Comp8(255 * val);
|
|
return ret;
|
|
}
|
|
inline CColor operator*(float val) const
|
|
{
|
|
CColor ret;
|
|
ret.r = r * Comp8(255 * val); ret.g = g * Comp8(255 * val); ret.b = b * Comp8(255 * val); ret.a = a * Comp8(255 * val);
|
|
return ret;
|
|
}
|
|
inline CColor operator/(float val) const
|
|
{
|
|
CColor ret;
|
|
ret.r = r / Comp8(255 * val); ret.g = g / Comp8(255 * val); ret.b = b / Comp8(255 * val); ret.a = a / Comp8(255 * val);
|
|
return ret;
|
|
}
|
|
inline const CColor& operator+=(const CColor& rhs)
|
|
{
|
|
r += rhs.r; g += rhs.g; b += rhs.b;
|
|
a += rhs.a; return *this;
|
|
}
|
|
inline const CColor& operator-=(const CColor& rhs)
|
|
{
|
|
r -= rhs.r; g -= rhs.g; b -= rhs.b; a -= rhs.a;
|
|
return *this;
|
|
}
|
|
inline const CColor& operator *=(const CColor& rhs)
|
|
{
|
|
r *= rhs.r; g *= rhs.g; b *= rhs.b; a *= rhs.a;
|
|
return *this;
|
|
}
|
|
inline const CColor& operator /=(const CColor& rhs)
|
|
{
|
|
r /= rhs.r; g /= rhs.g; b /= rhs.b; a /= rhs.a;
|
|
return *this;
|
|
}
|
|
inline void normalize()
|
|
{
|
|
float mag = magnitude();
|
|
*this *= mag;
|
|
}
|
|
inline CColor normalized()
|
|
{
|
|
float mag = magnitude();
|
|
return *this * mag;
|
|
}
|
|
inline float magSquared() const
|
|
{ return ((r * r + g * g + b * b + a * a) / 255.f); }
|
|
|
|
inline float magnitude() const
|
|
{
|
|
return Math::sqrtF(magSquared());
|
|
}
|
|
static inline CColor lerp(const CColor& a, const CColor& b, float t)
|
|
{
|
|
return (a + (b - a) * t);
|
|
}
|
|
static inline CColor nlerp(const CColor& a, const CColor& b, float t)
|
|
{
|
|
return lerp(a, b, t).normalized();
|
|
}
|
|
|
|
inline Comp8& operator[](size_t idx) {return (&r)[idx];}
|
|
inline const Comp8& operator[](size_t idx) const { return (&r)[idx]; }
|
|
inline void splat(float rgb, float a)
|
|
{
|
|
r = Comp8(255 * rgb);
|
|
g = Comp8(255 * rgb);
|
|
b = Comp8(255 * rgb);
|
|
this->a = Comp8(255 * a);
|
|
}
|
|
|
|
union
|
|
{
|
|
struct { Comp8 r, g, b, a; };
|
|
Comp32 rgba;
|
|
};
|
|
|
|
void fromRGBA8(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
|
|
{
|
|
this->r = r;
|
|
this->g = g;
|
|
this->b = b;
|
|
this->a = a;
|
|
}
|
|
|
|
/**
|
|
* @brief Assigns rgba from hsv
|
|
* @param h[0-1] The hue percentagee of the color.
|
|
* @param s[0-1] The saturation percentage of the color.
|
|
* @param v[0-1] The value percentage of the color.
|
|
* @param a[0-1] The alpha percentage of the color.
|
|
*/
|
|
void fromHSV(float h, float s, float v, float _a = 1.0);
|
|
|
|
/**
|
|
* @brief Converts rgba to hsv
|
|
* @param h[0-1] The hue percentagee of the color.
|
|
* @param s[0-1] The saturation percentage of the color.
|
|
* @param v[0-1] The value percentage of the color.
|
|
* @param a[0-1] The alpha percentage of the color.
|
|
*/
|
|
void toHSV(float& h, float& s, float& v) const;
|
|
|
|
|
|
void fromHSL(float h, float s, float l, float _a = 1.0);
|
|
|
|
void toHSL(float& h, float& s, float& l);
|
|
|
|
void fromRGBA32(unsigned int rgba)
|
|
{ this->rgba = COLOR(rgba); }
|
|
};
|
|
|
|
static inline CColor operator+(float lhs, const CColor& rhs)
|
|
{
|
|
CColor ret;
|
|
ret.r = Comp8(255 * lhs) + rhs.r;
|
|
ret.g = Comp8(255 * lhs) + rhs.g;
|
|
ret.b = Comp8(255 * lhs) + rhs.b;
|
|
ret.a = Comp8(255 * lhs) + rhs.a;
|
|
return ret;
|
|
}
|
|
|
|
static inline CColor operator-(float lhs, const CColor& rhs)
|
|
{
|
|
CColor ret;
|
|
ret.r = Comp8(255 * lhs) - rhs.r;
|
|
ret.g = Comp8(255 * lhs) - rhs.g;
|
|
ret.b = Comp8(255 * lhs) - rhs.b;
|
|
ret.a = Comp8(255 * lhs) - rhs.a;
|
|
return ret;
|
|
}
|
|
|
|
static inline CColor operator*(float lhs, const CColor& rhs)
|
|
{
|
|
CColor ret;
|
|
ret.r = Comp8(255 * lhs) * rhs.r;
|
|
ret.g = Comp8(255 * lhs) * rhs.g;
|
|
ret.b = Comp8(255 * lhs) * rhs.b;
|
|
ret.a = Comp8(255 * lhs) * rhs.a;
|
|
return ret;
|
|
}
|
|
|
|
static inline CColor operator/(float lhs, const CColor& rhs)
|
|
{
|
|
CColor ret;
|
|
ret.r = Comp8(255 * lhs) / rhs.r;
|
|
ret.g = Comp8(255 * lhs) / rhs.g;
|
|
ret.b = Comp8(255 * lhs) / rhs.b;
|
|
ret.a = Comp8(255 * lhs) / rhs.a;
|
|
return ret;
|
|
}
|
|
|
|
}
|
|
|
|
#endif // CCOLOR_HPP
|