color.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00080
00081
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