/// <summary> /// Dispose the created resource and removes the added rendering steps. /// </summary> protected override void Dispose(bool isDisposing) { if (isDisposing) { DiposeMsaaBuffers(); if (_mirrorTexture != null) { _mirrorTexture.Dispose(); _mirrorTexture = null; _mirrorTextureDesc = new MirrorTextureDesc(); } if (_eyeTextureSwapChains != null) { _eyeTextureSwapChains[0].Dispose(); _eyeTextureSwapChains[1].Dispose(); _eyeTextureSwapChains = null; } if (_resetViewportRenderingStep != null) { if (parentDXScene != null) { parentDXScene.RenderingSteps.Remove(_resetViewportRenderingStep); } _resetViewportRenderingStep.Dispose(); _resetViewportRenderingStep = null; } if (renderingStepsLoop != null) { if (parentDXScene != null) { parentDXScene.RenderingSteps.Remove(renderingStepsLoop); } renderingStepsLoop.Dispose(); renderingStepsLoop = null; } if (parentDXScene != null) { parentDXScene.DefaultResolveMultisampledBackBufferRenderingStep.DestinationBuffer = null; // Set to previous value } } base.Dispose(isDisposing); }
/// <summary> /// CreateResources is called when the VirtualRealityProvider is initialized and should create the DirectX resources. /// </summary> /// <remarks> /// <para> /// <b>CreateResources</b> is called when the VirtualRealityProvider is initialized and should create the DirectX resources. /// </para> /// <para> /// This method is called after this virtual reality provider is registered with calling the <see cref="DXScene.InitializeVirtualRealityRendering"/> method. /// This method then calls the <see cref="DXSceneResource.InitializeResources"/> and the <see cref="VirtualRealityProviderBase.OnInitializeResources"/>. /// OnInitializeResources calls the this CreateResources method and then <see cref="VirtualRealityProviderBase.InitializeRenderingSteps"/> method. /// </para> /// <para> /// This method usually creates pixel shaders and constant buffers. /// Other resources (back buffers and views) are usually created in <see cref="VirtualRealityProviderBase.UpdateRenderingContext"/> where the size of the current back buffer is compared with the size of back buffers for virtual reality. /// </para> /// </remarks> /// <param name="dxScene">parent DXScene</param> protected override void CreateResources(DXScene dxScene) { if (_eyeTextureSwapChains != null) { if (_eyeTextureSwapChains[0] != null) { _eyeTextureSwapChains[0].Dispose(); } if (_eyeTextureSwapChains[1] != null) { _eyeTextureSwapChains[1].Dispose(); } } else { _eyeTextureSwapChains = new OculusTextureSwapChain[2]; } _eyeTextureSwapChains[0] = new OculusTextureSwapChain(_ovr, _sessionPtr, dxScene.Device, EyeType.Left, Format.B8G8R8A8_UNorm_SRgb, _ovr.GetFovTextureSize(_sessionPtr, EyeType.Left, _hmdDesc.DefaultEyeFov[0], 1.0f), createDepthStencilView: true, isDebugDevice: dxScene.DXDevice.IsDebugDevice); _eyeTextureSwapChains[1] = new OculusTextureSwapChain(_ovr, _sessionPtr, dxScene.Device, EyeType.Left, Format.B8G8R8A8_UNorm_SRgb, _ovr.GetFovTextureSize(_sessionPtr, EyeType.Right, _hmdDesc.DefaultEyeFov[1], 1.0f), createDepthStencilView: true, isDebugDevice: dxScene.DXDevice.IsDebugDevice); _layerShared = new LayerEyeFov(); _layerShared.Header = new LayerHeader() { Type = LayerType.EyeFov, Flags = LayerFlags.HighQuality }; // Specify the texture to show on the HMD. _layerShared.ColorTextureLeft = _eyeTextureSwapChains[0].TextureSwapChainPtr; _layerShared.ColorTextureRight = _eyeTextureSwapChains[1].TextureSwapChainPtr; _layerShared.ViewportLeft.Position = new Vector2i(0, 0); _layerShared.ViewportLeft.Size = _eyeTextureSwapChains[0].Size; _layerShared.ViewportRight.Position = new Vector2i(0, 0); _layerShared.ViewportRight.Size = _eyeTextureSwapChains[1].Size; _layerShared.FovLeft = _hmdDesc.DefaultEyeFov[0]; _layerShared.FovRight = _hmdDesc.DefaultEyeFov[1]; _eyeRenderDesc[0] = _ovr.GetRenderDesc(_sessionPtr, EyeType.Left, _hmdDesc.DefaultEyeFov[0]); _hmdToEyeOffset[1] = _eyeRenderDesc[1].HmdToEyePose.Position; _eyeRenderDesc[1] = _ovr.GetRenderDesc(_sessionPtr, EyeType.Right, _hmdDesc.DefaultEyeFov[1]); _hmdToEyeOffset[1] = _eyeRenderDesc[1].HmdToEyePose.Position; // Create MSAA back buffer if needed UpdateMsaaBackBuffer(_eyeTextureSwapChains[0].Size.Width, _eyeTextureSwapChains[0].Size.Height, _multisamplingCount); _mirrorTextureDesc = new MirrorTextureDesc() { Format = SharpDXHelpers.GetTextureFormat(dxScene.BackBufferDescription.Format), Height = dxScene.BackBufferDescription.Height, MiscFlags = dxScene.BackBufferDescription.MipLevels != 1 ? TextureMiscFlags.AllowGenerateMips : TextureMiscFlags.None, Width = dxScene.BackBufferDescription.Width }; // FloorLevel will give tracking poses where the floor height is 0 _ovr.SetTrackingOriginType(_sessionPtr, TrackingOrigin.EyeLevel); IntPtr mirrorTexturePtr; var result = _ovr.CreateMirrorTextureDX(_sessionPtr, dxScene.Device.NativePointer, ref _mirrorTextureDesc, out mirrorTexturePtr); if (result < Ab3d.OculusWrap.Result.Success) { var lastError = _ovr.GetLastErrorInfo(); throw new OvrException("Failed to create Oculus mirror texture: " + lastError.ErrorString, lastError.Result); } _mirrorTexture = new OculusMirrorTexture(_ovr, _sessionPtr, mirrorTexturePtr); // Retrieve the Direct3D texture contained in the Oculus MirrorTexture. IntPtr mirrorTextureComPtr; result = _mirrorTexture.GetBufferDX(typeof(Texture2D).GUID, out mirrorTextureComPtr); if (result < Ab3d.OculusWrap.Result.Success) { var lastError = _ovr.GetLastErrorInfo(); throw new OvrException("Failed to retrieve the texture from the created mirror texture buffer: " + lastError.ErrorString, lastError.Result); } // Create a managed Texture2D, based on the unmanaged texture pointer. _mirrorTextureDX = new Texture2D(mirrorTextureComPtr); if (dxScene.DXDevice.IsDebugDevice) { _mirrorTextureDX.DebugName = "OculusMirrorTexture"; } // To prevent DirectX from rendering more then one frame in the background, // we need to set the MaximumFrameLatency to 1. // This prevents occasional dropped frames in Oculus Rift. var dxgiDevice = dxScene.Device.QueryInterface <SharpDX.DXGI.Device1>(); if (dxgiDevice != null) { dxgiDevice.MaximumFrameLatency = 1; dxgiDevice.Dispose(); } _frameIndex = 0; _matrixCamera = new MatrixCamera(); }