Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

glt/color.cpp

Go to the documentation of this file.
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     // Convert from HTML style color string
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     // Do a binary search through the list of names
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     // (from Colorspace FAQ)
00235     //  Y = 0.212671 * R + 0.715160 * G + 0.072169 * B;
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     // Based on http://www.cs.rit.edu/~ncs/color/t_convert.html
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         // Black
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;           // between yellow & magenta
00270         else 
00271             if(green()==max)
00272                 h = 2.0 + (blue()-red())/delta;     // between cyan & yellow
00273             else
00274                 h = 4.0 + (red()-green())/delta;    // between magenta & cyan
00275 
00276     // Scale h to degrees
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     // Based on http://www.cs.rit.edu/~ncs/color/t_convert.html
00288 
00289     // Achromatic case (grey)
00290 
00291     if (s==0.0) 
00292     {
00293         red() = green() = blue() = v;
00294         return;
00295     }
00296 
00297         
00298     const real hue = h/60.0;    // sector 0 to 5
00299     const int  i   = int(floor(hue));
00300     const real f   = hue-i;     // factorial part of h
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:        // case 5:
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 }

Generated on Tue Nov 5 11:11:03 2002 for GLT by doxygen1.2.18