コード例 #1
0
        public void Session_GetTextureSwapChainDesc()
        {
            IntPtr session = CreateSession();

            Assert.AreNotEqual(IntPtr.Zero, session);

            using (TestEngine testEngine = CreateTestEngine(session))
            {
                // Convert the SharpDX texture description to the native Direct3D texture description.
                TextureSwapChainDesc textureSwapChainDescription = CreateTextureSwapChainDescription(testEngine.Texture2DDescription);

                IntPtr textureSwapChainPtr;
                Result result = OVR.CreateTextureSwapChainDX(session, testEngine.Device.NativePointer, ref textureSwapChainDescription, out textureSwapChainPtr);

                TextureSwapChainDesc textureSwapChainDescriptionResult = new TextureSwapChainDesc();
                result = OVR.GetTextureSwapChainDesc(session, textureSwapChainPtr, ref textureSwapChainDescriptionResult);
                Assert.IsTrue(result >= Result.Success);

                Assert.AreEqual(textureSwapChainDescription.ArraySize, textureSwapChainDescriptionResult.ArraySize);
                Assert.AreEqual(textureSwapChainDescription.BindFlags, textureSwapChainDescriptionResult.BindFlags);
                Assert.AreEqual(textureSwapChainDescription.Format, textureSwapChainDescriptionResult.Format);
                Assert.AreEqual(textureSwapChainDescription.Height, textureSwapChainDescriptionResult.Height);
                Assert.AreEqual(textureSwapChainDescription.MipLevels, textureSwapChainDescriptionResult.MipLevels);
                Assert.AreEqual(textureSwapChainDescription.MiscFlags, textureSwapChainDescriptionResult.MiscFlags);
                Assert.AreEqual(textureSwapChainDescription.SampleCount, textureSwapChainDescriptionResult.SampleCount);
                Assert.AreEqual(textureSwapChainDescription.StaticImage, textureSwapChainDescriptionResult.StaticImage);
                Assert.AreEqual(textureSwapChainDescription.Type, textureSwapChainDescriptionResult.Type);
                Assert.AreEqual(textureSwapChainDescription.Width, textureSwapChainDescriptionResult.Width);
            }
        }
