2
0
Эх сурвалжийг харах

Merge pull request #447 from Karanlos/master

More right and left handed projection matrix support plus support for glClipControl GL_ZERO_TO_ONE #447
Christophe R 10 жил өмнө
parent
commit
0d2fd871af

+ 123 - 23
glm/gtc/matrix_transform.hpp

@@ -116,14 +116,14 @@ namespace glm
 		tmat4x4<T, P> const & m,
 		tvec3<T, P> const & v);
 
-	/// Creates a matrix for an orthographic parallel viewing volume.
-	/// 
-	/// @param left 
-	/// @param right 
-	/// @param bottom 
-	/// @param top 
-	/// @param zNear 
-	/// @param zFar 
+	/// Creates a matrix for an orthographic parallel viewing volume, using the default handedness.
+	///
+	/// @param left
+	/// @param right
+	/// @param bottom
+	/// @param top
+	/// @param zNear
+	/// @param zFar
 	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
 	/// @see gtc_matrix_transform
 	/// @see - glm::ortho(T const & left, T const & right, T const & bottom, T const & top)
@@ -136,12 +136,52 @@ namespace glm
 		T zNear,
 		T zFar);
 
+	/// Creates a matrix for an orthographic parallel viewing volume, using left-handedness.
+	///
+	/// @param left
+	/// @param right
+	/// @param bottom
+	/// @param top
+	/// @param zNear
+	/// @param zFar
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const & left, T const & right, T const & bottom, T const & top)
+	template <typename T>
+	GLM_FUNC_DECL tmat4x4<T, defaultp> orthoLH(
+		T left,
+		T right,
+		T bottom,
+		T top,
+		T zNear,
+		T zFar);
+
+	/// Creates a matrix for an orthographic parallel viewing volume, using right-handedness.
+	///
+	/// @param left
+	/// @param right
+	/// @param bottom
+	/// @param top
+	/// @param zNear
+	/// @param zFar
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
+	/// @see gtc_matrix_transform
+	/// @see - glm::ortho(T const & left, T const & right, T const & bottom, T const & top)
+	template <typename T>
+	GLM_FUNC_DECL tmat4x4<T, defaultp> orthoRH(
+		T left,
+		T right,
+		T bottom,
+		T top,
+		T zNear,
+		T zFar);
+
 	/// Creates a matrix for projecting two-dimensional coordinates onto the screen.
-	/// 
-	/// @param left 
-	/// @param right 
-	/// @param bottom 
-	/// @param top 
+	///
+	/// @param left
+	/// @param right
+	/// @param bottom
+	/// @param top
 	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
 	/// @see gtc_matrix_transform
 	/// @see - glm::ortho(T const & left, T const & right, T const & bottom, T const & top, T const & zNear, T const & zFar)
@@ -152,14 +192,14 @@ namespace glm
 		T bottom,
 		T top);
 
-	/// Creates a frustum matrix.
-	/// 
-	/// @param left 
-	/// @param right 
-	/// @param bottom 
-	/// @param top 
-	/// @param near 
-	/// @param far 
+	/// Creates a frustum matrix with default handedness.
+	///
+	/// @param left
+	/// @param right
+	/// @param bottom
+	/// @param top
+	/// @param near
+	/// @param far
 	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
 	/// @see gtc_matrix_transform
 	template <typename T>
@@ -171,6 +211,44 @@ namespace glm
 		T near,
 		T far);
 
+	/// Creates a left handed frustum matrix.
+	///
+	/// @param left
+	/// @param right
+	/// @param bottom
+	/// @param top
+	/// @param near
+	/// @param far
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
+	/// @see gtc_matrix_transform
+	template <typename T>
+	GLM_FUNC_DECL tmat4x4<T, defaultp> frustumLH(
+		T left,
+		T right,
+		T bottom,
+		T top,
+		T near,
+		T far);
+
+	/// Creates a right handed frustum matrix.
+	///
+	/// @param left
+	/// @param right
+	/// @param bottom
+	/// @param top
+	/// @param near
+	/// @param far
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
+	/// @see gtc_matrix_transform
+	template <typename T>
+	GLM_FUNC_DECL tmat4x4<T, defaultp> frustumRH(
+		T left,
+		T right,
+		T bottom,
+		T top,
+		T near,
+		T far);
+
 	/// Creates a matrix for a symetric perspective-view frustum based on the default handedness.
 	/// 
 	/// @param fovy Specifies the field of view angle in the y direction. Expressed in radians.
@@ -267,8 +345,8 @@ namespace glm
 		T near,
 		T far);
 
-	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite.
-	/// 
+	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite with default handedness.
+	///
 	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
 	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
 	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
@@ -278,6 +356,28 @@ namespace glm
 	GLM_FUNC_DECL tmat4x4<T, defaultp> infinitePerspective(
 		T fovy, T aspect, T near);
 
