2
0

CmColor.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. #include "CmColor.h"
  2. #include "CmMath.h"
  3. namespace BansheeEngine
  4. {
  5. const Color Color::ZERO = Color(0.0,0.0,0.0,0.0);
  6. const Color Color::Black = Color(0.0,0.0,0.0);
  7. const Color Color::White = Color(1.0,1.0,1.0);
  8. const Color Color::Red = Color(1.0,0.0,0.0);
  9. const Color Color::Green = Color(0.0,1.0,0.0);
  10. const Color Color::Blue = Color(0.0,0.0,1.0);
  11. ABGR Color::getAsABGR() const
  12. {
  13. UINT8 val8;
  14. UINT32 val32 = 0;
  15. // Convert to 32bit pattern
  16. // (RGBA = 8888)
  17. // Red
  18. val8 = static_cast<UINT8>(r * 255);
  19. val32 = val8 << 24;
  20. // Green
  21. val8 = static_cast<UINT8>(g * 255);
  22. val32 += val8 << 16;
  23. // Blue
  24. val8 = static_cast<UINT8>(b * 255);
  25. val32 += val8 << 8;
  26. // Alpha
  27. val8 = static_cast<UINT8>(a * 255);
  28. val32 += val8;
  29. return val32;
  30. }
  31. BGRA Color::getAsBGRA() const
  32. {
  33. UINT8 val8;
  34. UINT32 val32 = 0;
  35. // Convert to 32bit pattern
  36. // (ARGB = 8888)
  37. // Alpha
  38. val8 = static_cast<UINT8>(a * 255);
  39. val32 = val8 << 24;
  40. // Red
  41. val8 = static_cast<UINT8>(r * 255);
  42. val32 += val8 << 16;
  43. // Green
  44. val8 = static_cast<UINT8>(g * 255);
  45. val32 += val8 << 8;
  46. // Blue
  47. val8 = static_cast<UINT8>(b * 255);
  48. val32 += val8;
  49. return val32;
  50. }
  51. ARGB Color::getAsARGB() const
  52. {
  53. UINT8 val8;
  54. UINT32 val32 = 0;
  55. // Convert to 32bit pattern
  56. // (ARGB = 8888)
  57. // Blue
  58. val8 = static_cast<UINT8>(b * 255);
  59. val32 = val8 << 24;
  60. // Green
  61. val8 = static_cast<UINT8>(g * 255);
  62. val32 += val8 << 16;
  63. // Red
  64. val8 = static_cast<UINT8>(r * 255);
  65. val32 += val8 << 8;
  66. // Alpha
  67. val8 = static_cast<UINT8>(a * 255);
  68. val32 += val8;
  69. return val32;
  70. }
  71. RGBA Color::getAsRGBA() const
  72. {
  73. UINT8 val8;
  74. UINT32 val32 = 0;
  75. // Convert to 32bit pattern
  76. // (ABRG = 8888)
  77. // Alpha
  78. val8 = static_cast<UINT8>(a * 255);
  79. val32 = val8 << 24;
  80. // Blue
  81. val8 = static_cast<UINT8>(b * 255);
  82. val32 += val8 << 16;
  83. // Green
  84. val8 = static_cast<UINT8>(g * 255);
  85. val32 += val8 << 8;
  86. // Red
  87. val8 = static_cast<UINT8>(r * 255);
  88. val32 += val8;
  89. return val32;
  90. }
  91. void Color::setAsABGR(const ABGR val)
  92. {
  93. UINT32 val32 = val;
  94. // Convert from 32bit pattern
  95. // (RGBA = 8888)
  96. // Red
  97. r = ((val32 >> 24) & 0xFF) / 255.0f;
  98. // Green
  99. g = ((val32 >> 16) & 0xFF) / 255.0f;
  100. // Blue
  101. b = ((val32 >> 8) & 0xFF) / 255.0f;
  102. // Alpha
  103. a = (val32 & 0xFF) / 255.0f;
  104. }
  105. void Color::setAsBGRA(const BGRA val)
  106. {
  107. UINT32 val32 = val;
  108. // Convert from 32bit pattern
  109. // (ARGB = 8888)
  110. // Alpha
  111. a = ((val32 >> 24) & 0xFF) / 255.0f;
  112. // Red
  113. r = ((val32 >> 16) & 0xFF) / 255.0f;
  114. // Green
  115. g = ((val32 >> 8) & 0xFF) / 255.0f;
  116. // Blue
  117. b = (val32 & 0xFF) / 255.0f;
  118. }
  119. void Color::setAsARGB(const ARGB val)
  120. {
  121. UINT32 val32 = val;
  122. // Convert from 32bit pattern
  123. // (ARGB = 8888)
  124. // Blue
  125. b = ((val32 >> 24) & 0xFF) / 255.0f;
  126. // Green
  127. g = ((val32 >> 16) & 0xFF) / 255.0f;
  128. // Red
  129. r = ((val32 >> 8) & 0xFF) / 255.0f;
  130. // Alpha
  131. a = (val32 & 0xFF) / 255.0f;
  132. }
  133. void Color::setAsRGBA(const RGBA val)
  134. {
  135. UINT32 val32 = val;
  136. // Convert from 32bit pattern
  137. // (ABGR = 8888)
  138. // Alpha
  139. a = ((val32 >> 24) & 0xFF) / 255.0f;
  140. // Blue
  141. b = ((val32 >> 16) & 0xFF) / 255.0f;
  142. // Green
  143. g = ((val32 >> 8) & 0xFF) / 255.0f;
  144. // Red
  145. r = (val32 & 0xFF) / 255.0f;
  146. }
  147. bool Color::operator==(const Color& rhs) const
  148. {
  149. return (r == rhs.r &&
  150. g == rhs.g &&
  151. b == rhs.b &&
  152. a == rhs.a);
  153. }
  154. bool Color::operator!=(const Color& rhs) const
  155. {
  156. return !(*this == rhs);
  157. }
  158. void Color::setHSB(float hue, float saturation, float brightness)
  159. {
  160. // wrap hue
  161. if (hue > 1.0f)
  162. {
  163. hue -= (int)hue;
  164. }
  165. else if (hue < 0.0f)
  166. {
  167. hue += (int)hue + 1;
  168. }
  169. // clamp saturation / brightness
  170. saturation = std::min(saturation, (float)1.0);
  171. saturation = std::max(saturation, (float)0.0);
  172. brightness = std::min(brightness, (float)1.0);
  173. brightness = std::max(brightness, (float)0.0);
  174. if (brightness == 0.0f)
  175. {
  176. // early exit, this has to be black
  177. r = g = b = 0.0f;
  178. return;
  179. }
  180. if (saturation == 0.0f)
  181. {
  182. // early exit, this has to be grey
  183. r = g = b = brightness;
  184. return;
  185. }
  186. float hueDomain = hue * 6.0f;
  187. if (hueDomain >= 6.0f)
  188. {
  189. // wrap around, and allow mathematical errors
  190. hueDomain = 0.0f;
  191. }
  192. unsigned short domain = (unsigned short)hueDomain;
  193. float f1 = brightness * (1 - saturation);
  194. float f2 = brightness * (1 - saturation * (hueDomain - domain));
  195. float f3 = brightness * (1 - saturation * (1 - (hueDomain - domain)));
  196. switch (domain)
  197. {
  198. case 0:
  199. // red domain; green ascends
  200. r = brightness;
  201. g = f3;
  202. b = f1;
  203. break;
  204. case 1:
  205. // yellow domain; red descends
  206. r = f2;
  207. g = brightness;
  208. b = f1;
  209. break;
  210. case 2:
  211. // green domain; blue ascends
  212. r = f1;
  213. g = brightness;
  214. b = f3;
  215. break;
  216. case 3:
  217. // cyan domain; green descends
  218. r = f1;
  219. g = f2;
  220. b = brightness;
  221. break;
  222. case 4:
  223. // blue domain; red ascends
  224. r = f3;
  225. g = f1;
  226. b = brightness;
  227. break;
  228. case 5:
  229. // magenta domain; blue descends
  230. r = brightness;
  231. g = f1;
  232. b = f2;
  233. break;
  234. }
  235. }
  236. void Color::getHSB(float* hue, float* saturation, float* brightness) const
  237. {
  238. float vMin = std::min(r, std::min(g, b));
  239. float vMax = std::max(r, std::max(g, b));
  240. float delta = vMax - vMin;
  241. *brightness = vMax;
  242. if (Math::approxEquals(delta, 0.0f, 1e-6f))
  243. {
  244. // grey
  245. *hue = 0;
  246. *saturation = 0;
  247. }
  248. else
  249. {
  250. // a colour
  251. *saturation = delta / vMax;
  252. float deltaR = (((vMax - r) / 6.0f) + (delta / 2.0f)) / delta;
  253. float deltaG = (((vMax - g) / 6.0f) + (delta / 2.0f)) / delta;
  254. float deltaB = (((vMax - b) / 6.0f) + (delta / 2.0f)) / delta;
  255. if (Math::approxEquals(r, vMax))
  256. *hue = deltaB - deltaG;
  257. else if (Math::approxEquals(g, vMax))
  258. *hue = 0.3333333f + deltaR - deltaB;
  259. else if (Math::approxEquals(b, vMax))
  260. *hue = 0.6666667f + deltaG - deltaR;
  261. if (*hue < 0.0f)
  262. *hue += 1.0f;
  263. if (*hue > 1.0f)
  264. *hue -= 1.0f;
  265. }
  266. }
  267. }