コード例 #2
0
        public void Session_CreateTextureSwapChainDX()
        {
            IntPtr session = CreateSession();

            Assert.AreNotEqual(IntPtr.Zero, session);

            using (TestEngine testEngine = CreateTestEngine(session))
            {
                // Convert the SharpDX texture description to the native Direct3D texture description.
                TextureSwapChainDesc textureSwapChainDescription = CreateTextureSwapChainDescription(testEngine.Texture2DDescription);

                IntPtr textureSwapChainPtr = IntPtr.Zero;

                try
                {
                    Result result = OVR.CreateTextureSwapChainDX(session, testEngine.Device.NativePointer, ref textureSwapChainDescription, out textureSwapChainPtr);
                    Assert.IsTrue(result >= Result.Success);
                    Assert.AreNotEqual(IntPtr.Zero, textureSwapChainPtr);
                }
                finally
                {
                    if (textureSwapChainPtr != IntPtr.Zero)
                    {
                        OVR.DestroyTextureSwapChain(session, textureSwapChainPtr);
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Create a texture swap chain, used in unit tests.
        /// </summary>
        /// <param name="session">Existing session used to create the texture swap chain.</param>
        /// <param name="testEngine">Existing test engine, containing the Direct3D device and texture description to use.</param>
        /// <returns>Created texture swap chain pointer.</returns>
        private IntPtr CreateTextureSwapChain(IntPtr session, TestEngine testEngine)
        {
            // Convert the SharpDX texture description to the native Direct3D texture description.
            TextureSwapChainDesc textureSwapChainDescription = CreateTextureSwapChainDescription(testEngine.Texture2DDescription);

            IntPtr textureSwapChainPtr;
            Result result = OVR.CreateTextureSwapChainDX(session, testEngine.Device.NativePointer, ref textureSwapChainDescription, out textureSwapChainPtr);

            Assert.AreEqual(result, Result.Success);

            return(textureSwapChainPtr);
        }
コード例 #4
0
        /// <summary>
        /// Gets the description of the buffers in the TextureSwapChain
        /// </summary>
        /// <param name="textureSwapChainDescription">Returns the description of the specified chain.</param>
        /// <returns>Returns an ovrResult for which the return code is negative upon error. </returns>
        public Result GetDescription(out TextureSwapChainDesc textureSwapChainDescription)
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException("TextureSwapChain");
            }

            TextureSwapChainDesc textureSwapChainDesc = new TextureSwapChainDesc();

            Result result = _ovr.GetTextureSwapChainDesc(_sessionPtr, TextureSwapChainPtr, ref textureSwapChainDesc);

            textureSwapChainDescription = textureSwapChainDesc;

            return(result);
        }
コード例 #5
0
        /// <summary>
        /// Creates a TextureSwapChainDesc, based on a specified SharpDX texture description.
        /// </summary>
        /// <param name="texture2DDescription">SharpDX texture description.</param>
        /// <returns>TextureSwapChainDesc, based on the SharpDX texture description.</returns>
        public static TextureSwapChainDesc CreateTextureSwapChainDescription(Texture2DDescription texture2DDescription)
        {
            TextureSwapChainDesc textureSwapChainDescription = new TextureSwapChainDesc();

            textureSwapChainDescription.Type        = TextureType.Texture2D;
            textureSwapChainDescription.Format      = GetTextureFormat(texture2DDescription.Format);
            textureSwapChainDescription.ArraySize   = (int)texture2DDescription.ArraySize;
            textureSwapChainDescription.Width       = (int)texture2DDescription.Width;
            textureSwapChainDescription.Height      = (int)texture2DDescription.Height;
            textureSwapChainDescription.MipLevels   = (int)texture2DDescription.MipLevels;
            textureSwapChainDescription.SampleCount = (int)texture2DDescription.SampleDescription.Count;
            textureSwapChainDescription.StaticImage = false;
            textureSwapChainDescription.MiscFlags   = GetTextureMiscFlags(texture2DDescription, false);
            textureSwapChainDescription.BindFlags   = GetTextureBindFlags(texture2DDescription.BindFlags);

            return(textureSwapChainDescription);
        }
コード例 #6
0
        /// <summary>
        /// Creates a TextureSwapChainDesc, based on a specified SharpDX texture description.
        /// </summary>
        /// <param name="texture2DDescription">SharpDX texture description.</param>
        /// <returns>TextureSwapChainDesc, based on the SharpDX texture description.</returns>
        public static TextureSwapChainDesc CreateTextureSwapChainDescription(Texture2DDescription texture2DDescription)
        {
            var textureSwapChainDescription = new TextureSwapChainDesc
            {
                Type        = TextureType.Texture2D,
                Format      = GetTextureFormat(texture2DDescription.Format),
                ArraySize   = texture2DDescription.ArraySize,
                Width       = texture2DDescription.Width,
                Height      = texture2DDescription.Height,
                MipLevels   = texture2DDescription.MipLevels,
                SampleCount = texture2DDescription.SampleDescription.Count,
                StaticImage = false,
                MiscFlags   = GetTextureMiscFlags(texture2DDescription, false),
                BindFlags   = GetTextureBindFlags(texture2DDescription.BindFlags)
            };

            return(textureSwapChainDescription);
        }
コード例 #7
0
ファイル: program.cs プロジェクト: bholcomb/oculusSharp
			void initEyeTarget(EyeType eye)
			{
				EyeTarget e = new EyeTarget();
				e.eye = eye;
				e.fbo = GL.GenFramebuffer();
				e.depthTexture = GL.GenRenderbuffer();
				e.desc = OvrDLL.ovr_GetRenderDesc(session, eye, eye == EyeType.Left ? hmdDesc.LeftDefaultEyeFov : hmdDesc.RightDefaultEyeFov);
				e.renderTargetSize = OvrDLL.ovr_GetFovTextureSize(session, EyeType.Left, hmdDesc.LeftDefaultEyeFov, 1.0f);

				e.proj = OvrDLL.ovrMatrix4f_Projection(e.desc.Fov, 0.1f, 1000.0f, ProjectionModifier.ClipRangeOpenGL);

				//create the texture swap chain
				TextureSwapChainDesc swapDesc = new TextureSwapChainDesc()
				{
					Type = TextureType.Texture2D,
					ArraySize = 1,
					Format = TextureFormat.R8G8B8A8_UNORM_SRGB,
					Width = e.renderTargetSize.Width,
					Height = e.renderTargetSize.Height,
					MipLevels = 1,
					SampleCount = 1,
					StaticImage = 0
				};

				result = OvrDLL.ovr_CreateTextureSwapChainGL(session, ref swapDesc, ref e.swapChain);
				if (result < 0)
				{
					Console.WriteLine("Error creating swap chain");
					OvrDLL.ovr_GetLastErrorInfo(ref error);
					Console.WriteLine("Last Error Info: {0}-{1}", error.result, error.ErrorString);
				}

				int swapChainLength = 0;
				OvrDLL.ovr_GetTextureSwapChainLength(session, e.swapChain, ref swapChainLength);
				Console.WriteLine("Swapchain length: {0}", swapChainLength);

				for(int i = 0; i< swapChainLength; i++)
				{
					UInt32 texId = 0;
					OvrDLL.ovr_GetTextureSwapChainBufferGL(session, e.swapChain, i, ref texId);
					GL.BindTexture(TextureTarget.Texture2D, texId);
					GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
					GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
					GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
					GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);

				}

				int currentIndex = 0;
				OvrDLL.ovr_GetTextureSwapChainCurrentIndex(session, e.swapChain, ref currentIndex);
				Console.WriteLine("Swapchain current index: {0}", currentIndex);

				UInt32 chainTexId = 0;
				OvrDLL.ovr_GetTextureSwapChainBufferGL(session, e.swapChain, currentIndex, ref chainTexId);

				GL.BindFramebuffer(FramebufferTarget.Framebuffer, e.fbo);
				GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, e.depthTexture);
				GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent32f, e.renderTargetSize.Width, e.renderTargetSize.Height);
				GL.FramebufferRenderbuffer(FramebufferTarget.DrawFramebuffer, FramebufferAttachment.Depth, RenderbufferTarget.Renderbuffer, e.depthTexture);
				
				GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, chainTexId, 0);
				DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[1] { DrawBuffersEnum.ColorAttachment0 };
				GL.DrawBuffers(1, drawBuffers);

				//check frame buffer completeness
				FramebufferErrorCode err = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
				if(err != FramebufferErrorCode.FramebufferComplete)
				{
					Console.WriteLine("Error in frame buffer: {0}", err);
				}

				eyes[(int)eye] = e;

				GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
			}
