/// <summary> /// OVR initialization /// </summary> private void OVRInitialization() { try { this.adapter.GraphicsDevice.IsSrgbModeEnabled = true; var renderTargetManager = this.adapter.Graphics.RenderTargetManager as RenderTargetManager; OVRTypes.Result result; // Retrieve the DXGI device, in order to set the maximum frame latency. using (SharpDX.DXGI.Device1 dxgiDevice = this.device.QueryInterface <SharpDX.DXGI.Device1>()) { dxgiDevice.MaximumFrameLatency = 1; } this.ovrLayers = new Layers(); this.layerEyeFov = this.ovrLayers.AddLayerEyeFov(); // Create a set of layers to submit. this.eyeProperties = new VREye[3]; this.oculusEyePoses = new OVRTypes.Posef[2]; this.hmdToEyeViewOffsets = new OVRTypes.Vector3f[2]; for (int i = 0; i < this.eyeProperties.Length; i++) { this.eyeProperties[i] = new VREye(); } result = this.CreateVRSwapTextureSet(); OculusVRHelpers.WriteErrorDetails(this.Oculus, result, "Failed to create swap texture set."); for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++) { OVRTypes.EyeType eye = (OVRTypes.EyeType)eyeIndex; OculusVREyeTexture eyeTexture = new OculusVREyeTexture(); this.eyeProperties[eyeIndex].Texture = eyeTexture; // Retrieve size and position of the texture for the current eye. eyeTexture.FieldOfView = this.Hmd.DefaultEyeFov[eyeIndex]; eyeTexture.NearPlane = DefaultNearClip; eyeTexture.FarPlane = DefaultFarClip; eyeTexture.TextureSize = new OVRTypes.Sizei(this.swapRenderTargets[0].Width, this.swapRenderTargets[0].Height); eyeTexture.RenderDescription = this.Hmd.GetRenderDesc(eye, this.Hmd.DefaultEyeFov[eyeIndex]); eyeTexture.HmdToEyeViewOffset = eyeTexture.RenderDescription.HmdToEyeOffset; eyeTexture.ViewportSize.Position = new OVRTypes.Vector2i(this.recommendedTextureSize[0].Width * eyeIndex, 0); eyeTexture.ViewportSize.Size = this.recommendedTextureSize[eyeIndex]; eyeTexture.Viewport = new Viewport( eyeTexture.ViewportSize.Position.x / (float)this.swapRenderTargets[0].Width, eyeTexture.ViewportSize.Position.y / (float)this.swapRenderTargets[0].Height, eyeTexture.ViewportSize.Size.Width / (float)this.swapRenderTargets[0].Width, eyeTexture.ViewportSize.Size.Height / (float)this.swapRenderTargets[0].Height); this.hmdToEyeViewOffsets[eyeIndex] = eyeTexture.HmdToEyeViewOffset; // Specify the texture to show on the HMD. this.layerEyeFov.ColorTexture[eyeIndex] = this.eyeTextureSwapChain.TextureSwapChainPtr; this.layerEyeFov.Viewport[eyeIndex] = eyeTexture.ViewportSize; this.layerEyeFov.Fov[eyeIndex] = eyeTexture.FieldOfView; this.layerEyeFov.Header.Flags = OVRTypes.LayerFlags.HighQuality; } // Define the texture used to display the rendered result on the computer monitor. OVRTypes.MirrorTextureDesc mirrorTextureDescription = new OVRTypes.MirrorTextureDesc() { Format = OVRTypes.TextureFormat.R8G8B8A8_UNORM_SRGB, Width = this.Width, Height = this.Height, MiscFlags = OVRTypes.TextureMiscFlags.None }; OculusWrap.MirrorTexture mirrorTexture; // Create the texture used to display the rendered result on the computer monitor. result = this.Hmd.CreateMirrorTextureDX(this.device.NativePointer, mirrorTextureDescription, out mirrorTexture); OculusVRHelpers.WriteErrorDetails(this.Oculus, result, "Failed to create mirror texture."); // Retrieve the Direct3D texture contained in the Oculus MirrorTexture. IntPtr mirrorTextureComPtr = IntPtr.Zero; result = mirrorTexture.GetBufferDX(this.textureInterfaceId, out mirrorTextureComPtr); OculusVRHelpers.WriteErrorDetails(this.Oculus, result, "Failed to retrieve the texture from the created mirror texture buffer."); this.mirrorTexture = new Texture2D(mirrorTextureComPtr); this.HMDMirrorRenderTarget = renderTargetManager.CreateRenderTarget(this.mirrorTexture.NativePointer); WaveServices.RegisterService(new OculusVRService(this)); this.IsConnected = true; } catch (Exception e) { Console.WriteLine(e); } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); InitShader(); InitBuffer(); // Define initialization parameters with debug flag. OVRTypes.InitParams initializationParameters = new OVRTypes.InitParams(); initializationParameters.Flags = OVRTypes.InitFlags.Debug; // Initialize the Oculus runtime. bool success = wrap.Initialize(initializationParameters); if (!success) { MessageBox.Show("Failed to initialize the Oculus runtime library.", "Uh oh", MessageBoxButtons.OK, MessageBoxIcon.Error); Exit(); return; } // Use the head mounted display. OVRTypes.GraphicsLuid graphicsLuid; hmd = wrap.Hmd_Create(out graphicsLuid); if (hmd == null) { MessageBox.Show("Oculus Rift not detected.", "Uh oh", MessageBoxButtons.OK, MessageBoxIcon.Error); Exit(); return; } if (hmd.ProductName == string.Empty) { MessageBox.Show("The HMD is not enabled.", "There's a tear in the Rift", MessageBoxButtons.OK, MessageBoxIcon.Error); Exit(); return; } Console.WriteLine("SDK Version: " + wrap.GetVersionString()); try { for (int i = 0; i < 2; i++) { OVRTypes.Sizei idealTextureSize = hmd.GetFovTextureSize((OVRTypes.EyeType)i, hmd.DefaultEyeFov[i], 1); eyeRenderTexture[i] = new TextureBuffer(wrap, hmd, true, true, idealTextureSize, 1, IntPtr.Zero, 1); eyeDepthBuffer[i] = new DepthBuffer(eyeRenderTexture[i].GetSize(), 0); } // Note: the mirror window can be any size, for this sample we use 1/2 the HMD resolution windowSize = new OVRTypes.Sizei(hmd.Resolution.Width / 2, hmd.Resolution.Height / 2); //For image displayed at ordinary monitor - copy of Oculus rendered one. OVRTypes.MirrorTextureDesc mirrorTextureDescription = new OVRTypes.MirrorTextureDesc(); mirrorTextureDescription.Format = OVRTypes.TextureFormat.R8G8B8A8_UNORM_SRGB; mirrorTextureDescription.Width = windowSize.Width; mirrorTextureDescription.Height = windowSize.Height; mirrorTextureDescription.MiscFlags = OVRTypes.TextureMiscFlags.None; // Create the texture used to display the rendered result on the computer monitor. OVRTypes.Result result; result = hmd.CreateMirrorTextureGL(mirrorTextureDescription, out mirrorTexture); WriteErrorDetails(wrap, result, "Failed to create mirror texture."); layerFov = layers.AddLayerEyeFov(); layerFov.Header.Flags = OVRTypes.LayerFlags.TextureOriginAtBottomLeft; // OpenGL Texture coordinates start from bottom left layerFov.Header.Type = OVRTypes.LayerType.EyeFov; // Configure the mirror read buffer uint texId; result = mirrorTexture.GetBufferGL(out texId); WriteErrorDetails(wrap, result, "Failed to retrieve the texture from the created mirror texture buffer."); //Rendertarget for mirror desktop window GL.GenFramebuffers(1, out mirrorFbo); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, mirrorFbo); GL.FramebufferTexture2D(FramebufferTarget.ReadFramebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, texId, 0); GL.FramebufferRenderbuffer(FramebufferTarget.ReadFramebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, 0); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, 0); // Turn off vsync to let the compositor do its magic this.VSync = VSyncMode.Off; //wglSwapIntervalEXT(0); // FloorLevel will give tracking poses where the floor height is 0 result = hmd.SetTrackingOriginType(OVRTypes.TrackingOrigin.FloorLevel); WriteErrorDetails(wrap, result, "Failed to set tracking origin type."); GL.Enable(EnableCap.DepthTest); //DO NOT DELETE IT IN FUTURE UPDATES! } catch { // Release all resources Dispose(layers); if (mirrorFbo != 0) GL.DeleteFramebuffers(1, ref mirrorFbo); Dispose(mirrorTexture); for (int eyeIndex = 0; eyeIndex < 2; ++eyeIndex) { Dispose(eyeRenderTexture[eyeIndex]); Dispose(eyeDepthBuffer[eyeIndex]); } // 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(); Dispose(hmd); Dispose(wrap); } }