2
0

CmColor.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. -----------------------------------------------------------------------------
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org/
  6. Copyright (c) 2000-2011 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. -----------------------------------------------------------------------------
  23. */
  24. #include "CmColor.h"
  25. #include "CmMath.h"
  26. namespace CamelotFramework {
  27. const Color Color::ZERO = Color(0.0,0.0,0.0,0.0);
  28. const Color Color::Black = Color(0.0,0.0,0.0);
  29. const Color Color::White = Color(1.0,1.0,1.0);
  30. const Color Color::Red = Color(1.0,0.0,0.0);
  31. const Color Color::Green = Color(0.0,1.0,0.0);
  32. const Color Color::Blue = Color(0.0,0.0,1.0);
  33. //---------------------------------------------------------------------
  34. ABGR Color::getAsABGR(void) const
  35. {
  36. UINT8 val8;
  37. UINT32 val32 = 0;
  38. // Convert to 32bit pattern
  39. // (RGBA = 8888)
  40. // Red
  41. val8 = static_cast<UINT8>(r * 255);
  42. val32 = val8 << 24;
  43. // Green
  44. val8 = static_cast<UINT8>(g * 255);
  45. val32 += val8 << 16;
  46. // Blue
  47. val8 = static_cast<UINT8>(b * 255);
  48. val32 += val8 << 8;
  49. // Alpha
  50. val8 = static_cast<UINT8>(a * 255);
  51. val32 += val8;
  52. return val32;
  53. }
  54. //---------------------------------------------------------------------
  55. BGRA Color::getAsBGRA(void) const
  56. {
  57. UINT8 val8;
  58. UINT32 val32 = 0;
  59. // Convert to 32bit pattern
  60. // (ARGB = 8888)
  61. // Alpha
  62. val8 = static_cast<UINT8>(a * 255);
  63. val32 = val8 << 24;
  64. // Red
  65. val8 = static_cast<UINT8>(r * 255);
  66. val32 += val8 << 16;
  67. // Green
  68. val8 = static_cast<UINT8>(g * 255);
  69. val32 += val8 << 8;
  70. // Blue
  71. val8 = static_cast<UINT8>(b * 255);
  72. val32 += val8;
  73. return val32;
  74. }
  75. //---------------------------------------------------------------------
  76. ARGB Color::getAsARGB(void) const
  77. {
  78. UINT8 val8;
  79. UINT32 val32 = 0;
  80. // Convert to 32bit pattern
  81. // (ARGB = 8888)
  82. // Blue
  83. val8 = static_cast<UINT8>(b * 255);
  84. val32 = val8 << 24;
  85. // Green
  86. val8 = static_cast<UINT8>(g * 255);
  87. val32 += val8 << 16;
  88. // Red
  89. val8 = static_cast<UINT8>(r * 255);
  90. val32 += val8 << 8;
  91. // Alpha
  92. val8 = static_cast<UINT8>(a * 255);
  93. val32 += val8;
  94. return val32;
  95. }
  96. //---------------------------------------------------------------------
  97. RGBA Color::getAsRGBA(void) const
  98. {
  99. UINT8 val8;
  100. UINT32 val32 = 0;
  101. // Convert to 32bit pattern
  102. // (ABRG = 8888)
  103. // Alpha
  104. val8 = static_cast<UINT8>(a * 255);
  105. val32 = val8 << 24;
  106. // Blue
  107. val8 = static_cast<UINT8>(b * 255);
  108. val32 += val8 << 16;
  109. // Green
  110. val8 = static_cast<UINT8>(g * 255);
  111. val32 += val8 << 8;
  112. // Red
  113. val8 = static_cast<UINT8>(r * 255);
  114. val32 += val8;
  115. return val32;
  116. }
  117. //---------------------------------------------------------------------
  118. void Color::setAsABGR(const ABGR val)
  119. {
  120. UINT32 val32 = val;
  121. // Convert from 32bit pattern
  122. // (RGBA = 8888)
  123. // Red
  124. r = ((val32 >> 24) & 0xFF) / 255.0f;
  125. // Green
  126. g = ((val32 >> 16) & 0xFF) / 255.0f;
  127. // Blue
  128. b = ((val32 >> 8) & 0xFF) / 255.0f;
  129. // Alpha
  130. a = (val32 & 0xFF) / 255.0f;
  131. }
  132. //---------------------------------------------------------------------
  133. void Color::setAsBGRA(const BGRA val)
  134. {
  135. UINT32 val32 = val;
  136. // Convert from 32bit pattern
  137. // (ARGB = 8888)
  138. // Alpha
  139. a = ((val32 >> 24) & 0xFF) / 255.0f;
  140. // Red
  141. r = ((val32 >> 16) & 0xFF) / 255.0f;
  142. // Green
  143. g = ((val32 >> 8) & 0xFF) / 255.0f;
  144. // Blue
  145. b = (val32 & 0xFF) / 255.0f;
  146. }
  147. //---------------------------------------------------------------------
  148. void Color::setAsARGB(const ARGB val)
  149. {
  150. UINT32 val32 = val;
  151. // Convert from 32bit pattern
  152. // (ARGB = 8888)
  153. // Blue
  154. b = ((val32 >> 24) & 0xFF) / 255.0f;
  155. // Green
  156. g = ((val32 >> 16) & 0xFF) / 255.0f;
  157. // Red
  158. r = ((val32 >> 8) & 0xFF) / 255.0f;
  159. // Alpha
  160. a = (val32 & 0xFF) / 255.0f;
  161. }
  162. //---------------------------------------------------------------------
  163. void Color::setAsRGBA(const RGBA val)
  164. {
  165. UINT32 val32 = val;
  166. // Convert from 32bit pattern
  167. // (ABGR = 8888)
  168. // Alpha
  169. a = ((val32 >> 24) & 0xFF) / 255.0f;
  170. // Blue
  171. b = ((val32 >> 16) & 0xFF) / 255.0f;
  172. // Green
  173. g = ((val32 >> 8) & 0xFF) / 255.0f;
  174. // Red
  175. r = (val32 & 0xFF) / 255.0f;
  176. }
  177. //---------------------------------------------------------------------
  178. bool Color::operator==(const Color& rhs) const
  179. {
  180. return (r == rhs.r &&
  181. g == rhs.g &&
  182. b == rhs.b &&
  183. a == rhs.a);
  184. }
  185. //---------------------------------------------------------------------
  186. bool Color::operator!=(const Color& rhs) const
  187. {
  188. return !(*this == rhs);
  189. }
  190. //---------------------------------------------------------------------
  191. void Color::setHSB(float hue, float saturation, float brightness)
  192. {
  193. // wrap hue
  194. if (hue > 1.0f)
  195. {
  196. hue -= (int)hue;
  197. }
  198. else if (hue < 0.0f)
  199. {
  200. hue += (int)hue + 1;
  201. }
  202. // clamp saturation / brightness
  203. saturation = std::min(saturation, (float)1.0);
  204. saturation = std::max(saturation, (float)0.0);
  205. brightness = std::min(brightness, (float)1.0);
  206. brightness = std::max(brightness, (float)0.0);
  207. if (brightness == 0.0f)
  208. {
  209. // early exit, this has to be black
  210. r = g = b = 0.0f;
  211. return;
  212. }
  213. if (saturation == 0.0f)
  214. {
  215. // early exit, this has to be grey
  216. r = g = b = brightness;
  217. return;
  218. }
  219. float hueDomain = hue * 6.0f;
  220. if (hueDomain >= 6.0f)
  221. {
  222. // wrap around, and allow mathematical errors
  223. hueDomain = 0.0f;
  224. }
  225. unsigned short domain = (unsigned short)hueDomain;
  226. float f1 = brightness * (1 - saturation);
  227. float f2 = brightness * (1 - saturation * (hueDomain - domain));
  228. float f3 = brightness * (1 - saturation * (1 - (hueDomain - domain)));
  229. switch (domain)
  230. {
  231. case 0:
  232. // red domain; green ascends
  233. r = brightness;
  234. g = f3;
  235. b = f1;
  236. break;
  237. case 1:
  238. // yellow domain; red descends
  239. r = f2;
  240. g = brightness;
  241. b = f1;
  242. break;
  243. case 2:
  244. // green domain; blue ascends
  245. r = f1;
  246. g = brightness;
  247. b = f3;
  248. break;
  249. case 3:
  250. // cyan domain; green descends
  251. r = f1;
  252. g = f2;
  253. b = brightness;
  254. break;
  255. case 4:
  256. // blue domain; red ascends
  257. r = f3;
  258. g = f1;
  259. b = brightness;
  260. break;
  261. case 5:
  262. // magenta domain; blue descends
  263. r = brightness;
  264. g = f1;
  265. b = f2;
  266. break;
  267. }
  268. }
  269. //---------------------------------------------------------------------
  270. void Color::getHSB(float* hue, float* saturation, float* brightness) const
  271. {
  272. float vMin = std::min(r, std::min(g, b));
  273. float vMax = std::max(r, std::max(g, b));
  274. float delta = vMax - vMin;
  275. *brightness = vMax;
  276. if (Math::RealEqual(delta, 0.0f, 1e-6f))
  277. {
  278. // grey
  279. *hue = 0;
  280. *saturation = 0;
  281. }
  282. else
  283. {
  284. // a colour
  285. *saturation = delta / vMax;
  286. float deltaR = (((vMax - r) / 6.0f) + (delta / 2.0f)) / delta;
  287. float deltaG = (((vMax - g) / 6.0f) + (delta / 2.0f)) / delta;
  288. float deltaB = (((vMax - b) / 6.0f) + (delta / 2.0f)) / delta;
  289. if (Math::RealEqual(r, vMax))
  290. *hue = deltaB - deltaG;
  291. else if (Math::RealEqual(g, vMax))
  292. *hue = 0.3333333f + deltaR - deltaB;
  293. else if (Math::RealEqual(b, vMax))
  294. *hue = 0.6666667f + deltaG - deltaR;
  295. if (*hue < 0.0f)
  296. *hue += 1.0f;
  297. if (*hue > 1.0f)
  298. *hue -= 1.0f;
  299. }
  300. }
  301. }