コード例 #8
0
 public static extern Result ovr_CreateTextureSwapChainVk(ovrSession session, IntPtr device, ref TextureSwapChainDesc desc, out ovrTextureSwapChain out_TextureSwapChain);
コード例 #9
0
 public static extern Result ovr_CreateTextureSwapChainDX(ovrSession session, IntPtr d3dPtr, ref TextureSwapChainDesc desc, ref ovrTextureSwapChain outTextureSwapChain);
コード例 #10
0
 public static extern Result ovr_CreateTextureSwapChainGL(ovrSession session, ref TextureSwapChainDesc desc, ref ovrTextureSwapChain outTextureSwapChain);
コード例 #11
0
 public static extern Result ovr_GetTextureSwapChainDesc(ovrSession session, ovrTextureSwapChain chain, ref TextureSwapChainDesc outDesc);
コード例 #12
0
        public OculusTextureSwapChain(OvrWrap ovr,
                                      IntPtr sessionPtr,
                                      SharpDX.Direct3D11.Device device,
                                      EyeType eye,
                                      Format format,
                                      Sizei size,
                                      bool createDepthStencilView = false,
                                      bool isDebugDevice          = false)
        {
            _ovr          = ovr;
            _sessionPtr   = sessionPtr;
            _size         = size;
            _viewportSize = size;
            _viewport     = new ViewportF(0.0f, 0.0f, (float)size.Width, (float)size.Height);

            Format srgbFormat = GetSRgbFormat(format);

            TextureFormat        textureFormat = SharpDXHelpers.GetTextureFormat(srgbFormat);
            TextureSwapChainDesc swapChainDesc = new TextureSwapChainDesc()
            {
                ArraySize   = 1,
                BindFlags   = TextureBindFlags.DX_RenderTarget,
                Format      = textureFormat,
                Height      = _size.Height,
                MipLevels   = 1,
                MiscFlags   = TextureMiscFlags.DX_Typeless,
                SampleCount = 1,
                Width       = _size.Width
            };

            Texture2DDescription description1 = new Texture2DDescription()
            {
                ArraySize         = 1,
                BindFlags         = BindFlags.DepthStencil,
                CpuAccessFlags    = CpuAccessFlags.None,
                Format            = Format.R24G8_Typeless,
                Height            = _size.Height,
                MipLevels         = 1,
                OptionFlags       = ResourceOptionFlags.None,
                SampleDescription = new SampleDescription(1, 0),
                Usage             = ResourceUsage.Default,
                Width             = _size.Width
            };

            ShaderResourceViewDescription description2 = new ShaderResourceViewDescription()
            {
                Format    = srgbFormat,
                Dimension = ShaderResourceViewDimension.Texture2D
            };

            description2.Texture2D.MipLevels = 1;

            // Create a texture swap chain, which will contain the textures to render to, for the current eye.
            var result = _ovr.CreateTextureSwapChainDX(_sessionPtr, device.NativePointer, ref swapChainDesc, out _textureSwapChainPtr);

            if (result < Ab3d.OculusWrap.Result.Success)
            {
                var lastError = _ovr.GetLastErrorInfo();
                throw new OvrException("Error creating Oculus TextureSwapChain: " + lastError.ErrorString, lastError.Result);
            }


            int length;

            result = _ovr.GetTextureSwapChainLength(_sessionPtr, _textureSwapChainPtr, out length);

            if (result < Ab3d.OculusWrap.Result.Success)
            {
                var lastError = _ovr.GetLastErrorInfo();
                throw new OvrException("Failed to retrieve the number of buffers of the created swap chain: " + lastError.ErrorString, lastError.Result);
            }


            _textures = new TextureItem[length];

            for (int index = 0; index < length; ++index)
            {
                IntPtr bufferPtr;
                result = _ovr.GetTextureSwapChainBufferDX(_sessionPtr, _textureSwapChainPtr, index, typeof(Texture2D).GUID, out bufferPtr);

                if (result < Ab3d.OculusWrap.Result.Success)
                {
                    var lastError = _ovr.GetLastErrorInfo();
                    throw new OvrException("Failed to retrieve a texture from the created swap chain: " + lastError.ErrorString, lastError.Result);
                }

                Texture2D        texture2D1       = new Texture2D(bufferPtr);
                Texture2D        texture2D2       = null;
                DepthStencilView depthStencilView = null;

                if (createDepthStencilView)
                {
                    texture2D2       = new Texture2D(device, description1);
                    depthStencilView = new DepthStencilView(device, texture2D2, new DepthStencilViewDescription()
                    {
                        Flags     = DepthStencilViewFlags.None,
                        Dimension = DepthStencilViewDimension.Texture2D,
                        Format    = Format.D24_UNorm_S8_UInt
                    });
                }

                _textures[index] = new TextureItem()
                {
                    Texture            = texture2D1,
                    TextureDescription = texture2D1.Description,
                    DepthBuffer        = texture2D2,
                    DepthStencilView   = depthStencilView,
                    RTView             = new RenderTargetView(device, texture2D1, new RenderTargetViewDescription()
                    {
                        Format    = format,
                        Dimension = RenderTargetViewDimension.Texture2D
                    }),
                    SRView = new ShaderResourceView(device, texture2D1, description2)
                };


                if (isDebugDevice)
                {
                    var eyeTextAndIndex = eye.ToString() + index.ToString();

                    _textures[index].Texture.DebugName          = "OculusBackBuffer" + eyeTextAndIndex;
                    _textures[index].RTView.DebugName           = "OculusRT" + eyeTextAndIndex;
                    _textures[index].SRView.DebugName           = "OculusSR" + eyeTextAndIndex;
                    _textures[index].DepthBuffer.DebugName      = "OculusDepthBuffer" + eyeTextAndIndex;
                    _textures[index].DepthStencilView.DebugName = "OculusDepthStencilView" + eyeTextAndIndex;
                }
            }
        }
