Beispiel #1
0
        /// <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();
        }