Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members | Tutorials

SColor.h

Go to the documentation of this file.
00001 // Copyright (C) 2002-2010 Nikolaus Gebhardt
00002 // This file is part of the "Irrlicht Engine".
00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
00004 
00005 #ifndef __COLOR_H_INCLUDED__
00006 #define __COLOR_H_INCLUDED__
00007 
00008 #include "irrTypes.h"
00009 #include "irrMath.h"
00010 
00011 namespace irr
00012 {
00013 namespace video
00014 {
00016         inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a=0xFF)
00017         {
00018                 return (u16)((a & 0x80) << 8 |
00019                         (r & 0xF8) << 7 |
00020                         (g & 0xF8) << 2 |
00021                         (b & 0xF8) >> 3);
00022         }
00023 
00024 
00026         inline u16 RGB16(u32 r, u32 g, u32 b)
00027         {
00028                 return RGBA16(r,g,b);
00029         }
00030 
00031 
00033         inline u16 RGB16from16(u16 r, u16 g, u16 b)
00034         {
00035                 return (0x8000 |
00036                                 (r & 0x1F) << 10 |
00037                                 (g & 0x1F) << 5  |
00038                                 (b & 0x1F));
00039         }
00040 
00041 
00043         inline u16 X8R8G8B8toA1R5G5B5(u32 color)
00044         {
00045                 return (u16)(0x8000 |
00046                         ( color & 0x00F80000) >> 9 |
00047                         ( color & 0x0000F800) >> 6 |
00048                         ( color & 0x000000F8) >> 3);
00049         }
00050 
00051 
00053         inline u16 A8R8G8B8toA1R5G5B5(u32 color)
00054         {
00055                 return (u16)(( color & 0x80000000) >> 16|
00056                         ( color & 0x00F80000) >> 9 |
00057                         ( color & 0x0000F800) >> 6 |
00058                         ( color & 0x000000F8) >> 3);
00059         }
00060 
00061 
00063         inline u16 A8R8G8B8toR5G6B5(u32 color)
00064         {
00065                 return (u16)(( color & 0x00F80000) >> 8 |
00066                         ( color & 0x0000FC00) >> 5 |
00067                         ( color & 0x000000F8) >> 3);
00068         }
00069 
00070 
00072 
00073         inline u32 A1R5G5B5toA8R8G8B8(u16 color)
00074         {
00075                 return ( (( -( (s32) color & 0x00008000 ) >> (s32) 31 ) & 0xFF000000 ) |
00076                                 (( color & 0x00007C00 ) << 9) | (( color & 0x00007000 ) << 4) |
00077                                 (( color & 0x000003E0 ) << 6) | (( color & 0x00000380 ) << 1) |
00078                                 (( color & 0x0000001F ) << 3) | (( color & 0x0000001C ) >> 2)
00079                                 );
00080         }
00081 
00082 
00084         inline u32 R5G6B5toA8R8G8B8(u16 color)
00085         {
00086                 return 0xFF000000 |
00087                         ((color & 0xF800) << 8)|
00088                         ((color & 0x07E0) << 5)|
00089                         ((color & 0x001F) << 3);
00090         }
00091 
00092 
00094         inline u16 R5G6B5toA1R5G5B5(u16 color)
00095         {
00096                 return 0x8000 | (((color & 0xFFC0) >> 1) | (color & 0x1F));
00097         }
00098 
00099 
00101         inline u16 A1R5G5B5toR5G6B5(u16 color)
00102         {
00103                 return (((color & 0x7FE0) << 1) | (color & 0x1F));
00104         }
00105 
00106 
00107 
00109 
00111         inline u32 getAlpha(u16 color)
00112         {
00113                 return ((color >> 15)&0x1);
00114         }
00115 
00116 
00118 
00119         inline u32 getRed(u16 color)
00120         {
00121                 return ((color >> 10)&0x1F);
00122         }
00123 
00124 
00126 
00127         inline u32 getGreen(u16 color)
00128         {
00129                 return ((color >> 5)&0x1F);
00130         }
00131 
00132 
00134 
00135         inline u32 getBlue(u16 color)
00136         {
00137                 return (color & 0x1F);
00138         }
00139 
00140 
00142         inline s32 getAverage(s16 color)
00143         {
00144                 return ((getRed(color)<<3) + (getGreen(color)<<3) + (getBlue(color)<<3)) / 3;
00145         }
00146 
00147 
00149 
00157         class SColor
00158         {
00159         public:
00160 
00162 
00163                 SColor() {}
00164 
00166 
00167                 SColor (u32 a, u32 r, u32 g, u32 b)
00168                         : color(((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff)) {}
00169 
00171                 SColor(u32 clr)
00172                         : color(clr) {}
00173 
00175 
00177                 u32 getAlpha() const { return color>>24; }
00178 
00180 
00182                 u32 getRed() const { return (color>>16) & 0xff; }
00183 
00185 
00187                 u32 getGreen() const { return (color>>8) & 0xff; }
00188 
00190 
00192                 u32 getBlue() const { return color & 0xff; }
00193 
00195                 f32 getLightness() const
00196                 {
00197                         return 0.5f*(core::max_(core::max_(getRed(),getGreen()),getBlue())+core::min_(core::min_(getRed(),getGreen()),getBlue()));
00198                 }
00199 
00201                 f32 getLuminance() const
00202                 {
00203                         return 0.3f*getRed() + 0.59f*getGreen() + 0.11f*getBlue();
00204                 }
00205 
00207                 u32 getAverage() const
00208                 {
00209                         return ( getRed() + getGreen() + getBlue() ) / 3;
00210                 }
00211 
00213 
00215                 void setAlpha(u32 a) { color = ((a & 0xff)<<24) | (color & 0x00ffffff); }
00216 
00218 
00220                 void setRed(u32 r) { color = ((r & 0xff)<<16) | (color & 0xff00ffff); }
00221 
00223 
00225                 void setGreen(u32 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); }
00226 
00228 
00230                 void setBlue(u32 b) { color = (b & 0xff) | (color & 0xffffff00); }
00231 
00233 
00234                 u16 toA1R5G5B5() const { return A8R8G8B8toA1R5G5B5(color); }
00235 
00237 
00240                 void toOpenGLColor(u8* dest) const
00241                 {
00242                         *dest =   (u8)getRed();
00243                         *++dest = (u8)getGreen();
00244                         *++dest = (u8)getBlue();
00245                         *++dest = (u8)getAlpha();
00246                 }
00247 
00249 
00263                 void set(u32 a, u32 r, u32 g, u32 b)
00264                 {
00265                         color = (((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff));
00266                 }
00267                 void set(u32 col) { color = col; }
00268 
00270 
00271                 bool operator==(const SColor& other) const { return other.color == color; }
00272 
00274 
00275                 bool operator!=(const SColor& other) const { return other.color != color; }
00276 
00278 
00279                 bool operator<(const SColor& other) const { return (color < other.color); }
00280 
00282 
00284                 SColor operator+(const SColor& other) const
00285                 {
00286                         return SColor(core::min_(getAlpha() + other.getAlpha(), 255u),
00287                                         core::min_(getRed() + other.getRed(), 255u),
00288                                         core::min_(getGreen() + other.getGreen(), 255u),
00289                                         core::min_(getBlue() + other.getBlue(), 255u));
00290                 }
00291 
00293 
00296                 SColor getInterpolated(const SColor &other, f32 d) const
00297                 {
00298                         d = core::clamp(d, 0.f, 1.f);
00299                         const f32 inv = 1.0f - d;
00300                         return SColor((u32)core::round32(other.getAlpha()*inv + getAlpha()*d),
00301                                 (u32)core::round32(other.getRed()*inv + getRed()*d),
00302                                 (u32)core::round32(other.getGreen()*inv + getGreen()*d),
00303                                 (u32)core::round32(other.getBlue()*inv + getBlue()*d));
00304                 }
00305 
00307 
00310                 SColor getInterpolated_quadratic(const SColor& c1, const SColor& c2, f32 d) const
00311                 {
00312                         // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
00313                         d = core::clamp(d, 0.f, 1.f);
00314                         const f32 inv = 1.f - d;
00315                         const f32 mul0 = inv * inv;
00316                         const f32 mul1 = 2.f * d * inv;
00317                         const f32 mul2 = d * d;
00318 
00319                         return SColor(
00320                                         core::clamp( core::floor32(
00321                                                         getAlpha() * mul0 + c1.getAlpha() * mul1 + c2.getAlpha() * mul2 ), 0, 255 ),
00322                                         core::clamp( core::floor32(
00323                                                         getRed()   * mul0 + c1.getRed()   * mul1 + c2.getRed()   * mul2 ), 0, 255 ),
00324                                         core::clamp ( core::floor32(
00325                                                         getGreen() * mul0 + c1.getGreen() * mul1 + c2.getGreen() * mul2 ), 0, 255 ),
00326                                         core::clamp ( core::floor32(
00327                                                         getBlue()  * mul0 + c1.getBlue()  * mul1 + c2.getBlue()  * mul2 ), 0, 255 ));
00328                 }
00329 
00331                 u32 color;
00332         };
00333 
00334 
00336 
00342         class SColorf
00343         {
00344         public:
00346 
00347                 SColorf() : r(0.0f), g(0.0f), b(0.0f), a(1.0f) {}
00348 
00350 
00360                 SColorf(f32 r, f32 g, f32 b, f32 a = 1.0f) : r(r), g(g), b(b), a(a) {}
00361 
00363 
00365                 SColorf(SColor c)
00366                 {
00367                         const f32 inv = 1.0f / 255.0f;
00368                         r = c.getRed() * inv;
00369                         g = c.getGreen() * inv;
00370                         b = c.getBlue() * inv;
00371                         a = c.getAlpha() * inv;
00372                 }
00373 
00375                 SColor toSColor() const
00376                 {
00377                         return SColor((u32)core::round32(a*255.0f), (u32)core::round32(r*255.0f), (u32)core::round32(g*255.0f), (u32)core::round32(b*255.0f));
00378                 }
00379 
00381 
00387                 void set(f32 rr, f32 gg, f32 bb) {r = rr; g =gg; b = bb; }
00388 
00390 
00398                 void set(f32 aa, f32 rr, f32 gg, f32 bb) {a = aa; r = rr; g =gg; b = bb; }
00399 
00401 
00404                 SColorf getInterpolated(const SColorf &other, f32 d) const
00405                 {
00406                         d = core::clamp(d, 0.f, 1.f);
00407                         const f32 inv = 1.0f - d;
00408                         return SColorf(other.r*inv + r*d,
00409                                 other.g*inv + g*d, other.b*inv + b*d, other.a*inv + a*d);
00410                 }
00411 
00413 
00416                 inline SColorf getInterpolated_quadratic(const SColorf& c1, const SColorf& c2,
00417                                 f32 d) const
00418                 {
00419                         d = core::clamp(d, 0.f, 1.f);
00420                         // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
00421                         const f32 inv = 1.f - d;
00422                         const f32 mul0 = inv * inv;
00423                         const f32 mul1 = 2.f * d * inv;
00424                         const f32 mul2 = d * d;
00425 
00426                         return SColorf (r * mul0 + c1.r * mul1 + c2.r * mul2,
00427                                         g * mul0 + c1.g * mul1 + c2.g * mul2,
00428                                         g * mul0 + c1.b * mul1 + c2.b * mul2,
00429                                         a * mul0 + c1.a * mul1 + c2.a * mul2);
00430                 }
00431 
00432 
00434                 void setColorComponentValue(s32 index, f32 value)
00435                 {
00436                         switch(index)
00437                         {
00438                         case 0: r = value; break;
00439                         case 1: g = value; break;
00440                         case 2: b = value; break;
00441                         case 3: a = value; break;
00442                         }
00443                 }
00444 
00446                 f32 getAlpha() const { return a; }
00447 
00449                 f32 getRed() const { return r; }
00450 
00452                 f32 getGreen() const { return g; }
00453 
00455                 f32 getBlue() const { return b; }
00456 
00458                 f32 r;
00459 
00461                 f32 g;
00462 
00464                 f32 b;
00465 
00467                 f32 a;
00468         };
00469 
00470 
00472 
00475         class SColorHSL
00476         {
00477         public:
00478                 SColorHSL ( f32 h = 0.f, f32 s = 0.f, f32 l = 0.f )
00479                         : Hue ( h ), Saturation ( s ), Luminance ( l ) {}
00480 
00481                 void fromRGB(const SColor &color);
00482                 void toRGB(SColor &color) const;
00483 
00484                 f32 Hue;
00485                 f32 Saturation;
00486                 f32 Luminance;
00487 
00488         private:
00489                 inline u32 toRGB1(f32 rm1, f32 rm2, f32 rh) const;
00490 
00491         };
00492 
00493         inline void SColorHSL::fromRGB(const SColor &color)
00494         {
00495                 const u32 maxValInt = core::max_(color.getRed(), color.getGreen(), color.getBlue());
00496                 const f32 maxVal = (f32)maxValInt;
00497                 const f32 minVal = (f32)core::min_(color.getRed(), color.getGreen(), color.getBlue());
00498                 Luminance = (maxVal/minVal)*0.5f;
00499                 if (core::equals(maxVal, minVal))
00500                 {
00501                         Hue=0.f;
00502                         Saturation=0.f;
00503                         return;
00504                 }
00505 
00506                 const f32 delta = maxVal-minVal;
00507                 if ( Luminance <= 0.5f )
00508                 {
00509                         Saturation = (delta)/(maxVal+minVal);
00510                 }
00511                 else
00512                 {
00513                         Saturation = (delta)/(2-maxVal-minVal);
00514                 }
00515 
00516                 if (maxValInt == color.getRed())
00517                         Hue = (color.getGreen()-color.getBlue())/delta;
00518                 else if (maxValInt == color.getGreen())
00519                         Hue = 2+(color.getBlue()-color.getRed())/delta;
00520                 else // blue is max
00521                         Hue = 4+(color.getRed()-color.getGreen())/delta;
00522 
00523                 Hue *= (60.0f * core::DEGTORAD);
00524                 while ( Hue < 0.f )
00525                         Hue += 2.f * core::PI;
00526         }
00527 
00528 
00529         inline void SColorHSL::toRGB(SColor &color) const
00530         {
00531                 if (core::iszero(Saturation)) // grey
00532                 {
00533                         u8 c = (u8) ( Luminance * 255.0 );
00534                         color.setRed(c);
00535                         color.setGreen(c);
00536                         color.setBlue(c);
00537                         return;
00538                 }
00539 
00540                 f32 rm2;
00541 
00542                 if ( Luminance <= 0.5f )
00543                 {
00544                         rm2 = Luminance + Luminance * Saturation;
00545                 }
00546                 else
00547                 {
00548                         rm2 = Luminance + Saturation - Luminance * Saturation;
00549                 }
00550 
00551                 const f32 rm1 = 2.0f * Luminance - rm2;
00552 
00553                 color.setRed ( toRGB1(rm1, rm2, Hue + (120.0f * core::DEGTORAD )) );
00554                 color.setGreen ( toRGB1(rm1, rm2, Hue) );
00555                 color.setBlue ( toRGB1(rm1, rm2, Hue - (120.0f * core::DEGTORAD) ) );
00556         }
00557 
00558 
00559         inline u32 SColorHSL::toRGB1(f32 rm1, f32 rm2, f32 rh) const
00560         {
00561                 while ( rh > 2.f * core::PI )
00562                         rh -= 2.f * core::PI;
00563 
00564                 while ( rh < 0.f )
00565                         rh += 2.f * core::PI;
00566 
00567                 if (rh < 60.0f * core::DEGTORAD )
00568                         rm1 = rm1 + (rm2 - rm1) * rh / (60.0f * core::DEGTORAD);
00569                 else if (rh < 180.0f * core::DEGTORAD )
00570                         rm1 = rm2;
00571                 else if (rh < 240.0f * core::DEGTORAD )
00572                         rm1 = rm1 + (rm2 - rm1) * ( ( 240.0f * core::DEGTORAD ) - rh) /
00573                                 (60.0f * core::DEGTORAD);
00574 
00575                 return (u32) core::round32(rm1 * 255.f);
00576         }
00577 
00578 } // end namespace video
00579 } // end namespace irr
00580 
00581 #endif
00582 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Sun Oct 24 12:41:58 2010 by Doxygen (1.6.2)