コード例 #13
0
        private static void Main()
        {
            RenderForm form = new RenderForm("OculusWrap SharpDX demo");

            IntPtr          sessionPtr;
            InputLayout     inputLayout          = null;
            Buffer          contantBuffer        = null;
            Buffer          vertexBuffer         = null;
            ShaderSignature shaderSignature      = null;
            PixelShader     pixelShader          = null;
            ShaderBytecode  pixelShaderByteCode  = null;
            VertexShader    vertexShader         = null;
            ShaderBytecode  vertexShaderByteCode = null;
            Texture2D       mirrorTextureD3D     = null;

            EyeTexture[]      eyeTextures                = null;
            DeviceContext     immediateContext           = null;
            DepthStencilState depthStencilState          = null;
            DepthStencilView  depthStencilView           = null;
            Texture2D         depthBuffer                = null;
            RenderTargetView  backBufferRenderTargetView = null;
            Texture2D         backBuffer = null;

            SharpDX.DXGI.SwapChain swapChain = null;
            Factory       factory            = null;
            MirrorTexture mirrorTexture      = null;
            Guid          textureInterfaceId = new Guid("6f15aaf2-d208-4e89-9ab4-489535d34f9c");                                                            // Interface ID of the Direct3D Texture2D interface.

            Result result;

            OvrWrap OVR = OvrWrap.Create();

            // Define initialization parameters with debug flag.
            InitParams initializationParameters = new InitParams();

            initializationParameters.Flags = InitFlags.Debug | InitFlags.RequestVersion;
            initializationParameters.RequestedMinorVersion = 17;

            // Initialize the Oculus runtime.
            string errorReason = null;

            try
            {
                result = OVR.Initialize(initializationParameters);

                if (result < Result.Success)
                {
                    errorReason = result.ToString();
                }
            }
            catch (Exception ex)
            {
                errorReason = ex.Message;
            }

            if (errorReason != null)
            {
                MessageBox.Show("Failed to initialize the Oculus runtime library:\r\n" + errorReason, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Use the head mounted display.
            sessionPtr = IntPtr.Zero;
            var graphicsLuid = new GraphicsLuid();

            result = OVR.Create(ref sessionPtr, ref graphicsLuid);
            if (result < Result.Success)
            {
                MessageBox.Show("The HMD is not enabled: " + result.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var hmdDesc = OVR.GetHmdDesc(sessionPtr);


            try
            {
                // Create a set of layers to submit.
                eyeTextures = new EyeTexture[2];

                // Create DirectX drawing device.
                SharpDX.Direct3D11.Device device = new Device(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.Debug);

                // Create DirectX Graphics Interface factory, used to create the swap chain.
                factory = new SharpDX.DXGI.Factory4();

                immediateContext = device.ImmediateContext;

                // Define the properties of the swap chain.
                SwapChainDescription swapChainDescription = new SwapChainDescription();
                swapChainDescription.BufferCount            = 1;
                swapChainDescription.IsWindowed             = true;
                swapChainDescription.OutputHandle           = form.Handle;
                swapChainDescription.SampleDescription      = new SampleDescription(1, 0);
                swapChainDescription.Usage                  = Usage.RenderTargetOutput | Usage.ShaderInput;
                swapChainDescription.SwapEffect             = SwapEffect.Sequential;
                swapChainDescription.Flags                  = SwapChainFlags.AllowModeSwitch;
                swapChainDescription.ModeDescription.Width  = form.Width;
                swapChainDescription.ModeDescription.Height = form.Height;
                swapChainDescription.ModeDescription.Format = Format.R8G8B8A8_UNorm;
                swapChainDescription.ModeDescription.RefreshRate.Numerator   = 0;
                swapChainDescription.ModeDescription.RefreshRate.Denominator = 1;

                // Create the swap chain.
                swapChain = new SwapChain(factory, device, swapChainDescription);

                // Retrieve the back buffer of the swap chain.
                backBuffer = swapChain.GetBackBuffer <Texture2D>(0);
                backBufferRenderTargetView = new RenderTargetView(device, backBuffer);

                // Create a depth buffer, using the same width and height as the back buffer.
                Texture2DDescription depthBufferDescription = new Texture2DDescription();
                depthBufferDescription.Format            = Format.D32_Float;
                depthBufferDescription.ArraySize         = 1;
                depthBufferDescription.MipLevels         = 1;
                depthBufferDescription.Width             = form.Width;
                depthBufferDescription.Height            = form.Height;
                depthBufferDescription.SampleDescription = new SampleDescription(1, 0);
                depthBufferDescription.Usage             = ResourceUsage.Default;
                depthBufferDescription.BindFlags         = BindFlags.DepthStencil;
                depthBufferDescription.CpuAccessFlags    = CpuAccessFlags.None;
                depthBufferDescription.OptionFlags       = ResourceOptionFlags.None;

                // Define how the depth buffer will be used to filter out objects, based on their distance from the viewer.
                DepthStencilStateDescription depthStencilStateDescription = new DepthStencilStateDescription();
                depthStencilStateDescription.IsDepthEnabled  = true;
                depthStencilStateDescription.DepthComparison = Comparison.Less;
                depthStencilStateDescription.DepthWriteMask  = DepthWriteMask.Zero;

                // Create the depth buffer.
                depthBuffer       = new Texture2D(device, depthBufferDescription);
                depthStencilView  = new DepthStencilView(device, depthBuffer);
                depthStencilState = new DepthStencilState(device, depthStencilStateDescription);

                var viewport = new Viewport(0, 0, hmdDesc.Resolution.Width, hmdDesc.Resolution.Height, 0.0f, 1.0f);

                immediateContext.OutputMerger.SetDepthStencilState(depthStencilState);
                immediateContext.OutputMerger.SetRenderTargets(depthStencilView, backBufferRenderTargetView);
                immediateContext.Rasterizer.SetViewport(viewport);

                // Retrieve the DXGI device, in order to set the maximum frame latency.
                using (SharpDX.DXGI.Device1 dxgiDevice = device.QueryInterface <SharpDX.DXGI.Device1>())
                {
                    dxgiDevice.MaximumFrameLatency = 1;
                }

                var layerEyeFov = new LayerEyeFov();
                layerEyeFov.Header.Type  = LayerType.EyeFov;
                layerEyeFov.Header.Flags = LayerFlags.None;

                for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++)
                {
                    EyeType eye        = (EyeType)eyeIndex;
                    var     eyeTexture = new EyeTexture();
                    eyeTextures[eyeIndex] = eyeTexture;

                    // Retrieve size and position of the texture for the current eye.
                    eyeTexture.FieldOfView           = hmdDesc.DefaultEyeFov[eyeIndex];
                    eyeTexture.TextureSize           = OVR.GetFovTextureSize(sessionPtr, eye, hmdDesc.DefaultEyeFov[eyeIndex], 1.0f);
                    eyeTexture.RenderDescription     = OVR.GetRenderDesc(sessionPtr, eye, hmdDesc.DefaultEyeFov[eyeIndex]);
                    eyeTexture.HmdToEyeViewOffset    = eyeTexture.RenderDescription.HmdToEyePose.Position;
                    eyeTexture.ViewportSize.Position = new Vector2i(0, 0);
                    eyeTexture.ViewportSize.Size     = eyeTexture.TextureSize;
                    eyeTexture.Viewport = new Viewport(0, 0, eyeTexture.TextureSize.Width, eyeTexture.TextureSize.Height, 0.0f, 1.0f);

                    // Define a texture at the size recommended for the eye texture.
                    eyeTexture.Texture2DDescription                   = new Texture2DDescription();
                    eyeTexture.Texture2DDescription.Width             = eyeTexture.TextureSize.Width;
                    eyeTexture.Texture2DDescription.Height            = eyeTexture.TextureSize.Height;
                    eyeTexture.Texture2DDescription.ArraySize         = 1;
                    eyeTexture.Texture2DDescription.MipLevels         = 1;
                    eyeTexture.Texture2DDescription.Format            = Format.R8G8B8A8_UNorm;
                    eyeTexture.Texture2DDescription.SampleDescription = new SampleDescription(1, 0);
                    eyeTexture.Texture2DDescription.Usage             = ResourceUsage.Default;
                    eyeTexture.Texture2DDescription.CpuAccessFlags    = CpuAccessFlags.None;
                    eyeTexture.Texture2DDescription.BindFlags         = BindFlags.ShaderResource | BindFlags.RenderTarget;

                    // Convert the SharpDX texture description to the Oculus texture swap chain description.
                    TextureSwapChainDesc textureSwapChainDesc = SharpDXHelpers.CreateTextureSwapChainDescription(eyeTexture.Texture2DDescription);

                    // Create a texture swap chain, which will contain the textures to render to, for the current eye.
                    IntPtr textureSwapChainPtr;

                    result = OVR.CreateTextureSwapChainDX(sessionPtr, device.NativePointer, ref textureSwapChainDesc, out textureSwapChainPtr);
                    WriteErrorDetails(OVR, result, "Failed to create swap chain.");

                    eyeTexture.SwapTextureSet = new TextureSwapChain(OVR, sessionPtr, textureSwapChainPtr);


                    // Retrieve the number of buffers of the created swap chain.
                    int textureSwapChainBufferCount;
                    result = eyeTexture.SwapTextureSet.GetLength(out textureSwapChainBufferCount);
                    WriteErrorDetails(OVR, result, "Failed to retrieve the number of buffers of the created swap chain.");

                    // Create room for each DirectX texture in the SwapTextureSet.
                    eyeTexture.Textures          = new Texture2D[textureSwapChainBufferCount];
                    eyeTexture.RenderTargetViews = new RenderTargetView[textureSwapChainBufferCount];

                    // Create a texture 2D and a render target view, for each unmanaged texture contained in the SwapTextureSet.
                    for (int textureIndex = 0; textureIndex < textureSwapChainBufferCount; textureIndex++)
                    {
                        // Retrieve the Direct3D texture contained in the Oculus TextureSwapChainBuffer.
                        IntPtr swapChainTextureComPtr = IntPtr.Zero;
                        result = eyeTexture.SwapTextureSet.GetBufferDX(textureIndex, textureInterfaceId, out swapChainTextureComPtr);
                        WriteErrorDetails(OVR, result, "Failed to retrieve a texture from the created swap chain.");

                        // Create a managed Texture2D, based on the unmanaged texture pointer.
                        eyeTexture.Textures[textureIndex] = new Texture2D(swapChainTextureComPtr);

                        // Create a render target view for the current Texture2D.
                        eyeTexture.RenderTargetViews[textureIndex] = new RenderTargetView(device, eyeTexture.Textures[textureIndex]);
                    }

                    // Define the depth buffer, at the size recommended for the eye texture.
                    eyeTexture.DepthBufferDescription                   = new Texture2DDescription();
                    eyeTexture.DepthBufferDescription.Format            = Format.D32_Float;
                    eyeTexture.DepthBufferDescription.Width             = eyeTexture.TextureSize.Width;
                    eyeTexture.DepthBufferDescription.Height            = eyeTexture.TextureSize.Height;
                    eyeTexture.DepthBufferDescription.ArraySize         = 1;
                    eyeTexture.DepthBufferDescription.MipLevels         = 1;
                    eyeTexture.DepthBufferDescription.SampleDescription = new SampleDescription(1, 0);
                    eyeTexture.DepthBufferDescription.Usage             = ResourceUsage.Default;
                    eyeTexture.DepthBufferDescription.BindFlags         = BindFlags.DepthStencil;
                    eyeTexture.DepthBufferDescription.CpuAccessFlags    = CpuAccessFlags.None;
                    eyeTexture.DepthBufferDescription.OptionFlags       = ResourceOptionFlags.None;

                    // Create the depth buffer.
                    eyeTexture.DepthBuffer      = new Texture2D(device, eyeTexture.DepthBufferDescription);
                    eyeTexture.DepthStencilView = new DepthStencilView(device, eyeTexture.DepthBuffer);

                    // Specify the texture to show on the HMD.
                    if (eyeIndex == 0)
                    {
                        layerEyeFov.ColorTextureLeft      = eyeTexture.SwapTextureSet.TextureSwapChainPtr;
                        layerEyeFov.ViewportLeft.Position = new Vector2i(0, 0);
                        layerEyeFov.ViewportLeft.Size     = eyeTexture.TextureSize;
                        layerEyeFov.FovLeft = eyeTexture.FieldOfView;
                    }
                    else
                    {
                        layerEyeFov.ColorTextureRight      = eyeTexture.SwapTextureSet.TextureSwapChainPtr;
                        layerEyeFov.ViewportRight.Position = new Vector2i(0, 0);
                        layerEyeFov.ViewportRight.Size     = eyeTexture.TextureSize;
                        layerEyeFov.FovRight = eyeTexture.FieldOfView;
                    }
                }

                MirrorTextureDesc mirrorTextureDescription = new MirrorTextureDesc();
                mirrorTextureDescription.Format    = TextureFormat.R8G8B8A8_UNorm_SRgb;
                mirrorTextureDescription.Width     = form.Width;
                mirrorTextureDescription.Height    = form.Height;
                mirrorTextureDescription.MiscFlags = TextureMiscFlags.None;

                // Create the texture used to display the rendered result on the computer monitor.
                IntPtr mirrorTexturePtr;
                result = OVR.CreateMirrorTextureDX(sessionPtr, device.NativePointer, ref mirrorTextureDescription, out mirrorTexturePtr);
                WriteErrorDetails(OVR, result, "Failed to create mirror texture.");

                mirrorTexture = new MirrorTexture(OVR, sessionPtr, mirrorTexturePtr);


                // Retrieve the Direct3D texture contained in the Oculus MirrorTexture.
                IntPtr mirrorTextureComPtr = IntPtr.Zero;
                result = mirrorTexture.GetBufferDX(textureInterfaceId, out mirrorTextureComPtr);
                WriteErrorDetails(OVR, result, "Failed to retrieve the texture from the created mirror texture buffer.");

                // Create a managed Texture2D, based on the unmanaged texture pointer.
                mirrorTextureD3D = new Texture2D(mirrorTextureComPtr);

                #region Vertex and pixel shader
                // Create vertex shader.
                vertexShaderByteCode = ShaderBytecode.CompileFromFile("Shaders.fx", "VertexShaderPositionColor", "vs_4_0");
                vertexShader         = new VertexShader(device, vertexShaderByteCode);

                // Create pixel shader.
                pixelShaderByteCode = ShaderBytecode.CompileFromFile("Shaders.fx", "PixelShaderPositionColor", "ps_4_0");
                pixelShader         = new PixelShader(device, pixelShaderByteCode);

                shaderSignature = ShaderSignature.GetInputSignature(vertexShaderByteCode);

                // Specify that each vertex consists of a single vertex position and color.
                InputElement[] inputElements = new InputElement[]
                {
                    new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
                    new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0)
                };

                // Define an input layout to be passed to the vertex shader.
                inputLayout = new InputLayout(device, shaderSignature, inputElements);

                // Create a vertex buffer, containing our 3D model.
                vertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, m_vertices);

                // Create a constant buffer, to contain our WorldViewProjection matrix, that will be passed to the vertex shader.
                contantBuffer = new Buffer(device, Utilities.SizeOf <Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);

                // Setup the immediate context to use the shaders and model we defined.
                immediateContext.InputAssembler.InputLayout       = inputLayout;
                immediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
                immediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBuffer, sizeof(float) * 4 * 2, 0));
                immediateContext.VertexShader.SetConstantBuffer(0, contantBuffer);
                immediateContext.VertexShader.Set(vertexShader);
                immediateContext.PixelShader.Set(pixelShader);
                #endregion

                DateTime startTime = DateTime.Now;
                Vector3  position  = new Vector3(0, 0, -1);

                #region Render loop
                RenderLoop.Run(form, () =>
                {
                    Vector3f[] hmdToEyeViewOffsets = { eyeTextures[0].HmdToEyeViewOffset, eyeTextures[1].HmdToEyeViewOffset };
                    double displayMidpoint         = OVR.GetPredictedDisplayTime(sessionPtr, 0);
                    TrackingState trackingState    = OVR.GetTrackingState(sessionPtr, displayMidpoint, true);
                    Posef[] eyePoses = new Posef[2];

                    // Calculate the position and orientation of each eye.
                    OVR.CalcEyePoses(trackingState.HeadPose.ThePose, hmdToEyeViewOffsets, ref eyePoses);

                    float timeSinceStart = (float)(DateTime.Now - startTime).TotalSeconds;

                    for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++)
                    {
                        EyeType eye           = (EyeType)eyeIndex;
                        EyeTexture eyeTexture = eyeTextures[eyeIndex];

                        if (eyeIndex == 0)
                        {
                            layerEyeFov.RenderPoseLeft = eyePoses[0];
                        }
                        else
                        {
                            layerEyeFov.RenderPoseRight = eyePoses[1];
                        }

                        // Update the render description at each frame, as the HmdToEyeOffset can change at runtime.
                        eyeTexture.RenderDescription = OVR.GetRenderDesc(sessionPtr, eye, hmdDesc.DefaultEyeFov[eyeIndex]);

                        // Retrieve the index of the active texture
                        int textureIndex;
                        result = eyeTexture.SwapTextureSet.GetCurrentIndex(out textureIndex);
                        WriteErrorDetails(OVR, result, "Failed to retrieve texture swap chain current index.");

                        immediateContext.OutputMerger.SetRenderTargets(eyeTexture.DepthStencilView, eyeTexture.RenderTargetViews[textureIndex]);
                        immediateContext.ClearRenderTargetView(eyeTexture.RenderTargetViews[textureIndex], Color.Black);
                        immediateContext.ClearDepthStencilView(eyeTexture.DepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
                        immediateContext.Rasterizer.SetViewport(eyeTexture.Viewport);

                        // Retrieve the eye rotation quaternion and use it to calculate the LookAt direction and the LookUp direction.
                        Quaternion rotationQuaternion = SharpDXHelpers.ToQuaternion(eyePoses[eyeIndex].Orientation);
                        Matrix rotationMatrix         = Matrix.RotationQuaternion(rotationQuaternion);
                        Vector3 lookUp = Vector3.Transform(new Vector3(0, -1, 0), rotationMatrix).ToVector3();
                        Vector3 lookAt = Vector3.Transform(new Vector3(0, 0, 1), rotationMatrix).ToVector3();

                        Vector3 viewPosition = position - eyePoses[eyeIndex].Position.ToVector3();

                        Matrix world      = Matrix.Scaling(0.1f) * Matrix.RotationX(timeSinceStart / 10f) * Matrix.RotationY(timeSinceStart * 2 / 10f) * Matrix.RotationZ(timeSinceStart * 3 / 10f);
                        Matrix viewMatrix = Matrix.LookAtLH(viewPosition, viewPosition + lookAt, lookUp);

                        Matrix projectionMatrix = OVR.Matrix4f_Projection(eyeTexture.FieldOfView, 0.1f, 100.0f, ProjectionModifier.LeftHanded).ToMatrix();
                        projectionMatrix.Transpose();

                        Matrix worldViewProjection = world * viewMatrix * projectionMatrix;
                        worldViewProjection.Transpose();

                        // Update the transformation matrix.
                        immediateContext.UpdateSubresource(ref worldViewProjection, contantBuffer);

                        // Draw the cube
                        immediateContext.Draw(m_vertices.Length / 2, 0);

                        // Commits any pending changes to the TextureSwapChain, and advances its current index
                        result = eyeTexture.SwapTextureSet.Commit();
                        WriteErrorDetails(OVR, result, "Failed to commit the swap chain texture.");
                    }


                    result = OVR.SubmitFrame(sessionPtr, 0L, IntPtr.Zero, ref layerEyeFov);
                    WriteErrorDetails(OVR, result, "Failed to submit the frame of the current layers.");

                    immediateContext.CopyResource(mirrorTextureD3D, backBuffer);
                    swapChain.Present(0, PresentFlags.None);
                });
                #endregion
            }
            finally
            {
                if (immediateContext != null)
                {
                    immediateContext.ClearState();
                    immediateContext.Flush();
                }

                // Release all resources
                Dispose(inputLayout);
                Dispose(contantBuffer);
                Dispose(vertexBuffer);
                Dispose(shaderSignature);
                Dispose(pixelShader);
                Dispose(pixelShaderByteCode);
                Dispose(vertexShader);
                Dispose(vertexShaderByteCode);
                Dispose(mirrorTextureD3D);
                Dispose(mirrorTexture);
                Dispose(eyeTextures[0]);
                Dispose(eyeTextures[1]);
                Dispose(immediateContext);
                Dispose(depthStencilState);
                Dispose(depthStencilView);
                Dispose(depthBuffer);
                Dispose(backBufferRenderTargetView);
                Dispose(backBuffer);
                Dispose(swapChain);
                Dispose(factory);

                // Disposing the device, before the hmd, will cause the hmd to fail when disposing.
                // Disposing the device, after the hmd, will cause the dispose of the device to fail.
                // It looks as if the hmd steals ownership of the device and destroys it, when it's shutting down.
                // device.Dispose();
                OVR.Destroy(sessionPtr);
            }
        }