55 virtual void create(
const String& name,
unsigned int width,
unsigned int height,
56 bool fullScreen,
const NameValuePairList* miscParams)
override;
60 void _beginUpdate()
override;
61 void _endUpdate()
override;
63 ID3D11Texture2D* getSurface(
uint index)
const override;
65 uint getNumberOfViews()
const;
66 ID3D11RenderTargetView* getRenderTargetView(
uint index)
const;
67 Viewport* addViewport(Camera* cam,
int zOrder = 0,
float x = 0.0f,
float y = 0.0f,
float w = 0.0f,
float h = 0.0f)
override;
69 void setActiveEye(
size_t eye);
72 void notifyDeviceLost(D3D11Device* device);
73 void notifyDeviceRestored(D3D11Device* device);
76 Ogre::Camera* mEyeCameras[2];
77 size_t mNumberOfEyesAdded = 0;
78 size_t mActiveEye = 0;
89 XrViewState mXrViewState{ XR_TYPE_VIEW_STATE };
93 XrFrameState mXrFrameState{ XR_TYPE_FRAME_STATE };
94 XrCompositionLayerProjection mXrLayer{ XR_TYPE_COMPOSITION_LAYER_PROJECTION };
95 std::vector<XrCompositionLayerBaseHeader*>
mXrLayers;
97 bool sessionReady() {
return mXrSessionState == XR_SESSION_STATE_READY || XR_SESSION_STATE_FOCUSED; }
98 bool shouldRender() {
return sessionReady() && mXrFrameState.shouldRender; }
100 void ProcessOpenXREvents();
101 void _startXrFrame();
128 D3D11RenderWindowBase(static_cast<D3D11RenderSystem*>(rsys)->_getDevice()),
134 mIsFullScreen =
true;
145 LogManager::getSingleton().logMessage(
"\nOpenXR Interface loaded\nOriginal work produced by Glastonbridge Software Limited, MIT license");
146 LogManager::getSingleton().logMessage(
"OpenXR: Initializing...");
177 RenderTarget::_beginUpdate();
184 uint32_t viewCount = 2;
189 const CD3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDescL(D3D11_RTV_DIMENSION_TEXTURE2DARRAY,
swapchainL->ColorSwapchainPixelFormat);
194 const CD3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDescR(D3D11_RTV_DIMENSION_TEXTURE2DARRAY,
swapchainR->ColorSwapchainPixelFormat);
199 std::vector<xr::math::ViewProjection> vps(viewCount);
209 for (uint32_t i = 0; i < viewCount; ++i) {
214 auto deviceContext = mDevice.GetImmediateContext();
216 const uint32_t viewInstanceCount = (uint32_t)vps.size();
218 CD3D11_VIEWPORT viewport(
219 (
float)imageRect.offset.x, (
float)imageRect.offset.y, (
float)imageRect.extent.width, (
float)imageRect.extent.height);
220 deviceContext->RSSetViewports(1, &viewport);
224 const bool reversedZ = vps[0].NearFar.Near > vps[0].NearFar.Far;
225 const float depthClearValue = reversedZ ? 0.f : 1.f;
229 for (uint32_t k = 0; k < 2; ++k) {
231 Ogre::Quaternion orientation(vps[k].Pose.orientation.w, vps[k].Pose.orientation.x, vps[k].Pose.orientation.y, vps[k].Pose.orientation.z);
232 Ogre::Vector3 position(vps[k].Pose.position.x, vps[k].Pose.position.y, vps[k].Pose.position.z);
234 Ogre::Affine3 viewMatrix;
235 for (
size_t i = 0; i < 4; ++i) {
236 for (
size_t j = 0; j < 4; ++j) {
237 viewMatrix[i][j] = spaceToView.r[i].m128_f32[j];
243 DirectX::XMMATRIX projectionMatrix = ComposeProjectionMatrix(
246 Ogre::Matrix4 eyeProjectionMatrix;
249 for (
size_t i = 0; i < 4; ++i) {
250 for (
size_t j = 0; j < 4; ++j) {
251 eyeProjectionMatrix[i][j] = projectionMatrix.r[j].m128_f32[i];
258 mEyeCameras[k]->setCustomProjectionMatrix(
true, eyeProjectionMatrix);
260 mEyeCameras[k]->setAspectRatio(Ogre::Real(imageRect.extent.height / imageRect.extent.width));
324 auto pollEvent = [&](XrEventDataBuffer& eventData) ->
bool {
325 eventData.type = XR_TYPE_EVENT_DATA_BUFFER;
326 eventData.next =
nullptr;
328 xrPollEvent(
mXrState->GetInstanceHandle().Get(), &eventData)
332 XrEventDataBuffer eventData{};
333 while (pollEvent(eventData)) {
334 switch (eventData.type) {
335 case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: {
340 case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: {
341 auto& xrSession =
mXrState->GetSession();
342 const auto stateEvent = *
reinterpret_cast<const XrEventDataSessionStateChanged*
>(&eventData);
343 CHECK(xrSession.Get() != XR_NULL_HANDLE && xrSession.Get() == stateEvent.session);
346 case XR_SESSION_STATE_READY: {
347 CHECK(xrSession.Get() != XR_NULL_HANDLE);
348 XrSessionBeginInfo sessionBeginInfo{ XR_TYPE_SESSION_BEGIN_INFO };
350 CHECK_XRCMD(xrBeginSession(xrSession.Get(), &sessionBeginInfo));
353 case XR_SESSION_STATE_STOPPING: {
357 case XR_SESSION_STATE_EXITING: {
364 case XR_SESSION_STATE_LOSS_PENDING: {
374 case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING:
375 case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED:
377 DEBUG_PRINT(
"Ignoring event type %d", eventData.type);
390 auto& session =
mXrState->GetSession();
392 CHECK(session.Get() != XR_NULL_HANDLE);
394 XrFrameWaitInfo frameWaitInfo{ XR_TYPE_FRAME_WAIT_INFO };
397 XrFrameBeginInfo frameBeginInfo{ XR_TYPE_FRAME_BEGIN_INFO };
398 CHECK_XRCMD(xrBeginFrame(session.Get(), &frameBeginInfo));
407 mXrLayer = { XR_TYPE_COMPOSITION_LAYER_PROJECTION };
408 mXrLayer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
418 XrFrameEndInfo frameEndInfo{ XR_TYPE_FRAME_END_INFO };
419 frameEndInfo.displayTime =
mXrFrameState.predictedDisplayTime;
420 frameEndInfo.environmentBlendMode = *
mXrState->GetEnvironmentBlendModes();
421 frameEndInfo.layerCount =
mXrLayers.size();