CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
Color.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#include "Forward.hpp"
13
15
18
19namespace CeresEngine::inline Math {
20
21 template<typename T> class TColor {
22 public:
23 T r, g, b, a;
24
25 public:
26 constexpr explicit TColor(T value = 0.0) noexcept : TColor(value, value, value, value) {}
27 constexpr explicit TColor(T value, T alpha) noexcept : TColor(value, value, value, alpha) {}
28
29 constexpr explicit TColor(T red, T green, T blue, T alpha = 1.0) noexcept : r(red), g(green), b(blue), a(alpha) {}
30
31 constexpr TColor(const TColor&) noexcept = default;
32 constexpr TColor& operator=(const TColor&) noexcept = default;
33
34 template<typename U> constexpr explicit TColor(const TColor<U>& other) noexcept : r(T(other.r)), g(T(other.g)), b(T(other.b)), a(T(other.a)) {}
35
36 static TColor fromString(StringView string);
37
38 public:
40 [[nodiscard]] constexpr TColor changeRed(T red) const { return TColor(red, g, b, a); }
41
43 [[nodiscard]] constexpr TColor changeGreen(T green) const { return TColor(r, green, b, a); }
44
46 [[nodiscard]] constexpr TColor changeBlue(T blue) const { return TColor(r, g, blue, a); }
47
49 [[nodiscard]] constexpr TColor changeAlpha(T alpha) const { return TColor(r, g, b, alpha); }
50
51 public:
52 [[nodiscard]] constexpr TColor toHSL() const {
53 const double M = std::max({r, g, b});
54 const double m = std::min({r, g, b});
55 const double C = M - m;
56
57 const double L = 0.5 * (M + m);
58 const double S = L > 0.99999 ? 0.0 : C / (1.0 - std::abs(2.0 * L - 1.0));
59 const double H = [&]() {
60 double H_prime;
61
62 if(C < 0.00001) {
63 H_prime = 0.0;
64 } else if(M == r) {
65 H_prime = ((g - b) / C);
66 } else if(M == g) {
67 H_prime = ((b - r) / C) + 2.0;
68 } else if(M == b) {
69 H_prime = ((r - g) / C) + 4.0;
70 } else {
71 H_prime = 0;
72 assert(false);
73 }
74
75 return H_prime > 0.0 ? H_prime / 6.0 : H_prime / 6.0 + 1.0;
76 }();
77
78 return TColor(H, S, L, a);
79 }
80
81 [[nodiscard]] TColor toRGB() const {
82 const double H = r;
83 const double S = g;
84 const double L = b;
85
86 const double C = (1.0 - std::abs(2.0 * L - 1.0)) * S;
87 const double m = L - 0.5 * C;
88
89 const double H_prime = H * 6.0;
90 const double H_prime_mod_2 = [&]() {
91 if(H_prime < 2.0) {
92 return H_prime;
93 } else if(H_prime < 4.0) {
94 return H_prime - 2.0;
95 } else if(H_prime <= 6.0) {
96 return H_prime - 4.0;
97 }
98
100 }();
101
102 const double X = C * (1.0 - std::abs(H_prime_mod_2 - 1.0));
103
104 const TColor rgb_color_base = [&]() {
105 if(H_prime < 1.0) {
106 return TColor(C, X, 0.0, 0.0);
107 } else if(H_prime < 2.0) {
108 return TColor(X, C, 0.0, 0.0);
109 } else if(H_prime < 3.0) {
110 return TColor(0.0, C, X, 0.0);
111 } else if(H_prime < 4.0) {
112 return TColor(0.0, X, C, 0.0);
113 } else if(H_prime < 5.0) {
114 return TColor(X, 0.0, C, 0.0);
115 } else if(H_prime <= 6.0) {
116 return TColor(C, 0.0, X, 0.0);
117 }
118
120 }();
121
122 return rgb_color_base + TColor(m, m, m);
123 }
124
125 public:
135 [[nodiscard]] constexpr TColor darken(T amount) const {
136 TColor hsl = toHSL();
137 hsl.b -= amount;
138 hsl.b = Math::clamp(hsl.b, 0.0, 1.0);
139 return hsl.toRGB();
140 }
141
150 [[nodiscard]] constexpr TColor invert(T amount = 0.0, bool applyOnAlpha = false) const noexcept {
151 return TColor((T(1.0) - amount) - r, (T(1.0) - amount) - g, (T(1.0) - amount) - b, applyOnAlpha ? (T(1.0) - amount) - a : a);
152 }
153
163 [[nodiscard]] constexpr TColor opacity(T amount) const noexcept { return TColor(r, g, b, a * amount); }
164
174 [[nodiscard]] constexpr TColor saturate(T saturation) const noexcept {
175 const T s = saturation;
176 using std::clamp;
177 return TColor(clamp((0.213 + 0.787 * s) * r + (0.715 - 0.715 * s) * g + (0.072 - 0.072 * s) * b, 0.0, 1.0),
178 clamp((0.213 - 0.213 * s) * r + (0.715 + 0.285 * s) * g + (0.072 - 0.072 * s) * b, 0.0, 1.0),
179 clamp((0.213 - 0.213 * s) * r + (0.715 - 0.715 * s) * g + (0.072 + 0.928 * s) * b, 0.0, 1.0), a);
180 }
181
182 // /// Converts the color to sepia.
183 // ///
184 // /// The passed parameter defines the proportion of the conversion. A
185 // /// value of `1.0` is completely sepia. A value of `0.0` leaves the
186 // /// input unchanged. Values between `0.0` and `1.0` are linear
187 // /// multipliers on the effect.
188 // [[nodiscard]] TColor sepia() const noexcept {
189 // // TODO
190 // return *this;
191 // }
192
193 public:
194 constexpr TColor operator+(const TColor& rhs) const { return TColor(r + rhs.r, g + rhs.g, b + rhs.b, a + rhs.a); }
195 constexpr TColor operator-(const TColor& rhs) const { return TColor(r - rhs.r, g - rhs.g, b - rhs.b, a - rhs.a); }
196 constexpr TColor operator*(T rhs) const { return TColor(rhs * r, rhs * g, rhs * b, rhs * a); }
197 constexpr TColor operator*(const TColor& rhs) const { return TColor(rhs.r * r, rhs.g * g, rhs.b * b, rhs.a * a); }
198 constexpr TColor operator/(const TColor& rhs) const { return TColor(r / rhs.r, g / rhs.g, b / rhs.b, a / rhs.a); }
199
200 constexpr TColor operator/(T rhs) const {
201 assert(rhs != T(0));
202 const T invRhs = T(1) / rhs;
203
204 return TColor(r * invRhs, g * invRhs, b * invRhs, a * invRhs);
205 }
206
207 friend constexpr TColor operator*(T lhs, const TColor& rhs) { return TColor(lhs * rhs.r, lhs * rhs.g, lhs * rhs.b, lhs * rhs.a); }
208
209 constexpr TColor& operator+=(const TColor& rhs) {
210 r += rhs.r;
211 g += rhs.g;
212 b += rhs.b;
213 a += rhs.a;
214
215 return *this;
216 }
217
218 constexpr TColor& operator+=(T rhs) {
219 r += rhs;
220 g += rhs;
221 b += rhs;
222 a += rhs;
223 return *this;
224 }
225
226 constexpr TColor& operator-=(const TColor& rhs) {
227 r -= rhs.r;
228 g -= rhs.g;
229 b -= rhs.b;
230 a -= rhs.a;
231
232 return *this;
233 }
234
235 constexpr TColor& operator-=(T rhs) {
236 r -= rhs;
237 g -= rhs;
238 b -= rhs;
239 a -= rhs;
240 return *this;
241 }
242
243 constexpr TColor& operator*=(const TColor& rhs) {
244 r *= rhs.r;
245 g *= rhs.g;
246 b *= rhs.b;
247 a *= rhs.a;
248
249 return *this;
250 }
251
252 constexpr TColor& operator*=(T rhs) {
253 r *= rhs;
254 g *= rhs;
255 b *= rhs;
256 a *= rhs;
257 return *this;
258 }
259
260 constexpr TColor& operator/=(const TColor& rhs) {
261 assert(rhs.r != T(0));
262 assert(rhs.g != T(0));
263 assert(rhs.b != T(0));
264 assert(rhs.a != T(0));
265
266 r /= rhs.r;
267 g /= rhs.g;
268 b /= rhs.b;
269 a /= rhs.a;
270
271 return *this;
272 }
273
274 constexpr TColor& operator/=(T rhs) {
275 assert(rhs != T(0));
276 const T invRhs = T(1) / rhs;
277
278 r *= invRhs;
279 g *= invRhs;
280 b *= invRhs;
281 a *= invRhs;
282
283 return *this;
284 }
285
286 public:
287 constexpr bool operator==(const TColor& rhs) const { return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a; }
288 constexpr bool operator!=(const TColor& rhs) const { return !(*this == rhs); }
289
290 explicit constexpr operator TVector4<T>() const { return TVector4<T>{r, g, b, a}; }
291
292 public:
293 static const TColor zero;
294 static const TColor white;
295 static const TColor black;
296 static const TColor red;
297 static const TColor green;
298 static const TColor blue;
299 };
300
303
304 // clang-format off
305 template<typename T> const TColor<T> TColor<T>::zero{0, 0, 0, 0};
306 template<typename T> const TColor<T> TColor<T>::white{1, 1, 1, 1};
307 template<typename T> const TColor<T> TColor<T>::black{0, 0, 0, 1};
308 template<typename T> const TColor<T> TColor<T>::red{1, 0, 0, 1};
309 template<typename T> const TColor<T> TColor<T>::green{0, 1, 0, 1};
310 template<typename T> const TColor<T> TColor<T>::blue{0, 0, 1, 1};
311 // clang-format on
312
314 using Color CE_SCRIPT_EXPORT(name = "Color", external = true, plain = true)
316
318 using Colorf CE_SCRIPT_EXPORT(name = "Color", external = true, plain = true)
320
321} // namespace CeresEngine::inline Math
322
323template<typename T> struct std::hash<CeresEngine::Math::TColor<T>> {
324 using Type = CeresEngine::Math::TColor<T>;
325 constexpr size_t operator()(const Type& obj) const { return std::hash<CeresEngine::TVector4<T>>{}(CeresEngine::TVector4<T>(obj)); }
326};
327
328#define REFL_DECLARE_CE_COLOR(T)
#define CE_ASSERT_UNDEFINED()
Definition Macros.hpp:326
#define CE_SCRIPT_EXPORT(...)
The CE_SCRIPT_EXPORT macro marks a class or method as exportable and available in scripting environme...
Definition Macros.hpp:247
#define REFL_DECLARE_CE_COLOR(T)
Definition Color.hpp:328
Definition Color.hpp:21
constexpr TColor changeGreen(T green) const
Sets the green channel of a color to a new value.
Definition Color.hpp:43
constexpr TColor(T value, T alpha) noexcept
Definition Color.hpp:27
constexpr TColor operator/(T rhs) const
Definition Color.hpp:200
constexpr TColor(const TColor &) noexcept=default
static const TColor zero
Definition Color.hpp:293
constexpr TColor saturate(T saturation) const noexcept
Saturates the color.
Definition Color.hpp:174
constexpr bool operator==(const TColor &rhs) const
Definition Color.hpp:287
constexpr TColor operator/(const TColor &rhs) const
Definition Color.hpp:198
T b
Definition Color.hpp:23
constexpr TColor & operator*=(T rhs)
Definition Color.hpp:252
constexpr TColor & operator-=(const TColor &rhs)
Definition Color.hpp:226
TColor toRGB() const
Definition Color.hpp:81
static const TColor red
Definition Color.hpp:296
constexpr TColor operator*(const TColor &rhs) const
Definition Color.hpp:197
constexpr TColor changeRed(T red) const
Sets the red channel of a color to a new value.
Definition Color.hpp:40
constexpr TColor opacity(T amount) const noexcept
Applies transparency to the color.
Definition Color.hpp:163
T a
Definition Color.hpp:23
static TColor fromString(StringView string)
T r
Definition Color.hpp:23
constexpr TColor & operator/=(const TColor &rhs)
Definition Color.hpp:260
constexpr TColor & operator/=(T rhs)
Definition Color.hpp:274
constexpr TColor & operator=(const TColor &) noexcept=default
constexpr TColor operator*(T rhs) const
Definition Color.hpp:196
static const TColor white
Definition Color.hpp:294
static const TColor black
Definition Color.hpp:295
constexpr TColor & operator-=(T rhs)
Definition Color.hpp:235
constexpr TColor & operator*=(const TColor &rhs)
Definition Color.hpp:243
constexpr bool operator!=(const TColor &rhs) const
Definition Color.hpp:288
constexpr TColor changeAlpha(T alpha) const
Sets the alpha channel of a color to a new value.
Definition Color.hpp:49
constexpr TColor(const TColor< U > &other) noexcept
Definition Color.hpp:34
static const TColor green
Definition Color.hpp:297
T g
Definition Color.hpp:23
constexpr TColor toHSL() const
Definition Color.hpp:52
static const TColor blue
Definition Color.hpp:298
constexpr TColor & operator+=(const TColor &rhs)
Definition Color.hpp:209
constexpr TColor invert(T amount=0.0, bool applyOnAlpha=false) const noexcept
Inverts the color value.
Definition Color.hpp:150
constexpr TColor darken(T amount) const
Makes the color darker.
Definition Color.hpp:135
constexpr TColor changeBlue(T blue) const
Sets the blue channel of a color to a new value.
Definition Color.hpp:46
constexpr TColor operator+(const TColor &rhs) const
Definition Color.hpp:194
constexpr TColor & operator+=(T rhs)
Definition Color.hpp:218
constexpr TColor(T red, T green, T blue, T alpha=1.0) noexcept
Definition Color.hpp:29
constexpr TColor operator-(const TColor &rhs) const
Definition Color.hpp:195
constexpr TColor(T value=0.0) noexcept
Definition Color.hpp:26
friend constexpr TColor operator*(T lhs, const TColor &rhs)
Definition Color.hpp:207
BasicStringView< char > StringView
Narrow string view used for handling narrow encoded text in UTF-8.
Definition String.hpp:190
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
Definition Angle.hpp:20
TVector< 4, T > TVector4
A four dimensional vector type that uses a internal representation of type T
Definition Vector.hpp:115