packing.inl 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. /// @ref gtc_packing
  2. #include "../ext/scalar_relational.hpp"
  3. #include "../ext/vector_relational.hpp"
  4. #include "../common.hpp"
  5. #include "../vec2.hpp"
  6. #include "../vec3.hpp"
  7. #include "../vec4.hpp"
  8. #include "../detail/type_half.hpp"
  9. #include <cstring>
  10. #include <limits>
  11. namespace glm{
  12. namespace detail
  13. {
  14. GLM_FUNC_QUALIFIER glm::uint16 float2half(glm::uint32 f)
  15. {
  16. // 10 bits => EE EEEFFFFF
  17. // 11 bits => EEE EEFFFFFF
  18. // Half bits => SEEEEEFF FFFFFFFF
  19. // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
  20. // 0x00007c00 => 00000000 00000000 01111100 00000000
  21. // 0x000003ff => 00000000 00000000 00000011 11111111
  22. // 0x38000000 => 00111000 00000000 00000000 00000000
  23. // 0x7f800000 => 01111111 10000000 00000000 00000000
  24. // 0x00008000 => 00000000 00000000 10000000 00000000
  25. return
  26. ((f >> 16) & 0x8000) | // sign
  27. ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00) | // exponential
  28. ((f >> 13) & 0x03ff); // Mantissa
  29. }
  30. GLM_FUNC_QUALIFIER glm::uint32 float2packed11(glm::uint32 f)
  31. {
  32. // 10 bits => EE EEEFFFFF
  33. // 11 bits => EEE EEFFFFFF
  34. // Half bits => SEEEEEFF FFFFFFFF
  35. // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
  36. // 0x000007c0 => 00000000 00000000 00000111 11000000
  37. // 0x00007c00 => 00000000 00000000 01111100 00000000
  38. // 0x000003ff => 00000000 00000000 00000011 11111111
  39. // 0x38000000 => 00111000 00000000 00000000 00000000
  40. // 0x7f800000 => 01111111 10000000 00000000 00000000
  41. // 0x00008000 => 00000000 00000000 10000000 00000000
  42. return
  43. ((((f & 0x7f800000) - 0x38000000) >> 17) & 0x07c0) | // exponential
  44. ((f >> 17) & 0x003f); // Mantissa
  45. }
  46. GLM_FUNC_QUALIFIER glm::uint32 packed11ToFloat(glm::uint32 p)
  47. {
  48. // 10 bits => EE EEEFFFFF
  49. // 11 bits => EEE EEFFFFFF
  50. // Half bits => SEEEEEFF FFFFFFFF
  51. // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
  52. // 0x000007c0 => 00000000 00000000 00000111 11000000
  53. // 0x00007c00 => 00000000 00000000 01111100 00000000
  54. // 0x000003ff => 00000000 00000000 00000011 11111111
  55. // 0x38000000 => 00111000 00000000 00000000 00000000
  56. // 0x7f800000 => 01111111 10000000 00000000 00000000
  57. // 0x00008000 => 00000000 00000000 10000000 00000000
  58. return
  59. ((((p & 0x07c0) << 17) + 0x38000000) & 0x7f800000) | // exponential
  60. ((p & 0x003f) << 17); // Mantissa
  61. }
  62. GLM_FUNC_QUALIFIER glm::uint32 float2packed10(glm::uint32 f)
  63. {
  64. // 10 bits => EE EEEFFFFF
  65. // 11 bits => EEE EEFFFFFF
  66. // Half bits => SEEEEEFF FFFFFFFF
  67. // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
  68. // 0x0000001F => 00000000 00000000 00000000 00011111
  69. // 0x0000003F => 00000000 00000000 00000000 00111111
  70. // 0x000003E0 => 00000000 00000000 00000011 11100000
  71. // 0x000007C0 => 00000000 00000000 00000111 11000000
  72. // 0x00007C00 => 00000000 00000000 01111100 00000000
  73. // 0x000003FF => 00000000 00000000 00000011 11111111
  74. // 0x38000000 => 00111000 00000000 00000000 00000000
  75. // 0x7f800000 => 01111111 10000000 00000000 00000000
  76. // 0x00008000 => 00000000 00000000 10000000 00000000
  77. return
  78. ((((f & 0x7f800000) - 0x38000000) >> 18) & 0x03E0) | // exponential
  79. ((f >> 18) & 0x001f); // Mantissa
  80. }
  81. GLM_FUNC_QUALIFIER glm::uint32 packed10ToFloat(glm::uint32 p)
  82. {
  83. // 10 bits => EE EEEFFFFF
  84. // 11 bits => EEE EEFFFFFF
  85. // Half bits => SEEEEEFF FFFFFFFF
  86. // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
  87. // 0x0000001F => 00000000 00000000 00000000 00011111
  88. // 0x0000003F => 00000000 00000000 00000000 00111111
  89. // 0x000003E0 => 00000000 00000000 00000011 11100000
  90. // 0x000007C0 => 00000000 00000000 00000111 11000000
  91. // 0x00007C00 => 00000000 00000000 01111100 00000000
  92. // 0x000003FF => 00000000 00000000 00000011 11111111
  93. // 0x38000000 => 00111000 00000000 00000000 00000000
  94. // 0x7f800000 => 01111111 10000000 00000000 00000000
  95. // 0x00008000 => 00000000 00000000 10000000 00000000
  96. return
  97. ((((p & 0x03E0) << 18) + 0x38000000) & 0x7f800000) | // exponential
  98. ((p & 0x001f) << 18); // Mantissa
  99. }
  100. GLM_FUNC_QUALIFIER glm::uint half2float(glm::uint h)
  101. {
  102. return ((h & 0x8000) << 16) | ((( h & 0x7c00) + 0x1C000) << 13) | ((h & 0x03FF) << 13);
  103. }
  104. GLM_FUNC_QUALIFIER glm::uint floatTo11bit(float x)
  105. {
  106. if(x == 0.0f)
  107. return 0u;
  108. else if(glm::isnan(x))
  109. return ~0u;
  110. else if(glm::isinf(x))
  111. return 0x1Fu << 6u;
  112. uint Pack = 0u;
  113. memcpy(&Pack, &x, sizeof(Pack));
  114. return float2packed11(Pack);
  115. }
  116. GLM_FUNC_QUALIFIER float packed11bitToFloat(glm::uint x)
  117. {
  118. if(x == 0)
  119. return 0.0f;
  120. else if(x == ((1 << 11) - 1))
  121. return ~0;//NaN
  122. else if(x == (0x1f << 6))
  123. return ~0;//Inf
  124. uint Result = packed11ToFloat(x);
  125. float Temp = 0;
  126. memcpy(&Temp, &Result, sizeof(Temp));
  127. return Temp;
  128. }
  129. GLM_FUNC_QUALIFIER glm::uint floatTo10bit(float x)
  130. {
  131. if(x == 0.0f)
  132. return 0u;
  133. else if(glm::isnan(x))
  134. return ~0u;
  135. else if(glm::isinf(x))
  136. return 0x1Fu << 5u;
  137. uint Pack = 0;
  138. memcpy(&Pack, &x, sizeof(Pack));
  139. return float2packed10(Pack);
  140. }
  141. GLM_FUNC_QUALIFIER float packed10bitToFloat(glm::uint x)
  142. {
  143. if(x == 0)
  144. return 0.0f;
  145. else if(x == ((1 << 10) - 1))
  146. return ~0;//NaN
  147. else if(x == (0x1f << 5))
  148. return ~0;//Inf
  149. uint Result = packed10ToFloat(x);
  150. float Temp = 0;
  151. memcpy(&Temp, &Result, sizeof(Temp));
  152. return Temp;
  153. }
  154. // GLM_FUNC_QUALIFIER glm::uint f11_f11_f10(float x, float y, float z)
  155. // {
  156. // return ((floatTo11bit(x) & ((1 << 11) - 1)) << 0) | ((floatTo11bit(y) & ((1 << 11) - 1)) << 11) | ((floatTo10bit(z) & ((1 << 10) - 1)) << 22);
  157. // }
  158. #if GLM_SILENT_WARNINGS == GLM_ENABLE
  159. # if defined(__clang__)
  160. # pragma clang diagnostic push
  161. # pragma clang diagnostic ignored "-Wpadded"
  162. # endif
  163. #endif
  164. union u3u3u2
  165. {
  166. struct Data
  167. {
  168. uint x : 3;
  169. uint y : 3;
  170. uint z : 2;
  171. } data;
  172. uint8 pack;
  173. };
  174. union u4u4
  175. {
  176. struct Data
  177. {
  178. uint x : 4;
  179. uint y : 4;
  180. } data;
  181. uint8 pack;
  182. };
  183. union u4u4u4u4
  184. {
  185. struct Data
  186. {
  187. uint x : 4;
  188. uint y : 4;
  189. uint z : 4;
  190. uint w : 4;
  191. } data;
  192. uint16 pack;
  193. };
  194. union u5u6u5
  195. {
  196. struct Data
  197. {
  198. uint x : 5;
  199. uint y : 6;
  200. uint z : 5;
  201. } data;
  202. uint16 pack;
  203. };
  204. union u5u5u5u1
  205. {
  206. struct Data
  207. {
  208. uint x : 5;
  209. uint y : 5;
  210. uint z : 5;
  211. uint w : 1;
  212. } data;
  213. uint16 pack;
  214. };
  215. #if GLM_SILENT_WARNINGS == GLM_ENABLE
  216. # if defined(__clang__)
  217. # pragma clang diagnostic pop
  218. # endif
  219. #endif
  220. union u10u10u10u2
  221. {
  222. struct Data
  223. {
  224. uint x : 10;
  225. uint y : 10;
  226. uint z : 10;
  227. uint w : 2;
  228. } data;
  229. uint32 pack;
  230. };
  231. union i10i10i10i2
  232. {
  233. struct Data
  234. {
  235. int x : 10;
  236. int y : 10;
  237. int z : 10;
  238. int w : 2;
  239. } data;
  240. uint32 pack;
  241. };
  242. union u9u9u9e5
  243. {
  244. struct Data
  245. {
  246. uint x : 9;
  247. uint y : 9;
  248. uint z : 9;
  249. uint w : 5;
  250. } data;
  251. uint32 pack;
  252. };
  253. template<length_t L, qualifier Q>
  254. struct compute_half
  255. {};
  256. template<qualifier Q>
  257. struct compute_half<1, Q>
  258. {
  259. GLM_FUNC_QUALIFIER static vec<1, uint16, Q> pack(vec<1, float, Q> const& v)
  260. {
  261. int16 const Unpack(detail::toFloat16(v.x));
  262. u16vec1 Packed;
  263. memcpy(&Packed, &Unpack, sizeof(Packed));
  264. return Packed;
  265. }
  266. GLM_FUNC_QUALIFIER static vec<1, float, Q> unpack(vec<1, uint16, Q> const& v)
  267. {
  268. i16vec1 Unpack;
  269. memcpy(&Unpack, &v, sizeof(Unpack));
  270. return vec<1, float, Q>(detail::toFloat32(v.x));
  271. }
  272. };
  273. template<qualifier Q>
  274. struct compute_half<2, Q>
  275. {
  276. GLM_FUNC_QUALIFIER static vec<2, uint16, Q> pack(vec<2, float, Q> const& v)
  277. {
  278. vec<2, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y));
  279. u16vec2 Packed;
  280. memcpy(&Packed, &Unpack, sizeof(Packed));
  281. return Packed;
  282. }
  283. GLM_FUNC_QUALIFIER static vec<2, float, Q> unpack(vec<2, uint16, Q> const& v)
  284. {
  285. i16vec2 Unpack;
  286. memcpy(&Unpack, &v, sizeof(Unpack));
  287. return vec<2, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y));
  288. }
  289. };
  290. template<qualifier Q>
  291. struct compute_half<3, Q>
  292. {
  293. GLM_FUNC_QUALIFIER static vec<3, uint16, Q> pack(vec<3, float, Q> const& v)
  294. {
  295. vec<3, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y), detail::toFloat16(v.z));
  296. u16vec3 Packed;
  297. memcpy(&Packed, &Unpack, sizeof(Packed));
  298. return Packed;
  299. }
  300. GLM_FUNC_QUALIFIER static vec<3, float, Q> unpack(vec<3, uint16, Q> const& v)
  301. {
  302. i16vec3 Unpack;
  303. memcpy(&Unpack, &v, sizeof(Unpack));
  304. return vec<3, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y), detail::toFloat32(v.z));
  305. }
  306. };
  307. template<qualifier Q>
  308. struct compute_half<4, Q>
  309. {
  310. GLM_FUNC_QUALIFIER static vec<4, uint16, Q> pack(vec<4, float, Q> const& v)
  311. {
  312. vec<4, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y), detail::toFloat16(v.z), detail::toFloat16(v.w));
  313. u16vec4 Packed;
  314. memcpy(&Packed, &Unpack, sizeof(Packed));
  315. return Packed;
  316. }
  317. GLM_FUNC_QUALIFIER static vec<4, float, Q> unpack(vec<4, uint16, Q> const& v)
  318. {
  319. i16vec4 Unpack;
  320. memcpy(&Unpack, &v, sizeof(Unpack));
  321. return vec<4, float, Q>(detail::toFloat32(Unpack.x), detail::toFloat32(Unpack.y), detail::toFloat32(Unpack.z), detail::toFloat32(Unpack.w));
  322. }
  323. };
  324. }//namespace detail
  325. GLM_FUNC_QUALIFIER uint8 packUnorm1x8(float v)
  326. {
  327. return static_cast<uint8>(round(clamp(v, 0.0f, 1.0f) * 255.0f));
  328. }
  329. GLM_FUNC_QUALIFIER float unpackUnorm1x8(uint8 p)
  330. {
  331. float const Unpack(p);
  332. return Unpack * static_cast<float>(0.0039215686274509803921568627451); // 1 / 255
  333. }
  334. GLM_FUNC_QUALIFIER uint16 packUnorm2x8(vec2 const& v)
  335. {
  336. u8vec2 const Topack(round(clamp(v, 0.0f, 1.0f) * 255.0f));
  337. uint16 Unpack = 0;
  338. memcpy(&Unpack, &Topack, sizeof(Unpack));
  339. return Unpack;
  340. }
  341. GLM_FUNC_QUALIFIER vec2 unpackUnorm2x8(uint16 p)
  342. {
  343. u8vec2 Unpack;
  344. memcpy(&Unpack, &p, sizeof(Unpack));
  345. return vec2(Unpack) * float(0.0039215686274509803921568627451); // 1 / 255
  346. }
  347. GLM_FUNC_QUALIFIER uint8 packSnorm1x8(float v)
  348. {
  349. int8 const Topack(static_cast<int8>(round(clamp(v ,-1.0f, 1.0f) * 127.0f)));
  350. uint8 Packed = 0;
  351. memcpy(&Packed, &Topack, sizeof(Packed));
  352. return Packed;
  353. }
  354. GLM_FUNC_QUALIFIER float unpackSnorm1x8(uint8 p)
  355. {
  356. int8 Unpack = 0;
  357. memcpy(&Unpack, &p, sizeof(Unpack));
  358. return clamp(
  359. static_cast<float>(Unpack) * 0.00787401574803149606299212598425f, // 1.0f / 127.0f
  360. -1.0f, 1.0f);
  361. }
  362. GLM_FUNC_QUALIFIER uint16 packSnorm2x8(vec2 const& v)
  363. {
  364. i8vec2 const Topack(round(clamp(v, -1.0f, 1.0f) * 127.0f));
  365. uint16 Packed = 0;
  366. memcpy(&Packed, &Topack, sizeof(Packed));
  367. return Packed;
  368. }
  369. GLM_FUNC_QUALIFIER vec2 unpackSnorm2x8(uint16 p)
  370. {
  371. i8vec2 Unpack;
  372. memcpy(&Unpack, &p, sizeof(Unpack));
  373. return clamp(
  374. vec2(Unpack) * 0.00787401574803149606299212598425f, // 1.0f / 127.0f
  375. -1.0f, 1.0f);
  376. }
  377. GLM_FUNC_QUALIFIER uint16 packUnorm1x16(float s)
  378. {
  379. return static_cast<uint16>(round(clamp(s, 0.0f, 1.0f) * 65535.0f));
  380. }
  381. GLM_FUNC_QUALIFIER float unpackUnorm1x16(uint16 p)
  382. {
  383. float const Unpack(p);
  384. return Unpack * 1.5259021896696421759365224689097e-5f; // 1.0 / 65535.0
  385. }
  386. GLM_FUNC_QUALIFIER uint64 packUnorm4x16(vec4 const& v)
  387. {
  388. u16vec4 const Topack(round(clamp(v , 0.0f, 1.0f) * 65535.0f));
  389. uint64 Packed = 0;
  390. memcpy(&Packed, &Topack, sizeof(Packed));
  391. return Packed;
  392. }
  393. GLM_FUNC_QUALIFIER vec4 unpackUnorm4x16(uint64 p)
  394. {
  395. u16vec4 Unpack;
  396. memcpy(&Unpack, &p, sizeof(Unpack));
  397. return vec4(Unpack) * 1.5259021896696421759365224689097e-5f; // 1.0 / 65535.0
  398. }
  399. GLM_FUNC_QUALIFIER uint16 packSnorm1x16(float v)
  400. {
  401. int16 const Topack = static_cast<int16>(round(clamp(v ,-1.0f, 1.0f) * 32767.0f));
  402. uint16 Packed = 0;
  403. memcpy(&Packed, &Topack, sizeof(Packed));
  404. return Packed;
  405. }
  406. GLM_FUNC_QUALIFIER float unpackSnorm1x16(uint16 p)
  407. {
  408. int16 Unpack = 0;
  409. memcpy(&Unpack, &p, sizeof(Unpack));
  410. return clamp(
  411. static_cast<float>(Unpack) * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f,
  412. -1.0f, 1.0f);
  413. }
  414. GLM_FUNC_QUALIFIER uint64 packSnorm4x16(vec4 const& v)
  415. {
  416. i16vec4 const Topack(round(clamp(v ,-1.0f, 1.0f) * 32767.0f));
  417. uint64 Packed = 0;
  418. memcpy(&Packed, &Topack, sizeof(Packed));
  419. return Packed;
  420. }
  421. GLM_FUNC_QUALIFIER vec4 unpackSnorm4x16(uint64 p)
  422. {
  423. i16vec4 Unpack;
  424. memcpy(&Unpack, &p, sizeof(Unpack));
  425. return clamp(
  426. vec4(Unpack) * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f,
  427. -1.0f, 1.0f);
  428. }
  429. GLM_FUNC_QUALIFIER uint16 packHalf1x16(float v)
  430. {
  431. int16 const Topack(detail::toFloat16(v));
  432. uint16 Packed = 0;
  433. memcpy(&Packed, &Topack, sizeof(Packed));
  434. return Packed;
  435. }
  436. GLM_FUNC_QUALIFIER float unpackHalf1x16(uint16 v)
  437. {
  438. int16 Unpack = 0;
  439. memcpy(&Unpack, &v, sizeof(Unpack));
  440. return detail::toFloat32(Unpack);
  441. }
  442. GLM_FUNC_QUALIFIER uint64 packHalf4x16(glm::vec4 const& v)
  443. {
  444. i16vec4 const Unpack(
  445. detail::toFloat16(v.x),
  446. detail::toFloat16(v.y),
  447. detail::toFloat16(v.z),
  448. detail::toFloat16(v.w));
  449. uint64 Packed = 0;
  450. memcpy(&Packed, &Unpack, sizeof(Packed));
  451. return Packed;
  452. }
  453. GLM_FUNC_QUALIFIER glm::vec4 unpackHalf4x16(uint64 v)
  454. {
  455. i16vec4 Unpack;
  456. memcpy(&Unpack, &v, sizeof(Unpack));
  457. return vec4(
  458. detail::toFloat32(Unpack.x),
  459. detail::toFloat32(Unpack.y),
  460. detail::toFloat32(Unpack.z),
  461. detail::toFloat32(Unpack.w));
  462. }
  463. GLM_FUNC_QUALIFIER uint32 packI3x10_1x2(ivec4 const& v)
  464. {
  465. detail::i10i10i10i2 Result;
  466. Result.data.x = v.x;
  467. Result.data.y = v.y;
  468. Result.data.z = v.z;
  469. Result.data.w = v.w;
  470. return Result.pack;
  471. }
  472. GLM_FUNC_QUALIFIER ivec4 unpackI3x10_1x2(uint32 v)
  473. {
  474. detail::i10i10i10i2 Unpack;
  475. Unpack.pack = v;
  476. return ivec4(
  477. Unpack.data.x,
  478. Unpack.data.y,
  479. Unpack.data.z,
  480. Unpack.data.w);
  481. }
  482. GLM_FUNC_QUALIFIER uint32 packU3x10_1x2(uvec4 const& v)
  483. {
  484. detail::u10u10u10u2 Result;
  485. Result.data.x = v.x;
  486. Result.data.y = v.y;
  487. Result.data.z = v.z;
  488. Result.data.w = v.w;
  489. return Result.pack;
  490. }
  491. GLM_FUNC_QUALIFIER uvec4 unpackU3x10_1x2(uint32 v)
  492. {
  493. detail::u10u10u10u2 Unpack;
  494. Unpack.pack = v;
  495. return uvec4(
  496. Unpack.data.x,
  497. Unpack.data.y,
  498. Unpack.data.z,
  499. Unpack.data.w);
  500. }
  501. GLM_FUNC_QUALIFIER uint32 packSnorm3x10_1x2(vec4 const& v)
  502. {
  503. ivec4 const Pack(round(clamp(v,-1.0f, 1.0f) * vec4(511.f, 511.f, 511.f, 1.f)));
  504. detail::i10i10i10i2 Result;
  505. Result.data.x = Pack.x;
  506. Result.data.y = Pack.y;
  507. Result.data.z = Pack.z;
  508. Result.data.w = Pack.w;
  509. return Result.pack;
  510. }
  511. GLM_FUNC_QUALIFIER vec4 unpackSnorm3x10_1x2(uint32 v)
  512. {
  513. detail::i10i10i10i2 Unpack;
  514. Unpack.pack = v;
  515. vec4 const Result(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w);
  516. return clamp(Result * vec4(1.f / 511.f, 1.f / 511.f, 1.f / 511.f, 1.f), -1.0f, 1.0f);
  517. }
  518. GLM_FUNC_QUALIFIER uint32 packUnorm3x10_1x2(vec4 const& v)
  519. {
  520. uvec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec4(1023.f, 1023.f, 1023.f, 3.f)));
  521. detail::u10u10u10u2 Result;
  522. Result.data.x = Unpack.x;
  523. Result.data.y = Unpack.y;
  524. Result.data.z = Unpack.z;
  525. Result.data.w = Unpack.w;
  526. return Result.pack;
  527. }
  528. GLM_FUNC_QUALIFIER vec4 unpackUnorm3x10_1x2(uint32 v)
  529. {
  530. vec4 const ScaleFactors(1.0f / 1023.f, 1.0f / 1023.f, 1.0f / 1023.f, 1.0f / 3.f);
  531. detail::u10u10u10u2 Unpack;
  532. Unpack.pack = v;
  533. return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactors;
  534. }
  535. GLM_FUNC_QUALIFIER uint32 packF2x11_1x10(vec3 const& v)
  536. {
  537. return
  538. ((detail::floatTo11bit(v.x) & ((1 << 11) - 1)) << 0) |
  539. ((detail::floatTo11bit(v.y) & ((1 << 11) - 1)) << 11) |
  540. ((detail::floatTo10bit(v.z) & ((1 << 10) - 1)) << 22);
  541. }
  542. GLM_FUNC_QUALIFIER vec3 unpackF2x11_1x10(uint32 v)
  543. {
  544. return vec3(
  545. detail::packed11bitToFloat(v >> 0),
  546. detail::packed11bitToFloat(v >> 11),
  547. detail::packed10bitToFloat(v >> 22));
  548. }
  549. GLM_FUNC_QUALIFIER uint32 packF3x9_E1x5(vec3 const& v)
  550. {
  551. float const SharedExpMax = (pow(2.0f, 9.0f - 1.0f) / pow(2.0f, 9.0f)) * pow(2.0f, 31.f - 15.f);
  552. vec3 const Color = clamp(v, 0.0f, SharedExpMax);
  553. float const MaxColor = max(Color.x, max(Color.y, Color.z));
  554. float const ExpSharedP = max(-15.f - 1.f, floor(log2(MaxColor))) + 1.0f + 15.f;
  555. float const MaxShared = floor(MaxColor / pow(2.0f, (ExpSharedP - 15.f - 9.f)) + 0.5f);
  556. float const ExpShared = equal(MaxShared, pow(2.0f, 9.0f), epsilon<float>()) ? ExpSharedP + 1.0f : ExpSharedP;
  557. uvec3 const ColorComp(floor(Color / pow(2.f, (ExpShared - 15.f - 9.f)) + 0.5f));
  558. detail::u9u9u9e5 Unpack;
  559. Unpack.data.x = ColorComp.x;
  560. Unpack.data.y = ColorComp.y;
  561. Unpack.data.z = ColorComp.z;
  562. Unpack.data.w = uint(ExpShared);
  563. return Unpack.pack;
  564. }
  565. GLM_FUNC_QUALIFIER vec3 unpackF3x9_E1x5(uint32 v)
  566. {
  567. detail::u9u9u9e5 Unpack;
  568. Unpack.pack = v;
  569. return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * pow(2.0f, static_cast<float>(Unpack.data.w) - 15.f - 9.f);
  570. }
  571. // Based on Brian Karis http://graphicrants.blogspot.fr/2009/04/rgbm-color-encoding.html
  572. template<typename T, qualifier Q>
  573. GLM_FUNC_QUALIFIER vec<4, T, Q> packRGBM(vec<3, T, Q> const& rgb)
  574. {
  575. vec<3, T, Q> const Color(rgb * static_cast<T>(1.0 / 6.0));
  576. T Alpha = clamp(max(max(Color.x, Color.y), max(Color.z, static_cast<T>(1e-6))), static_cast<T>(0), static_cast<T>(1));
  577. Alpha = ceil(Alpha * static_cast<T>(255.0)) / static_cast<T>(255.0);
  578. return vec<4, T, Q>(Color / Alpha, Alpha);
  579. }
  580. template<typename T, qualifier Q>
  581. GLM_FUNC_QUALIFIER vec<3, T, Q> unpackRGBM(vec<4, T, Q> const& rgbm)
  582. {
  583. return vec<3, T, Q>(rgbm.x, rgbm.y, rgbm.z) * rgbm.w * static_cast<T>(6);
  584. }
  585. template<length_t L, qualifier Q>
  586. GLM_FUNC_QUALIFIER vec<L, uint16, Q> packHalf(vec<L, float, Q> const& v)
  587. {
  588. return detail::compute_half<L, Q>::pack(v);
  589. }
  590. template<length_t L, qualifier Q>
  591. GLM_FUNC_QUALIFIER vec<L, float, Q> unpackHalf(vec<L, uint16, Q> const& v)
  592. {
  593. return detail::compute_half<L, Q>::unpack(v);
  594. }
  595. template<typename uintType, length_t L, typename floatType, qualifier Q>
  596. GLM_FUNC_QUALIFIER vec<L, uintType, Q> packUnorm(vec<L, floatType, Q> const& v)
  597. {
  598. GLM_STATIC_ASSERT(std::numeric_limits<uintType>::is_integer, "uintType must be an integer type");
  599. GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "floatType must be a floating point type");
  600. return vec<L, uintType, Q>(round(clamp(v, static_cast<floatType>(0), static_cast<floatType>(1)) * static_cast<floatType>(std::numeric_limits<uintType>::max())));
  601. }
  602. template<typename floatType, length_t L, typename uintType, qualifier Q>
  603. GLM_FUNC_QUALIFIER vec<L, floatType, Q> unpackUnorm(vec<L, uintType, Q> const& v)
  604. {
  605. GLM_STATIC_ASSERT(std::numeric_limits<uintType>::is_integer, "uintType must be an integer type");
  606. GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "floatType must be a floating point type");
  607. return vec<L, floatType, Q>(v) * (static_cast<floatType>(1) / static_cast<floatType>(std::numeric_limits<uintType>::max()));
  608. }
  609. template<typename intType, length_t L, typename floatType, qualifier Q>
  610. GLM_FUNC_QUALIFIER vec<L, intType, Q> packSnorm(vec<L, floatType, Q> const& v)
  611. {
  612. GLM_STATIC_ASSERT(std::numeric_limits<intType>::is_integer, "uintType must be an integer type");
  613. GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "floatType must be a floating point type");
  614. return vec<L, intType, Q>(round(clamp(v , static_cast<floatType>(-1), static_cast<floatType>(1)) * static_cast<floatType>(std::numeric_limits<intType>::max())));
  615. }
  616. template<typename floatType, length_t L, typename intType, qualifier Q>
  617. GLM_FUNC_QUALIFIER vec<L, floatType, Q> unpackSnorm(vec<L, intType, Q> const& v)
  618. {
  619. GLM_STATIC_ASSERT(std::numeric_limits<intType>::is_integer, "uintType must be an integer type");
  620. GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "floatType must be a floating point type");
  621. return clamp(vec<L, floatType, Q>(v) * (static_cast<floatType>(1) / static_cast<floatType>(std::numeric_limits<intType>::max())), static_cast<floatType>(-1), static_cast<floatType>(1));
  622. }
  623. GLM_FUNC_QUALIFIER uint8 packUnorm2x4(vec2 const& v)
  624. {
  625. u32vec2 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f));
  626. detail::u4u4 Result;
  627. Result.data.x = Unpack.x;
  628. Result.data.y = Unpack.y;
  629. return Result.pack;
  630. }
  631. GLM_FUNC_QUALIFIER vec2 unpackUnorm2x4(uint8 v)
  632. {
  633. float const ScaleFactor(1.f / 15.f);
  634. detail::u4u4 Unpack;
  635. Unpack.pack = v;
  636. return vec2(Unpack.data.x, Unpack.data.y) * ScaleFactor;
  637. }
  638. GLM_FUNC_QUALIFIER uint16 packUnorm4x4(vec4 const& v)
  639. {
  640. u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f));
  641. detail::u4u4u4u4 Result;
  642. Result.data.x = Unpack.x;
  643. Result.data.y = Unpack.y;
  644. Result.data.z = Unpack.z;
  645. Result.data.w = Unpack.w;
  646. return Result.pack;
  647. }
  648. GLM_FUNC_QUALIFIER vec4 unpackUnorm4x4(uint16 v)
  649. {
  650. float const ScaleFactor(1.f / 15.f);
  651. detail::u4u4u4u4 Unpack;
  652. Unpack.pack = v;
  653. return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor;
  654. }
  655. GLM_FUNC_QUALIFIER uint16 packUnorm1x5_1x6_1x5(vec3 const& v)
  656. {
  657. u32vec3 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec3(31.f, 63.f, 31.f)));
  658. detail::u5u6u5 Result;
  659. Result.data.x = Unpack.x;
  660. Result.data.y = Unpack.y;
  661. Result.data.z = Unpack.z;
  662. return Result.pack;
  663. }
  664. GLM_FUNC_QUALIFIER vec3 unpackUnorm1x5_1x6_1x5(uint16 v)
  665. {
  666. vec3 const ScaleFactor(1.f / 31.f, 1.f / 63.f, 1.f / 31.f);
  667. detail::u5u6u5 Unpack;
  668. Unpack.pack = v;
  669. return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor;
  670. }
  671. GLM_FUNC_QUALIFIER uint16 packUnorm3x5_1x1(vec4 const& v)
  672. {
  673. u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec4(31.f, 31.f, 31.f, 1.f)));
  674. detail::u5u5u5u1 Result;
  675. Result.data.x = Unpack.x;
  676. Result.data.y = Unpack.y;
  677. Result.data.z = Unpack.z;
  678. Result.data.w = Unpack.w;
  679. return Result.pack;
  680. }
  681. GLM_FUNC_QUALIFIER vec4 unpackUnorm3x5_1x1(uint16 v)
  682. {
  683. vec4 const ScaleFactor(1.f / 31.f, 1.f / 31.f, 1.f / 31.f, 1.f);
  684. detail::u5u5u5u1 Unpack;
  685. Unpack.pack = v;
  686. return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor;
  687. }
  688. GLM_FUNC_QUALIFIER uint8 packUnorm2x3_1x2(vec3 const& v)
  689. {
  690. u32vec3 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec3(7.f, 7.f, 3.f)));
  691. detail::u3u3u2 Result;
  692. Result.data.x = Unpack.x;
  693. Result.data.y = Unpack.y;
  694. Result.data.z = Unpack.z;
  695. return Result.pack;
  696. }
  697. GLM_FUNC_QUALIFIER vec3 unpackUnorm2x3_1x2(uint8 v)
  698. {
  699. vec3 const ScaleFactor(1.f / 7.f, 1.f / 7.f, 1.f / 3.f);
  700. detail::u3u3u2 Unpack;
  701. Unpack.pack = v;
  702. return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor;
  703. }
  704. GLM_FUNC_QUALIFIER int16 packInt2x8(i8vec2 const& v)
  705. {
  706. int16 Pack = 0;
  707. memcpy(&Pack, &v, sizeof(Pack));
  708. return Pack;
  709. }
  710. GLM_FUNC_QUALIFIER i8vec2 unpackInt2x8(int16 p)
  711. {
  712. i8vec2 Unpack;
  713. memcpy(&Unpack, &p, sizeof(Unpack));
  714. return Unpack;
  715. }
  716. GLM_FUNC_QUALIFIER uint16 packUint2x8(u8vec2 const& v)
  717. {
  718. uint16 Pack = 0;
  719. memcpy(&Pack, &v, sizeof(Pack));
  720. return Pack;
  721. }
  722. GLM_FUNC_QUALIFIER u8vec2 unpackUint2x8(uint16 p)
  723. {
  724. u8vec2 Unpack;
  725. memcpy(&Unpack, &p, sizeof(Unpack));
  726. return Unpack;
  727. }
  728. GLM_FUNC_QUALIFIER int32 packInt4x8(i8vec4 const& v)
  729. {
  730. int32 Pack = 0;
  731. memcpy(&Pack, &v, sizeof(Pack));
  732. return Pack;
  733. }
  734. GLM_FUNC_QUALIFIER i8vec4 unpackInt4x8(int32 p)
  735. {
  736. i8vec4 Unpack;
  737. memcpy(&Unpack, &p, sizeof(Unpack));
  738. return Unpack;
  739. }
  740. GLM_FUNC_QUALIFIER uint32 packUint4x8(u8vec4 const& v)
  741. {
  742. uint32 Pack = 0;
  743. memcpy(&Pack, &v, sizeof(Pack));
  744. return Pack;
  745. }
  746. GLM_FUNC_QUALIFIER u8vec4 unpackUint4x8(uint32 p)
  747. {
  748. u8vec4 Unpack;
  749. memcpy(&Unpack, &p, sizeof(Unpack));
  750. return Unpack;
  751. }
  752. GLM_FUNC_QUALIFIER int packInt2x16(i16vec2 const& v)
  753. {
  754. int Pack = 0;
  755. memcpy(&Pack, &v, sizeof(Pack));
  756. return Pack;
  757. }
  758. GLM_FUNC_QUALIFIER i16vec2 unpackInt2x16(int p)
  759. {
  760. i16vec2 Unpack;
  761. memcpy(&Unpack, &p, sizeof(Unpack));
  762. return Unpack;
  763. }
  764. GLM_FUNC_QUALIFIER int64 packInt4x16(i16vec4 const& v)
  765. {
  766. int64 Pack = 0;
  767. memcpy(&Pack, &v, sizeof(Pack));
  768. return Pack;
  769. }
  770. GLM_FUNC_QUALIFIER i16vec4 unpackInt4x16(int64 p)
  771. {
  772. i16vec4 Unpack;
  773. memcpy(&Unpack, &p, sizeof(Unpack));
  774. return Unpack;
  775. }
  776. GLM_FUNC_QUALIFIER uint packUint2x16(u16vec2 const& v)
  777. {
  778. uint Pack = 0;
  779. memcpy(&Pack, &v, sizeof(Pack));
  780. return Pack;
  781. }
  782. GLM_FUNC_QUALIFIER u16vec2 unpackUint2x16(uint p)
  783. {
  784. u16vec2 Unpack;
  785. memcpy(&Unpack, &p, sizeof(Unpack));
  786. return Unpack;
  787. }
  788. GLM_FUNC_QUALIFIER uint64 packUint4x16(u16vec4 const& v)
  789. {
  790. uint64 Pack = 0;
  791. memcpy(&Pack, &v, sizeof(Pack));
  792. return Pack;
  793. }
  794. GLM_FUNC_QUALIFIER u16vec4 unpackUint4x16(uint64 p)
  795. {
  796. u16vec4 Unpack;
  797. memcpy(&Unpack, &p, sizeof(Unpack));
  798. return Unpack;
  799. }
  800. GLM_FUNC_QUALIFIER int64 packInt2x32(i32vec2 const& v)
  801. {
  802. int64 Pack = 0;
  803. memcpy(&Pack, &v, sizeof(Pack));
  804. return Pack;
  805. }
  806. GLM_FUNC_QUALIFIER i32vec2 unpackInt2x32(int64 p)
  807. {
  808. i32vec2 Unpack;
  809. memcpy(&Unpack, &p, sizeof(Unpack));
  810. return Unpack;
  811. }
  812. GLM_FUNC_QUALIFIER uint64 packUint2x32(u32vec2 const& v)
  813. {
  814. uint64 Pack = 0;
  815. memcpy(&Pack, &v, sizeof(Pack));
  816. return Pack;
  817. }
  818. GLM_FUNC_QUALIFIER u32vec2 unpackUint2x32(uint64 p)
  819. {
  820. u32vec2 Unpack;
  821. memcpy(&Unpack, &p, sizeof(Unpack));
  822. return Unpack;
  823. }
  824. }//namespace glm