1/////////////////////////////////////////////////////////////////////////////////////////////////// 2// OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) 3/////////////////////////////////////////////////////////////////////////////////////////////////// 4// Created : 2005-12-21 5// Updated : 2007-02-22 6// Licence : This source is under MIT License 7// File : glm/gtx/color_space.inl 8/////////////////////////////////////////////////////////////////////////////////////////////////// 9 10namespace glm 11{ 12 template <typename T, precision P> 13 GLM_FUNC_QUALIFIER detail::tvec3<T, P> rgbColor(const detail::tvec3<T, P>& hsvColor) 14 { 15 detail::tvec3<T, P> hsv = hsvColor; 16 detail::tvec3<T, P> rgbColor; 17 18 if(hsv.y == static_cast<T>(0)) 19 // achromatic (grey) 20 rgbColor = detail::tvec3<T, P>(hsv.z); 21 else 22 { 23 T sector = floor(hsv.x / T(60)); 24 T frac = (hsv.x / T(60)) - sector; 25 // factorial part of h 26 T o = hsv.z * (T(1) - hsv.y); 27 T p = hsv.z * (T(1) - hsv.y * frac); 28 T q = hsv.z * (T(1) - hsv.y * (T(1) - frac)); 29 30 switch(int(sector)) 31 { 32 default: 33 case 0: 34 rgbColor.r = hsv.z; 35 rgbColor.g = q; 36 rgbColor.b = o; 37 break; 38 case 1: 39 rgbColor.r = p; 40 rgbColor.g = hsv.z; 41 rgbColor.b = o; 42 break; 43 case 2: 44 rgbColor.r = o; 45 rgbColor.g = hsv.z; 46 rgbColor.b = q; 47 break; 48 case 3: 49 rgbColor.r = o; 50 rgbColor.g = p; 51 rgbColor.b = hsv.z; 52 break; 53 case 4: 54 rgbColor.r = q; 55 rgbColor.g = o; 56 rgbColor.b = hsv.z; 57 break; 58 case 5: 59 rgbColor.r = hsv.z; 60 rgbColor.g = o; 61 rgbColor.b = p; 62 break; 63 } 64 } 65 66 return rgbColor; 67 } 68 69 template <typename T, precision P> 70 GLM_FUNC_QUALIFIER detail::tvec3<T, P> hsvColor(const detail::tvec3<T, P>& rgbColor) 71 { 72 detail::tvec3<T, P> hsv = rgbColor; 73 float Min = min(min(rgbColor.r, rgbColor.g), rgbColor.b); 74 float Max = max(max(rgbColor.r, rgbColor.g), rgbColor.b); 75 float Delta = Max - Min; 76 77 hsv.z = Max; 78 79 if(Max != static_cast<T>(0)) 80 { 81 hsv.y = Delta / hsv.z; 82 T h = static_cast<T>(0); 83 84 if(rgbColor.r == Max) 85 // between yellow & magenta 86 h = static_cast<T>(0) + T(60) * (rgbColor.g - rgbColor.b) / Delta; 87 else if(rgbColor.g == Max) 88 // between cyan & yellow 89 h = static_cast<T>(120) + T(60) * (rgbColor.b - rgbColor.r) / Delta; 90 else 91 // between magenta & cyan 92 h = static_cast<T>(240) + T(60) * (rgbColor.r - rgbColor.g) / Delta; 93 94 if(h < T(0)) 95 hsv.x = h + T(360); 96 else 97 hsv.x = h; 98 } 99 else 100 { 101 // If r = g = b = 0 then s = 0, h is undefined 102 hsv.y = static_cast<T>(0); 103 hsv.x = static_cast<T>(0); 104 } 105 106 return hsv; 107 } 108 109 template <typename T, precision P> 110 GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> saturation(const T s) 111 { 112 detail::tvec3<T, P> rgbw = detail::tvec3<T, P>(T(0.2126), T(0.7152), T(0.0722)); 113 114 T col0 = (T(1) - s) * rgbw.r; 115 T col1 = (T(1) - s) * rgbw.g; 116 T col2 = (T(1) - s) * rgbw.b; 117 118 detail::tmat4x4<T, P> result(T(1)); 119 result[0][0] = col0 + s; 120 result[0][1] = col0; 121 result[0][2] = col0; 122 result[1][0] = col1; 123 result[1][1] = col1 + s; 124 result[1][2] = col1; 125 result[2][0] = col2; 126 result[2][1] = col2; 127 result[2][2] = col2 + s; 128 return result; 129 } 130 131 template <typename T, precision P> 132 GLM_FUNC_QUALIFIER detail::tvec3<T, P> saturation(const T s, const detail::tvec3<T, P>& color) 133 { 134 return detail::tvec3<T, P>(saturation(s) * detail::tvec4<T, P>(color, T(0))); 135 } 136 137 template <typename T, precision P> 138 GLM_FUNC_QUALIFIER detail::tvec4<T, P> saturation(const T s, const detail::tvec4<T, P>& color) 139 { 140 return saturation(s) * color; 141 } 142 143 template <typename T, precision P> 144 GLM_FUNC_QUALIFIER T luminosity(const detail::tvec3<T, P>& color) 145 { 146 const detail::tvec3<T, P> tmp = detail::tvec3<T, P>(0.33, 0.59, 0.11); 147 return dot(color, tmp); 148 } 149}//namespace glm 150