Browse Source

add infinitePerspectiveRH_ZO

azhirnov 2 years ago
parent
commit
ed1059731f
2 changed files with 63 additions and 3 deletions
  1. 23 3
      glm/ext/matrix_clip_space.inl
  2. 40 0
      test/gtc/gtc_matrix_transform.cpp

+ 23 - 3
glm/ext/matrix_clip_space.inl

@@ -483,7 +483,7 @@ namespace glm
 	}
 
 	template<typename T>
-	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveRH(T fovy, T aspect, T zNear)
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveRH_NO(T fovy, T aspect, T zNear)
 	{
 		T const range = tan(fovy / static_cast<T>(2)) * zNear;
 		T const left = -range * aspect;
@@ -499,6 +499,24 @@ namespace glm
 		Result[3][2] = - static_cast<T>(2) * zNear;
 		return Result;
 	}
+	
+	template<typename T>
+	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveRH_ZO(T fovy, T aspect, T zNear)
+	{
+		T const range = tan(fovy / static_cast<T>(2)) * zNear;
+		T const left = -range * aspect;
+		T const right = range * aspect;
+		T const bottom = -range;
+		T const top = range;
+
+		mat<4, 4, T, defaultp> Result(static_cast<T>(0));
+		Result[0][0] = (static_cast<T>(2) * zNear) / (right - left);
+		Result[1][1] = (static_cast<T>(2) * zNear) / (top - bottom);
+		Result[2][2] = - static_cast<T>(1);
+		Result[2][3] = - static_cast<T>(1);
+		Result[3][2] = - zNear;
+		return Result;
+	}
 
 	template<typename T>
 	GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveLH_NO(T fovy, T aspect, T zNear)
@@ -543,8 +561,10 @@ namespace glm
 			return infinitePerspectiveLH_ZO(fovy, aspect, zNear);
 #		elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
 			return infinitePerspectiveLH_NO(fovy, aspect, zNear);
-#		else
-			return infinitePerspectiveRH(fovy, aspect, zNear);
+#		elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO
+			return infinitePerspectiveRH_ZO(fovy, aspect, zNear);
+#		elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO
+			return infinitePerspectiveRH_NO(fovy, aspect, zNear);
 #		endif
 	}
 

+ 40 - 0
test/gtc/gtc_matrix_transform.cpp

@@ -32,6 +32,26 @@ int test_perspective()
 		Error += glm::notEqual(N.z, -1.f, Eps);
 		Error += glm::notEqual(F.z, 1.f, Eps);
 	}
+	
+	Projection = glm::perspectiveRH_ZO(glm::pi<float>() * 0.25f, 4.0f / 3.0f, Near, Far);
+	{
+		glm::vec4 N = Projection * glm::vec4{0.f, 0.f, -Near, 1.f};
+		glm::vec4 F = Projection * glm::vec4{0.f, 0.f, -Far, 1.f};
+		N /= N.w;
+		F /= F.w;
+		Error += glm::notEqual(N.z, 0.f, Eps);
+		Error += glm::notEqual(F.z, 1.f, Eps);
+	}
+
+	Projection = glm::perspectiveRH_NO(glm::pi<float>() * 0.25f, 4.0f / 3.0f, Near, Far);
+	{
+		glm::vec4 N = Projection * glm::vec4{0.f, 0.f, -Near, 1.f};
+		glm::vec4 F = Projection * glm::vec4{0.f, 0.f, -Far, 1.f};
+		N /= N.w;
+		F /= F.w;
+		Error += glm::notEqual(N.z, -1.f, Eps);
+		Error += glm::notEqual(F.z, 1.f, Eps);
+	}
 
 	return Error;
 }
@@ -66,6 +86,26 @@ int test_infinitePerspective()
 		Error += glm::notEqual(F.z, 1.f, Eps);
 	}
 
+	Projection = glm::infinitePerspectiveRH_ZO(glm::pi<float>() * 0.25f, 4.0f / 3.0f, Near);
+	{
+		glm::vec4 N = Projection * glm::vec4{0.f, 0.f, -Near, 1.f};
+		glm::vec4 F = Projection * glm::vec4{0.f, 0.f, -Inf, 1.f};
+		N /= N.w;
+		F /= F.w;
+		Error += glm::notEqual(N.z, 0.f, Eps);
+		Error += glm::notEqual(F.z, 1.f, Eps);
+	}
+
+	Projection = glm::infinitePerspectiveRH_NO(glm::pi<float>() * 0.25f, 4.0f / 3.0f, Near);
+	{
+		glm::vec4 N = Projection * glm::vec4{0.f, 0.f, -Near, 1.f};
+		glm::vec4 F = Projection * glm::vec4{0.f, 0.f, -Inf, 1.f};
+		N /= N.w;
+		F /= F.w;
+		Error += glm::notEqual(N.z, -1.f, Eps);
+		Error += glm::notEqual(F.z, 1.f, Eps);
+	}
+
 	return Error;
 }