1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #ifndef __COLOR_H_INCLUDED__
\r
6 #define __COLOR_H_INCLUDED__
\r
8 #include "irrTypes.h"
\r
15 //! An enum for the color format of textures used by the Irrlicht Engine.
\r
16 /** A color format specifies how color information is stored.
\r
17 NOTE: Byte order in memory is usually flipped (it's probably correct in bitmap files, but flipped on reading).
\r
18 So for example ECF_A8R8G8B8 is BGRA in memory same as in DX9's D3DFMT_A8R8G8B8 format.
\r
22 //! 16 bit color format used by the software driver.
\r
23 /** It is thus preferred by all other irrlicht engine video drivers.
\r
24 There are 5 bits for every color component, and a single bit is left
\r
25 for alpha information. */
\r
28 //! Standard 16 bit color format.
\r
31 //! 24 bit color, no alpha channel, but 8 bit for red, green and blue.
\r
32 //! Warning: 24 bit formats tend to be badly supported. Depending on driver it's usually converted to another
\r
33 // format or even not working at all. It's mostly better to use 16-bit or 32-bit formats.
\r
36 //! Default 32 bit color format. 8 bits are used for every component: red, green, blue and alpha.
\r
37 //! Warning: This tends to be BGRA in memory (it's ARGB on file, but with usual big-endian memory it's flipped)
\r
40 /** Compressed image formats. **/
\r
42 //! DXT1 color format.
\r
45 //! DXT2 color format.
\r
48 //! DXT3 color format.
\r
51 //! DXT4 color format.
\r
54 //! DXT5 color format.
\r
60 //! PVRTC ARGB 2bpp.
\r
66 //! PVRTC ARGB 4bpp.
\r
69 //! PVRTC2 ARGB 2bpp.
\r
72 //! PVRTC2 ARGB 4bpp.
\r
84 /** The following formats may only be used for render target textures. */
\r
86 /** Floating point formats. */
\r
88 //! 16 bit format using 16 bits for the red channel.
\r
91 //! 32 bit format using 16 bits for the red and green channels.
\r
94 //! 64 bit format using 16 bits for the red, green, blue and alpha channels.
\r
97 //! 32 bit format using 32 bits for the red channel.
\r
100 //! 64 bit format using 32 bits for the red and green channels.
\r
103 //! 128 bit format using 32 bits for the red, green, blue and alpha channels.
\r
106 /** Unsigned normalized integer formats. */
\r
108 //! 8 bit format using 8 bits for the red channel.
\r
111 //! 16 bit format using 8 bits for the red and green channels.
\r
114 //! 16 bit format using 16 bits for the red channel.
\r
117 //! 32 bit format using 16 bits for the red and green channels.
\r
120 /** Depth and stencil formats. */
\r
122 //! 16 bit format using 16 bits for depth.
\r
125 //! 32 bit format using 32 bits for depth.
\r
128 //! 32 bit format using 24 bits for depth and 8 bits for stencil.
\r
131 //! Unknown color format:
\r
135 //! Names for ECOLOR_FORMAT types
\r
136 const c8* const ColorFormatNames[ECF_UNKNOWN+2] =
\r
174 //! Creates a 16 bit A1R5G5B5 color
\r
175 inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a=0xFF)
\r
177 return (u16)((a & 0x80) << 8 |
\r
184 //! Creates a 16 bit A1R5G5B5 color
\r
185 inline u16 RGB16(u32 r, u32 g, u32 b)
\r
187 return RGBA16(r,g,b);
\r
191 //! Creates a 16bit A1R5G5B5 color, based on 16bit input values
\r
192 inline u16 RGB16from16(u16 r, u16 g, u16 b)
\r
201 //! Converts a 32bit (X8R8G8B8) color to a 16bit A1R5G5B5 color
\r
202 inline u16 X8R8G8B8toA1R5G5B5(u32 color)
\r
204 return (u16)(0x8000 |
\r
205 ( color & 0x00F80000) >> 9 |
\r
206 ( color & 0x0000F800) >> 6 |
\r
207 ( color & 0x000000F8) >> 3);
\r
211 //! Converts a 32bit (A8R8G8B8) color to a 16bit A1R5G5B5 color
\r
212 inline u16 A8R8G8B8toA1R5G5B5(u32 color)
\r
214 return (u16)(( color & 0x80000000) >> 16|
\r
215 ( color & 0x00F80000) >> 9 |
\r
216 ( color & 0x0000F800) >> 6 |
\r
217 ( color & 0x000000F8) >> 3);
\r
221 //! Converts a 32bit (A8R8G8B8) color to a 16bit R5G6B5 color
\r
222 inline u16 A8R8G8B8toR5G6B5(u32 color)
\r
224 return (u16)(( color & 0x00F80000) >> 8 |
\r
225 ( color & 0x0000FC00) >> 5 |
\r
226 ( color & 0x000000F8) >> 3);
\r
230 //! Convert A8R8G8B8 Color from A1R5G5B5 color
\r
231 /** build a nicer 32bit Color by extending dest lower bits with source high bits. */
\r
232 inline u32 A1R5G5B5toA8R8G8B8(u16 color)
\r
234 return ( (( -( (s32) color & 0x00008000 ) >> (s32) 31 ) & 0xFF000000 ) |
\r
235 (( color & 0x00007C00 ) << 9) | (( color & 0x00007000 ) << 4) |
\r
236 (( color & 0x000003E0 ) << 6) | (( color & 0x00000380 ) << 1) |
\r
237 (( color & 0x0000001F ) << 3) | (( color & 0x0000001C ) >> 2)
\r
242 //! Returns A8R8G8B8 Color from R5G6B5 color
\r
243 inline u32 R5G6B5toA8R8G8B8(u16 color)
\r
245 return 0xFF000000 |
\r
246 ((color & 0xF800) << 8)|
\r
247 ((color & 0x07E0) << 5)|
\r
248 ((color & 0x001F) << 3);
\r
252 //! Returns A1R5G5B5 Color from R5G6B5 color
\r
253 inline u16 R5G6B5toA1R5G5B5(u16 color)
\r
255 return 0x8000 | (((color & 0xFFC0) >> 1) | (color & 0x1F));
\r
259 //! Returns R5G6B5 Color from A1R5G5B5 color
\r
260 inline u16 A1R5G5B5toR5G6B5(u16 color)
\r
262 return (((color & 0x7FE0) << 1) | (color & 0x1F));
\r
267 //! Returns the alpha component from A1R5G5B5 color
\r
268 /** In Irrlicht, alpha refers to opacity.
\r
269 \return The alpha value of the color. 0 is transparent, 1 is opaque. */
\r
270 inline u32 getAlpha(u16 color)
\r
272 return ((color >> 15)&0x1);
\r
276 //! Returns the red component from A1R5G5B5 color.
\r
277 /** Shift left by 3 to get 8 bit value. */
\r
278 inline u32 getRed(u16 color)
\r
280 return ((color >> 10)&0x1F);
\r
284 //! Returns the green component from A1R5G5B5 color
\r
285 /** Shift left by 3 to get 8 bit value. */
\r
286 inline u32 getGreen(u16 color)
\r
288 return ((color >> 5)&0x1F);
\r
292 //! Returns the blue component from A1R5G5B5 color
\r
293 /** Shift left by 3 to get 8 bit value. */
\r
294 inline u32 getBlue(u16 color)
\r
296 return (color & 0x1F);
\r
300 //! Returns the average from a 16 bit A1R5G5B5 color
\r
301 inline s32 getAverage(s16 color)
\r
303 return ((getRed(color)<<3) + (getGreen(color)<<3) + (getBlue(color)<<3)) / 3;
\r
307 //! Class representing a 32 bit ARGB color.
\r
308 /** The color values for alpha, red, green, and blue are
\r
309 stored in a single u32. So all four values may be between 0 and 255.
\r
310 Alpha in Irrlicht is opacity, so 0 is fully transparent, 255 is fully opaque (solid).
\r
311 This class is used by most parts of the Irrlicht Engine
\r
312 to specify a color. Another way is using the class SColorf, which
\r
313 stores the color values in 4 floats.
\r
314 This class must consist of only one u32 and must not use virtual functions.
\r
320 //! Constructor of the Color. Does nothing.
\r
321 /** The color value is not initialized to save time. */
\r
324 //! Constructs the color from 4 values representing the alpha, red, green and blue component.
\r
325 /** Must be values between 0 and 255. */
\r
326 SColor (u32 a, u32 r, u32 g, u32 b)
\r
327 : color(((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff)) {}
\r
329 //! Constructs the color from a 32 bit value. Could be another color.
\r
333 //! Returns the alpha component of the color.
\r
334 /** The alpha component defines how opaque a color is.
\r
335 \return The alpha value of the color. 0 is fully transparent, 255 is fully opaque. */
\r
336 u32 getAlpha() const { return color>>24; }
\r
338 //! Returns the red component of the color.
\r
339 /** \return Value between 0 and 255, specifying how red the color is.
\r
340 0 means no red, 255 means full red. */
\r
341 u32 getRed() const { return (color>>16) & 0xff; }
\r
343 //! Returns the green component of the color.
\r
344 /** \return Value between 0 and 255, specifying how green the color is.
\r
345 0 means no green, 255 means full green. */
\r
346 u32 getGreen() const { return (color>>8) & 0xff; }
\r
348 //! Returns the blue component of the color.
\r
349 /** \return Value between 0 and 255, specifying how blue the color is.
\r
350 0 means no blue, 255 means full blue. */
\r
351 u32 getBlue() const { return color & 0xff; }
\r
353 //! Get lightness of the color in the range [0,255]
\r
354 f32 getLightness() const
\r
356 return 0.5f*(core::max_(core::max_(getRed(),getGreen()),getBlue())+core::min_(core::min_(getRed(),getGreen()),getBlue()));
\r
359 //! Get luminance of the color in the range [0,255].
\r
360 f32 getLuminance() const
\r
362 return 0.3f*getRed() + 0.59f*getGreen() + 0.11f*getBlue();
\r
365 //! Get average intensity of the color in the range [0,255].
\r
366 u32 getAverage() const
\r
368 return ( getRed() + getGreen() + getBlue() ) / 3;
\r
371 //! Sets the alpha component of the Color.
\r
372 /** The alpha component defines how transparent a color should be.
\r
373 \param a The alpha value of the color. 0 is fully transparent, 255 is fully opaque. */
\r
374 void setAlpha(u32 a) { color = ((a & 0xff)<<24) | (color & 0x00ffffff); }
\r
376 //! Sets the red component of the Color.
\r
377 /** \param r: Has to be a value between 0 and 255.
\r
378 0 means no red, 255 means full red. */
\r
379 void setRed(u32 r) { color = ((r & 0xff)<<16) | (color & 0xff00ffff); }
\r
381 //! Sets the green component of the Color.
\r
382 /** \param g: Has to be a value between 0 and 255.
\r
383 0 means no green, 255 means full green. */
\r
384 void setGreen(u32 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); }
\r
386 //! Sets the blue component of the Color.
\r
387 /** \param b: Has to be a value between 0 and 255.
\r
388 0 means no blue, 255 means full blue. */
\r
389 void setBlue(u32 b) { color = (b & 0xff) | (color & 0xffffff00); }
\r
391 //! Calculates a 16 bit A1R5G5B5 value of this color.
\r
392 /** \return 16 bit A1R5G5B5 value of this color. */
\r
393 u16 toA1R5G5B5() const { return A8R8G8B8toA1R5G5B5(color); }
\r
395 //! Converts color to OpenGL color format
\r
396 /** From ARGB to RGBA in 4 byte components for endian aware
\r
398 \param dest: address where the 4x8 bit OpenGL color is stored. */
\r
399 void toOpenGLColor(u8* dest) const
\r
401 *dest = (u8)getRed();
\r
402 *++dest = (u8)getGreen();
\r
403 *++dest = (u8)getBlue();
\r
404 *++dest = (u8)getAlpha();
\r
407 //! Sets all four components of the color at once.
\r
408 /** Constructs the color from 4 values representing the alpha,
\r
409 red, green and blue components of the color. Must be values
\r
411 \param a: Alpha component of the color. The alpha component
\r
412 defines how transparent a color should be. Has to be a value
\r
413 between 0 and 255. 255 means not transparent (opaque), 0 means
\r
415 \param r: Sets the red component of the Color. Has to be a
\r
416 value between 0 and 255. 0 means no red, 255 means full red.
\r
417 \param g: Sets the green component of the Color. Has to be a
\r
418 value between 0 and 255. 0 means no green, 255 means full
\r
420 \param b: Sets the blue component of the Color. Has to be a
\r
421 value between 0 and 255. 0 means no blue, 255 means full blue. */
\r
422 void set(u32 a, u32 r, u32 g, u32 b)
\r
424 color = (((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff));
\r
426 void set(u32 col) { color = col; }
\r
428 //! Compares the color to another color.
\r
429 /** \return True if the colors are the same, and false if not. */
\r
430 bool operator==(const SColor& other) const { return other.color == color; }
\r
432 //! Compares the color to another color.
\r
433 /** \return True if the colors are different, and false if they are the same. */
\r
434 bool operator!=(const SColor& other) const { return other.color != color; }
\r
436 //! comparison operator
\r
437 /** \return True if this color is smaller than the other one */
\r
438 bool operator<(const SColor& other) const { return (color < other.color); }
\r
440 //! Adds two colors, result is clamped to 0..255 values
\r
441 /** \param other Color to add to this color
\r
442 \return Addition of the two colors, clamped to 0..255 values */
\r
443 SColor operator+(const SColor& other) const
\r
445 return SColor(core::min_(getAlpha() + other.getAlpha(), 255u),
\r
446 core::min_(getRed() + other.getRed(), 255u),
\r
447 core::min_(getGreen() + other.getGreen(), 255u),
\r
448 core::min_(getBlue() + other.getBlue(), 255u));
\r
451 //! Interpolates the color with a f32 value to another color
\r
452 /** \param other: Other color
\r
453 \param d: value between 0.0f and 1.0f. d=0 returns other, d=1 returns this, values between interpolate.
\r
454 \return Interpolated color. */
\r
455 SColor getInterpolated(const SColor &other, f32 d) const
\r
457 d = core::clamp(d, 0.f, 1.f);
\r
458 const f32 inv = 1.0f - d;
\r
459 return SColor((u32)core::round32(other.getAlpha()*inv + getAlpha()*d),
\r
460 (u32)core::round32(other.getRed()*inv + getRed()*d),
\r
461 (u32)core::round32(other.getGreen()*inv + getGreen()*d),
\r
462 (u32)core::round32(other.getBlue()*inv + getBlue()*d));
\r
465 //! Returns interpolated color. ( quadratic )
\r
466 /** \param c1: first color to interpolate with
\r
467 \param c2: second color to interpolate with
\r
468 \param d: value between 0.0f and 1.0f. */
\r
469 SColor getInterpolated_quadratic(const SColor& c1, const SColor& c2, f32 d) const
\r
471 // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
\r
472 d = core::clamp(d, 0.f, 1.f);
\r
473 const f32 inv = 1.f - d;
\r
474 const f32 mul0 = inv * inv;
\r
475 const f32 mul1 = 2.f * d * inv;
\r
476 const f32 mul2 = d * d;
\r
479 core::clamp( core::floor32(
\r
480 getAlpha() * mul0 + c1.getAlpha() * mul1 + c2.getAlpha() * mul2 ), 0, 255 ),
\r
481 core::clamp( core::floor32(
\r
482 getRed() * mul0 + c1.getRed() * mul1 + c2.getRed() * mul2 ), 0, 255 ),
\r
483 core::clamp ( core::floor32(
\r
484 getGreen() * mul0 + c1.getGreen() * mul1 + c2.getGreen() * mul2 ), 0, 255 ),
\r
485 core::clamp ( core::floor32(
\r
486 getBlue() * mul0 + c1.getBlue() * mul1 + c2.getBlue() * mul2 ), 0, 255 ));
\r
489 //! set the color by expecting data in the given format
\r
490 /** \param data: must point to valid memory containing color information in the given format
\r
491 \param format: tells the format in which data is available
\r
493 void setData(const void *data, ECOLOR_FORMAT format)
\r
498 color = A1R5G5B5toA8R8G8B8(*(u16*)data);
\r
501 color = R5G6B5toA8R8G8B8(*(u16*)data);
\r
504 color = *(u32*)data;
\r
508 const u8* p = (u8*)data;
\r
509 set(255, p[0],p[1],p[2]);
\r
513 color = 0xffffffff;
\r
518 //! Write the color to data in the defined format
\r
519 /** \param data: target to write the color. Must contain sufficiently large memory to receive the number of bytes neede for format
\r
520 \param format: tells the format used to write the color into data
\r
522 void getData(void *data, ECOLOR_FORMAT format) const
\r
528 u16 * dest = (u16*)data;
\r
529 *dest = video::A8R8G8B8toA1R5G5B5( color );
\r
535 u16 * dest = (u16*)data;
\r
536 *dest = video::A8R8G8B8toR5G6B5( color );
\r
542 u8* dest = (u8*)data;
\r
543 dest[0] = (u8)getRed();
\r
544 dest[1] = (u8)getGreen();
\r
545 dest[2] = (u8)getBlue();
\r
551 u32 * dest = (u32*)data;
\r
561 //! color in A8R8G8B8 Format
\r
566 //! Class representing a color with four floats.
\r
567 /** The color values for red, green, blue
\r
568 and alpha are each stored in a 32 bit floating point variable.
\r
569 So all four values may be between 0.0f and 1.0f.
\r
570 Another, faster way to define colors is using the class SColor, which
\r
571 stores the color values in a single 32 bit integer.
\r
576 //! Default constructor for SColorf.
\r
577 /** Sets red, green and blue to 0.0f and alpha to 1.0f. */
\r
578 SColorf() : r(0.0f), g(0.0f), b(0.0f), a(1.0f) {}
\r
580 //! Constructs a color from up to four color values: red, green, blue, and alpha.
\r
581 /** \param r: Red color component. Should be a value between
\r
582 0.0f meaning no red and 1.0f, meaning full red.
\r
583 \param g: Green color component. Should be a value between 0.0f
\r
584 meaning no green and 1.0f, meaning full green.
\r
585 \param b: Blue color component. Should be a value between 0.0f
\r
586 meaning no blue and 1.0f, meaning full blue.
\r
587 \param a: Alpha color component of the color. The alpha
\r
588 component defines how transparent a color should be. Has to be
\r
589 a value between 0.0f and 1.0f, 1.0f means not transparent
\r
590 (opaque), 0.0f means fully transparent. */
\r
591 SColorf(f32 r, f32 g, f32 b, f32 a = 1.0f) : r(r), g(g), b(b), a(a) {}
\r
593 //! Constructs a color from 32 bit Color.
\r
594 /** \param c: 32 bit color from which this SColorf class is
\r
595 constructed from. */
\r
598 const f32 inv = 1.0f / 255.0f;
\r
599 r = c.getRed() * inv;
\r
600 g = c.getGreen() * inv;
\r
601 b = c.getBlue() * inv;
\r
602 a = c.getAlpha() * inv;
\r
605 //! Converts this color to a SColor without floats.
\r
606 SColor toSColor() const
\r
608 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));
\r
611 //! Sets three color components to new values at once.
\r
612 /** \param rr: Red color component. Should be a value between 0.0f meaning
\r
613 no red (=black) and 1.0f, meaning full red.
\r
614 \param gg: Green color component. Should be a value between 0.0f meaning
\r
615 no green (=black) and 1.0f, meaning full green.
\r
616 \param bb: Blue color component. Should be a value between 0.0f meaning
\r
617 no blue (=black) and 1.0f, meaning full blue. */
\r
618 void set(f32 rr, f32 gg, f32 bb) {r = rr; g =gg; b = bb; }
\r
620 //! Sets all four color components to new values at once.
\r
621 /** \param aa: Alpha component. Should be a value between 0.0f meaning
\r
622 fully transparent and 1.0f, meaning opaque.
\r
623 \param rr: Red color component. Should be a value between 0.0f meaning
\r
624 no red and 1.0f, meaning full red.
\r
625 \param gg: Green color component. Should be a value between 0.0f meaning
\r
626 no green and 1.0f, meaning full green.
\r
627 \param bb: Blue color component. Should be a value between 0.0f meaning
\r
628 no blue and 1.0f, meaning full blue. */
\r
629 void set(f32 aa, f32 rr, f32 gg, f32 bb) {a = aa; r = rr; g =gg; b = bb; }
\r
631 //! Interpolates the color with a f32 value to another color
\r
632 /** \param other: Other color
\r
633 \param d: value between 0.0f and 1.0f
\r
634 \return Interpolated color. */
\r
635 SColorf getInterpolated(const SColorf &other, f32 d) const
\r
637 d = core::clamp(d, 0.f, 1.f);
\r
638 const f32 inv = 1.0f - d;
\r
639 return SColorf(other.r*inv + r*d,
\r
640 other.g*inv + g*d, other.b*inv + b*d, other.a*inv + a*d);
\r
643 //! Returns interpolated color. ( quadratic )
\r
644 /** \param c1: first color to interpolate with
\r
645 \param c2: second color to interpolate with
\r
646 \param d: value between 0.0f and 1.0f. */
\r
647 inline SColorf getInterpolated_quadratic(const SColorf& c1, const SColorf& c2,
\r
650 d = core::clamp(d, 0.f, 1.f);
\r
651 // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
\r
652 const f32 inv = 1.f - d;
\r
653 const f32 mul0 = inv * inv;
\r
654 const f32 mul1 = 2.f * d * inv;
\r
655 const f32 mul2 = d * d;
\r
657 return SColorf (r * mul0 + c1.r * mul1 + c2.r * mul2,
\r
658 g * mul0 + c1.g * mul1 + c2.g * mul2,
\r
659 b * mul0 + c1.b * mul1 + c2.b * mul2,
\r
660 a * mul0 + c1.a * mul1 + c2.a * mul2);
\r
664 //! Sets a color component by index. R=0, G=1, B=2, A=3
\r
665 void setColorComponentValue(s32 index, f32 value)
\r
669 case 0: r = value; break;
\r
670 case 1: g = value; break;
\r
671 case 2: b = value; break;
\r
672 case 3: a = value; break;
\r
676 //! Returns the alpha component of the color in the range 0.0 (transparent) to 1.0 (opaque)
\r
677 f32 getAlpha() const { return a; }
\r
679 //! Returns the red component of the color in the range 0.0 to 1.0
\r
680 f32 getRed() const { return r; }
\r
682 //! Returns the green component of the color in the range 0.0 to 1.0
\r
683 f32 getGreen() const { return g; }
\r
685 //! Returns the blue component of the color in the range 0.0 to 1.0
\r
686 f32 getBlue() const { return b; }
\r
688 //! red color component
\r
691 //! green color component
\r
697 //! alpha color component
\r
702 //! Class representing a color in HSL format
\r
703 /** The color values for hue, saturation, luminance
\r
704 are stored in 32bit floating point variables. Hue is in range [0,360],
\r
705 Luminance and Saturation are in percent [0,100]
\r
710 SColorHSL ( f32 h = 0.f, f32 s = 0.f, f32 l = 0.f )
\r
711 : Hue ( h ), Saturation ( s ), Luminance ( l ) {}
\r
713 void fromRGB(const SColorf &color);
\r
714 void toRGB(SColorf &color) const;
\r
721 inline f32 toRGB1(f32 rm1, f32 rm2, f32 rh) const;
\r
725 inline void SColorHSL::fromRGB(const SColorf &color)
\r
727 const f32 maxVal = core::max_(color.getRed(), color.getGreen(), color.getBlue());
\r
728 const f32 minVal = (f32)core::min_(color.getRed(), color.getGreen(), color.getBlue());
\r
729 Luminance = (maxVal+minVal)*50;
\r
730 if (core::equals(maxVal, minVal))
\r
737 const f32 delta = maxVal-minVal;
\r
738 if ( Luminance <= 50 )
\r
740 Saturation = (delta)/(maxVal+minVal);
\r
744 Saturation = (delta)/(2-maxVal-minVal);
\r
748 if (core::equals(maxVal, color.getRed()))
\r
749 Hue = (color.getGreen()-color.getBlue())/delta;
\r
750 else if (core::equals(maxVal, color.getGreen()))
\r
751 Hue = 2+((color.getBlue()-color.getRed())/delta);
\r
752 else // blue is max
\r
753 Hue = 4+((color.getRed()-color.getGreen())/delta);
\r
756 while ( Hue < 0.f )
\r
761 inline void SColorHSL::toRGB(SColorf &color) const
\r
763 const f32 l = Luminance/100;
\r
764 if (core::iszero(Saturation)) // grey
\r
766 color.set(l, l, l);
\r
772 if ( Luminance <= 50 )
\r
774 rm2 = l + l * (Saturation/100);
\r
778 rm2 = l + (1 - l) * (Saturation/100);
\r
781 const f32 rm1 = 2.0f * l - rm2;
\r
783 const f32 h = Hue / 360.0f;
\r
784 color.set( toRGB1(rm1, rm2, h + 1.f/3.f),
\r
785 toRGB1(rm1, rm2, h),
\r
786 toRGB1(rm1, rm2, h - 1.f/3.f)
\r
791 // algorithm from Foley/Van-Dam
\r
792 inline f32 SColorHSL::toRGB1(f32 rm1, f32 rm2, f32 rh) const
\r
800 rm1 = rm1 + (rm2 - rm1) * rh*6.f;
\r
801 else if (rh < 0.5f)
\r
803 else if (rh < 2.f/3.f)
\r
804 rm1 = rm1 + (rm2 - rm1) * ((2.f/3.f)-rh)*6.f;
\r
809 } // end namespace video
\r
810 } // end namespace irr
\r