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); } }
public TextureBuffer(Wrap oculus, Hmd hmd, bool rendertarget, bool displayableOnHmd, OVRTypes.Sizei size, int mipLevels, IntPtr data, int sampleCount) { wrap = oculus; texSize = size; OVRTypes.Result result; Debug.Assert(sampleCount <= 1); // The code doesn't currently handle MSAA textures. if (displayableOnHmd) { // This texture isn't necessarily going to be a rendertarget, but it usually is. Debug.Assert(hmd != null); // No HMD? A little odd. // It looks like that in order to disable sRGB we have to // set the texture format to sRGB but omit the call the // enabling sRGB in the framebuffer. Info here: // https://forums.oculus.com/community/discussion/24347/srgb-and-sdk-0-6-0-0 OVRTypes.TextureSwapChainDesc desc = new OVRTypes.TextureSwapChainDesc(); desc.Type = OVRTypes.TextureType.Texture2D; desc.ArraySize = 1; desc.Width = size.Width; desc.Height = size.Height; desc.MipLevels = mipLevels; desc.Format = OVRTypes.TextureFormat.R8G8B8A8_UNORM_SRGB; //Remember to call GL.Disable(EnableCap.FramebufferSrgb) later desc.SampleCount = sampleCount; desc.StaticImage = 0; if (mipLevels > 1) desc.MiscFlags = OVRTypes.TextureMiscFlags.AllowGenerateMips; result = hmd.CreateTextureSwapChainGL(desc, out textureChain); WriteErrorDetails(wrap, result, "Failed to create swap chain."); int length = 0; result = TextureChain.GetLength(out length); WriteErrorDetails(wrap, result, "Failed to retrieve the number of buffers of the created swap chain."); if (result >= OVRTypes.Result.Success) { for (int i = 0; i < length; ++i) { uint chainTexId; // Retrieve the OpenGL texture contained in the Oculus TextureSwapChainBuffer. result = TextureChain.GetBufferGL(i, out chainTexId); WriteErrorDetails(wrap, result, "Failed to retrieve a texture from the created swap chain."); GL.BindTexture(TextureTarget.Texture2D, chainTexId); if (rendertarget) { GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); } else { GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.LinearMipmapLinear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.Repeat); } } } } else { GL.GenTextures(1, out texId); GL.BindTexture(TextureTarget.Texture2D, texId); if (rendertarget) { GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); } else { GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.LinearMipmapLinear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.Repeat); } GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Srgb8Alpha8, texSize.Width, texSize.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); } if (mipLevels > 1) { GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); } GL.GenFramebuffers(1, out fboId); }