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-2009 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 getLuminance() const
00196                 {
00197                         return 0.3f*getRed() + 0.59f*getGreen() + 0.11f*getBlue();
00198                 }
00199 
00201                 u32 getAverage() const
00202                 {
00203                         return ( getRed() + getGreen() + getBlue() ) / 3;
00204                 }
00205 
00207 
00209                 void setAlpha(u32 a) { color = ((a & 0xff)<<24) | (color & 0x00ffffff); }
00210 
00212 
00214                 void setRed(u32 r) { color = ((r & 0xff)<<16) | (color & 0xff00ffff); }
00215 
00217 
00219                 void setGreen(u32 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); }
00220 
00222 
00224                 void setBlue(u32 b) { color = (b & 0xff) | (color & 0xffffff00); }
00225 
00227 
00228                 u16 toA1R5G5B5() const { return A8R8G8B8toA1R5G5B5(color); }
00229 
00231 
00234                 void toOpenGLColor(u8* dest) const
00235                 {
00236                         *dest =   (u8)getRed();
00237                         *++dest = (u8)getGreen();
00238                         *++dest = (u8)getBlue();
00239                         *++dest = (u8)getAlpha();
00240                 }
00241 
00243 
00257                 void set(u32 a, u32 r, u32 g, u32 b)
00258                 {
00259                         color = (((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff));
00260                 }
00261                 void set(u32 col) { color = col; }
00262 
00264 
00265                 bool operator==(const SColor& other) const { return other.color == color; }
00266 
00268 
00269                 bool operator!=(const SColor& other) const { return other.color != color; }
00270 
00272 
00273                 bool operator<(const SColor& other) const { return (color < other.color); }
00274 
00276 
00278                 SColor operator+(const SColor& other) const
00279                 {
00280                         return SColor(core::min_(getAlpha() + other.getAlpha(), 255u),
00281                                         core::min_(getRed() + other.getRed(), 255u),
00282                                         core::min_(getGreen() + other.getGreen(), 255u),
00283                                         core::min_(getBlue() + other.getBlue(), 255u));
00284                 }
00285 
00287 
00290                 SColor getInterpolated(const SColor &other, f32 d) const
00291                 {
00292                         d = core::clamp(d, 0.f, 1.f);
00293                         const f32 inv = 1.0f - d;
00294                         return SColor((u32)(other.getAlpha()*inv + getAlpha()*d),
00295                                 (u32)(other.getRed()*inv + getRed()*d),
00296                                 (u32)(other.getGreen()*inv + getGreen()*d),
00297                                 (u32)(other.getBlue()*inv + getBlue()*d));
00298                 }
00299 
00301 
00304                 SColor getInterpolated_quadratic(const SColor& c1, const SColor& c2, f32 d) const
00305                 {
00306                         // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
00307                         d = core::clamp(d, 0.f, 1.f);
00308                         const f32 inv = 1.f - d;
00309                         const f32 mul0 = inv * inv;
00310                         const f32 mul1 = 2.f * d * inv;
00311                         const f32 mul2 = d * d;
00312 
00313                         return SColor(
00314                                         core::clamp( core::floor32(
00315                                                         getAlpha() * mul0 + c1.getAlpha() * mul1 + c2.getAlpha() * mul2 ), 0, 255 ),
00316                                         core::clamp( core::floor32(
00317                                                         getRed()   * mul0 + c1.getRed()   * mul1 + c2.getRed()   * mul2 ), 0, 255 ),
00318                                         core::clamp ( core::floor32(
00319                                                         getGreen() * mul0 + c1.getGreen() * mul1 + c2.getGreen() * mul2 ), 0, 255 ),
00320                                         core::clamp ( core::floor32(
00321                                                         getBlue()  * mul0 + c1.getBlue()  * mul1 + c2.getBlue()  * mul2 ), 0, 255 ));
00322                 }
00323 
00325                 u32 color;
00326         };
00327 
00328 
00330 
00336         class SColorf
00337         {
00338         public:
00340 
00341                 SColorf() : r(0.0f), g(0.0f), b(0.0f), a(1.0f) {}
00342 
00344 
00354                 SColorf(f32 r, f32 g, f32 b, f32 a = 1.0f) : r(r), g(g), b(b), a(a) {}
00355 
00357 
00359                 SColorf(SColor c)
00360                 {
00361                         const f32 inv = 1.0f / 255.0f;
00362                         r = c.getRed() * inv;
00363                         g = c.getGreen() * inv;
00364                         b = c.getBlue() * inv;
00365                         a = c.getAlpha() * inv;
00366                 }
00367 
00369                 SColor toSColor() const
00370                 {
00371                         return SColor((u32)(a*255.0f), (u32)(r*255.0f), (u32)(g*255.0f), (u32)(b*255.0f));
00372                 }
00373 
00375 
00381                 void set(f32 rr, f32 gg, f32 bb) {r = rr; g =gg; b = bb; }
00382 
00384 
00392                 void set(f32 aa, f32 rr, f32 gg, f32 bb) {a = aa; r = rr; g =gg; b = bb; }
00393 
00395 
00398                 SColorf getInterpolated(const SColorf &other, f32 d) const
00399                 {
00400                         d = core::clamp(d, 0.f, 1.f);
00401                         const f32 inv = 1.0f - d;
00402                         return SColorf(other.r*inv + r*d,
00403                                 other.g*inv + g*d, other.b*inv + b*d, other.a*inv + a*d);
00404                 }
00405 
00407 
00410                 inline SColorf getInterpolated_quadratic(const SColorf& c1, const SColorf& c2,
00411                                 f32 d) const
00412                 {
00413                         d = core::clamp(d, 0.f, 1.f);
00414                         // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
00415                         const f32 inv = 1.f - d;
00416                         const f32 mul0 = inv * inv;
00417                         const f32 mul1 = 2.f * d * inv;
00418                         const f32 mul2 = d * d;
00419 
00420                         return SColorf (r * mul0 + c1.r * mul1 + c2.r * mul2,
00421                                         g * mul0 + c1.g * mul1 + c2.g * mul2,
00422                                         g * mul0 + c1.b * mul1 + c2.b * mul2,
00423                                         a * mul0 + c1.a * mul1 + c2.a * mul2);
00424                 }
00425 
00426 
00428                 void setColorComponentValue(s32 index, f32 value)
00429                 {
00430                         switch(index)
00431                         {
00432                         case 0: r = value; break;
00433                         case 1: g = value; break;
00434                         case 2: b = value; break;
00435                         case 3: a = value; break;
00436                         }
00437                 }
00438 
00440                 f32 getAlpha() const { return a; }
00441 
00443                 f32 getRed() const { return r; }
00444 
00446                 f32 getGreen() const { return g; }
00447 
00449                 f32 getBlue() const { return b; }
00450 
00452                 f32 r;
00453 
00455                 f32 g;
00456 
00458                 f32 b;
00459 
00461                 f32 a;
00462         };
00463 
00464 
00466 
00469         class SColorHSL
00470         {
00471         public:
00472                 SColorHSL ( f32 h = 0.f, f32 s = 0.f, f32 l = 0.f )
00473                         : Hue ( h ), Saturation ( s ), Luminance ( l ) {}
00474 
00475                 void fromRGB(const SColor &color);
00476                 void toRGB(SColor &color) const;
00477 
00478                 f32 Hue;
00479                 f32 Saturation;
00480                 f32 Luminance;
00481 
00482         private:
00483                 inline u32 toRGB1(f32 rm1, f32 rm2, f32 rh) const;
00484 
00485         };
00486 
00487         inline void SColorHSL::fromRGB(const SColor &color)
00488         {
00489                 const f32 maxVal = (f32)core::max_(color.getRed(), color.getGreen(), color.getBlue());
00490                 const f32 minVal = (f32)core::min_(color.getRed(), color.getGreen(), color.getBlue());
00491                 Luminance = (maxVal/minVal)*0.5f;
00492                 if (core::equals(maxVal, minVal))
00493                 {
00494                         Hue=0.f;
00495                         Saturation=0.f;
00496                         return;
00497                 }
00498 
00499                 const f32 delta = maxVal-minVal;
00500                 if ( Luminance <= 0.5f )
00501                 {
00502                         Saturation = (delta)/(maxVal+minVal);
00503                 }
00504                 else
00505                 {
00506                         Saturation = (delta)/(2-maxVal-minVal);
00507                 }
00508 
00509                 if (maxVal==color.getRed())
00510                         Hue = (color.getGreen()-color.getBlue())/delta;
00511                 else if (maxVal==color.getGreen())
00512                         Hue = 2+(color.getBlue()-color.getRed())/delta;
00513                 else if (maxVal==color.getBlue())
00514                         Hue = 4+(color.getRed()-color.getGreen())/delta;
00515 
00516                 Hue *= (60.0f * core::DEGTORAD);
00517                 while ( Hue < 0.f )
00518                         Hue += 2.f * core::PI;
00519         }
00520 
00521 
00522         inline void SColorHSL::toRGB(SColor &color) const
00523         {
00524                 if (core::iszero(Saturation)) // grey
00525                 {
00526                         u8 c = (u8) ( Luminance * 255.0 );
00527                         color.setRed(c);
00528                         color.setGreen(c);
00529                         color.setBlue(c);
00530                         return;
00531                 }
00532 
00533                 f32 rm2;
00534 
00535                 if ( Luminance <= 0.5f )
00536                 {
00537                         rm2 = Luminance + Luminance * Saturation;
00538                 }
00539                 else
00540                 {
00541                         rm2 = Luminance + Saturation - Luminance * Saturation;
00542                 }
00543 
00544                 const f32 rm1 = 2.0f * Luminance - rm2;
00545 
00546                 color.setRed ( toRGB1(rm1, rm2, Hue + (120.0f * core::DEGTORAD )) );
00547                 color.setGreen ( toRGB1(rm1, rm2, Hue) );
00548                 color.setBlue ( toRGB1(rm1, rm2, Hue - (120.0f * core::DEGTORAD) ) );
00549         }
00550 
00551 
00552         inline u32 SColorHSL::toRGB1(f32 rm1, f32 rm2, f32 rh) const
00553         {
00554                 while ( rh > 2.f * core::PI )
00555                         rh -= 2.f * core::PI;
00556 
00557                 while ( rh < 0.f )
00558                         rh += 2.f * core::PI;
00559 
00560                 if (rh < 60.0f * core::DEGTORAD )
00561                         rm1 = rm1 + (rm2 - rm1) * rh / (60.0f * core::DEGTORAD);
00562                 else if (rh < 180.0f * core::DEGTORAD )
00563                         rm1 = rm2;
00564                 else if (rh < 240.0f * core::DEGTORAD )
00565                         rm1 = rm1 + (rm2 - rm1) * ( ( 240.0f * core::DEGTORAD ) - rh) /
00566                                 (60.0f * core::DEGTORAD);
00567 
00568                 return (u32) (rm1 * 255.f);
00569         }
00570 
00571 } // end namespace video
00572 } // end namespace irr
00573 
00574 #endif
00575 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2009 by Nikolaus Gebhardt. Generated on Sun Jan 10 09:24:05 2010 by Doxygen (1.5.6)