matrix_clip_space.inl 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. namespace glm
  2. {
  3. template<typename T>
  4. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top)
  5. {
  6. mat<4, 4, T, defaultp> Result(static_cast<T>(1));
  7. Result[0][0] = static_cast<T>(2) / (right - left);
  8. Result[1][1] = static_cast<T>(2) / (top - bottom);
  9. Result[2][2] = - static_cast<T>(1);
  10. Result[3][0] = - (right + left) / (right - left);
  11. Result[3][1] = - (top + bottom) / (top - bottom);
  12. return Result;
  13. }
  14. template<typename T>
  15. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH_ZO(T left, T right, T bottom, T top, T zNear, T zFar)
  16. {
  17. mat<4, 4, T, defaultp> Result(1);
  18. Result[0][0] = static_cast<T>(2) / (right - left);
  19. Result[1][1] = static_cast<T>(2) / (top - bottom);
  20. Result[2][2] = static_cast<T>(1) / (zFar - zNear);
  21. Result[3][0] = - (right + left) / (right - left);
  22. Result[3][1] = - (top + bottom) / (top - bottom);
  23. Result[3][2] = - zNear / (zFar - zNear);
  24. return Result;
  25. }
  26. template<typename T>
  27. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH_NO(T left, T right, T bottom, T top, T zNear, T zFar)
  28. {
  29. mat<4, 4, T, defaultp> Result(1);
  30. Result[0][0] = static_cast<T>(2) / (right - left);
  31. Result[1][1] = static_cast<T>(2) / (top - bottom);
  32. Result[2][2] = static_cast<T>(2) / (zFar - zNear);
  33. Result[3][0] = - (right + left) / (right - left);
  34. Result[3][1] = - (top + bottom) / (top - bottom);
  35. Result[3][2] = - (zFar + zNear) / (zFar - zNear);
  36. return Result;
  37. }
  38. template<typename T>
  39. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH_ZO(T left, T right, T bottom, T top, T zNear, T zFar)
  40. {
  41. mat<4, 4, T, defaultp> Result(1);
  42. Result[0][0] = static_cast<T>(2) / (right - left);
  43. Result[1][1] = static_cast<T>(2) / (top - bottom);
  44. Result[2][2] = - static_cast<T>(1) / (zFar - zNear);
  45. Result[3][0] = - (right + left) / (right - left);
  46. Result[3][1] = - (top + bottom) / (top - bottom);
  47. Result[3][2] = - zNear / (zFar - zNear);
  48. return Result;
  49. }
  50. template<typename T>
  51. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH_NO(T left, T right, T bottom, T top, T zNear, T zFar)
  52. {
  53. mat<4, 4, T, defaultp> Result(1);
  54. Result[0][0] = static_cast<T>(2) / (right - left);
  55. Result[1][1] = static_cast<T>(2) / (top - bottom);
  56. Result[2][2] = - static_cast<T>(2) / (zFar - zNear);
  57. Result[3][0] = - (right + left) / (right - left);
  58. Result[3][1] = - (top + bottom) / (top - bottom);
  59. Result[3][2] = - (zFar + zNear) / (zFar - zNear);
  60. return Result;
  61. }
  62. template<typename T>
  63. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoZO(T left, T right, T bottom, T top, T zNear, T zFar)
  64. {
  65. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
  66. return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
  67. # else
  68. return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
  69. # endif
  70. }
  71. template<typename T>
  72. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoNO(T left, T right, T bottom, T top, T zNear, T zFar)
  73. {
  74. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
  75. return orthoLH_NO(left, right, bottom, top, zNear, zFar);
  76. # else
  77. return orthoRH_NO(left, right, bottom, top, zNear, zFar);
  78. # endif
  79. }
  80. template<typename T>
  81. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH(T left, T right, T bottom, T top, T zNear, T zFar)
  82. {
  83. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
  84. return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
  85. # else
  86. return orthoLH_NO(left, right, bottom, top, zNear, zFar);
  87. # endif
  88. }
  89. template<typename T>
  90. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH(T left, T right, T bottom, T top, T zNear, T zFar)
  91. {
  92. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
  93. return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
  94. # else
  95. return orthoRH_NO(left, right, bottom, top, zNear, zFar);
  96. # endif
  97. }
  98. template<typename T>
  99. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top, T zNear, T zFar)
  100. {
  101. # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO
  102. return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
  103. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
  104. return orthoLH_NO(left, right, bottom, top, zNear, zFar);
  105. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO
  106. return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
  107. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO
  108. return orthoRH_NO(left, right, bottom, top, zNear, zFar);
  109. # endif
  110. }
  111. template<typename T>
  112. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH_ZO(T left, T right, T bottom, T top, T nearVal, T farVal)
  113. {
  114. mat<4, 4, T, defaultp> Result(0);
  115. Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
  116. Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
  117. Result[2][0] = (right + left) / (right - left);
  118. Result[2][1] = (top + bottom) / (top - bottom);
  119. Result[2][2] = farVal / (farVal - nearVal);
  120. Result[2][3] = static_cast<T>(1);
  121. Result[3][2] = -(farVal * nearVal) / (farVal - nearVal);
  122. return Result;
  123. }
  124. template<typename T>
  125. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH_NO(T left, T right, T bottom, T top, T nearVal, T farVal)
  126. {
  127. mat<4, 4, T, defaultp> Result(0);
  128. Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
  129. Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
  130. Result[2][0] = (right + left) / (right - left);
  131. Result[2][1] = (top + bottom) / (top - bottom);
  132. Result[2][2] = (farVal + nearVal) / (farVal - nearVal);
  133. Result[2][3] = static_cast<T>(1);
  134. Result[3][2] = - (static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal);
  135. return Result;
  136. }
  137. template<typename T>
  138. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH_ZO(T left, T right, T bottom, T top, T nearVal, T farVal)
  139. {
  140. mat<4, 4, T, defaultp> Result(0);
  141. Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
  142. Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
  143. Result[2][0] = (right + left) / (right - left);
  144. Result[2][1] = (top + bottom) / (top - bottom);
  145. Result[2][2] = farVal / (nearVal - farVal);
  146. Result[2][3] = static_cast<T>(-1);
  147. Result[3][2] = -(farVal * nearVal) / (farVal - nearVal);
  148. return Result;
  149. }
  150. template<typename T>
  151. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH_NO(T left, T right, T bottom, T top, T nearVal, T farVal)
  152. {
  153. mat<4, 4, T, defaultp> Result(0);
  154. Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
  155. Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
  156. Result[2][0] = (right + left) / (right - left);
  157. Result[2][1] = (top + bottom) / (top - bottom);
  158. Result[2][2] = - (farVal + nearVal) / (farVal - nearVal);
  159. Result[2][3] = static_cast<T>(-1);
  160. Result[3][2] = - (static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal);
  161. return Result;
  162. }
  163. template<typename T>
  164. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumZO(T left, T right, T bottom, T top, T nearVal, T farVal)
  165. {
  166. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
  167. return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
  168. # else
  169. return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
  170. # endif
  171. }
  172. template<typename T>
  173. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumNO(T left, T right, T bottom, T top, T nearVal, T farVal)
  174. {
  175. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
  176. return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
  177. # else
  178. return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
  179. # endif
  180. }
  181. template<typename T>
  182. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH(T left, T right, T bottom, T top, T nearVal, T farVal)
  183. {
  184. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
  185. return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
  186. # else
  187. return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
  188. # endif
  189. }
  190. template<typename T>
  191. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH(T left, T right, T bottom, T top, T nearVal, T farVal)
  192. {
  193. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
  194. return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
  195. # else
  196. return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
  197. # endif
  198. }
  199. template<typename T>
  200. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustum(T left, T right, T bottom, T top, T nearVal, T farVal)
  201. {
  202. # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO
  203. return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
  204. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
  205. return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
  206. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO
  207. return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
  208. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO
  209. return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
  210. # endif
  211. }
  212. template<typename T>
  213. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH_ZO(T fovy, T aspect, T zNear, T zFar)
  214. {
  215. assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
  216. T const tanHalfFovy = tan(fovy / static_cast<T>(2));
  217. mat<4, 4, T, defaultp> Result(static_cast<T>(0));
  218. Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
  219. Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
  220. Result[2][2] = zFar / (zNear - zFar);
  221. Result[2][3] = - static_cast<T>(1);
  222. Result[3][2] = -(zFar * zNear) / (zFar - zNear);
  223. return Result;
  224. }
  225. template<typename T>
  226. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH_NO(T fovy, T aspect, T zNear, T zFar)
  227. {
  228. assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
  229. T const tanHalfFovy = tan(fovy / static_cast<T>(2));
  230. mat<4, 4, T, defaultp> Result(static_cast<T>(0));
  231. Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
  232. Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
  233. Result[2][2] = - (zFar + zNear) / (zFar - zNear);
  234. Result[2][3] = - static_cast<T>(1);
  235. Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
  236. return Result;
  237. }
  238. template<typename T>
  239. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH_ZO(T fovy, T aspect, T zNear, T zFar)
  240. {
  241. assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
  242. T const tanHalfFovy = tan(fovy / static_cast<T>(2));
  243. mat<4, 4, T, defaultp> Result(static_cast<T>(0));
  244. Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
  245. Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
  246. Result[2][2] = zFar / (zFar - zNear);
  247. Result[2][3] = static_cast<T>(1);
  248. Result[3][2] = -(zFar * zNear) / (zFar - zNear);
  249. return Result;
  250. }
  251. template<typename T>
  252. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH_NO(T fovy, T aspect, T zNear, T zFar)
  253. {
  254. assert(abs(aspect - std::numeric_limits<T>::epsilon()) > static_cast<T>(0));
  255. T const tanHalfFovy = tan(fovy / static_cast<T>(2));
  256. mat<4, 4, T, defaultp> Result(static_cast<T>(0));
  257. Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
  258. Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
  259. Result[2][2] = (zFar + zNear) / (zFar - zNear);
  260. Result[2][3] = static_cast<T>(1);
  261. Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
  262. return Result;
  263. }
  264. template<typename T>
  265. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveZO(T fovy, T aspect, T zNear, T zFar)
  266. {
  267. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
  268. return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
  269. # else
  270. return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
  271. # endif
  272. }
  273. template<typename T>
  274. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveNO(T fovy, T aspect, T zNear, T zFar)
  275. {
  276. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
  277. return perspectiveLH_NO(fovy, aspect, zNear, zFar);
  278. # else
  279. return perspectiveRH_NO(fovy, aspect, zNear, zFar);
  280. # endif
  281. }
  282. template<typename T>
  283. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH(T fovy, T aspect, T zNear, T zFar)
  284. {
  285. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
  286. return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
  287. # else
  288. return perspectiveLH_NO(fovy, aspect, zNear, zFar);
  289. # endif
  290. }
  291. template<typename T>
  292. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH(T fovy, T aspect, T zNear, T zFar)
  293. {
  294. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
  295. return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
  296. # else
  297. return perspectiveRH_NO(fovy, aspect, zNear, zFar);
  298. # endif
  299. }
  300. template<typename T>
  301. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspective(T fovy, T aspect, T zNear, T zFar)
  302. {
  303. # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO
  304. return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
  305. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
  306. return perspectiveLH_NO(fovy, aspect, zNear, zFar);
  307. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO
  308. return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
  309. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO
  310. return perspectiveRH_NO(fovy, aspect, zNear, zFar);
  311. # endif
  312. }
  313. template<typename T>
  314. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH_ZO(T fov, T width, T height, T zNear, T zFar)
  315. {
  316. assert(width > static_cast<T>(0));
  317. assert(height > static_cast<T>(0));
  318. assert(fov > static_cast<T>(0));
  319. T const rad = fov;
  320. T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
  321. T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
  322. mat<4, 4, T, defaultp> Result(static_cast<T>(0));
  323. Result[0][0] = w;
  324. Result[1][1] = h;
  325. Result[2][2] = zFar / (zNear - zFar);
  326. Result[2][3] = - static_cast<T>(1);
  327. Result[3][2] = -(zFar * zNear) / (zFar - zNear);
  328. return Result;
  329. }
  330. template<typename T>
  331. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH_NO(T fov, T width, T height, T zNear, T zFar)
  332. {
  333. assert(width > static_cast<T>(0));
  334. assert(height > static_cast<T>(0));
  335. assert(fov > static_cast<T>(0));
  336. T const rad = fov;
  337. T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
  338. T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
  339. mat<4, 4, T, defaultp> Result(static_cast<T>(0));
  340. Result[0][0] = w;
  341. Result[1][1] = h;
  342. Result[2][2] = - (zFar + zNear) / (zFar - zNear);
  343. Result[2][3] = - static_cast<T>(1);
  344. Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
  345. return Result;
  346. }
  347. template<typename T>
  348. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH_ZO(T fov, T width, T height, T zNear, T zFar)
  349. {
  350. assert(width > static_cast<T>(0));
  351. assert(height > static_cast<T>(0));
  352. assert(fov > static_cast<T>(0));
  353. T const rad = fov;
  354. T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
  355. T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
  356. mat<4, 4, T, defaultp> Result(static_cast<T>(0));
  357. Result[0][0] = w;
  358. Result[1][1] = h;
  359. Result[2][2] = zFar / (zFar - zNear);
  360. Result[2][3] = static_cast<T>(1);
  361. Result[3][2] = -(zFar * zNear) / (zFar - zNear);
  362. return Result;
  363. }
  364. template<typename T>
  365. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH_NO(T fov, T width, T height, T zNear, T zFar)
  366. {
  367. assert(width > static_cast<T>(0));
  368. assert(height > static_cast<T>(0));
  369. assert(fov > static_cast<T>(0));
  370. T const rad = fov;
  371. T const h = glm::cos(static_cast<T>(0.5) * rad) / glm::sin(static_cast<T>(0.5) * rad);
  372. T const w = h * height / width; ///todo max(width , Height) / min(width , Height)?
  373. mat<4, 4, T, defaultp> Result(static_cast<T>(0));
  374. Result[0][0] = w;
  375. Result[1][1] = h;
  376. Result[2][2] = (zFar + zNear) / (zFar - zNear);
  377. Result[2][3] = static_cast<T>(1);
  378. Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
  379. return Result;
  380. }
  381. template<typename T>
  382. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovZO(T fov, T width, T height, T zNear, T zFar)
  383. {
  384. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
  385. return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
  386. # else
  387. return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
  388. # endif
  389. }
  390. template<typename T>
  391. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovNO(T fov, T width, T height, T zNear, T zFar)
  392. {
  393. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
  394. return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
  395. # else
  396. return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
  397. # endif
  398. }
  399. template<typename T>
  400. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH(T fov, T width, T height, T zNear, T zFar)
  401. {
  402. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
  403. return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
  404. # else
  405. return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
  406. # endif
  407. }
  408. template<typename T>
  409. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH(T fov, T width, T height, T zNear, T zFar)
  410. {
  411. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
  412. return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
  413. # else
  414. return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
  415. # endif
  416. }
  417. template<typename T>
  418. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFov(T fov, T width, T height, T zNear, T zFar)
  419. {
  420. # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO
  421. return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
  422. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
  423. return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
  424. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO
  425. return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
  426. # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO
  427. return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
  428. # endif
  429. }
  430. template<typename T>
  431. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveRH(T fovy, T aspect, T zNear)
  432. {
  433. T const range = tan(fovy / static_cast<T>(2)) * zNear;
  434. T const left = -range * aspect;
  435. T const right = range * aspect;
  436. T const bottom = -range;
  437. T const top = range;
  438. mat<4, 4, T, defaultp> Result(static_cast<T>(0));
  439. Result[0][0] = (static_cast<T>(2) * zNear) / (right - left);
  440. Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom);
  441. Result[2][2] = - static_cast<T>(1);
  442. Result[2][3] = - static_cast<T>(1);
  443. Result[3][2] = - static_cast<T>(2) * zNear;
  444. return Result;
  445. }
  446. template<typename T>
  447. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveLH(T fovy, T aspect, T zNear)
  448. {
  449. T const range = tan(fovy / static_cast<T>(2)) * zNear;
  450. T const left = -range * aspect;
  451. T const right = range * aspect;
  452. T const bottom = -range;
  453. T const top = range;
  454. mat<4, 4, T, defaultp> Result(T(0));
  455. Result[0][0] = (static_cast<T>(2) * zNear) / (right - left);
  456. Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom);
  457. Result[2][2] = static_cast<T>(1);
  458. Result[2][3] = static_cast<T>(1);
  459. Result[3][2] = - static_cast<T>(2) * zNear;
  460. return Result;
  461. }
  462. template<typename T>
  463. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspective(T fovy, T aspect, T zNear)
  464. {
  465. # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
  466. return infinitePerspectiveLH(fovy, aspect, zNear);
  467. # else
  468. return infinitePerspectiveRH(fovy, aspect, zNear);
  469. # endif
  470. }
  471. // Infinite projection matrix: http://www.terathon.com/gdc07_lengyel.pdf
  472. template<typename T>
  473. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear, T ep)
  474. {
  475. T const range = tan(fovy / static_cast<T>(2)) * zNear;
  476. T const left = -range * aspect;
  477. T const right = range * aspect;
  478. T const bottom = -range;
  479. T const top = range;
  480. mat<4, 4, T, defaultp> Result(static_cast<T>(0));
  481. Result[0][0] = (static_cast<T>(2) * zNear) / (right - left);
  482. Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom);
  483. Result[2][2] = ep - static_cast<T>(1);
  484. Result[2][3] = static_cast<T>(-1);
  485. Result[3][2] = (ep - static_cast<T>(2)) * zNear;
  486. return Result;
  487. }
  488. template<typename T>
  489. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear)
  490. {
  491. return tweakedInfinitePerspective(fovy, aspect, zNear, epsilon<T>());
  492. }
  493. }//namespace glm