00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #pragma once
00027
00028 #include "cinder/Cinder.h"
00029 #include "cinder/ChanTraits.h"
00030 #include "cinder/Vector.h"
00031 #include "cinder/CinderMath.h"
00032
00033 namespace cinder {
00034
00035 typedef enum {
00036 CM_RGB,
00037 CM_HSV
00038 } ColorModel;
00039
00040 template<typename T>
00041 class ColorT
00042 {
00043 public:
00044 T r,g,b;
00045
00046 ColorT() : r( 0 ), g( 0 ), b( 0 ) {}
00047 ColorT( T aR, T aG, T aB )
00048 : r( aR ), g( aG ), b( aB )
00049 {}
00050 ColorT( const ColorT<T> &src )
00051 : r( src.r ), g( src.g ), b( src.b )
00052 {}
00053
00054 ColorT( ColorModel cm, const Vec3f &v );
00055 ColorT( ColorModel cm, float x, float y, float z );
00056
00057 template<typename FromT>
00058 ColorT( const ColorT<FromT> &src )
00059 : r( CHANTRAIT<T>::convert( src.r ) ), g( CHANTRAIT<T>::convert( src.g ) ), b( CHANTRAIT<T>::convert( src.b ) )
00060 {}
00061
00062 void set( T ar, T ag, T ab )
00063 {
00064 r = ar; g = ag; b = ab;
00065 }
00066
00067 void set( const ColorT<T> &rhs )
00068 {
00069 r = rhs.r; g = rhs.g; b = rhs.b;
00070 }
00071
00072 void set( ColorModel cm, const Vec3f &v );
00073
00074 ColorT<T> operator=( const ColorT<T> &rhs )
00075 {
00076 r = rhs.r;
00077 g = rhs.g;
00078 b = rhs.b;
00079 return * this;
00080 }
00081
00082 template<class FromT>
00083 ColorT<T> operator=( const ColorT<FromT> &rhs )
00084 {
00085 r = CHANTRAIT<T>::convert( rhs.r );
00086 g = CHANTRAIT<T>::convert( rhs.g );
00087 b = CHANTRAIT<T>::convert( rhs.b );
00088 return * this;
00089 }
00090
00091 Vec3f get( ColorModel cm ) const;
00092
00093 T& operator[]( int n )
00094 {
00095 assert( n >= 0 && n <= 2 );
00096 return (&r)[n];
00097 }
00098
00099 const T& operator[]( int n ) const
00100 {
00101 assert( n >= 0 && n <= 2 );
00102 return (&r)[n];
00103 }
00104
00105 T* ptr() const { return &(const_cast<ColorT*>( this )->r); }
00106
00107 ColorT<T> operator+( const ColorT<T> &rhs ) const { return ColorT<T>( r + rhs.r, g + rhs.g, b + rhs.b ); }
00108 ColorT<T> operator-( const ColorT<T> &rhs ) const { return ColorT<T>( r - rhs.r, g - rhs.g, b - rhs.b ); }
00109 ColorT<T> operator*( const ColorT<T> &rhs ) const { return ColorT<T>( r * rhs.r, g * rhs.g, b * rhs.b ); }
00110 ColorT<T> operator/( const ColorT<T> &rhs ) const { return ColorT<T>( r / rhs.r, g / rhs.g, b / rhs.b ); }
00111 const ColorT<T>& operator+=( const ColorT<T> &rhs ) { r += rhs.r; g += rhs.g; b += rhs.b; return *this; }
00112 const ColorT<T>& operator-=( const ColorT<T> &rhs ) { r -= rhs.r; g -= rhs.g; b -= rhs.b; return *this; }
00113 const ColorT<T>& operator*=( const ColorT<T> &rhs ) { r *= rhs.r; g *= rhs.g; b *= rhs.b; return *this; }
00114 const ColorT<T>& operator/=( const ColorT<T> &rhs ) { r /= rhs.r; g /= rhs.g; b /= rhs.b; return *this; }
00115 ColorT<T> operator+( T rhs ) const { return ColorT<T>( r + rhs, g + rhs, b + rhs ); }
00116 ColorT<T> operator-( T rhs ) const { return ColorT<T>( r - rhs, g - rhs, b - rhs ); }
00117 ColorT<T> operator*( T rhs ) const { return ColorT<T>( r * rhs, g * rhs, b * rhs ); }
00118 ColorT<T> operator/( T rhs ) const { return ColorT<T>( r / rhs, g / rhs, b / rhs ); }
00119 const ColorT<T>& operator+=( T rhs ) { r += rhs; g += rhs; b += rhs; return *this; }
00120 const ColorT<T>& operator-=( T rhs ) { r -= rhs; g -= rhs; b -= rhs; return *this; }
00121 const ColorT<T>& operator*=( T rhs ) { r *= rhs; g *= rhs; b *= rhs; return *this; }
00122 const ColorT<T>& operator/=( T rhs ) { r /= rhs; g /= rhs; b /= rhs; return *this; }
00123
00124 bool operator==( const ColorT<T>& rhs ) const
00125 {
00126 return ( r == rhs.r ) && ( g == rhs.g ) && ( b == rhs.b );
00127 }
00128
00129 bool operator!=( const ColorT<T>& rhs ) const
00130 {
00131 return ! ( *this == rhs );
00132 }
00133
00134 typename CHANTRAIT<T>::Accum dot( const ColorT<T> &rhs ) const
00135 {
00136 return r*rhs.r + g*rhs.g + b*rhs.b;
00137 }
00138
00139 float distance( const ColorT<T> &rhs ) const
00140 {
00141 return math<float>::sqrt( static_cast<float>( (r - rhs.r)*(r - rhs.r) + (g - rhs.g)*(g - rhs.g) + (b - rhs.b)*(b - rhs.b)) );
00142 }
00143
00144 typename CHANTRAIT<T>::Accum distanceSquared( const ColorT<T> &rhs ) const
00145 {
00146 return (r - rhs.r) * (r - rhs.r) + (g - rhs.g) * (g - rhs.g) + (b - rhs.b) * (b - rhs.b);
00147 }
00148
00149 float length() const
00150 {
00151 return math<float>::sqrt( static_cast<float>( r*r + g*g + b*b ) );
00152 }
00153
00154 typename CHANTRAIT<T>::Accum lengthSquared() const
00155 {
00156 return r*r + g*g + b*b;
00157 }
00158
00159
00160 void normalize()
00161 {
00162 float s = length();
00163 if( s > 0.0f ) {
00164 r = static_cast<T>( r / s );
00165 g = static_cast<T>( g / s );
00166 b = static_cast<T>( b / s );
00167 }
00168 }
00169
00170 ColorT<T> lerp( float fact, const ColorT<T> &d ) const
00171 {
00172 return ColorT<T>( r + ( d.r - r ) * fact, g + ( d.g - g ) * fact, b + ( d.b - b ) * fact );
00173 }
00174
00175 static ColorT<T> max()
00176 {
00177 return ColorT<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max() );
00178 }
00179
00180 static ColorT<T> black()
00181 {
00182 return ColorT<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) );
00183 }
00184
00185 static ColorT<T> white()
00186 {
00187 return ColorT<T>( CHANTRAIT<T>::max(), CHANTRAIT<T>::max(), CHANTRAIT<T>::max() );
00188 }
00189
00190 static ColorT<T> gray( T value )
00191 {
00192 return ColorT<T>( value, value, value );
00193 }
00194
00196 static ColorT<T> hex( uint32_t hexValue )
00197 {
00198 uint8_t red = ( hexValue >> 16 ) & 255;
00199 uint8_t green = ( hexValue >> 8 ) & 255;
00200 uint8_t blue = hexValue & 255;
00201 return ColorT<T>( CHANTRAIT<T>::convert( red ), CHANTRAIT<T>::convert( green ), CHANTRAIT<T>::convert( blue ) );
00202 }
00203
00204 operator T*(){ return (T*) this; }
00205 operator const T*() const { return (const T*) this; }
00206 };
00207
00208
00210
00211
00212 template<typename T>
00213 class ColorAT {
00214 public:
00215 T r,g,b,a;
00216
00217 ColorAT()
00218 : r( 0 ), g( 0 ), b( 0 ), a( 0 )
00219 {}
00220 ColorAT( T aR, T aG, T aB, T aA = CHANTRAIT<T>::convert( 1.0f ) )
00221 : r( aR ), g( aG ), b( aB ), a( aA )
00222 {}
00223 ColorAT( const ColorAT<T> &src )
00224 : r( src.r ), g( src.g ), b( src.b ), a( src.a )
00225 {}
00226 ColorAT( const ColorT<T> &col, T aA = CHANTRAIT<T>::convert( 1.0f ) )
00227 : r( col.r ), g( col.g ), b( col.b ), a( aA )
00228 {}
00229
00230 ColorAT( ColorModel cm, float c1, float c2, float c3, float aA = CHANTRAIT<T>::convert( 1.0f ) );
00231
00232 template<typename FromT>
00233 ColorAT( const ColorT<FromT> &src )
00234 : r( CHANTRAIT<T>::convert( src.r ) ), g( CHANTRAIT<T>::convert( src.g ) ), b( CHANTRAIT<T>::convert( src.b ) ), a( CHANTRAIT<T>::convert( 1.0f ) )
00235 {}
00236
00237
00238 template<typename FromT>
00239 ColorAT( const ColorAT<FromT>& src )
00240 : r( CHANTRAIT<T>::convert( src.r ) ), g( CHANTRAIT<T>::convert( src.g ) ), b( CHANTRAIT<T>::convert( src.b ) ), a( CHANTRAIT<T>::convert( src.a ) )
00241 {}
00242
00243 void set( T ar, T ag, T ab , T aa )
00244 {
00245 r = ar; g = ag; b = ab; a = aa;
00246 }
00247
00248 void set( const ColorAT<T> &rhs )
00249 {
00250 r = rhs.r; g = rhs.g; b = rhs.b; a = rhs.a;
00251 }
00252
00253 ColorAT<T> operator=( const ColorAT<T>& rhs )
00254 {
00255 r = rhs.r;
00256 g = rhs.g;
00257 b = rhs.b;
00258 a = rhs.a;
00259 return * this;
00260 }
00261
00262 template<class FromT>
00263 ColorAT<T> operator=( const ColorAT<FromT>& rhs )
00264 {
00265 r = CHANTRAIT<T>::convert( rhs.r );
00266 g = CHANTRAIT<T>::convert( rhs.g );
00267 b = CHANTRAIT<T>::convert( rhs.b );
00268 a = CHANTRAIT<T>::convert( rhs.a );
00269 return * this;
00270 }
00271
00272 T& operator[]( int n )
00273 {
00274 assert( n >= 0 && n <= 3 );
00275 return (&r)[n];
00276 }
00277
00278 const T& operator[]( int n ) const
00279 {
00280 assert( n >= 0 && n <= 3 );
00281 return (&r)[n];
00282 }
00283
00284 T* ptr() const { return &(const_cast<ColorAT*>( this )->r); }
00285
00286 ColorAT<T> operator+( const ColorAT<T> &rhs ) const { return ColorAT<T>( r + rhs.r, g + rhs.g, b + rhs.b, a + rhs.a ); }
00287 ColorAT<T> operator-( const ColorAT<T> &rhs ) const { return ColorAT<T>( r - rhs.r, g - rhs.g, b - rhs.b, a - rhs.a ); }
00288 ColorAT<T> operator*( const ColorAT<T> &rhs ) const { return ColorAT<T>( r * rhs.r, g * rhs.g, b * rhs.b, a * rhs.a ); }
00289 ColorAT<T> operator/( const ColorAT<T> &rhs ) const { return ColorAT<T>( r / rhs.r, g / rhs.g, b / rhs.b, a / rhs.a ); }
00290 const ColorAT<T>& operator+=( const ColorAT<T> &rhs ) { r += rhs.r; g += rhs.g; b += rhs.b; a += rhs.a; return *this; }
00291 const ColorAT<T>& operator-=( const ColorAT<T> &rhs ) { r -= rhs.r; g -= rhs.g; b -= rhs.b; a -= rhs.a; return *this; }
00292 const ColorAT<T>& operator*=( const ColorAT<T> &rhs ) { r *= rhs.r; g *= rhs.g; b *= rhs.b; a *= rhs.a; return *this; }
00293 const ColorAT<T>& operator/=( const ColorAT<T> &rhs ) { r /= rhs.r; g /= rhs.g; b /= rhs.b; a /= rhs.a; return *this; }
00294 ColorAT<T> operator+( T rhs ) const { return ColorAT<T>( r + rhs, g + rhs, b + rhs, a + rhs ); }
00295 ColorAT<T> operator-( T rhs ) const { return ColorAT<T>( r - rhs, g - rhs, b - rhs, a - rhs ); }
00296 ColorAT<T> operator*( T rhs ) const { return ColorAT<T>( r * rhs, g * rhs, b * rhs, a * rhs ); }
00297 ColorAT<T> operator/( T rhs ) const { return ColorAT<T>( r / rhs, g / rhs, b / rhs, a / rhs ); }
00298 const ColorAT<T>& operator+=( T rhs ) { r += rhs; g += rhs; b += rhs; a += rhs; return *this; }
00299 const ColorAT<T>& operator-=( T rhs ) { r -= rhs; g -= rhs; b -= rhs; a -= rhs; return * this; }
00300 const ColorAT<T>& operator*=( T rhs ) { r *= rhs; g *= rhs; b *= rhs; a *= rhs; return * this; }
00301 const ColorAT<T>& operator/=( T rhs ) { r /= rhs; g /= rhs; b /= rhs; a /= rhs; return * this; }
00302
00303 bool operator==( const ColorAT<T>& rhs ) const
00304 {
00305 return ( r == rhs.r ) && ( g == rhs.g ) && ( b == rhs.b ) && ( a == rhs.a );
00306 }
00307
00308 bool operator!=( const ColorAT<T>& rhs ) const
00309 {
00310 return ! ( *this == rhs );
00311 }
00312
00313 float length() const
00314 {
00315 return math<float>::sqrt( static_cast<float>( r*r + g*g + b*b ) );
00316 }
00317
00318
00319 void normalize()
00320 {
00321 float s = length();
00322 if( s > 0.0f ) {
00323 r = static_cast<T>( r / s );
00324 g = static_cast<T>( g / s );
00325 b = static_cast<T>( b / s );
00326 }
00327 }
00328
00329 ColorAT<T> premultiplied() const
00330 {
00331 return ColorAT<T>( r * a, g * a, b * a, a );
00332 }
00333
00334 typename CHANTRAIT<T>::Accum lengthSquared() const
00335 {
00336 return r * r + g * g + b * b;
00337 }
00338
00339 ColorAT<T> lerp( T fact, const ColorAT<T> &d ) const
00340 {
00341 return ColorAT<T>( r + ( d.r - r ) * fact, g + ( d.g - g ) * fact, b + ( d.b - b ) * fact, a + ( d.a - a ) * fact );
00342 }
00343
00344 static ColorAT<T> zero()
00345 {
00346 return ColorAT<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) );
00347 }
00348
00349 static ColorAT<T> black()
00350 {
00351 return ColorAT<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), CHANTRAIT<T>::max() );
00352 }
00353
00354 static ColorAT<T> white()
00355 {
00356 return ColorAT<T>( CHANTRAIT<T>::max(), CHANTRAIT<T>::max(), CHANTRAIT<T>::max(), CHANTRAIT<T>::max() );
00357 }
00358
00359 static ColorAT<T> gray( T value, T alpha = CHANTRAIT<T>::max() )
00360 {
00361 return ColorAT<T>( value, value, value, alpha );
00362 }
00363
00365 static ColorAT<T> hex( uint32_t hexValue )
00366 {
00367 uint8_t red = ( hexValue >> 16 ) & 255;
00368 uint8_t green = ( hexValue >> 8 ) & 255;
00369 uint8_t blue = hexValue & 255;
00370 return ColorAT<T>( CHANTRAIT<T>::convert( red ), CHANTRAIT<T>::convert( green ), CHANTRAIT<T>::convert( blue ), CHANTRAIT<T>::max() );
00371 }
00372
00374 static ColorAT<T> hexA( uint32_t hexValue )
00375 {
00376 uint8_t alpha = ( hexValue >> 24 ) & 255;;
00377 uint8_t red = ( hexValue >> 16 ) & 255;
00378 uint8_t green = ( hexValue >> 8 ) & 255;
00379 uint8_t blue = hexValue & 255;
00380 return ColorAT<T>( CHANTRAIT<T>::convert( red ), CHANTRAIT<T>::convert( green ), CHANTRAIT<T>::convert( blue ), CHANTRAIT<T>::convert( alpha ) );
00381 }
00382
00383 operator T*(){ return (T*) this; }
00384 operator const T*() const { return (const T*) this; }
00385 operator ColorT<T>(){ return ColorT<T>( r, g, b ); }
00386 };
00387
00388
00389 template <typename T, typename Y> inline ColorT<T> operator*( Y s, const ColorT<T>& c ) { return ColorT<T>( s*c.r, s*c.g, s*c.b ); }
00390 template <typename T, typename Y> inline ColorAT<T> operator*( Y s, const ColorAT<T>& c ) { return ColorAT<T>( s*c.r, s*c.g, s*c.b, s*c.a ); }
00391
00392
00393 extern ColorT<float> hsvToRGB( const Vec3f &hsv );
00394 extern Vec3f rgbToHSV( const ColorT<float> &c );
00395
00396 extern std::ostream& operator<<( std::ostream &lhs, const ColorT<float> &rhs );
00397 extern std::ostream& operator<<( std::ostream &lhs, const ColorAT<float> &rhs );
00398 extern std::ostream& operator<<( std::ostream &lhs, const ColorT<uint8_t> &rhs );
00399 extern std::ostream& operator<<( std::ostream &lhs, const ColorAT<uint8_t> &rhs );
00400
00401 typedef ColorT<float> Color;
00402 typedef ColorT<float> Colorf;
00403 typedef ColorT<uint8_t> Color8u;
00404 typedef ColorAT<float> ColorA;
00405 typedef ColorAT<float> ColorAf;
00406 typedef ColorAT<uint8_t> ColorA8u;
00407
00408 }