The open source OpenXR runtime
at main 81 lines 2.2 kB view raw
1// Copyright 2019-2023, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Matrix function for creating projection matrices. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @ingroup aux_math 8 */ 9 10#include "m_mathinclude.h" 11#include "xrt/xrt_defines.h" 12 13 14/* 15 * 16 * Helpers. 17 * 18 */ 19 20template <typename Scalar, typename ResultType> 21void 22calc_vulkan_projection_infinite_reverse(const xrt_fov &fov, Scalar near_plane, ResultType &result) 23{ 24 const Scalar tan_left = static_cast<Scalar>(tan(fov.angle_left)); 25 const Scalar tan_right = static_cast<Scalar>(tan(fov.angle_right)); 26 27 const Scalar tan_down = static_cast<Scalar>(tan(fov.angle_down)); 28 const Scalar tan_up = static_cast<Scalar>(tan(fov.angle_up)); 29 30 // This is here for clarity. 31 const bool vulkan_projection_space_y = true; 32 33 const Scalar tan_width = tan_right - tan_left; 34 const Scalar tan_height = vulkan_projection_space_y // Projection space y direction: 35 ? (tan_down - tan_up) // Vulkan Y down 36 : (tan_up - tan_down); // OpenGL Y up 37 38 const Scalar a11 = 2 / tan_width; 39 const Scalar a22 = 2 / tan_height; 40 41 const Scalar a31 = (tan_right + tan_left) / tan_width; 42 const Scalar a32 = (tan_up + tan_down) / tan_height; 43 44 45 /* 46 * Vulkan's Z clip space is [0 .. 1] (OpenGL [-1 .. 0 .. 1]). 47 * We are using reverse depth for better floating value. 48 * - Near is 1 49 * - Far is 0 (infinite) 50 * 51 * https://vincent-p.github.io/posts/vulkan_perspective_matrix/ 52 */ 53 54 const Scalar a33 = 0; // vulkan = 0, opengl = -1 55 const Scalar a34 = -1; 56 const Scalar a43 = near_plane; // Reverse depth and half vs opengl, `-2 * near_plane`. 57 58 // clang-format off 59 result = ResultType({ 60 a11, 0, 0, 0, 61 0, a22, 0, 0, 62 a31, a32, a33, a34, 63 0, 0, a43, 0, 64 }); 65 // clang-format on 66} 67 68 69/* 70 * 71 * 'Exported' functions. 72 * 73 */ 74 75extern "C" void 76math_matrix_4x4_projection_vulkan_infinite_reverse(const struct xrt_fov *fov, 77 float near_plane, 78 struct xrt_matrix_4x4 *result) 79{ 80 calc_vulkan_projection_infinite_reverse<float, xrt_matrix_4x4>(*fov, near_plane, *result); 81}