My Project
ParaColor.h
1 #pragma once
2 
3 #define COLOR_ARGB(a,r,g,b) Color(r,g,b,a)
4 #define COLOR_RGBA(r,g,b,a) Color(r,g,b,a)
5 #define COLOR_XRGB(r,g,b) Color(r,g,b)
6 
7 namespace ParaEngine
8 {
12  struct LinearColor
13  {
14  float r, g, b, a;
15 
17  static float PowOneOver255Table[256];
18 
19  inline LinearColor() {}
20  inline explicit LinearColor(EnumForceInit)
21  : r(0), g(0), b(0), a(0)
22  {}
23  inline LinearColor(float InR, float InG, float InB, float InA = 1.0f) : r(InR), g(InG), b(InB), a(InA) {}
24  LinearColor(const class Color& C);
25  LinearColor(uint32 C);
26  LinearColor(const float * colors);
27  LinearColor(const class Vector3& Vector);
28 #ifdef __D3DX9_H__
29  LinearColor(const D3DCOLORVALUE& color);
30  operator D3DCOLORVALUE& ();
31  operator const D3DCOLORVALUE& () const;
32 #endif
33  operator const float*() const;
34 
35  // Operators.
36 
37  inline float& Component(int32 Index)
38  {
39  return (&r)[Index];
40  }
41 
42  inline const float& Component(int32 Index) const
43  {
44  return (&r)[Index];
45  }
46 
47  LinearColor& operator=(uint32 color);
48  LinearColor& operator=(const Color& color);
49 
50  operator uint32() const;
51 
52  inline LinearColor operator+(const LinearColor& ColorB) const
53  {
54  return LinearColor(
55  this->r + ColorB.r,
56  this->g + ColorB.g,
57  this->b + ColorB.b,
58  this->a + ColorB.a
59  );
60  }
61  inline LinearColor& operator+=(const LinearColor& ColorB)
62  {
63  r += ColorB.r;
64  g += ColorB.g;
65  b += ColorB.b;
66  a += ColorB.a;
67  return *this;
68  }
69 
70  inline LinearColor operator-(const LinearColor& ColorB) const
71  {
72  return LinearColor(
73  this->r - ColorB.r,
74  this->g - ColorB.g,
75  this->b - ColorB.b,
76  this->a - ColorB.a
77  );
78  }
79  inline LinearColor& operator-=(const LinearColor& ColorB)
80  {
81  r -= ColorB.r;
82  g -= ColorB.g;
83  b -= ColorB.b;
84  a -= ColorB.a;
85  return *this;
86  }
87 
88  inline LinearColor operator*(const LinearColor& ColorB) const
89  {
90  return LinearColor(
91  this->r * ColorB.r,
92  this->g * ColorB.g,
93  this->b * ColorB.b,
94  this->a * ColorB.a
95  );
96  }
97  inline LinearColor& operator*=(const LinearColor& ColorB)
98  {
99  r *= ColorB.r;
100  g *= ColorB.g;
101  b *= ColorB.b;
102  a *= ColorB.a;
103  return *this;
104  }
105 
106  inline LinearColor operator*(float Scalar) const
107  {
108  return LinearColor(
109  this->r * Scalar,
110  this->g * Scalar,
111  this->b * Scalar,
112  this->a * Scalar
113  );
114  }
115 
116  inline LinearColor& operator*=(float Scalar)
117  {
118  r *= Scalar;
119  g *= Scalar;
120  b *= Scalar;
121  a *= Scalar;
122  return *this;
123  }
124 
125  inline LinearColor operator/(const LinearColor& ColorB) const
126  {
127  return LinearColor(
128  this->r / ColorB.r,
129  this->g / ColorB.g,
130  this->b / ColorB.b,
131  this->a / ColorB.a
132  );
133  }
134  inline LinearColor& operator/=(const LinearColor& ColorB)
135  {
136  r /= ColorB.r;
137  g /= ColorB.g;
138  b /= ColorB.b;
139  a /= ColorB.a;
140  return *this;
141  }
142 
143  inline LinearColor operator/(float Scalar) const
144  {
145  const float InvScalar = 1.0f / Scalar;
146  return LinearColor(
147  this->r * InvScalar,
148  this->g * InvScalar,
149  this->b * InvScalar,
150  this->a * InvScalar
151  );
152  }
153  inline LinearColor& operator/=(float Scalar)
154  {
155  const float InvScalar = 1.0f / Scalar;
156  r *= InvScalar;
157  g *= InvScalar;
158  b *= InvScalar;
159  a *= InvScalar;
160  return *this;
161  }
162 
164  inline bool operator==(const LinearColor& ColorB) const
165  {
166  return this->r == ColorB.r && this->g == ColorB.g && this->b == ColorB.b && this->a == ColorB.a;
167  }
168  inline bool operator!=(const LinearColor& Other) const
169  {
170  return this->r != Other.r || this->g != Other.g || this->b != Other.b || this->a != Other.a;
171  }
172 
173  // Error-tolerant comparison.
174  inline bool Equals(const LinearColor& ColorB, float Tolerance = KINDA_SMALL_NUMBER) const
175  {
176  return Math::Abs(this->r - ColorB.r) < Tolerance && Math::Abs(this->g - ColorB.g) < Tolerance && Math::Abs(this->b - ColorB.b) < Tolerance && Math::Abs(this->a - ColorB.a) < Tolerance;
177  }
178 
179  LinearColor CopyWithNewOpacity(float NewOpacicty)
180  {
181  LinearColor NewCopy = *this;
182  NewCopy.a = NewOpacicty;
183  return NewCopy;
184  }
185 
189  static LinearColor FGetHSV(uint8 H, uint8 S, uint8 V);
190 
194  static inline float Dist(const LinearColor &V1, const LinearColor &V2)
195  {
196  return Math::Sqrt(Math::Sqr(V2.r - V1.r) + Math::Sqr(V2.g - V1.g) + Math::Sqr(V2.b - V1.b) + Math::Sqr(V2.a - V1.a));
197  }
198 
200  LinearColor LinearRGBToHSV() const;
201 
203  LinearColor HSVToLinearRGB() const;
204 
206  Color Quantize() const;
207 
209  Color ToColor(bool bSRGB = false) const;
210 
211  Vector3 ToVector3() const;
212 
219  LinearColor Desaturate(float Desaturation) const;
220 
222  float ComputeLuminance() const;
223 
229  inline float GetMax() const
230  {
231  return Math::Max(Math::Max(Math::Max(r, g), b), a);
232  }
233 
235  bool IsAlmostBlack() const
236  {
237  return Math::Sqr(r) < DELTA && Math::Sqr(g) < DELTA && Math::Sqr(b) < DELTA;
238  }
239 
245  inline float GetMin() const
246  {
247  return Math::Min(Math::Min(Math::Min(r, g), b), a);
248  }
249 
250  inline float GetLuminance() const
251  {
252  return r * 0.3f + g * 0.59f + b * 0.11f;
253  }
254 
255  // Common colors.
256  static const LinearColor White;
257  static const LinearColor Gray;
258  static const LinearColor Black;
259  static const LinearColor Transparent;
260  static const LinearColor Red;
261  static const LinearColor Green;
262  static const LinearColor Blue;
263  static const LinearColor Yellow;
264  };
265 
266  inline LinearColor operator*(float Scalar, const LinearColor& Color)
267  {
268  return Color.operator*(Scalar);
269  }
270 
271  //
272  // color
273  //
274 
275  class Color
276  {
277  public:
278  // Variables.
279 #if PLATFORM_LITTLE_ENDIAN
280 #if _MSC_VER
281  // Win32 x86
282  union { struct{ uint8 b, g, r, a; }; uint32 AlignmentDummy; };
283 #else
284  // Linux x86, etc
285  /*uint8 b GCC_ALIGN(4);
286  uint8 g, r, a;*/
287  union { struct{ uint8 b, g, r, a; }; uint32 AlignmentDummy; };
288 #endif
289 #else // PLATFORM_LITTLE_ENDIAN
290  union { struct{ uint8 a, r, g, b; }; uint32 AlignmentDummy; };
291 #endif
292 
293  uint32& DWColor(void) { return *((uint32*)this); }
294  const uint32& DWColor(void) const { return *((uint32*)this); }
295  operator const uint32 () const { return DWColor(); };
296  void operator=(const uint32 color);
297  void operator=(const LinearColor& color);
298 
299  // Constructors.
300  inline Color() {}
301  inline explicit Color(EnumForceInit)
302  {
303  // put these into the body for proper ordering with INTEL vs non-INTEL_BYTE_ORDER
304  r = g = b = a = 0;
305  }
306  inline Color(uint8 InR, uint8 InG, uint8 InB, uint8 InA = 255)
307  {
308  // put these into the body for proper ordering with INTEL vs non-INTEL_BYTE_ORDER
309  r = InR;
310  g = InG;
311  b = InB;
312  a = InA;
313  }
314 
315  // fast, for more accuracy use LinearColor::ToColor()
316  // TODO: doesn't handle negative colors well, implicit constructor can cause
317  // accidental conversion (better use .ToColor(true))
318  Color(const LinearColor& C);
319  // put these into the body for proper ordering with INTEL vs non-INTEL_BYTE_ORDER;
320  Color(uint32 InColor);
321 
323  std::string ToRGBString();
325  std::string ToRGBAString();
326 
327  // Operators.
328  inline bool operator==(const Color &C) const
329  {
330  return DWColor() == C.DWColor();
331  }
332 
333  inline bool operator!=(const Color& C) const
334  {
335  return DWColor() != C.DWColor();
336  }
337 
338  inline void operator+=(const Color& C)
339  {
340  r = (uint8)Math::Min((int32)r + (int32)C.r, (int32)255);
341  g = (uint8)Math::Min((int32)g + (int32)C.g, (int32)255);
342  b = (uint8)Math::Min((int32)b + (int32)C.b, (int32)255);
343  a = (uint8)Math::Min((int32)a + (int32)C.a, (int32)255);
344  }
345 
346  inline Color MutiplyOpacity(float fOpacity)
347  {
348  if (fOpacity == 1.f)
349  return *this;
350  else
351  {
352  Color c = *this;
353  c.a = (uint8)(c.a * fOpacity);
354  return c;
355  }
356  }
357 
358  LinearColor FromRGBE() const;
359 
361  static uint16 convert32_16(uint32 rgb);
362 
364  static uint32 convert16_32(uint16 rgb);
365 
369  static Color MakeRandomColor();
370 
374  static Color MakeRedToGreenColorFromScalar(float Scalar);
375 
376 
383  {
384  return LinearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
385  }
387  static Color FromString(const char* sColor);
388 
390  static const Color White;
391  static const Color Black;
392  static const Color Red;
393  static const Color Green;
394  static const Color Blue;
395  static const Color Yellow;
396  static const Color Cyan;
397  static const Color Magenta;
398  };
399 
400  inline uint32 GetTypeHash(const Color& Color)
401  {
402  return Color.DWColor();
403  }
404 
406  extern void ComputeAndFixedColorAndIntensity(const LinearColor& InLinearColor, Color& OutColor, float& OutIntensity);
407 }
408 
float ComputeLuminance() const
Computes the perceptually weighted luminance value of a color.
Definition: ParaColor.cpp:103
void ComputeAndFixedColorAndIntensity(const LinearColor &InLinearColor, Color &OutColor, float &OutIntensity)
Computes a brightness and a fixed point color from a floating point color.
Definition: ParaColor.cpp:343
LinearColor ReinterpretAsLinear() const
Reinterprets the color as a linear color.
Definition: ParaColor.h:382
float GetMin() const
Returns the minimum value in this color structure.
Definition: ParaColor.h:245
bool operator==(const LinearColor &ColorB) const
Comparison operators.
Definition: ParaColor.h:164
static LinearColor FGetHSV(uint8 H, uint8 S, uint8 V)
Converts byte hue-saturation-brightness to floating point red-green-blue.
Definition: ParaColor.cpp:123
different physics engine has different winding order.
Definition: EventBinding.h:32
LinearColor Desaturate(float Desaturation) const
Returns a desaturated color, with 0 meaning no desaturation and 1 == full desaturation.
Definition: ParaColor.cpp:96
Standard 3-dimensional vector.
Definition: ParaVector3.h:16
static float PowOneOver255Table[256]
Static lookup table used for color -> LinearColor conversion.
Definition: ParaColor.h:17
LinearColor LinearRGBToHSV() const
Converts a linear space RGB color to an HSV color.
Definition: ParaColor.cpp:135
static T Min(const T A, const T B)
Returns lower value in a generic way.
Definition: ParaMath.h:468
LinearColor HSVToLinearRGB() const
Converts an HSV color to a linear space RGB color.
Definition: ParaColor.cpp:157
bool IsAlmostBlack() const
useful to detect if a light contribution needs to be rendered
Definition: ParaColor.h:235
float GetMax() const
Returns the maximum value in this color structure.
Definition: ParaColor.h:229
Color ToColor(bool bSRGB=false) const
Quantizes the linear color and returns the result as a color with optional sRGB conversion and qualit...
Definition: ParaColor.cpp:55
A linear, 32-bit/component floating point RGBA color.
Definition: ParaColor.h:12
Definition: ParaColor.h:275
static const Color White
Some pre-inited colors, useful for debug code.
Definition: ParaColor.h:390
static T Max(const T A, const T B)
Returns higher value in a generic way.
Definition: ParaMath.h:462
Color Quantize() const
Quantizes the linear color and returns the result as a color.
Definition: ParaColor.cpp:80
static float Dist(const LinearColor &V1, const LinearColor &V2)
Euclidean distance between two points.
Definition: ParaColor.h:194