color.h
Engine/source/core/color.h
More...
Classes:
Detailed Description
1
2//-----------------------------------------------------------------------------
3// Copyright (c) 2012 GarageGames, LLC
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to
7// deal in the Software without restriction, including without limitation the
8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9// sell copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21// IN THE SOFTWARE.
22//-----------------------------------------------------------------------------
23
24#ifndef _COLOR_H_
25#define _COLOR_H_
26
27#ifndef _MPOINT3_H_
28#include "math/mPoint3.h"
29#endif
30#ifndef _MPOINT4_H_
31#include "math/mPoint4.h"
32#endif
33
34#ifndef _ENGINEAPI_H_
35#include "console/engineAPI.h"
36#endif
37
38class ColorI;
39
40
41class ColorF
42{
43 public:
44 F32 red;
45 F32 green;
46 F32 blue;
47 F32 alpha;
48
49 public:
50 ColorF() { }
51 ColorF(const ColorF& in_rCopy);
52 ColorF(const F32 in_r,
53 const F32 in_g,
54 const F32 in_b,
55 const F32 in_a = 1.0f);
56
57 ColorF( const char* pStockColorName );
58
59 void set(const F32 in_r,
60 const F32 in_g,
61 const F32 in_b,
62 const F32 in_a = 1.0f);
63
64 void set( const char* pStockColorName );
65
66 static const ColorF& StockColor( const char* pStockColorName );
67 StringTableEntry StockColor( void );
68
69 ColorF& operator*=(const ColorF& in_mul); // Can be useful for lighting
70 ColorF operator*(const ColorF& in_mul) const;
71 ColorF& operator+=(const ColorF& in_rAdd);
72 ColorF operator+(const ColorF& in_rAdd) const;
73 ColorF& operator-=(const ColorF& in_rSub);
74 ColorF operator-(const ColorF& in_rSub) const;
75
76 ColorF& operator*=(const F32 in_mul);
77 ColorF operator*(const F32 in_mul) const;
78 ColorF& operator/=(const F32 in_div);
79 ColorF operator/(const F32 in_div) const;
80
81 ColorF operator-() const;
82
83 bool operator==(const ColorF&) const;
84 bool operator!=(const ColorF&) const;
85
86 operator F32*() { return &red; }
87 operator const F32*() const { return &red; }
88
89 operator Point3F() const { return Point3F( red, green, blue ); }
90 operator Point4F() const { return Point4F( red, green, blue, alpha ); }
91
92 U32 getARGBPack() const;
93 U32 getRGBAPack() const;
94 U32 getABGRPack() const;
95
96 operator ColorI() const;
97
98 void interpolate(const ColorF& in_rC1,
99 const ColorF& in_rC2,
100 const F32 in_factor);
101
102 bool isValidColor() const { return (red >= 0.0f && red <= 1.0f) &&
103 (green >= 0.0f && green <= 1.0f) &&
104 (blue >= 0.0f && blue <= 1.0f) &&
105 (alpha >= 0.0f && alpha <= 1.0f); }
106 void clamp();
107
108 ColorF toLinear() const;
109 ColorF toGamma() const;
110
111 static const ColorF ZERO;
112 static const ColorF ONE;
113 static const ColorF WHITE;
114 static const ColorF BLACK;
115 static const ColorF RED;
116 static const ColorF GREEN;
117 static const ColorF BLUE;
118};
119
120
121//-------------------------------------- ColorI's are missing some of the operations
122// present in ColorF since they cannot recover
123// properly from over/underflow.
124class ColorI
125{
126 public:
127 U8 red;
128 U8 green;
129 U8 blue;
130 U8 alpha;
131
132 struct Hsb
133 {
134 Hsb() :hue(0), sat(0), brightness(0){};
135 Hsb(U32 h, U32 s, U32 b) :hue(h), sat(s), brightness(b){};
136
137 U32 hue; ///Hue
138 U32 sat; ///Saturation
139 U32 brightness; //Brightness/Value/Lightness
140 };
141
142 public:
143 ColorI() { }
144 ColorI(const ColorI& in_rCopy);
145 ColorI(const Hsb& color);
146 ColorI(const U8 in_r,
147 const U8 in_g,
148 const U8 in_b,
149 const U8 in_a = U8(255));
150 ColorI(const ColorI& in_rCopy, const U8 in_a);
151
152 ColorI( const char* pStockColorName );
153
154 void set(const Hsb& color);
155
156 void HSLtoRGB_Subfunction(U32& c, const F64& temp1, const F64& temp2, const F64& temp3);
157
158 void set(const String& hex);
159
160 void set(const U8 in_r,
161 const U8 in_g,
162 const U8 in_b,
163 const U8 in_a = U8(255));
164
165 void set(const ColorI& in_rCopy,
166 const U8 in_a);
167
168 void set( const char* pStockColorName );
169
170 static const ColorI& StockColor( const char* pStockColorName );
171 StringTableEntry StockColor( void );
172
173 ColorI& operator*=(const F32 in_mul);
174 ColorI operator*(const F32 in_mul) const;
175
176 ColorI operator+(const ColorI& in_rAdd) const;
177 ColorI& operator+=(const ColorI& in_rAdd);
178
179 ColorI& operator*=(const S32 in_mul);
180 ColorI& operator/=(const S32 in_mul);
181 ColorI operator*(const S32 in_mul) const;
182 ColorI operator/(const S32 in_mul) const;
183
184 bool operator==(const ColorI&) const;
185 bool operator!=(const ColorI&) const;
186
187 void interpolate(const ColorI& in_rC1,
188 const ColorI& in_rC2,
189 const F32 in_factor);
190
191 U32 getARGBPack() const;
192 U32 getRGBAPack() const;
193 U32 getABGRPack() const;
194
195 U32 getBGRPack() const;
196 U32 getRGBPack() const;
197
198 U32 getRGBEndian() const;
199 U32 getARGBEndian() const;
200
201 U16 get565() const;
202 U16 get4444() const;
203
204 Hsb getHSB() const;
205
206 String getHex() const;
207 S32 convertFromHex(const String& hex) const;
208
209 operator ColorF() const;
210
211 operator const U8*() const { return &red; }
212
213 static const ColorI ZERO;
214 static const ColorI ONE;
215 static const ColorI WHITE;
216 static const ColorI BLACK;
217 static const ColorI RED;
218 static const ColorI GREEN;
219 static const ColorI BLUE;
220};
221
222//-----------------------------------------------------------------------------
223
224class StockColorItem
225{
226private:
227 StockColorItem() {}
228
229public:
230 StockColorItem( const char* pName, const U8 red, const U8 green, const U8 blue, const U8 alpha = 255 )
231 {
232 // Sanity!
233 AssertFatal( pName != NULL, "Stock color name cannot be NULL." );
234
235 // Set stock color.
236 // NOTE:- We'll use the char pointer here. We can yet use the string-table unfortunately.
237 mColorName = pName;
238 mColorI.set( red, green, blue, alpha );
239 mColorF = mColorI;
240 }
241
242 inline const char* getColorName( void ) const { return mColorName; }
243 inline const ColorF& getColorF( void ) const { return mColorF; }
244 inline const ColorI& getColorI( void ) const { return mColorI; }
245
246 const char* mColorName;
247 ColorF mColorF;
248 ColorI mColorI;
249};
250
251//-----------------------------------------------------------------------------
252
253class StockColor
254{
255public:
256 static bool isColor( const char* pStockColorName );
257 static const ColorF& colorF( const char* pStockColorName );
258 static const ColorI& colorI( const char* pStockColorName );
259 static StringTableEntry name( const ColorF& color );
260 static StringTableEntry name( const ColorI& color );
261
262 static S32 getCount( void );
263 static const StockColorItem* getColorItem( const S32 index );
264
265 static void create( void );
266 static void destroy( void );
267};
268
269//------------------------------------------------------------------------------
270//-------------------------------------- INLINES (ColorF)
271//
272inline void ColorF::set(const F32 in_r,
273 const F32 in_g,
274 const F32 in_b,
275 const F32 in_a)
276{
277 red = in_r;
278 green = in_g;
279 blue = in_b;
280 alpha = in_a;
281}
282
283inline ColorF::ColorF(const ColorF& in_rCopy)
284{
285 red = in_rCopy.red;
286 green = in_rCopy.green;
287 blue = in_rCopy.blue;
288 alpha = in_rCopy.alpha;
289}
290
291inline ColorF::ColorF(const F32 in_r,
292 const F32 in_g,
293 const F32 in_b,
294 const F32 in_a)
295{
296 set(in_r, in_g, in_b, in_a);
297}
298
299inline ColorF& ColorF::operator*=(const ColorF& in_mul)
300{
301 red *= in_mul.red;
302 green *= in_mul.green;
303 blue *= in_mul.blue;
304 alpha *= in_mul.alpha;
305
306 return *this;
307}
308
309inline ColorF ColorF::operator*(const ColorF& in_mul) const
310{
311 return ColorF(red * in_mul.red,
312 green * in_mul.green,
313 blue * in_mul.blue,
314 alpha * in_mul.alpha);
315}
316
317inline ColorF& ColorF::operator+=(const ColorF& in_rAdd)
318{
319 red += in_rAdd.red;
320 green += in_rAdd.green;
321 blue += in_rAdd.blue;
322 alpha += in_rAdd.alpha;
323
324 return *this;
325}
326
327inline ColorF ColorF::operator+(const ColorF& in_rAdd) const
328{
329 return ColorF(red + in_rAdd.red,
330 green + in_rAdd.green,
331 blue + in_rAdd.blue,
332 alpha + in_rAdd.alpha);
333}
334
335inline ColorF& ColorF::operator-=(const ColorF& in_rSub)
336{
337 red -= in_rSub.red;
338 green -= in_rSub.green;
339 blue -= in_rSub.blue;
340 alpha -= in_rSub.alpha;
341
342 return *this;
343}
344
345inline ColorF ColorF::operator-(const ColorF& in_rSub) const
346{
347 return ColorF(red - in_rSub.red,
348 green - in_rSub.green,
349 blue - in_rSub.blue,
350 alpha - in_rSub.alpha);
351}
352
353inline ColorF& ColorF::operator*=(const F32 in_mul)
354{
355 red *= in_mul;
356 green *= in_mul;
357 blue *= in_mul;
358 alpha *= in_mul;
359
360 return *this;
361}
362
363inline ColorF ColorF::operator*(const F32 in_mul) const
364{
365 return ColorF(red * in_mul,
366 green * in_mul,
367 blue * in_mul,
368 alpha * in_mul);
369}
370
371inline ColorF& ColorF::operator/=(const F32 in_div)
372{
373 AssertFatal(in_div != 0.0f, "Error, div by zero...");
374 F32 inv = 1.0f / in_div;
375
376 red *= inv;
377 green *= inv;
378 blue *= inv;
379 alpha *= inv;
380
381 return *this;
382}
383
384inline ColorF ColorF::operator/(const F32 in_div) const
385{
386 AssertFatal(in_div != 0.0f, "Error, div by zero...");
387 F32 inv = 1.0f / in_div;
388
389 return ColorF(red * inv,
390 green * inv,
391 blue * inv,
392 alpha * inv);
393}
394
395inline ColorF ColorF::operator-() const
396{
397 return ColorF(-red, -green, -blue, -alpha);
398}
399
400inline bool ColorF::operator==(const ColorF& in_Cmp) const
401{
402 return (red == in_Cmp.red && green == in_Cmp.green && blue == in_Cmp.blue && alpha == in_Cmp.alpha);
403}
404
405inline bool ColorF::operator!=(const ColorF& in_Cmp) const
406{
407 return (red != in_Cmp.red || green != in_Cmp.green || blue != in_Cmp.blue || alpha != in_Cmp.alpha);
408}
409
410inline U32 ColorF::getARGBPack() const
411{
412 return (U32(alpha * 255.0f + 0.5) << 24) |
413 (U32(red * 255.0f + 0.5) << 16) |
414 (U32(green * 255.0f + 0.5) << 8) |
415 (U32(blue * 255.0f + 0.5) << 0);
416}
417
418inline U32 ColorF::getRGBAPack() const
419{
420 return ( U32( red * 255.0f + 0.5) << 0 ) |
421 ( U32( green * 255.0f + 0.5) << 8 ) |
422 ( U32( blue * 255.0f + 0.5) << 16 ) |
423 ( U32( alpha * 255.0f + 0.5) << 24 );
424}
425
426inline U32 ColorF::getABGRPack() const
427{
428 return (U32(alpha * 255.0f + 0.5) << 24) |
429 (U32(blue * 255.0f + 0.5) << 16) |
430 (U32(green * 255.0f + 0.5) << 8) |
431 (U32(red * 255.0f + 0.5) << 0);
432
433}
434
435inline void ColorF::interpolate(const ColorF& in_rC1,
436 const ColorF& in_rC2,
437 const F32 in_factor)
438{
439 F32 f2 = 1.0f - in_factor;
440 red = (in_rC1.red * f2) + (in_rC2.red * in_factor);
441 green = (in_rC1.green * f2) + (in_rC2.green * in_factor);
442 blue = (in_rC1.blue * f2) + (in_rC2.blue * in_factor);
443 alpha = (in_rC1.alpha * f2) + (in_rC2.alpha * in_factor);
444}
445
446inline void ColorF::clamp()
447{
448 if (red > 1.0f)
449 red = 1.0f;
450 else if (red < 0.0f)
451 red = 0.0f;
452
453 if (green > 1.0f)
454 green = 1.0f;
455 else if (green < 0.0f)
456 green = 0.0f;
457
458 if (blue > 1.0f)
459 blue = 1.0f;
460 else if (blue < 0.0f)
461 blue = 0.0f;
462
463 if (alpha > 1.0f)
464 alpha = 1.0f;
465 else if (alpha < 0.0f)
466 alpha = 0.0f;
467}
468
469inline ColorF ColorF::toLinear() const
470{
471 return ColorF(mPow(red, 2.2f), mPow(green, 2.2f), mPow(blue, 2.2f), alpha);
472}
473
474inline ColorF ColorF::toGamma() const
475{
476 return ColorF(mPow(red, 1.0f / 2.2f), mPow(green, 1.0f / 2.2f), mPow(blue, 1.0f / 2.2f), alpha);
477}
478
479//------------------------------------------------------------------------------
480//-------------------------------------- INLINES (ColorI)
481//
482inline void ColorI::set(const U8 in_r,
483 const U8 in_g,
484 const U8 in_b,
485 const U8 in_a)
486{
487 red = in_r;
488 green = in_g;
489 blue = in_b;
490 alpha = in_a;
491}
492
493inline void ColorI::set(const ColorI& in_rCopy,
494 const U8 in_a)
495{
496 red = in_rCopy.red;
497 green = in_rCopy.green;
498 blue = in_rCopy.blue;
499 alpha = in_a;
500}
501
502inline void ColorI::set(const Hsb& color)
503{
504 U32 r = 0;
505 U32 g = 0;
506 U32 b = 0;
507
508 F64 L = ((F64)color.brightness) / 100.0;
509 F64 S = ((F64)color.sat) / 100.0;
510 F64 H = ((F64)color.hue) / 360.0;
511
512 if (color.sat == 0)
513 {
514 r = color.brightness;
515 g = color.brightness;
516 b = color.brightness;
517 }
518 else
519 {
520 F64 temp1 = 0;
521 if (L < 0.50)
522 {
523 temp1 = L*(1 + S);
524 }
525 else
526 {
527 temp1 = L + S - (L*S);
528 }
529
530 F64 temp2 = 2.0*L - temp1;
531
532 F64 temp3 = 0;
533 for (S32 i = 0; i < 3; i++)
534 {
535 switch (i)
536 {
537 case 0: // red
538 {
539 temp3 = H + 0.33333;
540 if (temp3 > 1.0)
541 temp3 -= 1.0;
542 HSLtoRGB_Subfunction(r, temp1, temp2, temp3);
543 break;
544 }
545 case 1: // green
546 {
547 temp3 = H;
548 HSLtoRGB_Subfunction(g, temp1, temp2, temp3);
549 break;
550 }
551 case 2: // blue
552 {
553 temp3 = H - 0.33333;
554 if (temp3 < 0)
555 temp3 += 1;
556 HSLtoRGB_Subfunction(b, temp1, temp2, temp3);
557 break;
558 }
559 default:
560 {
561
562 }
563 }
564 }
565 }
566 red = (U32)((((F64)r) / 100) * 255);
567 green = (U32)((((F64)g) / 100) * 255);
568 blue = (U32)((((F64)b) / 100) * 255);
569}
570
571// This is a subfunction of HSLtoRGB
572inline void ColorI::HSLtoRGB_Subfunction(U32& c, const F64& temp1, const F64& temp2, const F64& temp3)
573{
574 if ((temp3 * 6.0) < 1.0)
575 c = (U32)((temp2 + (temp1 - temp2)*6.0*temp3)*100.0);
576 else
577 if ((temp3 * 2.0) < 1.0)
578 c = (U32)(temp1*100.0);
579 else
580 if ((temp3 * 3.0) < 2.0)
581 c = (U32)((temp2 + (temp1 - temp2)*(0.66666 - temp3)*6.0)*100.0);
582 else
583 c = (U32)(temp2*100.0);
584 return;
585}
586
587inline void ColorI::set(const String& hex)
588{
589 String redString;
590 String greenString;
591 String blueString;
592
593 //if the prefix # was attached to hex
594 if (hex[0] == '#')
595 {
596 redString = hex.substr(1, 2);
597 greenString = hex.substr(3, 2);
598 blueString = hex.substr(5, 2);
599 }
600 else
601 {
602 // since there is no prefix attached to hex
603 redString = hex.substr(0, 2);
604 greenString = hex.substr(2, 2);
605 blueString = hex.substr(4, 2);
606 }
607
608 red = (U8)(convertFromHex(redString));
609 green = (U8)(convertFromHex(greenString));
610 blue = (U8)(convertFromHex(blueString));
611}
612
613inline S32 ColorI::convertFromHex(const String& hex) const
614{
615 S32 hexValue = 0;
616
617 S32 a = 0;
618 S32 b = hex.length() - 1;
619
620 for (; b >= 0; a++, b--)
621 {
622 if (hex[b] >= '0' && hex[b] <= '9')
623 {
624 hexValue += (hex[b] - '0') * (1 << (a * 4));
625 }
626 else
627 {
628 switch (hex[b])
629 {
630 case 'A':
631 case 'a':
632 hexValue += 10 * (1 << (a * 4));
633 break;
634
635 case 'B':
636 case 'b':
637 hexValue += 11 * (1 << (a * 4));
638 break;
639
640 case 'C':
641 case 'c':
642 hexValue += 12 * (1 << (a * 4));
643 break;
644
645 case 'D':
646 case 'd':
647 hexValue += 13 * (1 << (a * 4));
648 break;
649
650 case 'E':
651 case 'e':
652 hexValue += 14 * (1 << (a * 4));
653 break;
654
655 case 'F':
656 case 'f':
657 hexValue += 15 * (1 << (a * 4));
658 break;
659
660 default:
661 Con::errorf("Error, invalid character '%c' in hex number", hex[a]);
662 break;
663 }
664 }
665 }
666
667 return hexValue;
668}
669
670inline ColorI::ColorI(const ColorI& in_rCopy)
671{
672 red = in_rCopy.red;
673 green = in_rCopy.green;
674 blue = in_rCopy.blue;
675 alpha = in_rCopy.alpha;
676}
677
678inline ColorI::ColorI(const Hsb& color)
679{
680 set(color);
681}
682
683inline ColorI::ColorI(const U8 in_r,
684 const U8 in_g,
685 const U8 in_b,
686 const U8 in_a)
687{
688 set(in_r, in_g, in_b, in_a);
689}
690
691inline ColorI::ColorI(const ColorI& in_rCopy,
692 const U8 in_a)
693{
694 set(in_rCopy, in_a);
695}
696
697inline ColorI& ColorI::operator*=(const F32 in_mul)
698{
699 red = U8((F32(red) * in_mul) + 0.5f);
700 green = U8((F32(green) * in_mul) + 0.5f);
701 blue = U8((F32(blue) * in_mul) + 0.5f);
702 alpha = U8((F32(alpha) * in_mul) + 0.5f);
703
704 return *this;
705}
706
707inline ColorI& ColorI::operator*=(const S32 in_mul)
708{
709 red = red * in_mul;
710 green = green * in_mul;
711 blue = blue * in_mul;
712 alpha = alpha * in_mul;
713
714 return *this;
715}
716
717inline ColorI& ColorI::operator/=(const S32 in_mul)
718{
719 AssertFatal(in_mul != 0.0f, "Error, div by zero...");
720 red = red / in_mul;
721 green = green / in_mul;
722 blue = blue / in_mul;
723 alpha = alpha / in_mul;
724
725 return *this;
726}
727
728inline ColorI ColorI::operator+(const ColorI &in_add) const
729{
730 ColorI tmp;
731
732 tmp.red = red + in_add.red;
733 tmp.green = green + in_add.green;
734 tmp.blue = blue + in_add.blue;
735 tmp.alpha = alpha + in_add.alpha;
736
737 return tmp;
738}
739
740inline ColorI ColorI::operator*(const F32 in_mul) const
741{
742 ColorI temp(*this);
743 temp *= in_mul;
744 return temp;
745}
746
747inline ColorI ColorI::operator*(const S32 in_mul) const
748{
749 ColorI temp(*this);
750 temp *= in_mul;
751 return temp;
752}
753
754inline ColorI ColorI::operator/(const S32 in_mul) const
755{
756 ColorI temp(*this);
757 temp /= in_mul;
758 return temp;
759}
760
761inline bool ColorI::operator==(const ColorI& in_Cmp) const
762{
763 return (red == in_Cmp.red && green == in_Cmp.green && blue == in_Cmp.blue && alpha == in_Cmp.alpha);
764}
765
766inline bool ColorI::operator!=(const ColorI& in_Cmp) const
767{
768 return (red != in_Cmp.red || green != in_Cmp.green || blue != in_Cmp.blue || alpha != in_Cmp.alpha);
769}
770
771inline ColorI& ColorI::operator+=(const ColorI& in_rAdd)
772{
773 red += in_rAdd.red;
774 green += in_rAdd.green;
775 blue += in_rAdd.blue;
776 alpha += in_rAdd.alpha;
777
778 return *this;
779}
780
781inline void ColorI::interpolate(const ColorI& in_rC1,
782 const ColorI& in_rC2,
783 const F32 in_factor)
784{
785 F32 f2= 1.0f - in_factor;
786 red = U8(((F32(in_rC1.red) * f2) + (F32(in_rC2.red) * in_factor)) + 0.5f);
787 green = U8(((F32(in_rC1.green) * f2) + (F32(in_rC2.green) * in_factor)) + 0.5f);
788 blue = U8(((F32(in_rC1.blue) * f2) + (F32(in_rC2.blue) * in_factor)) + 0.5f);
789 alpha = U8(((F32(in_rC1.alpha) * f2) + (F32(in_rC2.alpha) * in_factor)) + 0.5f);
790}
791
792inline U32 ColorI::getARGBPack() const
793{
794 return (U32(alpha) << 24) |
795 (U32(red) << 16) |
796 (U32(green) << 8) |
797 (U32(blue) << 0);
798}
799
800inline U32 ColorI::getRGBAPack() const
801{
802 return ( U32( red ) << 0 ) |
803 ( U32( green ) << 8 ) |
804 ( U32( blue ) << 16 ) |
805 ( U32( alpha ) << 24 );
806}
807
808inline U32 ColorI::getABGRPack() const
809{
810 return (U32(alpha) << 24) |
811 (U32(blue) << 16) |
812 (U32(green) << 8) |
813 (U32(red) << 0);
814}
815
816
817inline U32 ColorI::getBGRPack() const
818{
819 return (U32(blue) << 16) |
820 (U32(green) << 8) |
821 (U32(red) << 0);
822}
823
824inline U32 ColorI::getRGBPack() const
825{
826 return (U32(red) << 16) |
827 (U32(green) << 8) |
828 (U32(blue) << 0);
829}
830
831inline U32 ColorI::getRGBEndian() const
832{
833#if defined(TORQUE_BIG_ENDIAN)
834 return(getRGBPack());
835#else
836 return(getBGRPack());
837#endif
838}
839
840inline U32 ColorI::getARGBEndian() const
841{
842#if defined(TORQUE_BIG_ENDIAN)
843 return(getABGRPack());
844#else
845 return(getARGBPack());
846#endif
847}
848
849inline U16 ColorI::get565() const
850{
851 return U16((U16(red >> 3) << 11) |
852 (U16(green >> 2) << 5) |
853 (U16(blue >> 3) << 0));
854}
855
856inline U16 ColorI::get4444() const
857{
858 return U16(U16(U16(alpha >> 4) << 12) |
859 U16(U16(red >> 4) << 8) |
860 U16(U16(green >> 4) << 4) |
861 U16(U16(blue >> 4) << 0));
862}
863
864inline ColorI::Hsb ColorI::getHSB() const
865{
866 F64 rPercent = ((F64)red) / 255;
867 F64 gPercent = ((F64)green) / 255;
868 F64 bPercent = ((F64)blue) / 255;
869
870 F64 maxColor = 0.0;
871 if ((rPercent >= gPercent) && (rPercent >= bPercent))
872 maxColor = rPercent;
873 if ((gPercent >= rPercent) && (gPercent >= bPercent))
874 maxColor = gPercent;
875 if ((bPercent >= rPercent) && (bPercent >= gPercent))
876 maxColor = bPercent;
877
878 F64 minColor = 0.0;
879 if ((rPercent <= gPercent) && (rPercent <= bPercent))
880 minColor = rPercent;
881 if ((gPercent <= rPercent) && (gPercent <= bPercent))
882 minColor = gPercent;
883 if ((bPercent <= rPercent) && (bPercent <= gPercent))
884 minColor = bPercent;
885
886 F64 H = 0.0;
887 F64 S = 0.0;
888 F64 B = 0.0;
889
890 B = (maxColor + minColor) / 2.0;
891
892 if (maxColor == minColor)
893 {
894 H = 0.0;
895 S = 0.0;
896 }
897 else
898 {
899 if (B < 0.50)
900 {
901 S = (maxColor - minColor) / (maxColor + minColor);
902 }
903 else
904 {
905 S = (maxColor - minColor) / (2.0 - maxColor - minColor);
906 }
907 if (maxColor == rPercent)
908 {
909 H = (gPercent - bPercent) / (maxColor - minColor);
910 }
911 if (maxColor == gPercent)
912 {
913 H = 2.0 + (bPercent - rPercent) / (maxColor - minColor);
914 }
915 if (maxColor == bPercent)
916 {
917 H = 4.0 + (rPercent - gPercent) / (maxColor - minColor);
918 }
919 }
920
921 ColorI::Hsb val;
922 val.sat = (U32)(S * 100);
923 val.brightness = (U32)(B * 100);
924 H = H*60.0;
925 if (H < 0.0)
926 H += 360.0;
927 val.hue = (U32)H;
928
929 return val;
930}
931
932inline String ColorI::getHex() const
933{
934 char r[255];
935 dSprintf(r, sizeof(r), "%.2X", red);
936 String result(r);
937
938 char g[255];
939 dSprintf(g, sizeof(g), "%.2X", green);
940 result += g;
941
942 char b[255];
943 dSprintf(b, sizeof(b), "%.2X", blue);
944 result += b;
945
946 return result;
947}
948
949//-------------------------------------- INLINE CONVERSION OPERATORS
950inline ColorF::operator ColorI() const
951{
952 return ColorI(U8(red * 255.0f + 0.5),
953 U8(green * 255.0f + 0.5),
954 U8(blue * 255.0f + 0.5),
955 U8(alpha * 255.0f + 0.5));
956}
957
958inline ColorI::operator ColorF() const
959{
960 const F32 inv255 = 1.0f / 255.0f;
961
962 return ColorF(F32(red) * inv255,
963 F32(green) * inv255,
964 F32(blue) * inv255,
965 F32(alpha) * inv255);
966}
967
968#endif //_COLOR_H_
969