+	/// Creates a matrix for a left handed, symmetric perspective-view frustum with far plane at infinite.
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
+	/// @see gtc_matrix_transform
+	template <typename T>
+	GLM_FUNC_DECL tmat4x4<T, defaultp> infinitePerspectiveLH(
+		T fovy, T aspect, T near);
+
+	/// Creates a matrix for a right handed, symmetric perspective-view frustum with far plane at infinite.
+	///
+	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
+	/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
+	/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
+	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
+	/// @see gtc_matrix_transform
+	template <typename T>
+	GLM_FUNC_DECL tmat4x4<T, defaultp> infinitePerspectiveRH(
+		T fovy, T aspect, T near);
+
 	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite for graphics hardware that doesn't support depth clamping.
 	/// 
 	/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.

+ 177 - 11
glm/gtc/matrix_transform.inl

@@ -157,35 +157,86 @@ namespace glm
 		T zNear,
 		T zFar
 	)
+	{
+		#ifdef GLM_LEFT_HANDED
+			return orthoLH(left, right, bottom, top, zNear, zFar);
+		#else
+			return orthoRH(left, right, bottom, top, zNear, zFar);
+		#endif
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> orthoLH
+	(
+		T left,
+		T right,
+		T bottom,
+		T top,
+		T zNear,
+		T zFar
+	)
 	{
 		tmat4x4<T, defaultp> Result(1);
 		Result[0][0] = static_cast<T>(2) / (right - left);
 		Result[1][1] = static_cast<T>(2) / (top - bottom);
-		Result[2][2] = - static_cast<T>(2) / (zFar - zNear);
 		Result[3][0] = - (right + left) / (right - left);
 		Result[3][1] = - (top + bottom) / (top - bottom);
+
+#ifdef GLM_DEPTH_ZERO_TO_ONE
+		Result[2][2] = static_cast<T>(1) / (zFar - zNear);
+		Result[3][2] = - zNear / (zFar - zNear);
+#else
+		Result[2][2] = static_cast<T>(2) / (zFar - zNear);
 		Result[3][2] = - (zFar + zNear) / (zFar - zNear);
+#endif
 		return Result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> ortho
+	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> orthoRH
 	(
 		T left,
 		T right,
 		T bottom,
-		T top
+		T top,
+		T zNear,
+		T zFar
 	)
 	{
 		tmat4x4<T, defaultp> Result(1);
 		Result[0][0] = static_cast<T>(2) / (right - left);
 		Result[1][1] = static_cast<T>(2) / (top - bottom);
-		Result[2][2] = - static_cast<T>(1);
 		Result[3][0] = - (right + left) / (right - left);
 		Result[3][1] = - (top + bottom) / (top - bottom);
+
+#ifdef GLM_DEPTH_ZERO_TO_ONE
+		Result[2][2] = - static_cast<T>(1) / (zFar - zNear);
+		Result[3][2] = - zNear / (zFar - zNear);
+#else
+		Result[2][2] = - static_cast<T>(2) / (zFar - zNear);
+		Result[3][2] = - (zFar + zNear) / (zFar - zNear);
+#endif
 		return Result;
 	}
 
+	template <typename T>
+	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> ortho
+	(
+		T left,
+		T right,
+		T bottom,
+		T top
+	)
+	{
+	    tmat4x4<T, defaultp> Result(1);
+	    Result[0][0] = static_cast<T>(2) / (right - left);
+	    Result[1][1] = static_cast<T>(2) / (top - bottom);
+	    Result[2][2] = - static_cast<T>(1);
+	    Result[3][0] = - (right + left) / (right - left);
+	    Result[3][1] = - (top + bottom) / (top - bottom);
+	    return Result;
+	}
+
 	template <typename T>
 	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> frustum
 	(
@@ -196,15 +247,67 @@ namespace glm
 		T nearVal,
 		T farVal
 	)
+	{
+#ifdef GLM_LEFT_HANDED
+	return frustumLH(left, right, bottom, top, nearVal, farVal);
+#else
+	return frustumRH(left, right, bottom, top, nearVal, farVal);
+#endif
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> frustumLH
+	(
+		T left,
+		T right,
+		T bottom,
+		T top,
+		T nearVal,
+		T farVal
+	)
+	{
+		tmat4x4<T, defaultp> Result(0);
+		Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
+		Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
+		Result[2][0] = (right + left) / (right - left);
+		Result[2][1] = (top + bottom) / (top - bottom);
+		Result[2][3] = static_cast<T>(1);
+
+#ifdef GLM_DEPTH_ZERO_TO_ONE
+		Result[2][2] = farVal / (zFar - nearVal);
+		Result[3][2] = -(farVal * nearVal) / (zFar - nearVal);
+#else
+		Result[2][2] = (farVal + nearVal) / (farVal - nearVal);
+		Result[3][2] = - (static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal);
+#endif
+		return Result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> frustumRH
+	(
+		T left,
+		T right,
+		T bottom,
+		T top,
+		T nearVal,
+		T farVal
+	)
 	{
 		tmat4x4<T, defaultp> Result(0);
 		Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
 		Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
 		Result[2][0] = (right + left) / (right - left);
 		Result[2][1] = (top + bottom) / (top - bottom);
-		Result[2][2] = -(farVal + nearVal) / (farVal - nearVal);
 		Result[2][3] = static_cast<T>(-1);
-		Result[3][2] = -(static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal);
+
+#ifdef GLM_DEPTH_ZERO_TO_ONE
+		Result[2][2] = farVal / (nearVal - farVal);
+		Result[3][2] = -(farVal * nearVal) / (farVal - nearVal);
+#else
+		Result[2][2] = - (farVal + nearVal) / (farVal - nearVal);
+		Result[3][2] = - (static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal);
+#endif
 		return Result;
 	}
 
@@ -240,9 +343,15 @@ namespace glm
 		tmat4x4<T, defaultp> Result(static_cast<T>(0));
 		Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
 		Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
-		Result[2][2] = - (zFar + zNear) / (zFar - zNear);
 		Result[2][3] = - static_cast<T>(1);
+
+#ifdef GLM_DEPTH_ZERO_TO_ONE
+		Result[2][2] = zFar / (zNear - zFar);
+		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
+#else
+		Result[2][2] = - (zFar + zNear) / (zFar - zNear);
 		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
+#endif
 		return Result;
 	}
 	
@@ -262,9 +371,15 @@ namespace glm
 		tmat4x4<T, defaultp> Result(static_cast<T>(0));
 		Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
 		Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
-		Result[2][2] = (zFar + zNear) / (zFar - zNear);
 		Result[2][3] = static_cast<T>(1);
-		Result[3][2] = -(static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
+
+#ifdef GLM_DEPTH_ZERO_TO_ONE
+		Result[2][2] = zFar / (zFar - zNear);
+		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
+#else
+		Result[2][2] = (zFar + zNear) / (zFar - zNear);
+		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
+#endif
 		return Result;
 	}
 
@@ -306,9 +421,15 @@ namespace glm
 		tmat4x4<T, defaultp> Result(static_cast<T>(0));
 		Result[0][0] = w;
 		Result[1][1] = h;
-		Result[2][2] = - (zFar + zNear) / (zFar - zNear);
 		Result[2][3] = - static_cast<T>(1);
+
+#ifdef GLM_DEPTH_ZERO_TO_ONE
+		Result[2][2] = zFar / (zNear - zFar);
+		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
+#else
+		Result[2][2] = - (zFar + zNear) / (zFar - zNear);
 		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
+#endif
 		return Result;
 	}
 
@@ -333,9 +454,16 @@ namespace glm
 		tmat4x4<T, defaultp> Result(static_cast<T>(0));
 		Result[0][0] = w;
 		Result[1][1] = h;
-		Result[2][2] = (zFar + zNear) / (zFar - zNear);
 		Result[2][3] = static_cast<T>(1);
+
+#ifdef GLM_DEPTH_ZERO_TO_ONE
+		Result[2][2] = zFar / (zFar - zNear);
+		Result[3][2] = -(zFar * zNear) / (zFar - zNear);
+#else
+		Result[2][2] = (zFar + zNear) / (zFar - zNear);
 		Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
+#endif
+
 		return Result;
 	}
 
@@ -346,6 +474,21 @@ namespace glm
 		T aspect,
 		T zNear
 	)
