BsColor.cpp 7.0 KB

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