Skyscraper 2.0
OgreOpenXRState.cpp
Go to the documentation of this file.
1/*
2 Skyscraper 2.0 - OpenXR State
3 Portions Copyright (C)2024 Ryan Thoryk
4 MIT license - see LICENSE file
5 https://www.skyscrapersim.net
6 https://sourceforge.net/projects/skyscraper/
7 Contact - ryan@skyscrapersim.net
8*/
9
10/*
11 Original work produced by Glastonbridge Software Limited. This code is provided under the MIT license.
12 https://github.com/glastonbridge/OgreOpenXRRenderWindow
13*/
14
15#include "Ogre.h"
16#include "OgreOpenXRState.h"
17
18#include "OgreOpenXRInstance.h"
19
20#include <openxr/openxr_platform_defines.h>
21#include <chrono>
22#include <thread>
23
24#include "XrUtility/XrMath.h"
25
26namespace Ogre {
27
29 _systemId(XR_NULL_SYSTEM_ID),
30 m_xrInstance(new OpenXRInstance)
31 {}
32
33 void OpenXRState::Initialize(const std::string& applicationName) {
34 m_xrInstance->Initialize(applicationName);
35 }
36
38 CHECK(m_xrInstance->initialized());
39 CHECK(_systemId == XR_NULL_SYSTEM_ID);
40
41 XrSystemGetInfo systemInfo{ XR_TYPE_SYSTEM_GET_INFO };
42 systemInfo.formFactor = _formFactor;
43 while (true) {
44 XrResult result = xrGetSystem(m_xrInstance->getHandle().Get(), &systemInfo, &_systemId);
45 if (SUCCEEDED(result)) {
46 LogManager::getSingleton().logMessage("OpenXR: Headset detected");
47 break;
48 }
49 else if (result == XR_ERROR_FORM_FACTOR_UNAVAILABLE) {
50 LogManager::getSingleton().logMessage("OpenXR: No headset detected. Trying again in one second...");
51 using namespace std::chrono_literals;
52 std::this_thread::sleep_for(1s);
53 }
54 else {
55 CHECK_XRRESULT(result, "xrGetSystem");
56 }
57
58 };
59
60 // Choose an environment blend mode.
61 {
62 // Query the list of supported environment blend modes for the current system.
63 uint32_t count;
64 CHECK_XRCMD(xrEnumerateEnvironmentBlendModes(m_xrInstance->getHandle().Get(), _systemId, primaryViewConfigType, 0, &count, nullptr));
65 CHECK(count > 0); // A system must support at least one environment blend mode.
66
67 environmentBlendModes.resize(count);
68 CHECK_XRCMD(xrEnumerateEnvironmentBlendModes(
69 m_xrInstance->getHandle().Get(), _systemId, primaryViewConfigType, count, &count, environmentBlendModes.data()));
70
71 // This sample supports all modes, pick the system's preferred one.
72 //m_environmentBlendMode = environmentBlendModes[0];
73 }
74
75 // Choosing a reasonable depth range can help improve hologram visual quality.
76 // Use reversed-Z (near > far) for more uniform Z resolution.
77 // m_nearFar = { 20.f, 0.1f };
78 }
79
81 XrGraphicsRequirementsD3D11KHR graphicsRequirements{ XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR };
83 xrGetD3D11GraphicsRequirementsKHR(m_xrInstance->getHandle().Get(), _systemId, &graphicsRequirements));
84
85 return graphicsRequirements.adapterLuid;
86 }
87
89 {
90 return m_xrInstance->getHandle();
91 }
92
93 const uint64_t OpenXRState::GetSystemId()
94 {
95 return _systemId;
96 }
97
98 void OpenXRState::GetSystemProperties(XrSystemProperties& systemProperties)
99 {
100 CHECK_XRCMD(xrGetSystemProperties(m_xrInstance->getHandle().Get(), _systemId, &systemProperties));
101 }
102
103 void OpenXRState::initializeSession(D3D11Device& device)
104 {
105 CHECK(m_xrInstance->initialized());
107 XrGraphicsBindingD3D11KHR graphicsBinding{ XR_TYPE_GRAPHICS_BINDING_D3D11_KHR };
108 graphicsBinding.device = device.get();
109
110 XrSessionCreateInfo createInfo{ XR_TYPE_SESSION_CREATE_INFO };
111 createInfo.next = &graphicsBinding;
112 createInfo.systemId = _systemId;
113 CHECK_XRCMD(xrCreateSession(m_xrInstance->getHandle().Get(), &createInfo, _sessionHandle.Put(xrDestroySession)));
114
115 XrReferenceSpaceCreateInfo spaceCreateInfo{ XR_TYPE_REFERENCE_SPACE_CREATE_INFO };
116 spaceCreateInfo.referenceSpaceType = _appSpaceType;
117 spaceCreateInfo.poseInReferenceSpace = xr::math::Pose::Identity();
119 xrCreateReferenceSpace(GetSession().Get(), &spaceCreateInfo, _appSpace.Put(xrDestroySpace))
120 );
121 }
122
123
124 std::tuple<DXGI_FORMAT, DXGI_FORMAT> OpenXRState::SelectSwapchainPixelFormats()
125 {
126 CHECK(_sessionHandle.Get() != XR_NULL_HANDLE);
127
128 // Query the runtime's preferred swapchain formats.
129 uint32_t swapchainFormatCount;
130 CHECK_XRCMD(xrEnumerateSwapchainFormats(_sessionHandle.Get(), 0, &swapchainFormatCount, nullptr));
131
132 std::vector<int64_t> swapchainFormats(swapchainFormatCount);
133 CHECK_XRCMD(xrEnumerateSwapchainFormats(
134 _sessionHandle.Get(), (uint32_t)swapchainFormats.size(), &swapchainFormatCount, swapchainFormats.data()));
135
136 // Choose the first runtime-preferred format that this app supports.
137 auto SelectPixelFormat = [](const std::vector<int64_t>& runtimePreferredFormats,
138 const std::vector<DXGI_FORMAT>& applicationSupportedFormats) {
139 auto found = std::find_first_of(std::begin(runtimePreferredFormats),
140 std::end(runtimePreferredFormats),
141 std::begin(applicationSupportedFormats),
142 std::end(applicationSupportedFormats));
143 if (found == std::end(runtimePreferredFormats)) {
144 THROW("No runtime swapchain format is supported.");
145 }
146 return (DXGI_FORMAT)*found;
147 };
148
149 const static std::vector<DXGI_FORMAT> SupportedColorFormats = {
150 DXGI_FORMAT_R8G8B8A8_UNORM,
151 DXGI_FORMAT_B8G8R8A8_UNORM,
152 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
153 DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
154 };
155
156 const static std::vector<DXGI_FORMAT> SupportedDepthFormats = {
157 DXGI_FORMAT_D32_FLOAT,
158 DXGI_FORMAT_D16_UNORM,
159 DXGI_FORMAT_D24_UNORM_S8_UINT,
160 DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
161 };
162
163 DXGI_FORMAT colorSwapchainFormat = SelectPixelFormat(swapchainFormats, SupportedColorFormats);
164 DXGI_FORMAT depthSwapchainFormat = SelectPixelFormat(swapchainFormats, SupportedDepthFormats);
165
166 return { colorSwapchainFormat, depthSwapchainFormat };
167 }
168
173
175 {
176 return environmentBlendModes.data();
177 }
178
183
184}
#define CHECK_XRRESULT(res, cmdStr)
Definition XrError.h:15
#define CHECK(exp)
Definition XrError.h:59
#define CHECK_XRCMD(cmd)
Definition XrError.h:14
#define THROW(msg)
Definition XrError.h:58
void initializeSession(D3D11Device &device)
std::vector< XrEnvironmentBlendMode > environmentBlendModes
const LUID GetAdapterLUID()
xr::SpaceHandle _appSpace
void GetSystemProperties(XrSystemProperties &systemProperties)
const uint64_t GetSystemId()
xr::SpaceHandle & getAppSpace()
static constexpr XrViewConfigurationType primaryViewConfigType
void Initialize(const std::string &applicationName)
XrEnvironmentBlendMode * GetEnvironmentBlendModes()
static constexpr XrFormFactor _formFactor
xr::SessionHandle _sessionHandle
const xr::InstanceHandle & GetInstanceHandle()
std::unique_ptr< OpenXRInstance > m_xrInstance
XrReferenceSpaceType _appSpaceType
std::tuple< DXGI_FORMAT, DXGI_FORMAT > SelectSwapchainPixelFormats()
xr::SessionHandle & GetSession()
HandleType Get() const noexcept
Definition XrHandle.h:51
HandleType * Put(PFN_DestroyFunction destroyFunction) noexcept
Definition XrHandle.h:56
constexpr XrPosef Identity()
Definition XrMath.h:302