+	{
+#ifdef GLM_LEFT_HANDED
+	return infinitePerspectiveLH(fovy, aspect, zNear);
+#else
+	return infinitePerspectiveRH(fovy, aspect, zNear);
+#endif
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> infinitePerspectiveRH
+	(
+		T fovy,
+		T aspect,
+		T zNear
+	)
 	{
 		T const range = tan(fovy / T(2)) * zNear;
 		T const left = -range * aspect;
@@ -362,6 +505,29 @@ namespace glm
 		return Result;
 	}
 
+	template <typename T>
+	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> infinitePerspectiveLH
+	(
+		T fovy,
+		T aspect,
+		T zNear
+	)
+	{
+		T const range = tan(fovy / T(2)) * zNear;
+		T const left = -range * aspect;
+		T const right = range * aspect;
+		T const bottom = -range;
+		T const top = range;
+
+		tmat4x4<T, defaultp> Result(T(0));
+		Result[0][0] = (T(2) * zNear) / (right - left);
+		Result[1][1] = (T(2) * zNear) / (top - bottom);
+		Result[2][2] = T(1);
+		Result[2][3] = T(1);
+		Result[3][2] = - T(2) * zNear;
+		return Result;
+	}
+
 	// Infinite projection matrix: http://www.terathon.com/gdc07_lengyel.pdf
 	template <typename T>
 	GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> tweakedInfinitePerspective