Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.93 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <cstdint>
  4. #include <utility>
  5. #include <type_traits>
  6.  
  7. #define ASSERT_SIZE(x, sz) static_assert(sizeof(x) == sz, "Wrong size in " #x)
  8. #define ASSERT_STANDARD_LAYOUT(x) static_assert(std::is_standard_layout_v<x>, #x "is not standard layout")
  9.  
  10. struct rgb565_t {
  11. union {
  12. struct {
  13. uint16_t r: 5, g: 6, b: 5;
  14. } __attribute__((packed));
  15. uint16_t rgb;
  16. };
  17. inline rgb565_t(uint16_t raw): rgb(raw) { }
  18. inline rgb565_t(uint8_t r, uint8_t g, uint8_t b): r(r), g(g), b(b) { }
  19. };
  20. ASSERT_SIZE(rgb565_t, 2);
  21. ASSERT_STANDARD_LAYOUT(rgb565_t);
  22.  
  23. struct rgba4444_t {
  24. union {
  25. struct {
  26. uint16_t r: 4, g: 4, b: 4, a: 4;
  27. } __attribute__((packed));
  28. uint16_t rgba;
  29. };
  30. inline rgba4444_t(uint16_t raw): rgba(raw) { }
  31. inline rgba4444_t(uint8_t r, uint8_t g, uint8_t b, uint8_t a): r(r), g(g), b(b), a(a) { }
  32. };
  33. ASSERT_SIZE(rgba4444_t, 2);
  34. ASSERT_STANDARD_LAYOUT(rgba4444_t);
  35.  
  36. template<typename T, typename=void>
  37. struct has_alpha : std::false_type { };
  38.  
  39. template<typename T>
  40. struct has_alpha<T, decltype(std::declval<T>().a, void())> : std::true_type { };
  41.  
  42. template<typename T>
  43. inline constexpr bool has_alpha_v = has_alpha<T>::value;
  44.  
  45. template<typename T>
  46. struct col_underlying_type { typedef decltype(T::r) type; };
  47.  
  48. template<typename T>
  49. using col_underlying_type_t = typename col_underlying_type<T>::type;
  50.  
  51. template<typename T>
  52. inline T MakeColor(col_underlying_type_t<T> raw) {
  53. return T(raw);
  54. }
  55.  
  56. template<typename T>
  57. typename std::enable_if_t<!has_alpha_v<T>, T>
  58. inline MakeColor(decltype(T::r) r, decltype(T::g) g, decltype(T::b) b) {
  59. return T(r, g, b);
  60. }
  61.  
  62. template<typename T>
  63. typename std::enable_if_t<has_alpha_v<T>, T>
  64. inline MakeColor(decltype(T::r) r, decltype(T::g) g, decltype(T::b) b, decltype(T::a) a=-1) {
  65. return T(r, g, b, a);
  66. }
  67.  
  68. template<typename T>
  69. typename std::enable_if_t<!has_alpha_v<T>, T>
  70. inline make_color_min_alpha() {
  71. return MakeColor<T>(0, 0, 0);
  72. }
  73.  
  74. template<typename T>
  75. typename std::enable_if_t<has_alpha_v<T>, T>
  76. inline make_color_min_alpha() {
  77. return MakeColor<T>(0, 0, 0, 0);
  78. }
  79.  
  80. template<typename T>
  81. inline T make_color_max_alpha(decltype(T::r) r, decltype(T::g) g, decltype(T::b) b) {
  82. return MakeColor<T>(r, g, b);
  83. }
  84.  
  85. template<typename T>
  86. inline T make_color_max_all() {
  87. return MakeColor<T>(-1, -1, -1);
  88. }
  89.  
  90. #define BLEND_CHANNEL(x, y, a) (((a) * (x) + ((0xff - (a)) * (y))) / 0xff)
  91.  
  92. template<typename T>
  93. typename std::enable_if_t<!has_alpha_v<T>, T>
  94. inline Blend(T x, T y, uint8_t alpha) {
  95. return MakeColor<T>(
  96. BLEND_CHANNEL(x.r, y.r, alpha),
  97. BLEND_CHANNEL(x.g, y.g, alpha),
  98. BLEND_CHANNEL(x.b, y.b, alpha)
  99. );
  100. }
  101.  
  102. template<typename T>
  103. typename std::enable_if_t<has_alpha_v<T>, T>
  104. inline Blend(T x, T y, uint8_t alpha) {
  105. return MakeColor<T>(
  106. BLEND_CHANNEL(x.r, y.r, alpha),
  107. BLEND_CHANNEL(x.g, y.g, alpha),
  108. BLEND_CHANNEL(x.b, y.b, alpha),
  109. BLEND_CHANNEL(1, y.a, alpha)
  110. );
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement