aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/include/SColor.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/include/SColor.h')
-rw-r--r--src/others/irrlicht-1.8.1/include/SColor.h697
1 files changed, 697 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/include/SColor.h b/src/others/irrlicht-1.8.1/include/SColor.h
new file mode 100644
index 0000000..b61bbef
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/include/SColor.h
@@ -0,0 +1,697 @@
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
11namespace irr
12{
13namespace 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 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 SColor (u32 a, u32 r, u32 g, u32 b)
212 : 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 SColor(u32 clr)
216 : 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 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 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 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 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 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 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 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 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 void set(u32 a, u32 r, u32 g, u32 b)
308 {
309 color = (((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff));
310 }
311 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 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 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 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 SColor getInterpolated(const SColor &other, f32 d) const
341 {
342 d = core::clamp(d, 0.f, 1.f);
343 const f32 inv = 1.0f - d;
344 return SColor((u32)core::round32(other.getAlpha()*inv + getAlpha()*d),
345 (u32)core::round32(other.getRed()*inv + getRed()*d),
346 (u32)core::round32(other.getGreen()*inv + getGreen()*d),
347 (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 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 d = core::clamp(d, 0.f, 1.f);
358 const f32 inv = 1.f - d;
359 const f32 mul0 = inv * inv;
360 const f32 mul1 = 2.f * d * inv;
361 const f32 mul2 = d * d;
362
363 return SColor(
364 core::clamp( core::floor32(
365 getAlpha() * mul0 + c1.getAlpha() * mul1 + c2.getAlpha() * mul2 ), 0, 255 ),
366 core::clamp( core::floor32(
367 getRed() * mul0 + c1.getRed() * mul1 + c2.getRed() * mul2 ), 0, 255 ),
368 core::clamp ( core::floor32(
369 getGreen() * mul0 + c1.getGreen() * mul1 + c2.getGreen() * mul2 ), 0, 255 ),
370 core::clamp ( core::floor32(
371 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 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 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 SColorf(SColor c)
482 {
483 const f32 inv = 1.0f / 255.0f;
484 r = c.getRed() * inv;
485 g = c.getGreen() * inv;
486 b = c.getBlue() * inv;
487 a = c.getAlpha() * inv;
488 }
489
490 //! Converts this color to a SColor without floats.
491 SColor toSColor() const
492 {
493 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 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 SColorf getInterpolated(const SColorf &other, f32 d) const
521 {
522 d = core::clamp(d, 0.f, 1.f);
523 const f32 inv = 1.0f - d;
524 return SColorf(other.r*inv + r*d,
525 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