00001 #include "color.h"
00002
00015 #include <string>
00016
00017 #include <cassert>
00018 #include <cstdio>
00019
00020 using namespace std;
00021
00022 #include <glt/rgb.h>
00023 #include <glt/error.h>
00024 #include <glt/gl.h>
00025
00026 #include <misc/string.h>
00027 #include <math/matrix4.h>
00028
00029 GltColor::GltColor()
00030 : Vector(Vector0), _alpha(1.0)
00031 {
00032 }
00033
00034 GltColor::GltColor(const float red,const float green,const float blue,const float alpha)
00035 : Vector(red,green,blue), _alpha(alpha)
00036 {
00037 }
00038
00039 GltColor::GltColor(const double red,const double green,const double blue,const double alpha)
00040 : Vector(red,green,blue), _alpha(alpha)
00041 {
00042 }
00043
00044 GltColor::GltColor(const int red,const int green,const int blue,const int alpha)
00045 : Vector(red,green,blue), _alpha(alpha)
00046 {
00047 }
00048
00049 GltColor::GltColor(const GltColor &col,const real alpha)
00050 : Vector(col), _alpha(alpha)
00051 {
00052 }
00053
00054 GltColor::GltColor(const Vector &col)
00055 : Vector(col), _alpha(1.0)
00056 {
00057 }
00058
00059 GltColor::GltColor(const GltColor &col)
00060 : Vector(col), _alpha(col._alpha)
00061 {
00062 }
00063
00064 GltColor::GltColor(const string &name)
00065 : _alpha(1.0)
00066 {
00067
00068
00069 if (name.size()>=7)
00070 {
00071 if (name[0]=='#')
00072 {
00073 const int r = fromHex4(name[1])<<4 | fromHex4(name[2]);
00074 const int g = fromHex4(name[3])<<4 | fromHex4(name[4]);
00075 const int b = fromHex4(name[5])<<4 | fromHex4(name[6]);
00076
00077 red() = real(r)/255.0;
00078 green() = real(g)/255.0;
00079 blue() = real(b)/255.0;
00080
00081 return;
00082 }
00083 }
00084
00085
00086
00087 int i=0;
00088 int j=_rgbSize;
00089
00090 for (;;)
00091 {
00092 int k = ((j-i)>>1)+i;
00093 const int res = strcmp(name.c_str(),_rgbName[k]);
00094
00095 if (res<0)
00096 j = k;
00097 else
00098 if (res>0)
00099 i = k+1;
00100 else
00101 {
00102 operator=(*_rgbValue[k]);
00103 return;
00104 }
00105
00106 if (i==k && j==k || i==_rgbSize)
00107 {
00108 assert(!"Color not found");
00109 operator=(::black);
00110 return;
00111 }
00112 }
00113 }
00114
00115 GltColor::~GltColor()
00116 {
00117 }
00118
00119 GltColor &
00120 GltColor::operator=(const GltColor &col)
00121 {
00122 red() = col.red();
00123 green() = col.green();
00124 blue() = col.blue();
00125 alpha() = col.alpha();
00126
00127 return *this;
00128 }
00129
00130 void
00131 GltColor::glColor() const
00132 {
00133 #ifdef GLT_FAST_FLOAT
00134 ::glColor4f(x(),y(),z(),_alpha);
00135 #else
00136 ::glColor4d(x(),y(),z(),_alpha);
00137 #endif
00138 }
00139
00140 void
00141 GltColor::glColor(const GLdouble alpha) const
00142 {
00143 #ifdef GLT_FAST_FLOAT
00144 ::glColor4f(x(),y(),z(),alpha);
00145 #else
00146 ::glColor4d(x(),y(),z(),alpha);
00147 #endif
00148 }
00149
00150 void
00151 GltColor::glClearColor() const
00152 {
00153 ::glClearColor(x(),y(),z(),_alpha);
00154 }
00155
00156 void
00157 GltColor::glFogColor() const
00158 {
00159 const float col[4] = { x(), y(), z(), _alpha };
00160 ::glFogfv(GL_FOG_COLOR, col);
00161 }
00162
00163 void
00164 GltColor::glMaterial(const GLenum face,const GLenum field) const
00165 {
00166 assert(face==GL_FRONT_AND_BACK || face==GL_FRONT || face==GL_BACK);
00167 assert(field==GL_AMBIENT || field==GL_DIFFUSE || field==GL_SPECULAR || field==GL_EMISSION);
00168
00169 GLERROR
00170
00171 const GLfloat val[4] = { x(), y(), z(), _alpha };
00172 ::glMaterialfv(face,field,val);
00173
00174 GLERROR
00175 }
00176
00177 void
00178 GltColor::glGetMaterial(const GLenum face,const GLenum field)
00179 {
00180 assert(face==GL_FRONT_AND_BACK || face==GL_FRONT || face==GL_BACK);
00181 assert(field==GL_AMBIENT || field==GL_DIFFUSE || field==GL_SPECULAR || field==GL_EMISSION);
00182
00183 GLERROR
00184
00185 GLfloat val[4];
00186 ::glGetMaterialfv(face,field,val);
00187 x() = val[0]; y() = val[1]; z() = val[2]; _alpha = val[3];
00188
00189 GLERROR
00190 }
00191
00192 void
00193 GltColor::glLight(const GLenum light,const GLenum field) const
00194 {
00195 assert(light>=GL_LIGHT0 && light<=GL_LIGHT7);
00196 assert(field==GL_AMBIENT || field==GL_DIFFUSE || field==GL_SPECULAR || field==GL_POSITION || field==GL_SPOT_DIRECTION);
00197
00198 GLERROR
00199
00200 const GLfloat val[4] = { x(), y(), z(), _alpha };
00201 ::glLightfv(light,field,val);
00202
00203 GLERROR
00204 }
00205
00206 void
00207 GltColor::glGetLight(const GLenum light,const GLenum field)
00208 {
00209 assert(light>=GL_LIGHT0 && light<=GL_LIGHT7);
00210 assert(field==GL_AMBIENT || field==GL_DIFFUSE || field==GL_SPECULAR || field==GL_POSITION || field==GL_SPOT_DIRECTION);
00211
00212 GLERROR
00213
00214 GLfloat val[4];
00215 ::glGetLightfv(light,field,val);
00216 x() = val[0]; y() = val[1]; z() = val[2]; _alpha = val[3];
00217
00218 GLERROR
00219 }
00220
00221 real &GltColor::red() { return x(); }
00222 real &GltColor::green() { return y(); }
00223 real &GltColor::blue() { return z(); }
00224 real &GltColor::alpha() { return _alpha; }
00225
00226 const real &GltColor::red() const { return x(); }
00227 const real &GltColor::green() const { return y(); }
00228 const real &GltColor::blue() const { return z(); }
00229 const real &GltColor::alpha() const { return _alpha; }
00230
00231 const real
00232 GltColor::brightness() const
00233 {
00234
00235
00236
00237 return 0.212671*red() + 0.715160*green() + 0.072169*blue();
00238 }
00239
00240 void
00241 GltColor::toHSV(real &h,real &s,real &v) const
00242 {
00243
00244
00245 const real min = MIN(red(),MIN(green(),blue()));
00246 const real max = MAX(red(),MAX(green(),blue()));
00247
00248 v = max;
00249
00250 const real delta = max-min;
00251
00252 if (max!=0.0)
00253 s = delta/max;
00254 else
00255 {
00256
00257 h = 0.0;
00258 s = 0.0;
00259 return;
00260 }
00261
00262 if (delta==0.0)
00263 {
00264 h = 0.0;
00265 s = 0.0;
00266 }
00267 else
00268 if (red()==max)
00269 h = (green()-blue()) / delta;
00270 else
00271 if(green()==max)
00272 h = 2.0 + (blue()-red())/delta;
00273 else
00274 h = 4.0 + (red()-green())/delta;
00275
00276
00277
00278 h *= 60;
00279
00280 if (h<0.0)
00281 h += 360.0;
00282 }
00283
00284 void
00285 GltColor::fromHSV(const real h,const real s,const real v)
00286 {
00287
00288
00289
00290
00291 if (s==0.0)
00292 {
00293 red() = green() = blue() = v;
00294 return;
00295 }
00296
00297
00298 const real hue = h/60.0;
00299 const int i = int(floor(hue));
00300 const real f = hue-i;
00301 const real p = v*(1-s);
00302 const real q = v*(1-s*f);
00303 const real t = v*(1-s*(1-f));
00304
00305 switch (i)
00306 {
00307 case 0:
00308 red() = v;
00309 green() = t;
00310 blue() = p;
00311 break;
00312 case 1:
00313 red() = q;
00314 green() = v;
00315 blue() = p;
00316 break;
00317 case 2:
00318 red() = p;
00319 green() = v;
00320 blue() = t;
00321 break;
00322 case 3:
00323 red() = p;
00324 green() = q;
00325 blue() = v;
00326 break;
00327 case 4:
00328 red() = t;
00329 green() = p;
00330 blue() = v;
00331 break;
00332 default:
00333 red() = v;
00334 green() = p;
00335 blue() = q;
00336 break;
00337 }
00338 }
00339
00340
00341
00342 const bool
00343 GltColor::isGrey() const
00344 {
00345 return red()==green() && green()==blue();
00346 }
00347
00348 std::string
00349 GltColor::html() const
00350 {
00351 const int r = CLAMP(int(red() *255.0+0.5),0,255);
00352 const int g = CLAMP(int(green()*255.0+0.5),0,255);
00353 const int b = CLAMP(int(blue() *255.0+0.5),0,255);
00354
00355 char buffer[8];
00356 sprintf(buffer,"#%02X%02X%02X",r,g,b);
00357 return buffer;
00358 }
00359
00360 bool GltColor::operator< (const GltColor &c) const
00361 {
00362 if (red()!=c.red()) return red()<c.red();
00363 if (green()!=c.green()) return green()<c.green();
00364 return blue()<c.blue();
00365 }
00366
00367 bool GltColor::operator> (const GltColor &c) const
00368 {
00369 if (red()!=c.red()) return red()>c.red();
00370 if (green()!=c.green()) return green()>c.green();
00371 return blue()>c.blue();
00372 }
00373
00374 bool GltColor::operator==(const GltColor &c) const
00375 {
00376 return red()==c.red() && green()==c.green() && blue()==c.blue();
00377 }
00378
00383 GltColor operator*(const GltColor &c, const real x)
00384 {
00385 return GltColor(c.red()*x,c.green()*x,c.blue()*x,c.alpha()*x);
00386 }
00387
00392 GltColor operator/(const GltColor &c, const real x)
00393 {
00394 const double s = 1.0/x;
00395 return GltColor(c.red()*s,c.green()*s,c.blue()*s,c.alpha()*s);
00396 }
00397
00402 GltColor operator*(const real x, const GltColor &c)
00403 {
00404 return GltColor(c.red()*x,c.green()*x,c.blue()*x,c.alpha()*x);
00405 }
00406
00411 GltColor operator+(const GltColor &c1, const GltColor &c2)
00412 {
00413 return GltColor(c1.red()+c2.red(),c1.green()+c2.green(),c1.blue()+c2.blue(),c1.alpha()+c2.alpha());
00414 }
00415
00420 GltColor operator-(const GltColor &c1, const GltColor &c2)
00421 {
00422 return GltColor(c1.red()-c2.red(),c1.green()-c2.green(),c1.blue()-c2.blue(),c1.alpha()-c2.alpha());
00423 }
00424
00426
00427 GltClearColor::GltClearColor(bool getIt)
00428 {
00429 if (getIt)
00430 get();
00431 }
00432
00433 GltClearColor::~GltClearColor()
00434 {
00435 }
00436
00437 void
00438 GltClearColor::get()
00439 {
00440 GLdouble tmp[4];
00441 glGetDoublev(GL_COLOR_CLEAR_VALUE,tmp);
00442 x() = tmp[0];
00443 y() = tmp[1];
00444 z() = tmp[2];
00445 }
00446
00447 void
00448 GltClearColor::set() const
00449 {
00450 GltColor::glClearColor();
00451 }
00452
00453 void
00454 GltClearColor::set(const GltColor &col)
00455 {
00456 x() = col.x();
00457 y() = col.y();
00458 z() = col.z();
00459 GltColor::glClearColor();
00460 }