From d6c6b4c5429366b270307dcc7bcb3ba715394aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=20Emre=20G=C3=BClc=C3=BC?= Date: Tue, 10 Feb 2026 12:30:11 +0300 Subject: [PATCH] Implement infinite perspective projection matrix creation functions --- include/cglm/call/cam.h | 4 ++++ include/cglm/cam.h | 28 ++++++++++++++++++++++- include/cglm/clipspace/persp_lh_no.h | 32 +++++++++++++++++++++++++++ include/cglm/clipspace/persp_lh_zo.h | 33 ++++++++++++++++++++++++++++ include/cglm/clipspace/persp_rh_no.h | 32 +++++++++++++++++++++++++++ include/cglm/clipspace/persp_rh_zo.h | 33 ++++++++++++++++++++++++++++ src/cam.c | 6 +++++ 7 files changed, 167 insertions(+), 1 deletion(-) diff --git a/include/cglm/call/cam.h b/include/cglm/call/cam.h index d9567ec..fe0ee61 100644 --- a/include/cglm/call/cam.h +++ b/include/cglm/call/cam.h @@ -51,6 +51,10 @@ CGLM_EXPORT void glmc_perspective(float fovy, float aspect, float nearZ, float farZ, mat4 dest); +CGLM_EXPORT +void +glmc_perspective_infinite(float fovy, float aspect, float nearZ, mat4 dest); + CGLM_EXPORT void glmc_persp_move_far(mat4 proj, float deltaFar); diff --git a/include/cglm/cam.h b/include/cglm/cam.h index 816cb5e..4760e5b 100644 --- a/include/cglm/cam.h +++ b/include/cglm/cam.h @@ -25,6 +25,10 @@ float nearZ, float farZ, mat4 dest) + CGLM_INLINE void glm_perspective_infinite(float fovy, + float aspect, + float nearZ, + mat4 dest) CGLM_INLINE void glm_perspective_default(float aspect, mat4 dest) CGLM_INLINE void glm_perspective_resize(float aspect, mat4 proj) CGLM_INLINE void glm_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest) @@ -87,7 +91,7 @@ #endif /*! - * @brief set up perspective peprojection matrix + * @brief set up perspective projection matrix * * @param[in] left viewport.left * @param[in] right viewport.right @@ -274,6 +278,28 @@ glm_perspective(float fovy, float aspect, float nearZ, float farZ, mat4 dest) { #endif } +/*! + * @brief set up perspective projection matrix with infinite far plane + * + * @param[in] fovy field of view angle + * @param[in] aspect aspect ratio ( width / height ) + * @param[in] nearZ near clipping plane + * @param[out] dest result matrix + */ +CGLM_INLINE +void +glm_perspective_infinite(float fovy, float aspect, float nearZ, mat4 dest) { +#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO + glm_perspective_infinite_lh_zo(fovy, aspect, nearZ, dest); +#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO + glm_perspective_infinite_lh_no(fovy, aspect, nearZ, dest); +#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO + glm_perspective_infinite_rh_zo(fovy, aspect, nearZ, dest); +#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO + glm_perspective_infinite_rh_no(fovy, aspect, nearZ, dest); +#endif +} + /*! * @brief extend perspective projection matrix's far distance * diff --git a/include/cglm/clipspace/persp_lh_no.h b/include/cglm/clipspace/persp_lh_no.h index d28923a..1b7d030 100644 --- a/include/cglm/clipspace/persp_lh_no.h +++ b/include/cglm/clipspace/persp_lh_no.h @@ -16,6 +16,10 @@ float nearZ, float farZ, mat4 dest) + CGLM_INLINE void glm_perspective_infinite_lh_no(float fovy, + float aspect, + float nearZ, + mat4 dest) CGLM_INLINE void glm_perspective_default_lh_no(float aspect, mat4 dest) CGLM_INLINE void glm_perspective_resize_lh_no(float aspect, mat4 proj) CGLM_INLINE void glm_persp_move_far_lh_no(mat4 proj, @@ -116,7 +120,35 @@ glm_perspective_lh_no(float fovy, dest[2][2] =-(nearZ + farZ) * fn; dest[2][3] = 1.0f; dest[3][2] = 2.0f * nearZ * farZ * fn; +} +/*! + * @brief set up infinite perspective projection matrix + * with a left-hand coordinate system and a + * clip-space of [-1, 1]. + * + * @param[in] fovy field of view angle + * @param[in] aspect aspect ratio ( width / height ) + * @param[in] nearZ near clipping plane + * @param[out] dest result matrix + */ +CGLM_INLINE +void +glm_perspective_infinite_lh_no(float fovy, + float aspect, + float nearZ, + mat4 dest) { + float f; + + glm_mat4_zero(dest); + + f = 1.0f / tanf(fovy * 0.5f); + + dest[0][0] = f / aspect; + dest[1][1] = f; + dest[2][2] = 1.0f; + dest[2][3] = 1.0f; + dest[3][2] =-2.0f * nearZ; } /*! diff --git a/include/cglm/clipspace/persp_lh_zo.h b/include/cglm/clipspace/persp_lh_zo.h index de89643..a1d193e 100644 --- a/include/cglm/clipspace/persp_lh_zo.h +++ b/include/cglm/clipspace/persp_lh_zo.h @@ -16,6 +16,10 @@ float nearZ, float farZ, mat4 dest) + CGLM_INLINE void glm_perspective_infinite_lh_zo(float fovy, + float aspect, + float nearZ, + mat4 dest) CGLM_INLINE void glm_perspective_default_lh_zo(float aspect, mat4 dest) CGLM_INLINE void glm_perspective_resize_lh_zo(float aspect, mat4 proj) CGLM_INLINE void glm_persp_move_far_lh_zo(mat4 proj, @@ -116,6 +120,35 @@ glm_perspective_lh_zo(float fovy, dest[3][2] = nearZ * farZ * fn; } +/*! +* @brief set up infinite perspective projection matrix + * with a left-hand coordinate system and a + * clip-space of [0, 1]. + * + * @param[in] fovy field of view angle + * @param[in] aspect aspect ratio ( width / height ) + * @param[in] nearZ near clipping plane + * @param[out] dest result matrix + */ +CGLM_INLINE +void +glm_perspective_infinite_lh_zo(float fovy, + float aspect, + float nearZ, + mat4 dest) { + float f; + + glm_mat4_zero(dest); + + f = 1.0f / tanf(fovy * 0.5f); + + dest[0][0] = f / aspect; + dest[1][1] = f; + dest[2][2] = 1.0f; + dest[2][3] = 1.0f; + dest[3][2] =-nearZ; +} + /*! * @brief extend perspective projection matrix's far distance with a * left-hand coordinate system and a clip-space with depth values diff --git a/include/cglm/clipspace/persp_rh_no.h b/include/cglm/clipspace/persp_rh_no.h index 9252332..a052470 100644 --- a/include/cglm/clipspace/persp_rh_no.h +++ b/include/cglm/clipspace/persp_rh_no.h @@ -16,6 +16,10 @@ float nearZ, float farZ, mat4 dest) + CGLM_INLINE void glm_perspective_infinite_rh_no(float fovy, + float aspect, + float nearZ, + mat4 dest) CGLM_INLINE void glm_perspective_default_rh_no(float aspect, mat4 dest) CGLM_INLINE void glm_perspective_resize_rh_no(float aspect, mat4 proj) CGLM_INLINE void glm_persp_move_far_rh_no(mat4 proj, @@ -116,7 +120,35 @@ glm_perspective_rh_no(float fovy, dest[2][2] = (nearZ + farZ) * fn; dest[2][3] =-1.0f; dest[3][2] = 2.0f * nearZ * farZ * fn; +} +/*! + * @brief set up infinite perspective projection matrix + * with a right-hand coordinate system and a + * clip-space of [-1, 1]. + * + * @param[in] fovy field of view angle + * @param[in] aspect aspect ratio ( width / height ) + * @param[in] nearZ near clipping plane + * @param[out] dest result matrix + */ +CGLM_INLINE +void +glm_perspective_infinite_rh_no(float fovy, + float aspect, + float nearZ, + mat4 dest) { + float f; + + glm_mat4_zero(dest); + + f = 1.0f / tanf(fovy * 0.5f); + + dest[0][0] = f / aspect; + dest[1][1] = f; + dest[2][2] =-1.0f; + dest[2][3] =-1.0f; + dest[3][2] =-2.0f * nearZ; } /*! diff --git a/include/cglm/clipspace/persp_rh_zo.h b/include/cglm/clipspace/persp_rh_zo.h index ce632b3..9c38191 100644 --- a/include/cglm/clipspace/persp_rh_zo.h +++ b/include/cglm/clipspace/persp_rh_zo.h @@ -16,6 +16,10 @@ float nearZ, float farZ, mat4 dest) + CGLM_INLINE void glm_perspective_infinite_rh_zo(float fovy, + float aspect, + float nearZ, + mat4 dest) CGLM_INLINE void glm_perspective_default_rh_zo(float aspect, mat4 dest) CGLM_INLINE void glm_perspective_resize_rh_zo(float aspect, mat4 proj) CGLM_INLINE void glm_persp_move_far_rh_zo(mat4 proj, @@ -116,6 +120,35 @@ glm_perspective_rh_zo(float fovy, dest[3][2] = nearZ * farZ * fn; } +/*! + * @brief set up infinite perspective projection matrix + * with a right-hand coordinate system and a + * clip-space of [0, 1]. + * + * @param[in] fovy field of view angle + * @param[in] aspect aspect ratio ( width / height ) + * @param[in] nearZ near clipping plane + * @param[out] dest result matrix + */ +CGLM_INLINE +void +glm_perspective_infinite_rh_zo(float fovy, + float aspect, + float nearZ, + mat4 dest) { + float f; + + glm_mat4_zero(dest); + + f = 1.0f / tanf(fovy * 0.5f); + + dest[0][0] = f / aspect; + dest[1][1] = f; + dest[2][2] =-1.0f; + dest[2][3] =-1.0f; + dest[3][2] =-nearZ; +} + /*! * @brief set up perspective projection matrix with default near/far * and angle values with a right-hand coordinate system and a diff --git a/src/cam.c b/src/cam.c index 40db351..24ac602 100644 --- a/src/cam.c +++ b/src/cam.c @@ -62,6 +62,12 @@ glmc_perspective(float fovy, float aspect, float nearZ, float farZ, mat4 dest) { glm_perspective(fovy, aspect, nearZ, farZ, dest); } +CGLM_EXPORT +void +glmc_perspective_infinite(float fovy, float aspect, float nearZ, mat4 dest) { + glm_perspective_infinite(fovy, aspect, nearZ, dest); +} + CGLM_EXPORT void glmc_persp_move_far(mat4 proj, float deltaFar) {