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