Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members | Tutorials
SColor.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2010 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 {
16  inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a=0xFF)
17  {
18  return (u16)((a & 0x80) << 8 |
19  (r & 0xF8) << 7 |
20  (g & 0xF8) << 2 |
21  (b & 0xF8) >> 3);
22  }
23 
24 
26  inline u16 RGB16(u32 r, u32 g, u32 b)
27  {
28  return RGBA16(r,g,b);
29  }
30 
31 
33  inline u16 RGB16from16(u16 r, u16 g, u16 b)
34  {
35  return (0x8000 |
36  (r & 0x1F) << 10 |
37  (g & 0x1F) << 5 |
38  (b & 0x1F));
39  }
40 
41 
43  inline u16 X8R8G8B8toA1R5G5B5(u32 color)
44  {
45  return (u16)(0x8000 |
46  ( color & 0x00F80000) >> 9 |
47  ( color & 0x0000F800) >> 6 |
48  ( color & 0x000000F8) >> 3);
49  }
50 
51 
53  inline u16 A8R8G8B8toA1R5G5B5(u32 color)
54  {
55  return (u16)(( color & 0x80000000) >> 16|
56  ( color & 0x00F80000) >> 9 |
57  ( color & 0x0000F800) >> 6 |
58  ( color & 0x000000F8) >> 3);
59  }
60 
61 
63  inline u16 A8R8G8B8toR5G6B5(u32 color)
64  {
65  return (u16)(( color & 0x00F80000) >> 8 |
66  ( color & 0x0000FC00) >> 5 |
67  ( color & 0x000000F8) >> 3);
68  }
69 
70 
72 
73  inline u32 A1R5G5B5toA8R8G8B8(u16 color)
74  {
75  return ( (( -( (s32) color & 0x00008000 ) >> (s32) 31 ) & 0xFF000000 ) |
76  (( color & 0x00007C00 ) << 9) | (( color & 0x00007000 ) << 4) |
77  (( color & 0x000003E0 ) << 6) | (( color & 0x00000380 ) << 1) |
78  (( color & 0x0000001F ) << 3) | (( color & 0x0000001C ) >> 2)
79  );
80  }
81 
82 
84  inline u32 R5G6B5toA8R8G8B8(u16 color)
85  {
86  return 0xFF000000 |
87  ((color & 0xF800) << 8)|
88  ((color & 0x07E0) << 5)|
89  ((color & 0x001F) << 3);
90  }
91 
92 
94  inline u16 R5G6B5toA1R5G5B5(u16 color)
95  {
96  return 0x8000 | (((color & 0xFFC0) >> 1) | (color & 0x1F));
97  }
98 
99 
101  inline u16 A1R5G5B5toR5G6B5(u16 color)
102  {
103  return (((color & 0x7FE0) << 1) | (color & 0x1F));
104  }
105 
106 
107 
109 
111  inline u32 getAlpha(u16 color)
112  {
113  return ((color >> 15)&0x1);
114  }
115 
116 
118 
119  inline u32 getRed(u16 color)
120  {
121  return ((color >> 10)&0x1F);
122  }
123 
124 
126 
127  inline u32 getGreen(u16 color)
128  {
129  return ((color >> 5)&0x1F);
130  }
131 
132 
134 
135  inline u32 getBlue(u16 color)
136  {
137  return (color & 0x1F);
138  }
139 
140 
142  inline s32 getAverage(s16 color)
143  {
144  return ((getRed(color)<<3) + (getGreen(color)<<3) + (getBlue(color)<<3)) / 3;
145  }
146 
147 
149 
157  class SColor
158  {
159  public:
160 
162 
163  SColor() {}
164 
166 
167  SColor (u32 a, u32 r, u32 g, u32 b)
168  : color(((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff)) {}
169 
171  SColor(u32 clr)
172  : color(clr) {}
173 
175 
177  u32 getAlpha() const { return color>>24; }
178 
180 
182  u32 getRed() const { return (color>>16) & 0xff; }
183 
185 
187  u32 getGreen() const { return (color>>8) & 0xff; }
188 
190 
192  u32 getBlue() const { return color & 0xff; }
193 
196  {
198  }
199 
202  {
203  return 0.3f*getRed() + 0.59f*getGreen() + 0.11f*getBlue();
204  }
205 
207  u32 getAverage() const
208  {
209  return ( getRed() + getGreen() + getBlue() ) / 3;
210  }
211 
213 
215  void setAlpha(u32 a) { color = ((a & 0xff)<<24) | (color & 0x00ffffff); }
216 
218 
220  void setRed(u32 r) { color = ((r & 0xff)<<16) | (color & 0xff00ffff); }
221 
223 
225  void setGreen(u32 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); }
226 
228 
230  void setBlue(u32 b) { color = (b & 0xff) | (color & 0xffffff00); }
231 
233 
234  u16 toA1R5G5B5() const { return A8R8G8B8toA1R5G5B5(color); }
235 
237 
240  void toOpenGLColor(u8* dest) const
241  {
242  *dest = (u8)getRed();
243  *++dest = (u8)getGreen();
244  *++dest = (u8)getBlue();
245  *++dest = (u8)getAlpha();
246  }
247 
249 
263  void set(u32 a, u32 r, u32 g, u32 b)
264  {
265  color = (((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff));
266  }
267  void set(u32 col) { color = col; }
268 
270 
271  bool operator==(const SColor& other) const { return other.color == color; }
272 
274 
275  bool operator!=(const SColor& other) const { return other.color != color; }
276 
278 
279  bool operator<(const SColor& other) const { return (color < other.color); }
280 
282 
284  SColor operator+(const SColor& other) const
285  {
286  return SColor(core::min_(getAlpha() + other.getAlpha(), 255u),
287  core::min_(getRed() + other.getRed(), 255u),
288  core::min_(getGreen() + other.getGreen(), 255u),
289  core::min_(getBlue() + other.getBlue(), 255u));
290  }
291 
293 
296  SColor getInterpolated(const SColor &other, f32 d) const
297  {
298  d = core::clamp(d, 0.f, 1.f);
299  const f32 inv = 1.0f - d;
300  return SColor((u32)core::round32(other.getAlpha()*inv + getAlpha()*d),
301  (u32)core::round32(other.getRed()*inv + getRed()*d),
302  (u32)core::round32(other.getGreen()*inv + getGreen()*d),
303  (u32)core::round32(other.getBlue()*inv + getBlue()*d));
304  }
305 
307 
310  SColor getInterpolated_quadratic(const SColor& c1, const SColor& c2, f32 d) const
311  {
312  // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
313  d = core::clamp(d, 0.f, 1.f);
314  const f32 inv = 1.f - d;
315  const f32 mul0 = inv * inv;
316  const f32 mul1 = 2.f * d * inv;
317  const f32 mul2 = d * d;
318 
319  return SColor(
321  getAlpha() * mul0 + c1.getAlpha() * mul1 + c2.getAlpha() * mul2 ), 0, 255 ),
323  getRed() * mul0 + c1.getRed() * mul1 + c2.getRed() * mul2 ), 0, 255 ),
325  getGreen() * mul0 + c1.getGreen() * mul1 + c2.getGreen() * mul2 ), 0, 255 ),
327  getBlue() * mul0 + c1.getBlue() * mul1 + c2.getBlue() * mul2 ), 0, 255 ));
328  }
329 
332  };
333 
334 
336 
342  class SColorf
343  {
344  public:
346 
347  SColorf() : r(0.0f), g(0.0f), b(0.0f), a(1.0f) {}
348 
350 
360  SColorf(f32 r, f32 g, f32 b, f32 a = 1.0f) : r(r), g(g), b(b), a(a) {}
361 
363 
366  {
367  const f32 inv = 1.0f / 255.0f;
368  r = c.getRed() * inv;
369  g = c.getGreen() * inv;
370  b = c.getBlue() * inv;
371  a = c.getAlpha() * inv;
372  }
373 
375  SColor toSColor() const
376  {
377  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));
378  }
379 
381 
387  void set(f32 rr, f32 gg, f32 bb) {r = rr; g =gg; b = bb; }
388 
390 
398  void set(f32 aa, f32 rr, f32 gg, f32 bb) {a = aa; r = rr; g =gg; b = bb; }
399 
401 
404  SColorf getInterpolated(const SColorf &other, f32 d) const
405  {
406  d = core::clamp(d, 0.f, 1.f);
407  const f32 inv = 1.0f - d;
408  return SColorf(other.r*inv + r*d,
409  other.g*inv + g*d, other.b*inv + b*d, other.a*inv + a*d);
410  }
411 
413 
416  inline SColorf getInterpolated_quadratic(const SColorf& c1, const SColorf& c2,
417  f32 d) const
418  {
419  d = core::clamp(d, 0.f, 1.f);
420  // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d;
421  const f32 inv = 1.f - d;
422  const f32 mul0 = inv * inv;
423  const f32 mul1 = 2.f * d * inv;
424  const f32 mul2 = d * d;
425 
426  return SColorf (r * mul0 + c1.r * mul1 + c2.r * mul2,
427  g * mul0 + c1.g * mul1 + c2.g * mul2,
428  b * mul0 + c1.b * mul1 + c2.b * mul2,
429  a * mul0 + c1.a * mul1 + c2.a * mul2);
430  }
431 
432 
434  void setColorComponentValue(s32 index, f32 value)
435  {
436  switch(index)
437  {
438  case 0: r = value; break;
439  case 1: g = value; break;
440  case 2: b = value; break;
441  case 3: a = value; break;
442  }
443  }
444 
446  f32 getAlpha() const { return a; }
447 
449  f32 getRed() const { return r; }
450 
452  f32 getGreen() const { return g; }
453 
455  f32 getBlue() const { return b; }
456 
459 
462 
465 
468  };
469 
470 
472 
475  class SColorHSL
476  {
477  public:
478  SColorHSL ( f32 h = 0.f, f32 s = 0.f, f32 l = 0.f )
479  : Hue ( h ), Saturation ( s ), Luminance ( l ) {}
480 
481  void fromRGB(const SColor &color);
482  void toRGB(SColor &color) const;
483 
487 
488  private:
489  inline u32 toRGB1(f32 rm1, f32 rm2, f32 rh) const;
490 
491  };
492 
493  inline void SColorHSL::fromRGB(const SColor &color)
494  {
495  const u32 maxValInt = core::max_(color.getRed(), color.getGreen(), color.getBlue());
496  const f32 maxVal = (f32)maxValInt;
497  const f32 minVal = (f32)core::min_(color.getRed(), color.getGreen(), color.getBlue());
498  Luminance = (maxVal/minVal)*0.5f;
499  if (core::equals(maxVal, minVal))
500  {
501  Hue=0.f;
502  Saturation=0.f;
503  return;
504  }
505 
506  const f32 delta = maxVal-minVal;
507  if ( Luminance <= 0.5f )
508  {
509  Saturation = (delta)/(maxVal+minVal);
510  }
511  else
512  {
513  Saturation = (delta)/(2-maxVal-minVal);
514  }
515 
516  if (maxValInt == color.getRed())
517  Hue = (color.getGreen()-color.getBlue())/delta;
518  else if (maxValInt == color.getGreen())
519  Hue = 2+(color.getBlue()-color.getRed())/delta;
520  else // blue is max
521  Hue = 4+(color.getRed()-color.getGreen())/delta;
522 
523  Hue *= (60.0f * core::DEGTORAD);
524  while ( Hue < 0.f )
525  Hue += 2.f * core::PI;
526  }
527 
528 
529  inline void SColorHSL::toRGB(SColor &color) const
530  {
531  if (core::iszero(Saturation)) // grey
532  {
533  u8 c = (u8) ( Luminance * 255.0 );
534  color.setRed(c);
535  color.setGreen(c);
536  color.setBlue(c);
537  return;
538  }
539 
540  f32 rm2;
541 
542  if ( Luminance <= 0.5f )
543  {
544  rm2 = Luminance + Luminance * Saturation;
545  }
546  else
547  {
549  }
550 
551  const f32 rm1 = 2.0f * Luminance - rm2;
552 
553  color.setRed ( toRGB1(rm1, rm2, Hue + (120.0f * core::DEGTORAD )) );
554  color.setGreen ( toRGB1(rm1, rm2, Hue) );
555  color.setBlue ( toRGB1(rm1, rm2, Hue - (120.0f * core::DEGTORAD) ) );
556  }
557 
558 
559  inline u32 SColorHSL::toRGB1(f32 rm1, f32 rm2, f32 rh) const
560  {
561  while ( rh > 2.f * core::PI )
562  rh -= 2.f * core::PI;
563 
564  while ( rh < 0.f )
565  rh += 2.f * core::PI;
566 
567  if (rh < 60.0f * core::DEGTORAD )
568  rm1 = rm1 + (rm2 - rm1) * rh / (60.0f * core::DEGTORAD);
569  else if (rh < 180.0f * core::DEGTORAD )
570  rm1 = rm2;
571  else if (rh < 240.0f * core::DEGTORAD )
572  rm1 = rm1 + (rm2 - rm1) * ( ( 240.0f * core::DEGTORAD ) - rh) /
573  (60.0f * core::DEGTORAD);
574 
575  return (u32) core::round32(rm1 * 255.f);
576  }
577 
578 } // end namespace video
579 } // end namespace irr
580 
581 #endif
582 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Tue Jun 5 2012 17:57:14 by Doxygen (1.8.1)