25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

154 satır
4.1 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2004—2017 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // Lol Engine is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #include <lol/engine-internal.h>
  13. /*
  14. * Image merge operations: merge, min/max, overlay, screen, multiply,
  15. * divide, add, sub, difference
  16. */
  17. namespace lol
  18. {
  19. enum class MergeMode
  20. {
  21. Mix,
  22. Min,
  23. Max,
  24. Overlay,
  25. Screen,
  26. Divide,
  27. Multiply,
  28. Add,
  29. Sub,
  30. Difference,
  31. };
  32. template<PixelFormat FORMAT, MergeMode MODE>
  33. static image generic_merge(image &src1, image &src2, float alpha)
  34. {
  35. typedef typename PixelType<FORMAT>::type pixel_t;
  36. ASSERT(src1.size() == src2.size());
  37. int const count = src1.size().x * src2.size().y;
  38. image dst(src1.size());
  39. pixel_t const *src1p = src1.lock<FORMAT>();
  40. pixel_t const *src2p = src2.lock<FORMAT>();
  41. pixel_t *dstp = dst.lock<FORMAT>();
  42. for (int n = 0; n < count; ++n)
  43. {
  44. if (MODE == MergeMode::Mix)
  45. dstp[n] = lol::mix(src1p[n], src2p[n], alpha);
  46. else if (MODE == MergeMode::Min)
  47. dstp[n] = lol::min(src1p[n], src2p[n]);
  48. else if (MODE == MergeMode::Max)
  49. dstp[n] = lol::max(src1p[n], src2p[n]);
  50. else if (MODE == MergeMode::Overlay)
  51. dstp[n] = src1p[n] * (src1p[n] + 2.f * src2p[n]
  52. * (pixel_t(1.f) - src1p[n]));
  53. else if (MODE == MergeMode::Screen)
  54. dstp[n] = src1p[n] + src2p[n] - src1p[n] * src2p[n];
  55. else if (MODE == MergeMode::Divide)
  56. dstp[n] = src1p[n] / (lol::max(src1p[n], src2p[n]) + pixel_t(1e-8f));
  57. else if (MODE == MergeMode::Multiply)
  58. dstp[n] = src1p[n] * src2p[n];
  59. else if (MODE == MergeMode::Add)
  60. dstp[n] = lol::min(src1p[n] + src2p[n], pixel_t(1.f));
  61. else if (MODE == MergeMode::Sub)
  62. dstp[n] = lol::max(src1p[n] - src2p[n], pixel_t(0.f));
  63. else if (MODE == MergeMode::Difference)
  64. dstp[n] = lol::abs(src1p[n] - src2p[n]);
  65. }
  66. src1.unlock(src1p);
  67. src2.unlock(src2p);
  68. dst.unlock(dstp);
  69. return dst;
  70. }
  71. template<MergeMode MODE>
  72. static image generic_merge(image &src1, image &src2, float alpha)
  73. {
  74. bool gray1 = src1.format() == PixelFormat::Y_8
  75. || src1.format() == PixelFormat::Y_F32;
  76. bool gray2 = src2.format() == PixelFormat::Y_8
  77. || src2.format() == PixelFormat::Y_F32;
  78. if (gray1 && gray2)
  79. return generic_merge<PixelFormat::Y_F32, MODE>(src1, src2, alpha);
  80. else
  81. return generic_merge<PixelFormat::RGBA_F32, MODE>(src1, src2, alpha);
  82. }
  83. image image::Merge(image &src1, image &src2, float alpha)
  84. {
  85. return generic_merge<MergeMode::Mix>(src1, src2, alpha);
  86. }
  87. image image::Mean(image &src1, image &src2)
  88. {
  89. return generic_merge<MergeMode::Mix>(src1, src2, 0.5f);
  90. }
  91. image image::Min(image &src1, image &src2)
  92. {
  93. return generic_merge<MergeMode::Min>(src1, src2, 0.0f);
  94. }
  95. image image::Max(image &src1, image &src2)
  96. {
  97. return generic_merge<MergeMode::Max>(src1, src2, 0.0f);
  98. }
  99. image image::Overlay(image &src1, image &src2)
  100. {
  101. return generic_merge<MergeMode::Overlay>(src1, src2, 0.0f);
  102. }
  103. image image::Screen(image &src1, image &src2)
  104. {
  105. return generic_merge<MergeMode::Screen>(src1, src2, 0.0f);
  106. }
  107. image image::Divide(image &src1, image &src2)
  108. {
  109. return generic_merge<MergeMode::Divide>(src1, src2, 0.0f);
  110. }
  111. image image::Multiply(image &src1, image &src2)
  112. {
  113. return generic_merge<MergeMode::Multiply>(src1, src2, 0.0f);
  114. }
  115. image image::Add(image &src1, image &src2)
  116. {
  117. return generic_merge<MergeMode::Add>(src1, src2, 0.0f);
  118. }
  119. image image::Sub(image &src1, image &src2)
  120. {
  121. return generic_merge<MergeMode::Sub>(src1, src2, 0.0f);
  122. }
  123. image image::Difference(image &src1, image &src2)
  124. {
  125. return generic_merge<MergeMode::Difference>(src1, src2, 0.0f);
  126. }
  127. } /* namespace lol */