color.cpp

Go to the documentation of this file.
00001 /*
00002     RenderStack  Support library for OpenGL 3+
00003     Copyright (C) 2010  Timo Suoranta
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Lesser General Public
00007     License as published by the Free Software Foundation; either
00008     version 2.1 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Lesser General Public License for more details.
00014 
00015     You should have received a copy of the GNU Lesser General Public
00016     License along with this library; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018 */
00019 
00027 #include "renderstack/color.hpp"
00028 #include <math.h>
00029 
00030 #ifdef  _MSC_VER
00031 #   define isnan(x) _isnan(x)
00032 #endif
00033 
00034 namespace renderstack {
00035 
00036 float srgb_to_linear(float cs)
00037 {
00038     float cl = 0.0f;
00039 
00040     RS_ASSERT(cs >= 0.0f);
00041     RS_ASSERT(cs <= 1.0f);
00042 
00043     if(cs <= 0.04045f)
00044     {
00045         cl = cs / 12.92f;
00046     }
00047     else
00048     {
00049         cl = powf(
00050             (cs + 0.055f) / 1.055f, 
00051             2.4f
00052         );
00053     }
00054 
00055     return cl;
00056 }
00057 
00058 float linear_to_srgb(float cl)
00059 {
00060     if(cl > 1.0f)
00061     {
00062         return 1.0f;
00063     }
00064     else if(cl < 0.0)
00065     {
00066         return 0.0f;
00067     }
00068     else if(cl < 0.0031308f)
00069     {
00070         return 12.92f * cl;
00071     }
00072     else
00073     {
00074         return 1.055f * powf(cl, 0.41666f) - 0.055f;
00075     }
00076 }
00077 
00078 /*
00079 unsigned char rs_float_to_byte(float c)
00080 {
00081     return (unsigned char)(floorf(255.0f * c + 0.5f));
00082 }*/ 
00083 
00084 float color::max_component() const
00085 {
00086     float max;
00087 
00088     if(r > g)
00089     {
00090         max = r;
00091     }
00092     else
00093     {
00094         max = g;
00095     }
00096     if(b > max)
00097     {
00098         max = b;
00099     }
00100     return max;
00101 }
00102 
00103 float color::min_component() const
00104 {
00105     float min;
00106 
00107     if(r < g)
00108     {
00109         min = r;
00110     }
00111     else
00112     {
00113         min = g;
00114     }
00115     if(b < min)
00116     {
00117         min = b;
00118     }
00119     return min;
00120 }
00121 
00122 vec3 color::hsv() const
00123 {
00124     float h = 0;
00125     float s = 1.0f;
00126     float v = 1.0f;
00127     float max_v;
00128     float min_v;
00129     float diff;
00130     float r_dist;
00131     float g_dist;
00132     float b_dist;
00133     float undefined = 0;
00134 
00135     max_v = max_component();
00136     min_v = min_component();
00137     diff  = max_v - min_v;
00138     v     = max_v;
00139 
00140     if(RS_NEAR_ZERO(max_v))
00141     {
00142         s = 0;
00143     }
00144     else
00145     {
00146         s = diff / max_v;
00147     }
00148     if(s == 0)
00149     {
00150         h = undefined;
00151     }
00152     else
00153     {
00154         r_dist = (max_v - r) / diff;
00155         g_dist = (max_v - g) / diff;
00156         b_dist = (max_v - b) / diff;
00157         if(r == max_v)
00158         {
00159             h = b_dist - g_dist;
00160         }
00161         else
00162         {
00163             if(g == max_v)
00164             {
00165                 h = 2.0f + r_dist - b_dist;
00166             }
00167             else
00168             {
00169                 if(b == max_v)
00170                 {
00171                     h = 4.0f + g_dist - r_dist;
00172                 }
00173             }
00174         }
00175         h = h * 60.0f;
00176         if(h < 0)
00177         {
00178             h += 360.0f;
00179         }
00180     }
00181     return vec3(h, s, v);
00182 }
00183 
00184 color make_color_from_hsv(vec3 const &hsv)
00185 {
00186     float h = hsv.x;
00187     float s = hsv.y;
00188     float v = hsv.z;
00189     float r = 0.0f;
00190     float g = 0.0f;
00191     float b = 0.0f;
00192     float f;
00193     float p;
00194     float q;
00195     float t;
00196     int   i;
00197 
00198     if(s == 0.0f)
00199     {
00200         r = v;
00201         g = v;
00202         b = v;
00203     }
00204     else
00205     {
00206         if(h == 360.0f)
00207         {
00208             h = 0.0;
00209         }
00210         h = h / 60.0f;
00211         i = (int)(h);
00212         f = h - i;
00213         p = v * (1.0f -  s             );
00214         q = v * (1.0f - (s *         f ));
00215         t = v * (1.0f - (s * (1.0f - f)));
00216         switch(i)
00217         {
00218             case 0:
00219             {
00220                 r = v;
00221                 g = t;
00222                 b = p;
00223                 break;
00224             }
00225             case 1:
00226             {
00227                 r = q;
00228                 g = v;
00229                 b = p;
00230                 break;
00231             }
00232             case 2:
00233             {
00234                 r = p;
00235                 g = v;
00236                 b = t;
00237                 break;
00238             }
00239             case 3:
00240             {
00241                 r = p;
00242                 g = q;
00243                 b = v;
00244                 break;
00245             }
00246             case 4:
00247             {
00248                 r = t;
00249                 g = p;
00250                 b = v;
00251                 break;
00252             }
00253             case 5:
00254             {
00255                 r = v;
00256                 g = p;
00257                 b = q;
00258                 break;
00259             }
00260             default:
00261             {
00262                 r = 1.0f;
00263                 b = 1.0f;
00264                 b = 1.0f;
00265                 break;
00266             }
00267         }
00268     }
00269     return color(r, g, b);
00270 }
00271 
00272 }
00273 
Generated on Sun Apr 11 12:23:08 2010 for RenderStack by  doxygen 1.6.3