Platformer in OpenGL
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.

458 lines
8.9 KiB

5 years ago
  1. #include <glm/gtc/round.hpp>
  2. #include <glm/gtc/type_precision.hpp>
  3. #include <glm/gtc/vec1.hpp>
  4. #include <glm/gtc/epsilon.hpp>
  5. #include <vector>
  6. #include <ctime>
  7. #include <cstdio>
  8. namespace isPowerOfTwo
  9. {
  10. template<typename genType>
  11. struct type
  12. {
  13. genType Value;
  14. bool Return;
  15. };
  16. int test_int16()
  17. {
  18. type<glm::int16> const Data[] =
  19. {
  20. {0x0001, true},
  21. {0x0002, true},
  22. {0x0004, true},
  23. {0x0080, true},
  24. {0x0000, true},
  25. {0x0003, false}
  26. };
  27. int Error(0);
  28. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<glm::int16>); i < n; ++i)
  29. {
  30. bool Result = glm::isPowerOfTwo(Data[i].Value);
  31. Error += Data[i].Return == Result ? 0 : 1;
  32. }
  33. return Error;
  34. }
  35. int test_uint16()
  36. {
  37. type<glm::uint16> const Data[] =
  38. {
  39. {0x0001, true},
  40. {0x0002, true},
  41. {0x0004, true},
  42. {0x0000, true},
  43. {0x0000, true},
  44. {0x0003, false}
  45. };
  46. int Error(0);
  47. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<glm::uint16>); i < n; ++i)
  48. {
  49. bool Result = glm::isPowerOfTwo(Data[i].Value);
  50. Error += Data[i].Return == Result ? 0 : 1;
  51. }
  52. return Error;
  53. }
  54. int test_int32()
  55. {
  56. type<int> const Data[] =
  57. {
  58. {0x00000001, true},
  59. {0x00000002, true},
  60. {0x00000004, true},
  61. {0x0000000f, false},
  62. {0x00000000, true},
  63. {0x00000003, false}
  64. };
  65. int Error(0);
  66. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<int>); i < n; ++i)
  67. {
  68. bool Result = glm::isPowerOfTwo(Data[i].Value);
  69. Error += Data[i].Return == Result ? 0 : 1;
  70. }
  71. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<int>); i < n; ++i)
  72. {
  73. glm::bvec1 Result = glm::isPowerOfTwo(glm::ivec1(Data[i].Value));
  74. Error += glm::all(glm::equal(glm::bvec1(Data[i].Return), Result)) ? 0 : 1;
  75. }
  76. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<int>); i < n; ++i)
  77. {
  78. glm::bvec2 Result = glm::isPowerOfTwo(glm::ivec2(Data[i].Value));
  79. Error += glm::all(glm::equal(glm::bvec2(Data[i].Return), Result)) ? 0 : 1;
  80. }
  81. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<int>); i < n; ++i)
  82. {
  83. glm::bvec3 Result = glm::isPowerOfTwo(glm::ivec3(Data[i].Value));
  84. Error += glm::all(glm::equal(glm::bvec3(Data[i].Return), Result)) ? 0 : 1;
  85. }
  86. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<int>); i < n; ++i)
  87. {
  88. glm::bvec4 Result = glm::isPowerOfTwo(glm::ivec4(Data[i].Value));
  89. Error += glm::all(glm::equal(glm::bvec4(Data[i].Return), Result)) ? 0 : 1;
  90. }
  91. return Error;
  92. }
  93. int test_uint32()
  94. {
  95. type<glm::uint> const Data[] =
  96. {
  97. {0x00000001, true},
  98. {0x00000002, true},
  99. {0x00000004, true},
  100. {0x80000000, true},
  101. {0x00000000, true},
  102. {0x00000003, false}
  103. };
  104. int Error(0);
  105. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<glm::uint>); i < n; ++i)
  106. {
  107. bool Result = glm::isPowerOfTwo(Data[i].Value);
  108. Error += Data[i].Return == Result ? 0 : 1;
  109. }
  110. return Error;
  111. }
  112. int test()
  113. {
  114. int Error(0);
  115. Error += test_int16();
  116. Error += test_uint16();
  117. Error += test_int32();
  118. Error += test_uint32();
  119. return Error;
  120. }
  121. }//isPowerOfTwo
  122. namespace ceilPowerOfTwo_advanced
  123. {
  124. template<typename genIUType>
  125. GLM_FUNC_QUALIFIER genIUType highestBitValue(genIUType Value)
  126. {
  127. genIUType tmp = Value;
  128. genIUType result = genIUType(0);
  129. while(tmp)
  130. {
  131. result = (tmp & (~tmp + 1)); // grab lowest bit
  132. tmp &= ~result; // clear lowest bit
  133. }
  134. return result;
  135. }
  136. template<typename genType>
  137. GLM_FUNC_QUALIFIER genType ceilPowerOfTwo_loop(genType value)
  138. {
  139. return glm::isPowerOfTwo(value) ? value : highestBitValue(value) << 1;
  140. }
  141. template<typename genType>
  142. struct type
  143. {
  144. genType Value;
  145. genType Return;
  146. };
  147. int test_int32()
  148. {
  149. type<glm::int32> const Data[] =
  150. {
  151. {0x0000ffff, 0x00010000},
  152. {-3, -4},
  153. {-8, -8},
  154. {0x00000001, 0x00000001},
  155. {0x00000002, 0x00000002},
  156. {0x00000004, 0x00000004},
  157. {0x00000007, 0x00000008},
  158. {0x0000fff0, 0x00010000},
  159. {0x0000f000, 0x00010000},
  160. {0x08000000, 0x08000000},
  161. {0x00000000, 0x00000000},
  162. {0x00000003, 0x00000004}
  163. };
  164. int Error(0);
  165. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<glm::int32>); i < n; ++i)
  166. {
  167. glm::int32 Result = glm::ceilPowerOfTwo(Data[i].Value);
  168. Error += Data[i].Return == Result ? 0 : 1;
  169. }
  170. return Error;
  171. }
  172. int test_uint32()
  173. {
  174. type<glm::uint32> const Data[] =
  175. {
  176. {0x00000001, 0x00000001},
  177. {0x00000002, 0x00000002},
  178. {0x00000004, 0x00000004},
  179. {0x00000007, 0x00000008},
  180. {0x0000ffff, 0x00010000},
  181. {0x0000fff0, 0x00010000},
  182. {0x0000f000, 0x00010000},
  183. {0x80000000, 0x80000000},
  184. {0x00000000, 0x00000000},
  185. {0x00000003, 0x00000004}
  186. };
  187. int Error(0);
  188. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<glm::uint32>); i < n; ++i)
  189. {
  190. glm::uint32 Result = glm::ceilPowerOfTwo(Data[i].Value);
  191. Error += Data[i].Return == Result ? 0 : 1;
  192. }
  193. return Error;
  194. }
  195. int perf()
  196. {
  197. int Error(0);
  198. std::vector<glm::uint> v;
  199. v.resize(100000000);
  200. std::clock_t Timestramp0 = std::clock();
  201. for(glm::uint32 i = 0, n = static_cast<glm::uint>(v.size()); i < n; ++i)
  202. v[i] = ceilPowerOfTwo_loop(i);
  203. std::clock_t Timestramp1 = std::clock();
  204. for(glm::uint32 i = 0, n = static_cast<glm::uint>(v.size()); i < n; ++i)
  205. v[i] = glm::ceilPowerOfTwo(i);
  206. std::clock_t Timestramp2 = std::clock();
  207. std::printf("ceilPowerOfTwo_loop: %d clocks\n", static_cast<int>(Timestramp1 - Timestramp0));
  208. std::printf("glm::ceilPowerOfTwo: %d clocks\n", static_cast<int>(Timestramp2 - Timestramp1));
  209. return Error;
  210. }
  211. int test()
  212. {
  213. int Error(0);
  214. Error += test_int32();
  215. Error += test_uint32();
  216. return Error;
  217. }
  218. }//namespace ceilPowerOfTwo_advanced
  219. namespace roundPowerOfTwo
  220. {
  221. int test()
  222. {
  223. int Error = 0;
  224. glm::uint32 const A = glm::roundPowerOfTwo(7u);
  225. Error += A == 8u ? 0 : 1;
  226. glm::uint32 const B = glm::roundPowerOfTwo(15u);
  227. Error += B == 16u ? 0 : 1;
  228. glm::uint32 const C = glm::roundPowerOfTwo(31u);
  229. Error += C == 32u ? 0 : 1;
  230. glm::uint32 const D = glm::roundPowerOfTwo(9u);
  231. Error += D == 8u ? 0 : 1;
  232. glm::uint32 const E = glm::roundPowerOfTwo(17u);
  233. Error += E == 16u ? 0 : 1;
  234. glm::uint32 const F = glm::roundPowerOfTwo(33u);
  235. Error += F == 32u ? 0 : 1;
  236. return Error;
  237. }
  238. }//namespace roundPowerOfTwo
  239. namespace floorPowerOfTwo
  240. {
  241. int test()
  242. {
  243. int Error = 0;
  244. glm::uint32 const A = glm::floorPowerOfTwo(7u);
  245. Error += A == 4u ? 0 : 1;
  246. glm::uint32 const B = glm::floorPowerOfTwo(15u);
  247. Error += B == 8u ? 0 : 1;
  248. glm::uint32 const C = glm::floorPowerOfTwo(31u);
  249. Error += C == 16u ? 0 : 1;
  250. return Error;
  251. }
  252. }//namespace floorPowerOfTwo
  253. namespace ceilPowerOfTwo
  254. {
  255. int test()
  256. {
  257. int Error = 0;
  258. glm::uint32 const A = glm::ceilPowerOfTwo(7u);
  259. Error += A == 8u ? 0 : 1;
  260. glm::uint32 const B = glm::ceilPowerOfTwo(15u);
  261. Error += B == 16u ? 0 : 1;
  262. glm::uint32 const C = glm::ceilPowerOfTwo(31u);
  263. Error += C == 32u ? 0 : 1;
  264. return Error;
  265. }
  266. }//namespace ceilPowerOfTwo
  267. namespace floorMultiple
  268. {
  269. template<typename genType>
  270. struct type
  271. {
  272. genType Source;
  273. genType Multiple;
  274. genType Return;
  275. genType Epsilon;
  276. };
  277. int test_float()
  278. {
  279. type<glm::float64> const Data[] =
  280. {
  281. {3.4, 0.3, 3.3, 0.0001},
  282. {-1.4, 0.3, -1.5, 0.0001},
  283. };
  284. int Error(0);
  285. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<glm::float64>); i < n; ++i)
  286. {
  287. glm::float64 Result = glm::floorMultiple(Data[i].Source, Data[i].Multiple);
  288. Error += glm::epsilonEqual(Data[i].Return, Result, Data[i].Epsilon) ? 0 : 1;
  289. }
  290. return Error;
  291. }
  292. int test()
  293. {
  294. int Error(0);
  295. Error += test_float();
  296. return Error;
  297. }
  298. }//namespace floorMultiple
  299. namespace ceilMultiple
  300. {
  301. template<typename genType>
  302. struct type
  303. {
  304. genType Source;
  305. genType Multiple;
  306. genType Return;
  307. genType Epsilon;
  308. };
  309. int test_float()
  310. {
  311. type<glm::float64> const Data[] =
  312. {
  313. {3.4, 0.3, 3.6, 0.0001},
  314. {-1.4, 0.3, -1.2, 0.0001},
  315. };
  316. int Error(0);
  317. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<glm::float64>); i < n; ++i)
  318. {
  319. glm::float64 Result = glm::ceilMultiple(Data[i].Source, Data[i].Multiple);
  320. Error += glm::epsilonEqual(Data[i].Return, Result, Data[i].Epsilon) ? 0 : 1;
  321. }
  322. return Error;
  323. }
  324. int test_int()
  325. {
  326. type<int> const Data[] =
  327. {
  328. {3, 4, 4, 0},
  329. {7, 4, 8, 0},
  330. {5, 4, 8, 0},
  331. {1, 4, 4, 0},
  332. {1, 3, 3, 0},
  333. {4, 3, 6, 0},
  334. {4, 1, 4, 0},
  335. {1, 1, 1, 0},
  336. {7, 1, 7, 0},
  337. };
  338. int Error(0);
  339. for(std::size_t i = 0, n = sizeof(Data) / sizeof(type<int>); i < n; ++i)
  340. {
  341. int Result = glm::ceilMultiple(Data[i].Source, Data[i].Multiple);
  342. Error += Data[i].Return == Result ? 0 : 1;
  343. }
  344. return Error;
  345. }
  346. int test()
  347. {
  348. int Error(0);
  349. Error += test_int();
  350. Error += test_float();
  351. return Error;
  352. }
  353. }//namespace ceilMultiple
  354. int main()
  355. {
  356. int Error(0);
  357. Error += isPowerOfTwo::test();
  358. Error += floorPowerOfTwo::test();
  359. Error += roundPowerOfTwo::test();
  360. Error += ceilPowerOfTwo::test();
  361. Error += ceilPowerOfTwo_advanced::test();
  362. # ifdef NDEBUG
  363. Error += ceilPowerOfTwo_advanced::perf();
  364. # endif//NDEBUG
  365. Error += floorMultiple::test();
  366. Error += ceilMultiple::test();
  367. return Error;
  368. }