Esempio n. 1
0
        /// <summary>
        ///
        /// </summary>
        public override void CreateDisplayResources()
        {
            base.CreateDisplayResources();

            backbufferColor = new RenderTarget2D(device, swapChain.GetBackBuffer <D3D.Texture2D>(0));

            oculusSwapChains = new OculusTextureSwapChain[2];
            eyeTextures      = new EyeTexture[2];

            for (int i = 0; i < 2; i++)
            {
                OVR.Sizei idealSize = hmd.GetFovTextureSize((OVR.EyeType)i, hmd.DefaultEyeFov[i], 1.0f);
                oculusSwapChains[i] = hmd.CreateTextureSwapChain(d3dDevice.NativePointer, idealSize.Width, idealSize.Height);

                eyeTextures[i] = new EyeTexture(device, oculusSwapChains[i])
                {
                    DepthStencil2D = new DepthStencil2D(device, DepthFormat.D24S8, idealSize.Width, idealSize.Height),
                    Viewport       = new Viewport(0, 0, idealSize.Width, idealSize.Height),
                    ViewportSize   = new OVR.Recti(new OVR.Vector2i(0, 0), new OVR.Sizei {
                        Width = idealSize.Width, Height = idealSize.Height
                    })
                };

                //eyeTextures[i].DepthBufferDescription = new Texture2DDescription {
                //	Width			= idealSize.Width,
                //	Height			= idealSize.Height,
                //	ArraySize		= 1,
                //	MipLevels		= 1,
                //	Format			= Format.D32_Float,
                //	CpuAccessFlags	= CpuAccessFlags.None,
                //	Usage			= ResourceUsage.Default,
                //	BindFlags		= BindFlags.DepthStencil,
                //	OptionFlags		= ResourceOptionFlags.None,
                //	SampleDescription = new SampleDescription(1, 0)
                //};
            }


            hmd.CreateMirrorTexture(d3dDevice.NativePointer,
                                    new OVR.MirrorTextureDesc {
                Format    = OVR.TextureFormat.OVR_FORMAT_R8G8B8A8_UNORM_SRGB,
                Width     = backbufferColor.Width,
                Height    = backbufferColor.Height,
                MiscFlags = OVR.TextureMiscFlags.None
            }, out mirrorTexture);


            layers      = new Layers();
            layerEyeFov = layers.AddLayerEyeFov();

            hmd.SetTrackingOriginType(OVR.TrackingOrigin.EyeLevel);

            frameIndex = 0;
            Game.RenderSystem.Width  = eyeTextures[0].Viewport.Width;
            Game.RenderSystem.Height = eyeTextures[0].Viewport.Height;
        }
		/// <summary>
		/// 
		/// </summary>
		public override void CreateDisplayResources()
		{
			base.CreateDisplayResources();

			backbufferColor = new RenderTarget2D(device, swapChain.GetBackBuffer<D3D.Texture2D>(0));

			oculusSwapChains	= new OculusTextureSwapChain[2];
			eyeTextures			= new EyeTexture[2];

			for (int i = 0; i < 2; i++) {
				OVR.Sizei idealSize = hmd.GetFovTextureSize((OVR.EyeType)i, hmd.DefaultEyeFov[i], 1.0f);
				oculusSwapChains[i] = hmd.CreateTextureSwapChain(d3dDevice.NativePointer, idealSize.Width, idealSize.Height);
				
				eyeTextures[i]		= new EyeTexture(device, oculusSwapChains[i]) {
					DepthStencil2D		= new DepthStencil2D(device, DepthFormat.D24S8, idealSize.Width, idealSize.Height),
					Viewport			= new Viewport(0, 0, idealSize.Width, idealSize.Height),
					ViewportSize		= new OVR.Recti(new OVR.Vector2i(0, 0), new OVR.Sizei {Width = idealSize.Width, Height = idealSize.Height})
				};

				//eyeTextures[i].DepthBufferDescription = new Texture2DDescription {
				//	Width			= idealSize.Width,
				//	Height			= idealSize.Height,
				//	ArraySize		= 1,
				//	MipLevels		= 1,
				//	Format			= Format.D32_Float,
				//	CpuAccessFlags	= CpuAccessFlags.None,
				//	Usage			= ResourceUsage.Default,
				//	BindFlags		= BindFlags.DepthStencil,
				//	OptionFlags		= ResourceOptionFlags.None,
				//	SampleDescription = new SampleDescription(1, 0)
				//};

			}


			hmd.CreateMirrorTexture(d3dDevice.NativePointer,
				new OVR.MirrorTextureDesc {
					Format		= OVR.TextureFormat.OVR_FORMAT_R8G8B8A8_UNORM_SRGB,
					Width		= backbufferColor.Width,
					Height		= backbufferColor.Height,
					MiscFlags	 = OVR.TextureMiscFlags.None
				}, out mirrorTexture);


			layers		= new Layers();
			layerEyeFov = layers.AddLayerEyeFov();

			hmd.SetTrackingOriginType(OVR.TrackingOrigin.EyeLevel);

			frameIndex = 0;
			Game.RenderSystem.Width		= eyeTextures[0].Viewport.Width;
			Game.RenderSystem.Height	= eyeTextures[0].Viewport.Height;
		}
