BsColor.cpp 6.9 KB

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