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); } }
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); } } } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
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); }
public static extern Result ovr_CreateTextureSwapChainVk(ovrSession session, IntPtr device, ref TextureSwapChainDesc desc, out ovrTextureSwapChain out_TextureSwapChain);
public static extern Result ovr_CreateTextureSwapChainDX(ovrSession session, IntPtr d3dPtr, ref TextureSwapChainDesc desc, ref ovrTextureSwapChain outTextureSwapChain);
public static extern Result ovr_CreateTextureSwapChainGL(ovrSession session, ref TextureSwapChainDesc desc, ref ovrTextureSwapChain outTextureSwapChain);
public static extern Result ovr_GetTextureSwapChainDesc(ovrSession session, ovrTextureSwapChain chain, ref TextureSwapChainDesc outDesc);
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; } } }
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); } }