LCOV - code coverage report
Current view: top level - usr/include/irrlicht - SColor.h (source / functions) Hit Total Coverage
Test: report Lines: 41 58 70.7 %
Date: 2015-07-11 18:23:49 Functions: 20 24 83.3 %

          Line data    Source code
       1             : // Copyright (C) 2002-2012 Nikolaus Gebhardt
       2             : // This file is part of the "Irrlicht Engine".
       3             : // For conditions of distribution and use, see copyright notice in irrlicht.h
       4             : 
       5             : #ifndef __COLOR_H_INCLUDED__
       6             : #define __COLOR_H_INCLUDED__
       7             : 
       8             : #include "irrTypes.h"
       9             : #include "irrMath.h"
      10             : 
      11             : namespace irr
      12             : {
      13             : namespace video
      14             : {
      15             :         //! An enum for the color format of textures used by the Irrlicht Engine.
      16             :         /** A color format specifies how color information is stored. */
      17             :         enum ECOLOR_FORMAT
      18             :         {
      19             :                 //! 16 bit color format used by the software driver.
      20             :                 /** It is thus preferred by all other irrlicht engine video drivers.
      21             :                 There are 5 bits for every color component, and a single bit is left
      22             :                 for alpha information. */
      23             :                 ECF_A1R5G5B5 = 0,
      24             : 
      25             :                 //! Standard 16 bit color format.
      26             :                 ECF_R5G6B5,
      27             : 
      28             :                 //! 24 bit color, no alpha channel, but 8 bit for red, green and blue.
      29             :                 ECF_R8G8B8,
      30             : 
      31             :                 //! Default 32 bit color format. 8 bits are used for every component: red, green, blue and alpha.
      32             :                 ECF_A8R8G8B8,
      33             : 
      34             :                 /** Floating Point formats. The following formats may only be used for render target textures. */
      35             : 
      36             :                 //! 16 bit floating point format using 16 bits for the red channel.
      37             :                 ECF_R16F,
      38             : 
      39             :                 //! 32 bit floating point format using 16 bits for the red channel and 16 bits for the green channel.
      40             :                 ECF_G16R16F,
      41             : 
      42             :                 //! 64 bit floating point format 16 bits are used for the red, green, blue and alpha channels.
      43             :                 ECF_A16B16G16R16F,
      44             : 
      45             :                 //! 32 bit floating point format using 32 bits for the red channel.
      46             :                 ECF_R32F,
      47             : 
      48             :                 //! 64 bit floating point format using 32 bits for the red channel and 32 bits for the green channel.
      49             :                 ECF_G32R32F,
      50             : 
      51             :                 //! 128 bit floating point format. 32 bits are used for the red, green, blue and alpha channels.
      52             :                 ECF_A32B32G32R32F,
      53             : 
      54             :                 //! Unknown color format:
      55             :                 ECF_UNKNOWN
      56             :         };
      57             : 
      58             : 
      59             :         //! Creates a 16 bit A1R5G5B5 color
      60             :         inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a=0xFF)
      61             :         {
      62             :                 return (u16)((a & 0x80) << 8 |
      63             :                         (r & 0xF8) << 7 |
      64             :                         (g & 0xF8) << 2 |
      65             :                         (b & 0xF8) >> 3);
      66             :         }
      67             : 
      68             : 
      69             :         //! Creates a 16 bit A1R5G5B5 color
      70             :         inline u16 RGB16(u32 r, u32 g, u32 b)
      71             :         {
      72             :                 return RGBA16(r,g,b);
      73             :         }
      74             : 
      75             : 
      76             :         //! Creates a 16bit A1R5G5B5 color, based on 16bit input values
      77             :         inline u16 RGB16from16(u16 r, u16 g, u16 b)
      78             :         {
      79             :                 return (0x8000 |
      80             :                                 (r & 0x1F) << 10 |
      81             :                                 (g & 0x1F) << 5  |
      82             :                                 (b & 0x1F));
      83             :         }
      84             : 
      85             : 
      86             :         //! Converts a 32bit (X8R8G8B8) color to a 16bit A1R5G5B5 color
      87             :         inline u16 X8R8G8B8toA1R5G5B5(u32 color)
      88             :         {
      89             :                 return (u16)(0x8000 |
      90             :                         ( color & 0x00F80000) >> 9 |
      91             :                         ( color & 0x0000F800) >> 6 |
      92             :                         ( color & 0x000000F8) >> 3);
      93             :         }
      94             : 
      95             : 
      96             :         //! Converts a 32bit (A8R8G8B8) color to a 16bit A1R5G5B5 color
      97             :         inline u16 A8R8G8B8toA1R5G5B5(u32 color)
      98             :         {
      99             :                 return (u16)(( color & 0x80000000) >> 16|
     100             :                         ( color & 0x00F80000) >> 9 |
     101             :                         ( color & 0x0000F800) >> 6 |
     102             :                         ( color & 0x000000F8) >> 3);
     103             :         }
     104             : 
     105             : 
     106             :         //! Converts a 32bit (A8R8G8B8) color to a 16bit R5G6B5 color
     107             :         inline u16 A8R8G8B8toR5G6B5(u32 color)
     108             :         {
     109             :                 return (u16)(( color & 0x00F80000) >> 8 |
     110             :                         ( color & 0x0000FC00) >> 5 |
     111             :                         ( color & 0x000000F8) >> 3);
     112             :         }
     113             : 
     114             : 
     115             :         //! Convert A8R8G8B8 Color from A1R5G5B5 color
     116             :         /** build a nicer 32bit Color by extending dest lower bits with source high bits. */
     117             :         inline u32 A1R5G5B5toA8R8G8B8(u16 color)
     118             :         {
     119             :                 return ( (( -( (s32) color & 0x00008000 ) >> (s32) 31 ) & 0xFF000000 ) |
     120             :                                 (( color & 0x00007C00 ) << 9) | (( color & 0x00007000 ) << 4) |
     121             :                                 (( color & 0x000003E0 ) << 6) | (( color & 0x00000380 ) << 1) |
     122             :                                 (( color & 0x0000001F ) << 3) | (( color & 0x0000001C ) >> 2)
     123             :                                 );
     124             :         }
     125             : 
     126             : 
     127             :         //! Returns A8R8G8B8 Color from R5G6B5 color
     128             :         inline u32 R5G6B5toA8R8G8B8(u16 color)
     129             :         {
     130             :                 return 0xFF000000 |
     131             :                         ((color & 0xF800) << 8)|
     132             :                         ((color & 0x07E0) << 5)|
     133             :                         ((color & 0x001F) << 3);
     134             :         }
     135             : 
     136             : 
     137             :         //! Returns A1R5G5B5 Color from R5G6B5 color
     138             :         inline u16 R5G6B5toA1R5G5B5(u16 color)
     139             :         {
     140             :                 return 0x8000 | (((color & 0xFFC0) >> 1) | (color & 0x1F));
     141             :         }
     142             : 
     143             : 
     144             :         //! Returns R5G6B5 Color from A1R5G5B5 color
     145             :         inline u16 A1R5G5B5toR5G6B5(u16 color)
     146             :         {
     147             :                 return (((color & 0x7FE0) << 1) | (color & 0x1F));
     148             :         }
     149             : 
     150             : 
     151             : 
     152             :         //! Returns the alpha component from A1R5G5B5 color
     153             :         /** In Irrlicht, alpha refers to opacity.
     154             :         \return The alpha value of the color. 0 is transparent, 1 is opaque. */
     155             :         inline u32 getAlpha(u16 color)
     156             :         {
     157             :                 return ((color >> 15)&0x1);
     158             :         }
     159             : 
     160             : 
     161             :         //! Returns the red component from A1R5G5B5 color.
     162             :         /** Shift left by 3 to get 8 bit value. */
     163             :         inline u32 getRed(u16 color)
     164             :         {
     165             :                 return ((color >> 10)&0x1F);
     166             :         }
     167             : 
     168             : 
     169             :         //! Returns the green component from A1R5G5B5 color
     170             :         /** Shift left by 3 to get 8 bit value. */
     171             :         inline u32 getGreen(u16 color)
     172             :         {
     173             :                 return ((color >> 5)&0x1F);
     174             :         }
     175             : 
     176             : 
     177             :         //! Returns the blue component from A1R5G5B5 color
     178             :         /** Shift left by 3 to get 8 bit value. */
     179             :         inline u32 getBlue(u16 color)
     180             :         {
     181             :                 return (color & 0x1F);
     182             :         }
     183             : 
     184             : 
     185             :         //! Returns the average from a 16 bit A1R5G5B5 color
     186             :         inline s32 getAverage(s16 color)
     187             :         {
     188             :                 return ((getRed(color)<<3) + (getGreen(color)<<3) + (getBlue(color)<<3)) / 3;
     189             :         }
     190             : 
     191             : 
     192             :         //! Class representing a 32 bit ARGB color.
     193             :         /** The color values for alpha, red, green, and blue are
     194             :         stored in a single u32. So all four values may be between 0 and 255.
     195             :         Alpha in Irrlicht is opacity, so 0 is fully transparent, 255 is fully opaque (solid).
     196             :         This class is used by most parts of the Irrlicht Engine
     197             :         to specify a color. Another way is using the class SColorf, which
     198             :         stores the color values in 4 floats.
     199             :         This class must consist of only one u32 and must not use virtual functions.
     200             :         */
     201             :         class SColor
     202             :         {
     203             :         public:
     204             : 
     205             :                 //! Constructor of the Color. Does nothing.
     206             :                 /** The color value is not initialized to save time. */
     207     7292905 :                 SColor() {}
     208             : 
     209             :                 //! Constructs the color from 4 values representing the alpha, red, green and blue component.
     210             :                 /** Must be values between 0 and 255. */
     211    23917185 :                 SColor (u32 a, u32 r, u32 g, u32 b)
     212    23917185 :                         : color(((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff)) {}
     213             : 
     214             :                 //! Constructs the color from a 32 bit value. Could be another color.
     215         123 :                 SColor(u32 clr)
     216         123 :                         : color(clr) {}
     217             : 
     218             :                 //! Returns the alpha component of the color.
     219             :                 /** The alpha component defines how opaque a color is.
     220             :                 \return The alpha value of the color. 0 is fully transparent, 255 is fully opaque. */
     221    54794374 :                 u32 getAlpha() const { return color>>24; }
     222             : 
     223             :                 //! Returns the red component of the color.
     224             :                 /** \return Value between 0 and 255, specifying how red the color is.
     225             :                 0 means no red, 255 means full red. */
     226    44744634 :                 u32 getRed() const { return (color>>16) & 0xff; }
     227             : 
     228             :                 //! Returns the green component of the color.
     229             :                 /** \return Value between 0 and 255, specifying how green the color is.
     230             :                 0 means no green, 255 means full green. */
     231    42702561 :                 u32 getGreen() const { return (color>>8) & 0xff; }
     232             : 
     233             :                 //! Returns the blue component of the color.
     234             :                 /** \return Value between 0 and 255, specifying how blue the color is.
     235             :                 0 means no blue, 255 means full blue. */
     236    44837249 :                 u32 getBlue() const { return color & 0xff; }
     237             : 
     238             :                 //! Get lightness of the color in the range [0,255]
     239             :                 f32 getLightness() const
     240             :                 {
     241             :                         return 0.5f*(core::max_(core::max_(getRed(),getGreen()),getBlue())+core::min_(core::min_(getRed(),getGreen()),getBlue()));
     242             :                 }
     243             : 
     244             :                 //! Get luminance of the color in the range [0,255].
     245             :                 f32 getLuminance() const
     246             :                 {
     247             :                         return 0.3f*getRed() + 0.59f*getGreen() + 0.11f*getBlue();
     248             :                 }
     249             : 
     250             :                 //! Get average intensity of the color in the range [0,255].
     251             :                 u32 getAverage() const
     252             :                 {
     253             :                         return ( getRed() + getGreen() + getBlue() ) / 3;
     254             :                 }
     255             : 
     256             :                 //! Sets the alpha component of the Color.
     257             :                 /** The alpha component defines how transparent a color should be.
     258             :                 \param a The alpha value of the color. 0 is fully transparent, 255 is fully opaque. */
     259      366430 :                 void setAlpha(u32 a) { color = ((a & 0xff)<<24) | (color & 0x00ffffff); }
     260             : 
     261             :                 //! Sets the red component of the Color.
     262             :                 /** \param r: Has to be a value between 0 and 255.
     263             :                 0 means no red, 255 means full red. */
     264     5148936 :                 void setRed(u32 r) { color = ((r & 0xff)<<16) | (color & 0xff00ffff); }
     265             : 
     266             :                 //! Sets the green component of the Color.
     267             :                 /** \param g: Has to be a value between 0 and 255.
     268             :                 0 means no green, 255 means full green. */
     269     5148835 :                 void setGreen(u32 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); }
     270             : 
     271             :                 //! Sets the blue component of the Color.
     272             :                 /** \param b: Has to be a value between 0 and 255.
     273             :                 0 means no blue, 255 means full blue. */
     274      161271 :                 void setBlue(u32 b) { color = (b & 0xff) | (color & 0xffffff00); }
     275             : 
     276             :                 //! Calculates a 16 bit A1R5G5B5 value of this color.
     277             :                 /** \return 16 bit A1R5G5B5 value of this color. */
     278             :                 u16 toA1R5G5B5() const { return A8R8G8B8toA1R5G5B5(color); }
     279             : 
     280             :                 //! Converts color to OpenGL color format
     281             :                 /** From ARGB to RGBA in 4 byte components for endian aware
     282             :                 passing to OpenGL
     283             :                 \param dest: address where the 4x8 bit OpenGL color is stored. */
     284             :                 void toOpenGLColor(u8* dest) const
     285             :                 {
     286             :                         *dest =   (u8)getRed();
     287             :                         *++dest = (u8)getGreen();
     288             :                         *++dest = (u8)getBlue();
     289             :                         *++dest = (u8)getAlpha();
     290             :                 }
     291             : 
     292             :                 //! Sets all four components of the color at once.
     293             :                 /** Constructs the color from 4 values representing the alpha,
     294             :                 red, green and blue components of the color. Must be values
     295             :                 between 0 and 255.
     296             :                 \param a: Alpha component of the color. The alpha component
     297             :                 defines how transparent a color should be. Has to be a value
     298             :                 between 0 and 255. 255 means not transparent (opaque), 0 means
     299             :                 fully transparent.
     300             :                 \param r: Sets the red component of the Color. Has to be a
     301             :                 value between 0 and 255. 0 means no red, 255 means full red.
     302             :                 \param g: Sets the green component of the Color. Has to be a
     303             :                 value between 0 and 255. 0 means no green, 255 means full
     304             :                 green.
     305             :                 \param b: Sets the blue component of the Color. Has to be a
     306             :                 value between 0 and 255. 0 means no blue, 255 means full blue. */
     307        5830 :                 void set(u32 a, u32 r, u32 g, u32 b)
     308             :                 {
     309        5830 :                         color = (((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff));
     310        5830 :                 }
     311           0 :                 void set(u32 col) { color = col; }
     312             : 
     313             :                 //! Compares the color to another color.
     314             :                 /** \return True if the colors are the same, and false if not. */
     315           0 :                 bool operator==(const SColor& other) const { return other.color == color; }
     316             : 
     317             :                 //! Compares the color to another color.
     318             :                 /** \return True if the colors are different, and false if they are the same. */
     319     4651720 :                 bool operator!=(const SColor& other) const { return other.color != color; }
     320             : 
     321             :                 //! comparison operator
     322             :                 /** \return True if this color is smaller than the other one */
     323           0 :                 bool operator<(const SColor& other) const { return (color < other.color); }
     324             : 
     325             :                 //! Adds two colors, result is clamped to 0..255 values
     326             :                 /** \param other Color to add to this color
     327             :                 \return Addition of the two colors, clamped to 0..255 values */
     328             :                 SColor operator+(const SColor& other) const
     329             :                 {
     330             :                         return SColor(core::min_(getAlpha() + other.getAlpha(), 255u),
     331             :                                         core::min_(getRed() + other.getRed(), 255u),
     332             :                                         core::min_(getGreen() + other.getGreen(), 255u),
     333             :                                         core::min_(getBlue() + other.getBlue(), 255u));
     334             :                 }
     335             : 
     336             :                 //! Interpolates the color with a f32 value to another color
     337             :                 /** \param other: Other color
     338             :                 \param d: value between 0.0f and 1.0f
     339             :                 \return Interpolated color. */
     340    17302482 :                 SColor getInterpolated(const SColor &other, f32 d) const
     341             :                 {
     342    17302482 :                         d = core::clamp(d, 0.f, 1.f);
     343    17302482 :                         const f32 inv = 1.0f - d;
     344    17302482 :                         return SColor((u32)core::round32(other.getAlpha()*inv + getAlpha()*d),
     345    17302482 :                                 (u32)core::round32(other.getRed()*inv + getRed()*d),
     346    17302482 :                                 (u32)core::round32(other.getGreen()*inv + getGreen()*d),
     347    69209928 :                                 (u32)core::round32(other.getBlue()*inv + getBlue()*d));
     348             :                 }
     349             : 
     350             :                 //! Returns interpolated color. ( quadratic )
     351             :                 /** \param c1: first color to interpolate with
     352             :                 \param c2: second color to interpolate with
     353             :                 \param d: value between 0.0f and 1.0f. */
     354           0 :                 SColor getInterpolated_quadratic(const SColor& c1, const SColor& c2, f32 d) const
     355             :                 {
     356             :                         // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
     357           0 :                         d = core::clamp(d, 0.f, 1.f);
     358           0 :                         const f32 inv = 1.f - d;
     359           0 :                         const f32 mul0 = inv * inv;
     360           0 :                         const f32 mul1 = 2.f * d * inv;
     361           0 :                         const f32 mul2 = d * d;
     362             : 
     363             :                         return SColor(
     364           0 :                                         core::clamp( core::floor32(
     365           0 :                                                         getAlpha() * mul0 + c1.getAlpha() * mul1 + c2.getAlpha() * mul2 ), 0, 255 ),
     366           0 :                                         core::clamp( core::floor32(
     367           0 :                                                         getRed()   * mul0 + c1.getRed()   * mul1 + c2.getRed()   * mul2 ), 0, 255 ),
     368           0 :                                         core::clamp ( core::floor32(
     369           0 :                                                         getGreen() * mul0 + c1.getGreen() * mul1 + c2.getGreen() * mul2 ), 0, 255 ),
     370           0 :                                         core::clamp ( core::floor32(
     371           0 :                                                         getBlue()  * mul0 + c1.getBlue()  * mul1 + c2.getBlue()  * mul2 ), 0, 255 ));
     372             :                 }
     373             : 
     374             :                 //! set the color by expecting data in the given format
     375             :                 /** \param data: must point to valid memory containing color information in the given format
     376             :                         \param format: tells the format in which data is available
     377             :                 */
     378             :                 void setData(const void *data, ECOLOR_FORMAT format)
     379             :                 {
     380             :                         switch (format)
     381             :                         {
     382             :                                 case ECF_A1R5G5B5:
     383             :                                         color = A1R5G5B5toA8R8G8B8(*(u16*)data);
     384             :                                         break;
     385             :                                 case ECF_R5G6B5:
     386             :                                         color = R5G6B5toA8R8G8B8(*(u16*)data);
     387             :                                         break;
     388             :                                 case ECF_A8R8G8B8:
     389             :                                         color = *(u32*)data;
     390             :                                         break;
     391             :                                 case ECF_R8G8B8:
     392             :                                         {
     393             :                                                 u8* p = (u8*)data;
     394             :                                                 set(255, p[0],p[1],p[2]);
     395             :                                         }
     396             :                                         break;
     397             :                                 default:
     398             :                                         color = 0xffffffff;
     399             :                                 break;
     400             :                         }
     401             :                 }
     402             : 
     403             :                 //! Write the color to data in the defined format
     404             :                 /** \param data: target to write the color. Must contain sufficiently large memory to receive the number of bytes neede for format
     405             :                         \param format: tells the format used to write the color into data
     406             :                 */
     407             :                 void getData(void *data, ECOLOR_FORMAT format)
     408             :                 {
     409             :                         switch(format)
     410             :                         {
     411             :                                 case ECF_A1R5G5B5:
     412             :                                 {
     413             :                                         u16 * dest = (u16*)data;
     414             :                                         *dest = video::A8R8G8B8toA1R5G5B5( color );
     415             :                                 } 
     416             :                                 break;
     417             : 
     418             :                                 case ECF_R5G6B5:
     419             :                                 {
     420             :                                         u16 * dest = (u16*)data;
     421             :                                         *dest = video::A8R8G8B8toR5G6B5( color );
     422             :                                 } 
     423             :                                 break;
     424             : 
     425             :                                 case ECF_R8G8B8:
     426             :                                 {
     427             :                                         u8* dest = (u8*)data;
     428             :                                         dest[0] = (u8)getRed();
     429             :                                         dest[1] = (u8)getGreen();
     430             :                                         dest[2] = (u8)getBlue();
     431             :                                 } 
     432             :                                 break;
     433             : 
     434             :                                 case ECF_A8R8G8B8:
     435             :                                 {
     436             :                                         u32 * dest = (u32*)data;
     437             :                                         *dest = color;
     438             :                                 } 
     439             :                                 break;
     440             : 
     441             :                                 default:
     442             :                                 break;
     443             :                         }
     444             :                 }
     445             : 
     446             :                 //! color in A8R8G8B8 Format
     447             :                 u32 color;
     448             :         };
     449             : 
     450             : 
     451             :         //! Class representing a color with four floats.
     452             :         /** The color values for red, green, blue
     453             :         and alpha are each stored in a 32 bit floating point variable.
     454             :         So all four values may be between 0.0f and 1.0f.
     455             :         Another, faster way to define colors is using the class SColor, which
     456             :         stores the color values in a single 32 bit integer.
     457             :         */
     458             :         class SColorf
     459             :         {
     460             :         public:
     461             :                 //! Default constructor for SColorf.
     462             :                 /** Sets red, green and blue to 0.0f and alpha to 1.0f. */
     463           6 :                 SColorf() : r(0.0f), g(0.0f), b(0.0f), a(1.0f) {}
     464             : 
     465             :                 //! Constructs a color from up to four color values: red, green, blue, and alpha.
     466             :                 /** \param r: Red color component. Should be a value between
     467             :                 0.0f meaning no red and 1.0f, meaning full red.
     468             :                 \param g: Green color component. Should be a value between 0.0f
     469             :                 meaning no green and 1.0f, meaning full green.
     470             :                 \param b: Blue color component. Should be a value between 0.0f
     471             :                 meaning no blue and 1.0f, meaning full blue.
     472             :                 \param a: Alpha color component of the color. The alpha
     473             :                 component defines how transparent a color should be. Has to be
     474             :                 a value between 0.0f and 1.0f, 1.0f means not transparent
     475             :                 (opaque), 0.0f means fully transparent. */
     476       16053 :                 SColorf(f32 r, f32 g, f32 b, f32 a = 1.0f) : r(r), g(g), b(b), a(a) {}
     477             : 
     478             :                 //! Constructs a color from 32 bit Color.
     479             :                 /** \param c: 32 bit color from which this SColorf class is
     480             :                 constructed from. */
     481     1433472 :                 SColorf(SColor c)
     482             :                 {
     483     1433472 :                         const f32 inv = 1.0f / 255.0f;
     484     1433472 :                         r = c.getRed() * inv;
     485     1433472 :                         g = c.getGreen() * inv;
     486     1433472 :                         b = c.getBlue() * inv;
     487     1433472 :                         a = c.getAlpha() * inv;
     488     1433472 :                 }
     489             : 
     490             :                 //! Converts this color to a SColor without floats.
     491       12518 :                 SColor toSColor() const
     492             :                 {
     493       12518 :                         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));
     494             :                 }
     495             : 
     496             :                 //! Sets three color components to new values at once.
     497             :                 /** \param rr: Red color component. Should be a value between 0.0f meaning
     498             :                 no red (=black) and 1.0f, meaning full red.
     499             :                 \param gg: Green color component. Should be a value between 0.0f meaning
     500             :                 no green (=black) and 1.0f, meaning full green.
     501             :                 \param bb: Blue color component. Should be a value between 0.0f meaning
     502             :                 no blue (=black) and 1.0f, meaning full blue. */
     503             :                 void set(f32 rr, f32 gg, f32 bb) {r = rr; g =gg; b = bb; }
     504             : 
     505             :                 //! Sets all four color components to new values at once.
     506             :                 /** \param aa: Alpha component. Should be a value between 0.0f meaning
     507             :                 fully transparent and 1.0f, meaning opaque.
     508             :                 \param rr: Red color component. Should be a value between 0.0f meaning
     509             :                 no red and 1.0f, meaning full red.
     510             :                 \param gg: Green color component. Should be a value between 0.0f meaning
     511             :                 no green and 1.0f, meaning full green.
     512             :                 \param bb: Blue color component. Should be a value between 0.0f meaning
     513             :                 no blue and 1.0f, meaning full blue. */
     514           2 :                 void set(f32 aa, f32 rr, f32 gg, f32 bb) {a = aa; r = rr; g =gg; b = bb; }
     515             : 
     516             :                 //! Interpolates the color with a f32 value to another color
     517             :                 /** \param other: Other color
     518             :                 \param d: value between 0.0f and 1.0f
     519             :                 \return Interpolated color. */
     520        3795 :                 SColorf getInterpolated(const SColorf &other, f32 d) const
     521             :                 {
     522        3795 :                         d = core::clamp(d, 0.f, 1.f);
     523        3795 :                         const f32 inv = 1.0f - d;
     524        3795 :                         return SColorf(other.r*inv + r*d,
     525        7590 :                                 other.g*inv + g*d, other.b*inv + b*d, other.a*inv + a*d);
     526             :                 }
     527             : 
     528             :                 //! Returns interpolated color. ( quadratic )
     529             :                 /** \param c1: first color to interpolate with
     530             :                 \param c2: second color to interpolate with
     531             :                 \param d: value between 0.0f and 1.0f. */
     532             :                 inline SColorf getInterpolated_quadratic(const SColorf& c1, const SColorf& c2,
     533             :                                 f32 d) const
     534             :                 {
     535             :                         d = core::clamp(d, 0.f, 1.f);
     536             :                         // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
     537             :                         const f32 inv = 1.f - d;
     538             :                         const f32 mul0 = inv * inv;
     539             :                         const f32 mul1 = 2.f * d * inv;
     540             :                         const f32 mul2 = d * d;
     541             : 
     542             :                         return SColorf (r * mul0 + c1.r * mul1 + c2.r * mul2,
     543             :                                         g * mul0 + c1.g * mul1 + c2.g * mul2,
     544             :                                         b * mul0 + c1.b * mul1 + c2.b * mul2,
     545             :                                         a * mul0 + c1.a * mul1 + c2.a * mul2);
     546             :                 }
     547             : 
     548             : 
     549             :                 //! Sets a color component by index. R=0, G=1, B=2, A=3
     550             :                 void setColorComponentValue(s32 index, f32 value)
     551             :                 {
     552             :                         switch(index)
     553             :                         {
     554             :                         case 0: r = value; break;
     555             :                         case 1: g = value; break;
     556             :                         case 2: b = value; break;
     557             :                         case 3: a = value; break;
     558             :                         }
     559             :                 }
     560             : 
     561             :                 //! Returns the alpha component of the color in the range 0.0 (transparent) to 1.0 (opaque)
     562             :                 f32 getAlpha() const { return a; }
     563             : 
     564             :                 //! Returns the red component of the color in the range 0.0 to 1.0
     565             :                 f32 getRed() const { return r; }
     566             : 
     567             :                 //! Returns the green component of the color in the range 0.0 to 1.0
     568             :                 f32 getGreen() const { return g; }
     569             : 
     570             :                 //! Returns the blue component of the color in the range 0.0 to 1.0
     571             :                 f32 getBlue() const { return b; }
     572             : 
     573             :                 //! red color component
     574             :                 f32 r;
     575             : 
     576             :                 //! green color component
     577             :                 f32 g;
     578             : 
     579             :                 //! blue component
     580             :                 f32 b;
     581             : 
     582             :                 //! alpha color component
     583             :                 f32 a;
     584             :         };
     585             : 
     586             : 
     587             :         //! Class representing a color in HSL format
     588             :         /** The color values for hue, saturation, luminance
     589             :         are stored in 32bit floating point variables. Hue is in range [0,360],
     590             :         Luminance and Saturation are in percent [0,100]
     591             :         */
     592             :         class SColorHSL
     593             :         {
     594             :         public:
     595             :                 SColorHSL ( f32 h = 0.f, f32 s = 0.f, f32 l = 0.f )
     596             :                         : Hue ( h ), Saturation ( s ), Luminance ( l ) {}
     597             : 
     598             :                 void fromRGB(const SColorf &color);
     599             :                 void toRGB(SColorf &color) const;
     600             : 
     601             :                 f32 Hue;
     602             :                 f32 Saturation;
     603             :                 f32 Luminance;
     604             : 
     605             :         private:
     606             :                 inline f32 toRGB1(f32 rm1, f32 rm2, f32 rh) const;
     607             : 
     608             :         };
     609             : 
     610             :         inline void SColorHSL::fromRGB(const SColorf &color)
     611             :         {
     612             :                 const f32 maxVal = core::max_(color.getRed(), color.getGreen(), color.getBlue());
     613             :                 const f32 minVal = (f32)core::min_(color.getRed(), color.getGreen(), color.getBlue());
     614             :                 Luminance = (maxVal+minVal)*50;
     615             :                 if (core::equals(maxVal, minVal))
     616             :                 {
     617             :                         Hue=0.f;
     618             :                         Saturation=0.f;
     619             :                         return;
     620             :                 }
     621             : 
     622             :                 const f32 delta = maxVal-minVal;
     623             :                 if ( Luminance <= 50 )
     624             :                 {
     625             :                         Saturation = (delta)/(maxVal+minVal);
     626             :                 }
     627             :                 else
     628             :                 {
     629             :                         Saturation = (delta)/(2-maxVal-minVal);
     630             :                 }
     631             :                 Saturation *= 100;
     632             : 
     633             :                 if (core::equals(maxVal, color.getRed()))
     634             :                         Hue = (color.getGreen()-color.getBlue())/delta;
     635             :                 else if (core::equals(maxVal, color.getGreen()))
     636             :                         Hue = 2+((color.getBlue()-color.getRed())/delta);
     637             :                 else // blue is max
     638             :                         Hue = 4+((color.getRed()-color.getGreen())/delta);
     639             : 
     640             :                 Hue *= 60.0f;
     641             :                 while ( Hue < 0.f )
     642             :                         Hue += 360;
     643             :         }
     644             : 
     645             : 
     646             :         inline void SColorHSL::toRGB(SColorf &color) const
     647             :         {
     648             :                 const f32 l = Luminance/100;
     649             :                 if (core::iszero(Saturation)) // grey
     650             :                 {
     651             :                         color.set(l, l, l);
     652             :                         return;
     653             :                 }
     654             : 
     655             :                 f32 rm2;
     656             : 
     657             :                 if ( Luminance <= 50 )
     658             :                 {
     659             :                         rm2 = l + l * (Saturation/100);
     660             :                 }
     661             :                 else
     662             :                 {
     663             :                         rm2 = l + (1 - l) * (Saturation/100);
     664             :                 }
     665             : 
     666             :                 const f32 rm1 = 2.0f * l - rm2;
     667             : 
     668             :                 const f32 h = Hue / 360.0f;
     669             :                 color.set( toRGB1(rm1, rm2, h + 1.f/3.f),
     670             :                         toRGB1(rm1, rm2, h),
     671             :                         toRGB1(rm1, rm2, h - 1.f/3.f)
     672             :                         );
     673             :         }
     674             : 
     675             : 
     676             :         // algorithm from Foley/Van-Dam
     677             :         inline f32 SColorHSL::toRGB1(f32 rm1, f32 rm2, f32 rh) const
     678             :         {
     679             :                 if (rh<0)
     680             :                         rh += 1;
     681             :                 if (rh>1)
     682             :                         rh -= 1;
     683             : 
     684             :                 if (rh < 1.f/6.f)
     685             :                         rm1 = rm1 + (rm2 - rm1) * rh*6.f;
     686             :                 else if (rh < 0.5f)
     687             :                         rm1 = rm2;
     688             :                 else if (rh < 2.f/3.f)
     689             :                         rm1 = rm1 + (rm2 - rm1) * ((2.f/3.f)-rh)*6.f;
     690             : 
     691             :                 return rm1;
     692             :         }
     693             : 
     694             : } // end namespace video
     695             : } // end namespace irr
     696             : 
     697             : #endif

Generated by: LCOV version 1.11