Esempio n. 3
0
        override protected void Render()
        {
            Lock = true;

            using (Wrap oculus = new Wrap())
            {
                // Initialize the Oculus runtime.
                if (!oculus.Initialize(initializationParameters))
                {
                    throw new HeadsetError("Failed to initialize the Oculus runtime library.");
                }

                OVRTypes.GraphicsLuid graphicsLuid;

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

                // Create a depth buffer, using the same width and height as the back buffer.
                Texture2DDescription depthBufferDescription = new Texture2DDescription()
                {
                    Format            = Format.D32_Float,
                    ArraySize         = 1,
                    MipLevels         = 1,
                    Width             = 1920,            // TODO: FIXME?
                    Height            = 1080,
                    SampleDescription = new SampleDescription(1, 0),
                    Usage             = ResourceUsage.Default,
                    BindFlags         = BindFlags.DepthStencil,
                    CpuAccessFlags    = CpuAccessFlags.None,
                    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()
                {
                    IsDepthEnabled  = true,
                    DepthComparison = Comparison.Less,
                    DepthWriteMask  = DepthWriteMask.Zero
                };

                //#if DEBUG
                //				SharpDX.Configuration.EnableObjectTracking = true;
                //#endif


                using (Hmd hmd = oculus.Hmd_Create(out graphicsLuid))
                    // Create DirectX drawing device.
                    using (_device = new Device(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.BgraSupport, new SharpDX.Direct3D.FeatureLevel[] { SharpDX.Direct3D.FeatureLevel.Level_10_0 }))
                        // Create DirectX Graphics Interface factory, used to create the swap chain.
                        using (Factory factory = new Factory())
                            using (DeviceContext immediateContext = _device.ImmediateContext)
                                // Create the depth buffer.
                                using (Texture2D depthBuffer = new Texture2D(_device, depthBufferDescription))
                                    using (DepthStencilView depthStencilView = new DepthStencilView(_device, depthBuffer))
                                        using (DepthStencilState depthStencilState = new DepthStencilState(_device, depthStencilStateDescription))
                                            using (Layers layers = new Layers())
                                                using (_gd = SharpDX.Toolkit.Graphics.GraphicsDevice.New(_device))
                                                    using (vrui = new VRUI(_device, _gd))
                                                        using (customEffectL = GetCustomEffect(_gd))
                                                            using (customEffectR = GetCustomEffect(_gd))
                                                            //using (SharpDX.Toolkit.Graphics.GeometricPrimitive primitive = GraphicTools.CreateGeometry(_projection, _gd, false))
                                                            {
                                                                if (hmd == null)
                                                                {
                                                                    throw new HeadsetError("Oculus Rift not detected.");
                                                                }
                                                                if (hmd.ProductName == string.Empty)
                                                                {
                                                                    throw new HeadsetError("The HMD is not enabled.");
                                                                }

                                                                Viewport    viewport    = new Viewport(0, 0, hmd.Resolution.Width, hmd.Resolution.Height, 0.0f, 1.0f);
                                                                LayerEyeFov layerEyeFov = layers.AddLayerEyeFov();

                                                                // 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;
                                                                }

                                                                for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++)
                                                                {
                                                                    OVRTypes.EyeType eye         = (OVRTypes.EyeType)eyeIndex;
                                                                    var        textureSize       = hmd.GetFovTextureSize(eye, hmd.DefaultEyeFov[eyeIndex], 1.0f);
                                                                    var        renderDescription = hmd.GetRenderDesc(eye, hmd.DefaultEyeFov[eyeIndex]);
                                                                    EyeTexture eyeTexture        = eyeTextures[eyeIndex] = new EyeTexture()
                                                                    {
                                                                        // Retrieve size and position of the texture for the current eye.
                                                                        FieldOfView       = hmd.DefaultEyeFov[eyeIndex],
                                                                        TextureSize       = textureSize,
                                                                        RenderDescription = renderDescription,
                                                                        // Define a texture at the size recommended for the eye texture.
                                                                        Viewport             = new Viewport(0, 0, textureSize.Width, textureSize.Height, 0.0f, 1.0f),
                                                                        HmdToEyeViewOffset   = renderDescription.HmdToEyeOffset,
                                                                        Texture2DDescription = new Texture2DDescription()
                                                                        {
                                                                            Width             = textureSize.Width,
                                                                            Height            = textureSize.Height,
                                                                            ArraySize         = 1,
                                                                            MipLevels         = 1,
                                                                            Format            = Format.R8G8B8A8_UNorm_SRgb,
                                                                            SampleDescription = new SampleDescription(1, 0),
                                                                            Usage             = ResourceUsage.Default,
                                                                            CpuAccessFlags    = CpuAccessFlags.None,
                                                                            BindFlags         = BindFlags.ShaderResource | BindFlags.RenderTarget
                                                                        }
                                                                    };
                                                                    eyeTexture.ViewportSize.Position = new OVRTypes.Vector2i(0, 0);
                                                                    eyeTexture.ViewportSize.Size     = textureSize;


                                                                    // Convert the SharpDX texture description to the native Direct3D texture description.
                                                                    OVRTypes.TextureSwapChainDesc textureSwapChainDesc = SharpDXHelpers.CreateTextureSwapChainDescription(eyeTexture.Texture2DDescription);

                                                                    AssertSuccess(hmd.CreateTextureSwapChainDX(_device.NativePointer, textureSwapChainDesc, out eyeTexture.SwapTextureSet),
                                                                                  oculus, "Failed to create swap chain.");

                                                                    // Retrieve the number of buffers of the created swap chain.
                                                                    int textureSwapChainBufferCount;
                                                                    AssertSuccess(eyeTexture.SwapTextureSet.GetLength(out textureSwapChainBufferCount),
                                                                                  oculus, "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++)
                                                                    {
                                                                        // Interface ID of the Direct3D Texture2D interface.
                                                                        Guid textureInterfaceId = new Guid("6f15aaf2-d208-4e89-9ab4-489535d34f9c");

                                                                        // Retrieve the Direct3D texture contained in the Oculus TextureSwapChainBuffer.
                                                                        IntPtr swapChainTextureComPtr = IntPtr.Zero;
                                                                        AssertSuccess(eyeTexture.SwapTextureSet.GetBufferDX(textureIndex, textureInterfaceId, out swapChainTextureComPtr),
                                                                                      oculus, "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()
                                                                    {
                                                                        Format            = Format.D32_Float,
                                                                        Width             = eyeTexture.TextureSize.Width,
                                                                        Height            = eyeTexture.TextureSize.Height,
                                                                        ArraySize         = 1,
                                                                        MipLevels         = 1,
                                                                        SampleDescription = new SampleDescription(1, 0),
                                                                        Usage             = ResourceUsage.Default,
                                                                        BindFlags         = BindFlags.DepthStencil,
                                                                        CpuAccessFlags    = CpuAccessFlags.None,
                                                                        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.
                                                                    layerEyeFov.ColorTexture[eyeIndex]      = eyeTexture.SwapTextureSet.TextureSwapChainPtr;
                                                                    layerEyeFov.Viewport[eyeIndex].Position = new OVRTypes.Vector2i(0, 0);
                                                                    layerEyeFov.Viewport[eyeIndex].Size     = eyeTexture.TextureSize;
                                                                    layerEyeFov.Fov[eyeIndex] = eyeTexture.FieldOfView;
                                                                    layerEyeFov.Header.Flags  = OVRTypes.LayerFlags.HighQuality;
                                                                }

                                                                #region Render loop
                                                                DateTime startTime = DateTime.Now;
                                                                DateTime lastTime  = DateTime.Now;
                                                                float    deltaTime = 0;

                                                                // Start with default background
                                                                SetDefaultScene();

                                                                while (!abort)
                                                                {
                                                                    UpdateContentIfRequested();

                                                                    OVRTypes.Vector3f[] hmdToEyeViewOffsets = { eyeTextures[0].HmdToEyeViewOffset, eyeTextures[1].HmdToEyeViewOffset };
                                                                    //OVR.FrameTiming frameTiming = hmd.GetFrameTiming(0);
                                                                    //OVR.TrackingState trackingState = hmd.GetTrackingState(frameTiming.DisplayMidpointSeconds);
                                                                    double displayMidpoint = hmd.GetPredictedDisplayTime(0);
                                                                    OVRTypes.TrackingState trackingState = hmd.GetTrackingState(displayMidpoint, true);
                                                                    OVRTypes.Posef[]       eyePoses      = new OVRTypes.Posef[2];

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

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

                                                                    Vector3 centerEye = (eyePoses[0].Position.ToVector3() + eyePoses[1].Position.ToVector3()) * 0.5f;

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

                                                                        layerEyeFov.RenderPose[eyeIndex] = eyePoses[eyeIndex];

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

                                                                        // Retrieve the index of the active texture
                                                                        int textureIndex;
                                                                        AssertSuccess(eyeTexture.SwapTextureSet.GetCurrentIndex(out textureIndex),
                                                                                      oculus, "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 lookRotation = SharpDXHelpers.ToQuaternion(eyePoses[eyeIndex].Orientation);
                                                                        lookRotation = new Quaternion(1, 0, 0, 0) * lookRotation;
                                                                        Matrix  rotationMatrix = Matrix.RotationQuaternion(lookRotation);
                                                                        Vector3 lookUp         = Vector3.Transform(new Vector3(0, -1, 0), rotationMatrix).ToVector3();
                                                                        Vector3 lookAt         = Vector3.Transform(new Vector3(0, 0, 1), rotationMatrix).ToVector3();

                                                                        //Vector3 eyeDiff = eyePoses[eyeIndex].Position.ToVector3() - eyePoses[1 - eyeIndex].Position.ToVector3();
                                                                        Vector3 lookPosition = new Vector3(
                                                                            -eyePoses[eyeIndex].Position.X,
                                                                            eyePoses[eyeIndex].Position.Y,
                                                                            eyePoses[eyeIndex].Position.Z
                                                                            );

                                                                        Matrix worldMatrix = Matrix.Translation(lookPosition);

                                                                        Matrix viewMatrix = Matrix.LookAtLH(lookPosition, lookPosition + lookAt, lookUp);

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

                                                                        Matrix MVP = worldMatrix * viewMatrix * projectionMatrix;
                                                                        customEffectL.Parameters["WorldViewProj"].SetValue(MVP);
                                                                        customEffectR.Parameters["WorldViewProj"].SetValue(MVP);

                                                                        lock (localCritical)
                                                                        {
                                                                            try
                                                                            {
                                                                                if (eyeIndex == 0)
                                                                                {
                                                                                    primitive?.Draw(customEffectL);
                                                                                }
                                                                                if (eyeIndex == 1)
                                                                                {
                                                                                    primitive?.Draw(customEffectR);
                                                                                }
                                                                            }
                                                                            catch (NullReferenceException)
                                                                            {
                                                                                ;
                                                                            }
                                                                        }

                                                                        if (ProvideLook != null && eyeIndex == 0)
                                                                        {
                                                                            lookRotation.Invert();
                                                                            lookRotation = lookRotation * new Quaternion(1, 0, 0, 0); // rotate 180 in x

                                                                            Vector3 forward = Vector3.Transform(Vector3.ForwardRH, lookRotation);
                                                                            Vector3 up      = Vector3.Transform(Vector3.Up, lookRotation);

                                                                            log.Publish("oculus.forward", forward.ToString("0.00"));
                                                                            log.Publish("oculus.up", up.ToString("0.00"));
                                                                            log.Publish("oculus.lookAt", lookAt.ToString("0.00"));
                                                                            log.Publish("oculus.lookUp", lookUp.ToString("0.00"));
                                                                            log.Publish("oculus.vr_quat", lookRotation);
                                                                            log.Publish("q.sent", lookRotation);

                                                                            ProvideLook(lookPosition, lookRotation, OculusFOV);
                                                                        }

                                                                        // reset UI position every frame if it is not visible
                                                                        if (vrui.isUIHidden)
                                                                        {
                                                                            vrui.SetWorldPosition(viewMatrix.Forward, lookPosition, false);
                                                                        }


                                                                        vrui.Draw(Media, currentTime, Duration);
                                                                        vrui.Render(deltaTime, viewMatrix, projectionMatrix, lookPosition, ShouldShowVRUI);

                                                                        // Commits any pending changes to the TextureSwapChain, and advances its current index
                                                                        AssertSuccess(eyeTexture.SwapTextureSet.Commit(), oculus, "Failed to commit the swap chain texture.");

                                                                        //Console.WriteLine("xbox: " + ((hmd.ovr_GetConnectedControllerTypes() & OVRTypes.ControllerType.XBox) != 0));
                                                                        //Console.WriteLine("remote: " + ((hmd.ovr_GetConnectedControllerTypes() & OVRTypes.ControllerType.Remote) != 0));
                                                                        //Console.WriteLine("active: " + hmd.GetInputState(OVRTypes.ControllerType.Active));
                                                                        //Console.WriteLine("buttons: " + hmd.GetInputState(OVRTypes.ControllerType.Remote).Buttons);
                                                                    }

                                                                    hmd.SubmitFrame(0, layers);
                                                                }

                                                                #endregion
                                                                //debugWindow.Stop();

                                                                waitForRendererStop.Set();

                                                                // Release all resources
                                                                primitive?.Dispose();
                                                                eyeTextures[0].Dispose();
                                                                eyeTextures[1].Dispose();
                                                                immediateContext.ClearState();
                                                                immediateContext.Flush();
                                                            }
            }

            Lock = false;
        }
Esempio n. 4
0
        private void InitializeOculus()
        {
            RenderForm form = new RenderForm("OculusWrap SharpDX demo");

			Wrap	oculus	= new Wrap();
			Hmd		hmd;

            form.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Window_KeyUp);

            //form.moused

            //form.Activate();
            //form.Show();

            int textureWidth = 0, textureHeight = 0;
            newTextureArrived = false;

            //zoom == 2 is not implemented, because the visual quality would be too low.
            //zoom == 4 will be implemented in the future.
            if (zoom == 3)
            {
                textureWidth = 3328;
                textureHeight = 1664;
            }

            bool success = oculus.Initialize();
            if (!success)
            {
                System.Windows.Forms.MessageBox.Show("Failed to initialize the Oculus runtime library.", "Uh oh", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Use the head mounted display, if it's available, otherwise use the debug HMD.
            int numberOfHeadMountedDisplays = oculus.Hmd_Detect();
            if (numberOfHeadMountedDisplays > 0)
                hmd = oculus.Hmd_Create(0);
            else
                hmd = oculus.Hmd_CreateDebug(OculusWrap.OVR.HmdType.DK2);

            if (hmd == null)
            {
                System.Windows.Forms.MessageBox.Show("Oculus Rift not detected.", "Uh oh", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (hmd.ProductName == string.Empty)
                System.Windows.Forms.MessageBox.Show("The HMD is not enabled.", "There's a tear in the Rift", MessageBoxButtons.OK, MessageBoxIcon.Error);

            // Specify which head tracking capabilities to enable.
            hmd.SetEnabledCaps(OVR.HmdCaps.LowPersistence | OVR.HmdCaps.DynamicPrediction);

            // Start the sensor which informs of the Rift's pose and motion
            hmd.ConfigureTracking(OVR.TrackingCaps.ovrTrackingCap_Orientation | OVR.TrackingCaps.ovrTrackingCap_MagYawCorrection | OVR.TrackingCaps.ovrTrackingCap_Position, OVR.TrackingCaps.None);

            // Create a set of layers to submit.
            EyeTexture[] eyeTextures = new EyeTexture[2];
            OVR.ovrResult result;

            // 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 factory = new Factory();

            DeviceContext 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.
            SharpDX.DXGI.SwapChain swapChain = new SwapChain(factory, device, swapChainDescription);

            // Retrieve the back buffer of the swap chain.
            Texture2D backBuffer = swapChain.GetBackBuffer<Texture2D>(0);
            RenderTargetView 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.
            Texture2D depthBuffer = new Texture2D(device, depthBufferDescription);
            DepthStencilView depthStencilView = new DepthStencilView(device, depthBuffer);
            DepthStencilState depthStencilState = new DepthStencilState(device, depthStencilStateDescription);
            Viewport viewport = new Viewport(0, 0, hmd.Resolution.Width, hmd.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;
            }

            Layers layers = new Layers();
            LayerEyeFov layerEyeFov = layers.AddLayerEyeFov();

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

                // Retrieve size and position of the texture for the current eye.
                eyeTexture.FieldOfView = hmd.DefaultEyeFov[eyeIndex];
                eyeTexture.TextureSize = hmd.GetFovTextureSize(eye, hmd.DefaultEyeFov[eyeIndex], 1.0f);
                eyeTexture.RenderDescription = hmd.GetRenderDesc(eye, hmd.DefaultEyeFov[eyeIndex]);
                eyeTexture.HmdToEyeViewOffset = eyeTexture.RenderDescription.HmdToEyeViewOffset;
                eyeTexture.ViewportSize.Position = new OVR.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 native Direct3D texture description.
                OVR.D3D11.D3D11_TEXTURE2D_DESC swapTextureDescriptionD3D11 = SharpDXHelpers.CreateTexture2DDescription(eyeTexture.Texture2DDescription);

                // Create a SwapTextureSet, which will contain the textures to render to, for the current eye.
                result = hmd.CreateSwapTextureSetD3D11(device.NativePointer, ref swapTextureDescriptionD3D11, out eyeTexture.SwapTextureSet);
                WriteErrorDetails(oculus, result, "Failed to create swap texture set.");

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

                // Create a texture 2D and a render target view, for each unmanaged texture contained in the SwapTextureSet.
                for (int textureIndex = 0; textureIndex < eyeTexture.SwapTextureSet.TextureCount; textureIndex++)
                {
                    // Retrieve the current textureData object.
                    OVR.D3D11.D3D11TextureData textureData = eyeTexture.SwapTextureSet.Textures[textureIndex];

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

                    // 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.
                layerEyeFov.ColorTexture[eyeIndex] = eyeTexture.SwapTextureSet.SwapTextureSetPtr;
                layerEyeFov.Viewport[eyeIndex].Position = new OVR.Vector2i(0, 0);
                layerEyeFov.Viewport[eyeIndex].Size = eyeTexture.TextureSize;
                layerEyeFov.Fov[eyeIndex] = eyeTexture.FieldOfView;
                layerEyeFov.Header.Flags = OVR.LayerFlags.TextureOriginAtBottomLeft;
            }

            // Define the texture used to display the rendered result on the computer monitor.
            Texture2DDescription mirrorTextureDescription = new Texture2DDescription();
            mirrorTextureDescription.Width = form.Width;
            mirrorTextureDescription.Height = form.Height;
            mirrorTextureDescription.ArraySize = 1;
            mirrorTextureDescription.MipLevels = 1;
            mirrorTextureDescription.Format = Format.R8G8B8A8_UNorm;
            mirrorTextureDescription.SampleDescription = new SampleDescription(1, 0);
            mirrorTextureDescription.Usage = ResourceUsage.Default;
            mirrorTextureDescription.CpuAccessFlags = CpuAccessFlags.None;
            mirrorTextureDescription.BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget;

            SamplerStateDescription samplerStateDescription = new SamplerStateDescription
            {
                AddressU = TextureAddressMode.Wrap,
                AddressV = TextureAddressMode.Wrap,
                AddressW = TextureAddressMode.Wrap,
                Filter = Filter.Anisotropic
            };

            RasterizerStateDescription rasterizerStateDescription = RasterizerStateDescription.Default();
            rasterizerStateDescription.IsFrontCounterClockwise = true;

            // Convert the SharpDX texture description to the native Direct3D texture description.
            OVR.D3D11.D3D11_TEXTURE2D_DESC mirrorTextureDescriptionD3D11 = SharpDXHelpers.CreateTexture2DDescription(mirrorTextureDescription);

            OculusWrap.D3D11.MirrorTexture mirrorTexture;

            // Create the texture used to display the rendered result on the computer monitor.
            result = hmd.CreateMirrorTextureD3D11(device.NativePointer, ref mirrorTextureDescriptionD3D11, out mirrorTexture);
            WriteErrorDetails(oculus, result, "Failed to create mirror texture.");

            Texture2D mirrorTextureD3D11 = new Texture2D(mirrorTexture.Texture.Texture);

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

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

            ShaderSignature shaderSignature = ShaderSignature.GetInputSignature(vertexShaderByteCode);



            Texture2D myTexture = new Texture2D(device, new Texture2DDescription()
            {
                Format = Format.R8G8B8A8_UNorm,
                ArraySize = 1,
                MipLevels = 1,
                Width = textureWidth,
                Height = textureHeight,
                SampleDescription = new SampleDescription(1, 0),
                Usage = ResourceUsage.Dynamic,
                BindFlags = BindFlags.ShaderResource,
                CpuAccessFlags = CpuAccessFlags.Write,
                OptionFlags = ResourceOptionFlags.None,
            });


            ShaderResourceView textureView = new ShaderResourceView(device, myTexture);


            //set sampler for texture
            SamplerState samplerState = new SamplerState(device, samplerStateDescription);

            //initialize rasterizer
            RasterizerState rasterizerState = new RasterizerState(device, rasterizerStateDescription);

            // Specify that each vertex consists of a single vertex position and color.

            int[] indices = null;
            Vertex[] vertices = null;
            CreateGeometry(out indices, out vertices);

            InputElement[] inputElements = new InputElement[]
            {
                new InputElement("SV_Position", 0, Format.R32G32B32A32_Float, 0, 0),
                new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 32, 0),
                /*new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 32, 0),*/
            };

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

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

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

            Buffer indexBuffer = SharpDX.Direct3D11.Buffer.Create(device, BindFlags.IndexBuffer, indices);

            // 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, Utilities.SizeOf<Vertex>(), 0));
            immediateContext.InputAssembler.SetIndexBuffer(indexBuffer, Format.R32_UInt, 0);

            immediateContext.VertexShader.SetConstantBuffer(0, constantBuffer);

            immediateContext.VertexShader.Set(vertexShader);
            immediateContext.PixelShader.Set(pixelShader);

            immediateContext.PixelShader.SetShaderResource(0, textureView);
            immediateContext.PixelShader.SetSampler(0, samplerState);
            #endregion

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

            oculusReady = true;

            #region Render loop
            RenderLoop.Run(form, () =>
            {
                OVR.Vector3f[] hmdToEyeViewOffsets = { eyeTextures[0].HmdToEyeViewOffset, eyeTextures[1].HmdToEyeViewOffset };
                OVR.FrameTiming frameTiming = hmd.GetFrameTiming(0);
                OVR.TrackingState trackingState = hmd.GetTrackingState(frameTiming.DisplayMidpointSeconds);
                OVR.Posef[] eyePoses = new OVR.Posef[2];

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

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

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

                    layerEyeFov.RenderPose[eyeIndex] = eyePoses[eyeIndex];

                    // Retrieve the index of the active texture and select the next texture as being active next.
                    int textureIndex = eyeTexture.SwapTextureSet.CurrentIndex++;

                    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);
                    //added a custom rasterizer
                    immediateContext.Rasterizer.State = rasterizerState;

                    // 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();

                    //use this to get the first rotation to goal
                    Matrix world = Matrix.Scaling(1.0f) /** Matrix.RotationX(timeSinceStart*0.2f) */* Matrix.RotationY(timeSinceStart * 2 / 10f) /** Matrix.RotationZ(timeSinceStart*3/10f)*/;
                    Matrix viewMatrix = Matrix.LookAtRH(viewPosition, viewPosition + lookAt, lookUp);

                    Matrix projectionMatrix = OVR.ovrMatrix4f_Projection(eyeTexture.FieldOfView, 0.1f, 10.0f, OVR.ProjectionModifier.None).ToMatrix();
                    projectionMatrix.Transpose();

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

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

                    // Draw the cube
                    //immediateContext.Draw(vertices.Length/2, 0);
                    immediateContext.DrawIndexed(indices.Length, 0, 0);
                }

                hmd.SubmitFrame(0, layers);

                immediateContext.CopyResource(mirrorTextureD3D11, backBuffer);
                swapChain.Present(0, PresentFlags.None);


                if (newTextureArrived == true)
                {
                    newTextureArrived = false;
                    DataBox map = device.ImmediateContext.MapSubresource(myTexture, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None);

                    //load the BitMapSource with appropriate formating (Format32bppPRGBA)
                    SharpDX.WIC.BitmapSource bitMap = LoadBitmap(new SharpDX.WIC.ImagingFactory(), streamTexture);
                    //string newFile = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\img_merged.jpg";
                    //SharpDX.WIC.BitmapSource bitMap = LoadBitmapFromFile(new SharpDX.WIC.ImagingFactory(), newFile);

                    int width = bitMap.Size.Width;
                    int height = bitMap.Size.Height;
                    int stride = bitMap.Size.Width * 4;

                    bitMap.CopyPixels(stride, map.DataPointer, height * stride);

                    device.ImmediateContext.UnmapSubresource(myTexture, 0);

                    //bitMap.Dispose();
                    streamTexture.Seek(0, SeekOrigin.Begin);
                }


            });
            #endregion
            // Release all resources
            inputLayout.Dispose();
            constantBuffer.Dispose();
            indexBuffer.Dispose();
            vertexBuffer.Dispose();
            inputLayout.Dispose();
            shaderSignature.Dispose();
            pixelShader.Dispose();
            pixelShaderByteCode.Dispose();
            vertexShader.Dispose();
            vertexShaderByteCode.Dispose();
            mirrorTextureD3D11.Dispose();
            layers.Dispose();
            eyeTextures[0].Dispose();
            eyeTextures[1].Dispose();
            immediateContext.ClearState();
            immediateContext.Flush();
            immediateContext.Dispose();
            depthStencilState.Dispose();
            depthStencilView.Dispose();
            depthBuffer.Dispose();
            backBufferRenderTargetView.Dispose();
            backBuffer.Dispose();
            swapChain.Dispose();
            factory.Dispose();

            // 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();

            hmd.Dispose();
            oculus.Dispose();
        }