00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_RGBA_H
00027 #define NL_RGBA_H
00028
00029 #include "nel/misc/types_nl.h"
00030 #include "nel/misc/common.h"
00031
00032
00033 namespace NLMISC
00034 {
00035
00036 class IStream;
00037
00044 class CRGBA
00045 {
00046 public:
00047
00049 CRGBA() {};
00050
00058 CRGBA(uint8 r, uint8 g, uint8 b, uint8 a=255) :
00059 R(r), G(g), B(b), A(a) {}
00060
00064 uint getPacked() const {return ((uint)R<<24) + ((uint)G<<16) + ((uint)B<<8) + A;}
00065
00069 bool operator<(CRGBA c) const {return getPacked()<c.getPacked();}
00073 bool operator!=(CRGBA c) const {return !(*this==c);}
00074
00078 bool operator==(CRGBA c) const
00079 {return R==c.R && G==c.G && B==c.B && A==c.A;}
00080
00085 void serial (class NLMISC::IStream &f);
00086
00093 void blendFromui(CRGBA c0, CRGBA c1, uint coef)
00094 {
00095 uint a1 = coef;
00096 uint a2 = 256-a1;
00097 R = (c0.R*a2 + c1.R*a1) >>8;
00098 G = (c0.G*a2 + c1.G*a1) >>8;
00099 B = (c0.B*a2 + c1.B*a1) >>8;
00100 A = (c0.A*a2 + c1.A*a1) >>8;
00101 }
00102
00108 void modulateFromui (CRGBA c0, uint a)
00109 {
00110 R = (c0.R*a) >>8;
00111 G = (c0.G*a) >>8;
00112 B = (c0.B*a) >>8;
00113 A = (c0.A*a) >>8;
00114 }
00115
00116
00122 void modulateFromColor (CRGBA c0, CRGBA c1)
00123 {
00124 R = (c0.R*c1.R) >>8;
00125 G = (c0.G*c1.G) >>8;
00126 B = (c0.B*c1.B) >>8;
00127 A = (c0.A*c1.A) >>8;
00128 }
00129
00130
00138 void set (uint8 r, uint8 g, uint8 b, uint8 a=255);
00139
00143 uint16 get565 () const
00144 {
00145 return ((uint16)(R&0xf8)<<8) | ((uint16)(G&0xfc)<<3) | (uint16)(B>>3);
00146 }
00147
00151 void set565(uint16 col)
00152 {
00153
00154 R= col>>11;
00155 G= (col>>5)&0x3F;
00156 B= (col)&0x1F;
00157
00158 R= (R<<3) + (R>>2);
00159 G= (G<<2) + (G>>4);
00160 B= (B<<3) + (B>>2);
00161 }
00162
00163
00167 void avg2(CRGBA a, CRGBA b)
00168 {
00169 R= ((uint)a.R+(uint)b.R)>>1;
00170 G= ((uint)a.G+(uint)b.G)>>1;
00171 B= ((uint)a.B+(uint)b.B)>>1;
00172 A= ((uint)a.A+(uint)b.A)>>1;
00173 }
00174
00179 void avg4(CRGBA a, CRGBA b, CRGBA c, CRGBA d)
00180 {
00181 R= ((uint)a.R+(uint)b.R+(uint)c.R+(uint)d.R+ 1)>>2;
00182 G= ((uint)a.G+(uint)b.G+(uint)c.G+(uint)d.G+ 1)>>2;
00183 B= ((uint)a.B+(uint)b.B+(uint)c.B+(uint)d.B+ 1)>>2;
00184 A= ((uint)a.A+(uint)b.A+(uint)c.A+(uint)d.A+ 1)>>2;
00185 }
00186
00190 void add(CRGBA c0, CRGBA c1)
00191 {
00192 uint r,g,b,a;
00193 r= c0.R + c1.R; r= std::min(r, 255U); R= (uint8)r;
00194 g= c0.G + c1.G; g= std::min(g, 255U); G= (uint8)g;
00195 b= c0.B + c1.B; b= std::min(b, 255U); B= (uint8)b;
00196 a= c0.A + c1.A; a= std::min(a, 255U); A= (uint8)a;
00197 }
00198
00202 void sub(CRGBA c0, CRGBA c1)
00203 {
00204 sint r,g,b,a;
00205 r= c0.R - c1.R; r= std::max(r, 0); R= (uint8)r;
00206 g= c0.G - c1.G; g= std::max(g, 0); G= (uint8)g;
00207 b= c0.B - c1.B; b= std::max(b, 0); B= (uint8)b;
00208 a= c0.A - c1.A; a= std::max(a, 0); A= (uint8)a;
00209 }
00210
00211
00213
00214
00216 void blendFromuiRGBOnly(CRGBA c0, CRGBA c1, uint coef)
00217 {
00218 uint a1 = coef;
00219 uint a2 = 256-a1;
00220 R = (c0.R*a2 + c1.R*a1) >>8;
00221 G = (c0.G*a2 + c1.G*a1) >>8;
00222 B = (c0.B*a2 + c1.B*a1) >>8;
00223 }
00225 void modulateFromuiRGBOnly(CRGBA c0, uint a)
00226 {
00227 R = (c0.R*a) >>8;
00228 G = (c0.G*a) >>8;
00229 B = (c0.B*a) >>8;
00230 }
00232 void modulateFromColorRGBOnly(CRGBA c0, CRGBA c1)
00233 {
00234 R = (c0.R*c1.R) >>8;
00235 G = (c0.G*c1.G) >>8;
00236 B = (c0.B*c1.B) >>8;
00237 }
00239 void avg2RGBOnly(CRGBA a, CRGBA b)
00240 {
00241 R= ((uint)a.R+(uint)b.R)>>1;
00242 G= ((uint)a.G+(uint)b.G)>>1;
00243 B= ((uint)a.B+(uint)b.B)>>1;
00244 }
00246 void avg4RGBOnly(CRGBA a, CRGBA b, CRGBA c, CRGBA d)
00247 {
00248 R= ((uint)a.R+(uint)b.R+(uint)c.R+(uint)d.R+ 1)>>2;
00249 G= ((uint)a.G+(uint)b.G+(uint)c.G+(uint)d.G+ 1)>>2;
00250 B= ((uint)a.B+(uint)b.B+(uint)c.B+(uint)d.B+ 1)>>2;
00251 }
00253 void addRGBOnly(CRGBA c0, CRGBA c1)
00254 {
00255 uint r,g,b;
00256 r= c0.R + c1.R; r= std::min(r, 255U); R= (uint8)r;
00257 g= c0.G + c1.G; g= std::min(g, 255U); G= (uint8)g;
00258 b= c0.B + c1.B; b= std::min(b, 255U); B= (uint8)b;
00259 }
00261 void subRGBOnly(CRGBA c0, CRGBA c1)
00262 {
00263 sint r,g,b;
00264 r= c0.R - c1.R; r= std::max(r, 0); R= (uint8)r;
00265 g= c0.G - c1.G; g= std::max(g, 0); G= (uint8)g;
00266 b= c0.B - c1.B; b= std::max(b, 0); B= (uint8)b;
00267 }
00268
00269
00270
00271
00272
00274
00275
00284 static void addColors(CRGBA *dest, const CRGBA *src1, const CRGBA *src2, uint numColors, uint srcStride = sizeof(CRGBA), uint destStride = sizeof(CRGBA), uint dup = 1);
00285
00293 static void modulateColors(CRGBA *dest, const CRGBA *src1, const CRGBA *src2, uint numColors, uint srcStride = sizeof(CRGBA), uint destStride = sizeof(CRGBA), uint dup = 1);
00294
00302 static void subtractColors(CRGBA *dest, const CRGBA *src1, const CRGBA *src2, uint numColors, uint srcStride = sizeof(CRGBA), uint destStride = sizeof(CRGBA), uint dup = 1);
00304
00306
00307
00312 bool convertToHLS(float &h, float &l, float &S) const;
00313
00317 void buildFromHLS(float h, float l, float s);
00319
00320
00321
00323 uint8 R;
00325 uint8 G;
00327 uint8 B;
00329 uint8 A;
00330
00331
00333 static const CRGBA Black ;
00334 static const CRGBA Red ;
00335 static const CRGBA Green ;
00336 static const CRGBA Yellow ;
00337 static const CRGBA Blue ;
00338 static const CRGBA Magenta ;
00339 static const CRGBA Cyan ;
00340 static const CRGBA White ;
00341 };
00342
00343
00350 class CBGRA
00351 {
00352 public:
00353
00355 CBGRA() {};
00356
00361 CBGRA(CRGBA c)
00362 {
00363 R=c.R;
00364 G=c.G;
00365 B=c.B;
00366 A=c.A;
00367 };
00368
00376 CBGRA(uint8 r, uint8 g, uint8 b, uint8 a=255) :
00377 R(r), G(g), B(b), A(a) {}
00378
00382 operator CRGBA()
00383 {
00384 return CRGBA (R, G, B, A);
00385 }
00386
00390 uint getPacked() const
00391 {
00392 return ((uint)R<<24) + ((uint)G<<16) + ((uint)B<<8) + A;
00393 }
00394
00398 bool operator<(const CBGRA &c) const
00399 {
00400 return getPacked()<c.getPacked();
00401 }
00402
00406 bool operator==(const CBGRA &c) const
00407 {
00408 return R==c.R && G==c.G && B==c.B && A==c.A;
00409 }
00410
00415 void serial(class NLMISC::IStream &f);
00416
00423 void blendFromui(CBGRA &c0, CBGRA &c1, uint factor);
00424
00432 void set(uint8 r, uint8 g, uint8 b, uint8 a);
00433
00435 uint8 R;
00437 uint8 G;
00439 uint8 B;
00441 uint8 A;
00442 };
00443
00444
00451 class CRGBAF
00452 {
00453 public:
00455 CRGBAF ()
00456 {}
00457
00465 CRGBAF (float _r, float _g, float _b, float _a=1.f)
00466 {
00467 R=_r;
00468 G=_g;
00469 B=_b;
00470 A=_a;
00471 }
00472
00477 CRGBAF (CRGBA c)
00478 {
00479 R=(float)c.R/255.f;
00480 G=(float)c.G/255.f;
00481 B=(float)c.B/255.f;
00482 A=(float)c.A/255.f;
00483 }
00484
00488 operator CRGBA() const
00489 {
00490 uint8 _r=(uint8)(R*255.f);
00491 uint8 _g=(uint8)(G*255.f);
00492 uint8 _b=(uint8)(B*255.f);
00493 uint8 _a=(uint8)(A*255.f);
00494 return CRGBA (_r, _g, _b, _a);
00495 }
00496
00500 void normalize ()
00501 {
00502 R= (R>1.f) ? 1.f : (R<0.f) ? 0.f : R;
00503 G= (G>1.f) ? 1.f : (G<0.f) ? 0.f : G;
00504 B= (B>1.f) ? 1.f : (B<0.f) ? 0.f : B;
00505 A= (A>1.f) ? 1.f : (A<0.f) ? 0.f : A;
00506 }
00507
00513 CRGBAF operator+ (const CRGBAF& c) const
00514 {
00515 return CRGBAF (R+c.R, G+c.G, B+c.B, A+c.A);
00516 }
00517
00523 CRGBAF operator- (const CRGBAF& c) const
00524 {
00525 return CRGBAF (R-c.R, G-c.G, B-c.B, A-c.A);
00526 }
00527
00533 CRGBAF operator* (const CRGBAF& c) const
00534 {
00535 return CRGBAF (R*c.R, G*c.G, B*c.B, A*c.A);
00536 }
00537
00543 CRGBAF operator* (float f) const
00544 {
00545 return CRGBAF (R*f, G*f, B*f, A*f);
00546 }
00547
00553 CRGBAF operator/ (float f) const
00554 {
00555 return CRGBAF (R/f, G/f, B/f, A/f);
00556 }
00557
00563 CRGBAF& operator+= (const CRGBAF& c)
00564 {
00565 R+=c.R;
00566 G+=c.G;
00567 B+=c.B;
00568 A+=c.A;
00569 return *this;
00570 }
00571
00577 CRGBAF& operator-= (const CRGBAF& c)
00578 {
00579 R-=c.R;
00580 G-=c.G;
00581 B-=c.B;
00582 A-=c.A;
00583 return *this;
00584 }
00585
00591 CRGBAF& operator*= (const CRGBAF& c)
00592 {
00593 R*=c.R;
00594 G*=c.G;
00595 B*=c.B;
00596 A*=c.A;
00597 return *this;
00598 }
00599
00605 CRGBAF& operator*= (float f)
00606 {
00607 R*=f;
00608 G*=f;
00609 B*=f;
00610 A*=f;
00611 return *this;
00612 }
00613
00619 CRGBAF& operator/= (float f)
00620 {
00621 R/=f;
00622 G/=f;
00623 B/=f;
00624 A/=f;
00625 return *this;
00626 }
00627
00632 void serial(class NLMISC::IStream &f);
00633
00641 void set(float r, float g, float b, float a);
00642
00644 float R;
00646 float G;
00648 float B;
00650 float A;
00651 };
00652
00658 inline CRGBAF operator* (float f, const CRGBAF& c)
00659 {
00660 return CRGBAF (c.R*f, c.G*f, c.B*f, c.A*f);
00661 }
00662
00663 }
00664
00665
00666 #endif // NL_RGBA_H
00667
00668