General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
5.8 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. #include "test_scaffold.h"
  2. #include "gp/containers/array.hpp"
  3. #include "gp/utils/pair.hpp"
  4. #include "gp/math.hpp"
  5. #include "gp/math/rendering/renderer.hpp"
  6. #include "gp/math/rendering/bmp_viewport.hpp"
  7. #include <chrono>
  8. #include <cmath>
  9. #include <fstream>
  10. #include <iomanip>
  11. #include <iostream>
  12. #include <random>
  13. #include <string>
  14. typedef std::mt19937_64 cheap_rand;
  15. struct sin_test : public test_scaffold {
  16. sin_test() {
  17. name = __FILE__ ":1";
  18. }
  19. virtual int run() {
  20. int res = 0;
  21. for(float i = 0; i < 100; i += 0.1) {
  22. float v = gp::math::sin(i);
  23. float ref = sin(i);
  24. res += 0.3 < gp::math::abs<float>(ref - v)*100.0/(gp::math::abs(ref+0.00000001));
  25. }
  26. for(float i = 0; i < 100; i += 0.1) {
  27. float v = gp::math::cos(i);
  28. float ref = cos(i);
  29. res += 0.3 < gp::math::abs<float>(ref - v)*100.0/(gp::math::abs(ref+0.00000001));
  30. }
  31. for(float i = 0; i < 100; i += 0.1) {
  32. float v = gp::math::cos(i)*gp::math::cos(i) + gp::math::sin(i)*gp::math::sin(i);
  33. res += 1 + gp_config::rendering::epsilon < v;
  34. res += 1 - gp_config::rendering::epsilon > v;
  35. }
  36. return res;
  37. }
  38. };
  39. append_test dummy_mldffh6f(new sin_test{});
  40. struct render_test : public test_scaffold {
  41. render_test() {
  42. name = __FILE__ ":2";
  43. }
  44. virtual int run() {
  45. using namespace gp::math::rendering;
  46. int res = 0;
  47. gp::array<char, 2048> allocation_buffer;
  48. renderer a{allocation_buffer.as_buffer()};
  49. a._resolution = vec2{128,64};
  50. a.passes = 5;
  51. a.projection_end = 3;
  52. a.sky_box = material_t([](vec3) -> color_t {
  53. color_t ret;
  54. ret.r() = 0.5;
  55. ret.g() = 0.5;
  56. ret.b() = 1;
  57. ret.a() = 1;
  58. return ret;
  59. }, a.get_allocator());
  60. auto red = a.materials.push(
  61. material_t([&](vec3 p) -> color_t {
  62. color_t ret;
  63. ret.r() = 1;
  64. ret.g() = 0;
  65. ret.b() = 0;
  66. ret.a() = 1;
  67. return ret;
  68. }, a.get_allocator())
  69. );
  70. auto green = a.materials.push(
  71. material_t([&](vec3 p) -> color_t {
  72. color_t ret;
  73. ret.r() = 0;
  74. ret.g() = 1;
  75. ret.b() = 0;
  76. ret.a() = 1;
  77. return ret;
  78. }, a.get_allocator())
  79. );
  80. auto sphere = a.scene_elements.push(
  81. sdf_t([&](vec3 pos) -> render_point {
  82. auto l_sdf = gp::math::difference_sdf<float>(
  83. gp::math::sphere_sdf<float>({0.0,0.0,0.0}, 1.0),
  84. gp::math::sphere_sdf<float>({-0.75,0.0,0.0}, 1.0)
  85. );
  86. render_point ret;
  87. ret.distance = l_sdf(pos);
  88. ret.material = red;
  89. return ret;
  90. }, a.get_allocator())
  91. );
  92. auto sphere2 = a.scene_elements.push(
  93. sdf_t([&](vec3 pos) -> render_point {
  94. auto l_sdf_b = gp::math::sphere_sdf<float>({-0.75,0.0,0.0}, 0.05);
  95. render_point ret;
  96. ret.distance = l_sdf_b(pos);
  97. ret.material = green;
  98. return ret;
  99. }, a.get_allocator())
  100. );
  101. a._camera.position = vec3{0, 0, -5};
  102. a._camera.normal = vec3{0, 0, 1};
  103. using pic_color = gp::math::vec4_g<uint8_t>;
  104. using viewport = gp::bmp_viewport<true, pic_color>;
  105. viewport vp{
  106. {128,64},
  107. viewport::src_t{[&](gp::math::vec2_g<int32_t> p) -> pic_color {
  108. auto orig = a.render({(float)p.x,(float)p.y});
  109. pic_color ret{};
  110. ret.x = (uint8_t)(orig.x*255);
  111. ret.y = (uint8_t)(orig.y*255);
  112. ret.z = (uint8_t)(orig.z*255);
  113. ret.w = (uint8_t)(orig.w*255);
  114. return ret;
  115. }, a.get_allocator()}
  116. };
  117. auto buff = std::make_unique<gp::array<char, 300000>>();
  118. auto begin = std::chrono::steady_clock::now();
  119. auto r_end = vp.write(buff->as_buffer());
  120. auto end = std::chrono::steady_clock::now();
  121. std::cout << "render time: " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
  122. auto myfile = std::fstream("render.bmp", std::ios::out | std::ios::binary);
  123. myfile.write(buff->begin().data, r_end - buff->begin());
  124. //gp_config::assertion(a.render(vec2{64,32}).x == color_t{1.0,0,0,1.0}.x, "red sphere not perceived");
  125. //gp_config::assertion(a.render(vec2{0,0}).x == color_t{0.0,0,1.0,1.0}.x, "blue sky not perceived");
  126. return res;
  127. }
  128. };
  129. append_test dummy_pzj6f(new render_test{});
  130. struct function_test : public test_scaffold {
  131. function_test() {
  132. name = __FILE__ ":3";
  133. }
  134. virtual int run() {
  135. using namespace gp::math::rendering;
  136. int res = 0;
  137. gp::array<char, 2048> allocation_buffer;
  138. gp::buddy<> allocator{allocation_buffer.begin().data, allocation_buffer.size()};
  139. gp::function<float(vec3)> l_sdf_b{gp::math::sphere_sdf<float>({0.0,0.0,0.0}, 1.0), allocator};
  140. {
  141. gp::function<float(vec3)> sdf{l_sdf_b};
  142. gp_config::assertion(l_sdf_b(vec3(0,0,0)) == -1 && sdf(vec3(0,0,0)) == -1, "Bad sdf");
  143. }
  144. return res;
  145. }
  146. };
  147. append_test dummy_ml8576f(new function_test{});
  148. template<typename T>
  149. struct math_funcs_test : public test_scaffold {
  150. uint32_t seed;
  151. T low;
  152. T high;
  153. math_funcs_test(T low = std::numeric_limits<T>::min(), T high = std::numeric_limits<T>::max()) {
  154. this->low = low;
  155. this->high = high;
  156. seed = std::random_device{}();
  157. name = __FILE__ ":4_math_funcs";
  158. name += std::to_string(seed);
  159. }
  160. virtual int run() {
  161. cheap_rand setter(seed);
  162. bool result = true;
  163. std::uniform_real_distribution<T> dist{low, high};
  164. for(int i = 0 ; i < 10000; i++)
  165. {
  166. // TODO: Verify things, like, for real
  167. gp::pair<T, T> v{dist(setter), dist(setter)};
  168. gp::pair<T, T>
  169. floorsign{gp::math::floor<T>(v.first), gp::math::sign(v.second)},
  170. sincos{gp::math::sin(v.first), gp::math::cos(v.second)},
  171. isqrt{gp::math::isqrt(v.first), gp::math::fast_isqrt(v.second)};
  172. double tan_v = gp::math::tan(dist(setter));
  173. double sign_v = gp::math::sign<T>(0);
  174. result += floorsign.first > v.first;
  175. result += gp::math::abs(floorsign.second) == 1;
  176. //result = ascending.first == descending.second ? result : false;
  177. }
  178. return !result;
  179. }
  180. };
  181. append_test dummy_5qsz5ert443(new math_funcs_test<float>{});
  182. append_test dummy_436z5ert443(new math_funcs_test<double>{});
  183. append_test dummy_mqlsdf123(new math_funcs_test<float>{-10,10});
  184. append_test dummy_mqlsdf456(new math_funcs_test<double>{-10,10});