/// <summary> /// Destroys the SwapChain and all related instances. /// </summary> void DestroySwapChain() { _swapChain2?.Dispose(); _swapChain2 = null; _device3?.Dispose(); _device3 = null; _swapChain?.Dispose(); _swapChain = null; _device?.Dispose(); _device = null; _d3D11Device?.Dispose(); _d3D11Device = null; }
void InitializeDirect2D() { d3dDevice = new D3D.Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport); dxgiDevice = d3dDevice.QueryInterface <DXGI.Device1>(); var desc = new SwapChainDescription1() { Width = 0, Height = 0, Format = Format.B8G8R8A8_UNorm, Stereo = false, SampleDescription = new SampleDescription(1, 0), Usage = Usage.RenderTargetOutput, BufferCount = 3, Scaling = Scaling.None, SwapEffect = SwapEffect.FlipSequential, Flags = SwapChainFlags.None }; DXGI.Factory2 dxgiFactory = dxgiDevice.Adapter.GetParent <DXGI.Factory2>(); swapChain = new SwapChain1(dxgiFactory, d3dDevice, Child.Handle, ref desc); swapChain.BackgroundColor = Color4.White; dxgiFactory.Dispose(); d2dFactory = new D2D.Factory1(FactoryType.SingleThreaded); d2dDevice = new D2D.Device(d2dFactory, dxgiDevice); d2dDeviceContext = new D2D.DeviceContext(d2dDevice, DeviceContextOptions.None); d2dDeviceContext.TextAntialiasMode = TextAntialiasMode.Cleartype; //d2dDeviceContext.DotsPerInch = new Size2F(96, 96); var props = new BitmapProperties1(new PixelFormat(Format.B8G8R8A8_UNorm, D2D.AlphaMode.Ignore), d2dDeviceContext.DotsPerInch.Width, d2dDeviceContext.DotsPerInch.Height, BitmapOptions.Target | BitmapOptions.CannotDraw); Surface1 dxgiSurface = swapChain.GetBackBuffer <Surface1>(0); d2dSurface = new Bitmap1(d2dDeviceContext, dxgiSurface, props); dxgiSurface.Dispose(); d2dDeviceContext.Target = d2dSurface; VertexFillBrush = new SolidColorBrush(d2dDeviceContext, new Color4(1, 0.5f, 0, 1)); VertexDrawBrush = new SolidColorBrush(d2dDeviceContext, new Color4(0.2f, 0.2f, 0.2f, 1)); EdgeDrawBrush = new SolidColorBrush(d2dDeviceContext, Color4.Black); RasterDrawBrush = new SolidColorBrush(d2dDeviceContext, new Color4(0.5f, 0.5f, 0.5f, 1)); }
private void StartD3D() { //this.Device = new Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport | DeviceCreationFlags.VideoSupport | DeviceCreationFlags.Debug, FeatureLevel.Level_11_0); this.Device = new Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport | DeviceCreationFlags.VideoSupport, FeatureLevel.Level_10_0); this.dxdevice = Device.QueryInterface <SharpDX.DXGI.Device1>(); //MessageBox.Show(dxdevice.Adapter.Description.Description); dxdevice.Disposing += (e, s) => { Console.WriteLine("DISPOSING WPF D3D"); }; this.D3DSurface = new DX11ImageSource(); this.D3DSurface.IsFrontBufferAvailableChanged += OnIsFrontBufferAvailableChanged; this.CreateAndBindTargets(); this.Source = this.D3DSurface; }
/// <summary> /// Initializes the SwapChain for use with LibVLC /// </summary> void CreateSwapChain() { SharpDX.DXGI.Factory2 dxgiFactory = null; try { var deviceCreationFlags = DeviceCreationFlags.BgraSupport | DeviceCreationFlags.VideoSupport; #if DEBUG if (Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily != Mobile) { deviceCreationFlags |= DeviceCreationFlags.Debug; } try { dxgiFactory = new SharpDX.DXGI.Factory2(true); } catch (SharpDXException) { dxgiFactory = new SharpDX.DXGI.Factory2(false); } #else dxgiFactory = new SharpDX.DXGI.Factory2(false); #endif _d3D11Device = null; foreach (var adapter in dxgiFactory.Adapters) { try { _d3D11Device = new SharpDX.Direct3D11.Device(adapter, deviceCreationFlags); break; } catch (SharpDXException) { } } if (_d3D11Device is null) { throw new VLCException("Could not create Direct3D11 device : No compatible adapter found."); } _device = _d3D11Device.QueryInterface <SharpDX.DXGI.Device1>(); //Create the swapchain var swapChainDescription = new SharpDX.DXGI.SwapChainDescription1 { Width = (int)(_panel.ActualWidth * _panel.CompositionScaleX), Height = (int)(_panel.ActualHeight * _panel.CompositionScaleY), Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm, Stereo = false, SampleDescription = { Count = 1, Quality = 0 }, Usage = Usage.RenderTargetOutput, BufferCount = 2, SwapEffect = SwapEffect.FlipSequential, Flags = SwapChainFlags.None, AlphaMode = AlphaMode.Unspecified }; _swapChain = new SharpDX.DXGI.SwapChain1(dxgiFactory, _d3D11Device, ref swapChainDescription); _device.MaximumFrameLatency = 1; using (var panelNative = ComObject.As <ISwapChainPanelNative>(_panel)) { panelNative.SwapChain = _swapChain; } // This is necessary so we can call Trim() on suspend _device3 = _device.QueryInterface <SharpDX.DXGI.Device3>(); if (_device3 == null) { throw new VLCException("Failed to query interface \"Device3\""); } _swapChain2 = _swapChain.QueryInterface <SharpDX.DXGI.SwapChain2>(); if (_swapChain2 == null) { throw new VLCException("Failed to query interface \"SwapChain2\""); } UpdateScale(); UpdateSize(); _loaded = true; Initialized?.Invoke(this, new InitializedEventArgs(SwapChainOptions)); } catch (Exception ex) { DestroySwapChain(); if (ex is SharpDXException) { throw new VLCException("SharpDX operation failed, see InnerException for details", ex); } throw; } finally { dxgiFactory?.Dispose(); } }
/// <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); } }
override protected void Render() { Lock = true; int mainRetry = 5; ClientContext context; do { context = new ClientContext("com.bivrost360.desktopplayer"); Thread.Sleep(50); }while (context == null && mainRetry-- > 0); DisplayConfig displayConfig = null; for (int retry = 0; retry < 12; retry++) { if (abort) { context.Dispose(); Lock = false; return; } displayConfig = context.GetDisplayConfig(); if (displayConfig != null) { int contextRetry = 0; do { context.update(); contextRetry++; if (abort) { context.Dispose(); Lock = false; return; } Thread.Sleep(1); } while (!displayConfig.CheckDisplayStartup() || contextRetry < 300); if (displayConfig.CheckDisplayStartup()) { break; } } } if (displayConfig == null) { context.Dispose(); Lock = false; return; } var numDisplayInputs = displayConfig.GetNumDisplayInputs(); if (numDisplayInputs != 1) { context.Dispose(); Lock = false; return; } var displayDimensions = displayConfig.GetDisplayDimensions(0); var numViewers = displayConfig.GetNumViewers(); if (numViewers != 1) { context.Dispose(); Lock = false; return; } var form = new RenderForm("BIVROST - OSVR"); form.Width = displayDimensions.Width; form.Height = displayDimensions.Height; form.ShowInTaskbar = false; var desc = new SwapChainDescription() { BufferCount = 1, ModeDescription = new ModeDescription(displayDimensions.Width, displayDimensions.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm), IsWindowed = true, OutputHandle = form.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; SwapChain swapChain; // Create DirectX drawing device. //SharpDX.Direct3D11.Device device = new Device(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.BgraSupport, new SharpDX.Direct3D.FeatureLevel[] { SharpDX.Direct3D.FeatureLevel.Level_10_0 }); Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.BgraSupport, desc, out _device, out swapChain); // Create DirectX Graphics Interface factory, used to create the swap chain. Factory factory = swapChain.GetParent <Factory>(); factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll); form.FormBorderStyle = FormBorderStyle.None; form.TopMost = true; DeviceContext immediateContext = _device.ImmediateContext; using (SharpDX.DXGI.Device2 dxgiDevice = _device.QueryInterface <SharpDX.DXGI.Device2>()) { //var bounds = dxgiDevice.Adapter.Outputs[1].Description.DesktopBounds; //form.DesktopBounds = new System.Drawing.Rectangle(bounds.X, bounds.Y, bounds.Width, bounds.Height); //dxgiDevice.Adapter.Outputs.ToList().ForEach(o => //{ // if (o.Description.DeviceName.EndsWith("2")) // { // swapChain.SetFullscreenState(true, o); // } //}); Rectangle bounds; if (Features.IsDebug) { log.Info("OSVR: available screens: " + string.Join("\n", dxgiDevice.Adapter.Outputs.ToList().ConvertAll(o => o.Description.DeviceName + " (" + o.Description.DesktopBounds + ")"))); } if (Logic.Instance.settings.OSVRScreen == ScreenSelection.Autodetect) { // start with last screen Output output = dxgiDevice.Adapter.Outputs[dxgiDevice.Adapter.Outputs.Length - 1]; // but something resembling a HDK 1.4 (1920x1080) will be better foreach (var o in dxgiDevice.Adapter.Outputs) { var b = o.Description.DesktopBounds; if (b.Width == 1920 && b.Height == 1080) { log.Info("OSVR: found a 1920x1080 candidate for a HDK 1.4"); output = o; } } // and something resembling a HDK 2.0 (2160x1200) will be even more better foreach (var o in dxgiDevice.Adapter.Outputs) { var b = o.Description.DesktopBounds; if (b.Width == 2160 && b.Height == 1200) { log.Info("OSVR: found a 2160x1200 candidate for a HDK 2.0"); output = o; } } bounds = output.Description.DesktopBounds; log.Info($"OSVR: guessed output ({bounds})"); } else { int osvrScreen = (int)Logic.Instance.settings.OSVRScreen; if (osvrScreen >= dxgiDevice.Adapter.Outputs.Length) { osvrScreen = dxgiDevice.Adapter.Outputs.Length - 1; } bounds = dxgiDevice.Adapter.Outputs[osvrScreen].Description.DesktopBounds; log.Info($"OSVR: selected output #{osvrScreen} ({bounds})"); } form.DesktopBounds = new System.Drawing.Rectangle(bounds.X, bounds.Y, bounds.Width, bounds.Height); if (dxgiDevice.Adapter.Outputs.Length <= 1) { Logic.Notify("Only one screen is active. Press Control+S to stop the movie if needed."); } } // 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 = displayDimensions.Width, Height = displayDimensions.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; // 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; using (_gd = SharpDX.Toolkit.Graphics.GraphicsDevice.New(_device)) using (customEffectL = GetCustomEffect(_gd)) using (customEffectR = GetCustomEffect(_gd)) //using (var primitive = GraphicTools.CreateGeometry(_projection, _gd)) using (vrui = new VRUI(_device, _gd)) using (Texture2D depthBuffer = new Texture2D(_device, depthBufferDescription)) using (DepthStencilView depthView = new DepthStencilView(_device, depthBuffer)) using (Texture2D backBuffer = Texture2D.FromSwapChain <Texture2D>(swapChain, 0)) using (RenderTargetView renderView = new RenderTargetView(_device, backBuffer)) { //primitive = GraphicTools.CreateGeometry(Projection, _gd); DateTime startTime = DateTime.Now; Vector3 position = new Vector3(0, 0, -1); #region Render loop DateTime lastTime = DateTime.Now; float deltaTime = 0; immediateContext.OutputMerger.SetTargets(depthView, renderView); form.GotFocus += (s, e) => OnGotFocus(); bool first = true; RenderLoop.Run(form, () => { if (abort) { form.Close(); return; } if (first) { // Start with default background SetDefaultScene(); OnGotFocus(); first = false; } UpdateContentIfRequested(); context.update(); float timeSinceStart = (float)(DateTime.Now - startTime).TotalSeconds; deltaTime = (float)(DateTime.Now - lastTime).TotalSeconds; lastTime = DateTime.Now; immediateContext.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0); immediateContext.ClearRenderTargetView(renderView, Color.Black); uint viewer = 0; for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++) { var numEyes = displayConfig.GetNumEyesForViewer(viewer); var viewerPose = displayConfig.GetViewerPose(viewer); for (byte eye = 0; eye < numEyes; eye++) { uint numSurfaces = displayConfig.GetNumSurfacesForViewerEye(viewer, eye); Pose3 viewerEyePose = displayConfig.GetViewerEyePose(viewer, eye); Matrix44f viewerEyeMatrixf = displayConfig.GetViewerEyeViewMatrixf(viewer, eye, MatrixConventionsFlags.Default); uint surface = 0; OSVR.ClientKit.Viewport viewport = displayConfig.GetRelativeViewportForViewerEyeSurface(viewer, eye, surface); Matrix44f projectionf = displayConfig.GetProjectionMatrixForViewerEyeSurfacef(viewer, eye, surface, 0.001f, 1000.0f, MatrixConventionsFlags.Default); ProjectionClippingPlanes projectionClippingPlanes = displayConfig.GetViewerEyeSurfaceProjectionClippingPlanes(viewer, eye, surface); ViewportF vp = new ViewportF(viewport.Left, viewport.Bottom, viewport.Width, viewport.Height); immediateContext.Rasterizer.SetViewport(vp); Vector3 lookPosition = viewerEyePose.translation.ToVector3(); SharpDX.Quaternion lookRotation = viewerEyePose.rotation.ToQuaternion(); 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(); Matrix viewMatrix = Matrix.LookAtRH(lookPosition, lookPosition + lookAt, lookUp); Matrix projectionMatrix = projectionf.ToMatrix(); Matrix worldMatrix = Matrix.Translation(lookPosition); Matrix MVP = worldMatrix * viewMatrix * projectionMatrix; customEffectL.Parameters["WorldViewProj"].SetValue(MVP); customEffectR.Parameters["WorldViewProj"].SetValue(MVP); lock (localCritical) { if (eye == 0) { primitive?.Draw(customEffectL); } if (eye == 1) { primitive?.Draw(customEffectR); } } // reset UI position every frame if it is not visible if (vrui.isUIHidden) { vrui.SetWorldPosition(viewMatrix.Forward, lookPosition, true); } if (eye == 0) { lookRotation.Invert(); ProvideLook?.Invoke(lookPosition, lookRotation, OSVRFOV); } vrui.Draw(Media, currentTime, Duration); vrui.Render(deltaTime, viewMatrix, projectionMatrix, lookPosition, ShouldShowVRUI); } } swapChain.Present(0, PresentFlags.None); }); #endregion //debugWindow.Stop(); waitForRendererStop.Set(); //swapChain.SetFullscreenState(false, null); immediateContext.ClearState(); immediateContext.Flush(); immediateContext.Dispose(); swapChain.Dispose(); factory.Dispose(); //swapChain.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(); base._device.Dispose(); //hmd.Dispose(); //oculus.Dispose(); displayConfig.Dispose(); context.Dispose(); } Lock = false; }
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; }
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); } }
public void Start() { running = true; Task.Factory.StartNew(() => { form = new SharpDX.Windows.RenderForm("Oculus UI Debug"); form.Width = 1024 + 16; form.Height = 512 + 39; form.AllowUserResizing = false; // 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 = 1024; swapChainDescription.ModeDescription.Height = 512; 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 = 1024; depthBufferDescription.Height = 512; 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, 1024, 512, 0.0f, 1.0f); immediateContext.OutputMerger.SetDepthStencilState(depthStencilState); immediateContext.OutputMerger.SetRenderTargets(depthStencilView, backBufferRenderTargetView); immediateContext.Rasterizer.SetViewport(viewport); SharpDX.Toolkit.Graphics.GraphicsDevice gd = SharpDX.Toolkit.Graphics.GraphicsDevice.New(device); var blendStateDescription = new BlendStateDescription(); blendStateDescription.AlphaToCoverageEnable = false; blendStateDescription.RenderTarget[0].IsBlendEnabled = true; blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDescription.RenderTarget[0].SourceAlphaBlend = BlendOption.Zero; blendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero; blendStateDescription.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; var blendState = SharpDX.Toolkit.Graphics.BlendState.New(gd, blendStateDescription); gd.SetBlendState(blendState); var resource = sharedTexture.QueryInterface <SharpDX.DXGI.Resource>(); var texture = device.OpenSharedResource <Texture2D>(resource.SharedHandle); var basicEffect = new SharpDX.Toolkit.Graphics.BasicEffect(gd); basicEffect.PreferPerPixelLighting = false; basicEffect.Texture = SharpDX.Toolkit.Graphics.Texture2D.New(gd, texture); basicEffect.TextureEnabled = true; basicEffect.LightingEnabled = false; // background texture var backgroundTexture = SharpDX.Toolkit.Graphics.Texture2D.Load(gd, "Graphics/debug.png"); var backEffect = new SharpDX.Toolkit.Graphics.BasicEffect(gd); backEffect.PreferPerPixelLighting = false; backEffect.Texture = backgroundTexture; backEffect.TextureEnabled = true; backEffect.LightingEnabled = false; var primitive = SharpDX.Toolkit.Graphics.GeometricPrimitive.Plane.New(gd, 2f, 2f, 1); // 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; } RenderLoop.Run(form, () => { immediateContext.ClearRenderTargetView(backBufferRenderTargetView, new Color4(1f, 0.5f, 0.3f, 1f)); immediateContext.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); backEffect.World = basicEffect.World = Matrix.Identity; backEffect.View = basicEffect.View = Matrix.Identity; backEffect.Projection = basicEffect.Projection = Matrix.Identity; primitive.Draw(backEffect); primitive.Draw(basicEffect); swapChain.Present(0, PresentFlags.None); if (!running) { form.Close(); } }); }); }
/// <summary> /// deviceを作成します。 /// </summary> /// <param name="control">レンダリング先となるcontrol</param> /// <param name="ocu_config">設定</param> /// <returns>deviceの作成に成功したか</returns> public bool InitializeApplication(Control control, OcuConfig ocu_config) { this.ocu_config = ocu_config; oculus = new OculusWrap.Wrap(); // Initialize the Oculus runtime. bool success = oculus.Initialize(); if (!success) { MessageBox.Show("Failed to initialize the Oculus runtime library.", "Uh oh", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } // 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) { MessageBox.Show("Oculus Rift not detected.", "Uh oh", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } if (hmd.ProductName == string.Empty) { 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(OculusWrap.OVR.HmdCaps.LowPersistence | OculusWrap.OVR.HmdCaps.DynamicPrediction); // Start the sensor which informs of the Rift's pose and motion hmd.ConfigureTracking(OculusWrap.OVR.TrackingCaps.ovrTrackingCap_Orientation | OculusWrap.OVR.TrackingCaps.ovrTrackingCap_MagYawCorrection | OculusWrap.OVR.TrackingCaps.ovrTrackingCap_Position, OculusWrap.OVR.TrackingCaps.None); // Create DirectX drawing device. device = new Device(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.None); ctx = device.ImmediateContext; Stopwatch sw = new Stopwatch(); sw.Start(); string effect_file = Path.Combine(Application.StartupPath, @"toonshader.fx.bin"); if (!File.Exists(effect_file)) { Console.WriteLine("File not found: " + effect_file); return(false); } try { var shader_bytecode = ShaderBytecode.FromFile(effect_file); effect = new Effect(device, shader_bytecode); } catch (SharpDX.CompilationException e) { Console.WriteLine(e.Message + ": " + effect_file); return(false); } sw.Stop(); Console.WriteLine("toonshader.fx.bin read time: " + sw.Elapsed); string techmap_file = Path.Combine(Application.StartupPath, @"techmap.txt"); if (!File.Exists(techmap_file)) { Console.WriteLine("File not found: " + techmap_file); return(false); } techmap.Load(techmap_file); control.MouseDown += new MouseEventHandler(form_OnMouseDown); // Define the properties of the swap chain. SwapChainDescription swapChainDescription = DefineSwapChainDescription(control); // Create DirectX Graphics Interface factory, used to create the swap chain. dxgi_factory = new SharpDX.DXGI.Factory(); // Create the swap chain. swap_chain = new SwapChain(dxgi_factory, device, swapChainDescription); // Retrieve the back buffer of the swap chain. buf0 = swap_chain.GetBackBuffer <Texture2D>(0); buf0_view = new RenderTargetView(device, buf0); // Create a depth buffer, using the same width and height as the back buffer. Texture2DDescription depthBufferDescription = DefineDepthBufferDescription(control); // Create the depth buffer. ztex = new Texture2D(device, depthBufferDescription); ztex_view = new DepthStencilView(device, ztex); ctx.OutputMerger.SetRenderTargets(ztex_view, buf0_view); viewport = new Viewport(0, 0, hmd.Resolution.Width, hmd.Resolution.Height, 0.0f, 1.0f); ctx.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 = new OculusWrap.Layers(); layer_eye_fov = layers.AddLayerEyeFov(); CreateEyeTextures(); CreateMirrorTexture(control); World_variable = effect.GetVariableBySemantic("World").AsMatrix(); WorldView_variable = effect.GetVariableBySemantic("WorldView").AsMatrix(); WorldViewProjection_variable = effect.GetVariableBySemantic("WorldViewProjection").AsMatrix(); /* for HUD */ Projection_variable = effect.GetVariableBySemantic("Projection").AsMatrix(); LocalBoneMats_variable = effect.GetVariableByName("LocalBoneMats").AsMatrix(); LightDirForced_variable = effect.GetVariableByName("LightDirForced").AsVector(); UVSCR_variable = effect.GetVariableByName("UVSCR").AsVector(); cb_variable = effect.GetConstantBufferByName("cb"); ShadeTex_texture_variable = effect.GetVariableByName("ShadeTex_texture").AsShaderResource(); ColorTex_texture_variable = effect.GetVariableByName("ColorTex_texture").AsShaderResource(); //figures.Camera = camera; figures.TSOFileOpen += delegate(TSOFile tso) { tso.Open(device, effect); techmap.AssignTechniqueIndices(tso); }; // Define an input layout to be passed to the vertex shader. var technique = effect.GetTechniqueByIndex(0); il = new InputLayout(device, technique.GetPassByIndex(0).Description.Signature, TSOSubMesh.ie); // Setup the immediate context to use the shaders and model we defined. ctx.InputAssembler.InputLayout = il; DefineBlendState(); DefineDepthStencilState(); DefineRasterizerState(); main_camera = new Camera() { Position = ocu_config.Position, Rotation = Quaternion.Identity, }; directInput = new DirectInput(); keyboard = new Keyboard(directInput); keyboard.Acquire(); keyboardState = keyboard.GetCurrentState(); return(true); }
/// <summary> /// OVR initialization /// </summary> private void OVRInitialization() { try { this.adapter.GraphicsDevice.IsSrgbModeEnabled = true; var renderTargetManager = this.adapter.Graphics.RenderTargetManager as RenderTargetManager; // Specify which head tracking capabilities to enable. this.Hmd.SetEnabledCaps(OVR.HmdCaps.DebugDevice); // Start the sensor which informs of the Rift's pose and motion this.Hmd.ConfigureTracking(OVR.TrackingCaps.ovrTrackingCap_Orientation | OVR.TrackingCaps.ovrTrackingCap_MagYawCorrection | OVR.TrackingCaps.ovrTrackingCap_Position, OVR.TrackingCaps.None); OVR.ovrResult result; // 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; } this.ovrLayers = new Layers(); this.layerEyeFov = this.ovrLayers.AddLayerEyeFov(); // Create a set of layers to submit. this.eyeTextures = new OculusVREyeTexture[2]; this.eyePoses = new VREyePose[3]; this.oculusEyePoses = new OVR.Posef[2]; this.hmdToEyeViewOffsets = new OVR.Vector3f[2]; result = this.CreateVRSwapTextureSet(); OculusVRHelpers.WriteErrorDetails(this.Oculus, result, "Failed to create swap texture set."); for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++) { OVR.EyeType eye = (OVR.EyeType)eyeIndex; OculusVREyeTexture eyeTexture = new OculusVREyeTexture(); this.eyeTextures[eyeIndex] = 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 OVR.Sizei(this.swapRenderTargets[0].Width, this.swapRenderTargets[0].Height); eyeTexture.RenderDescription = this.Hmd.GetRenderDesc(eye, this.Hmd.DefaultEyeFov[eyeIndex]); eyeTexture.HmdToEyeViewOffset = eyeTexture.RenderDescription.HmdToEyeViewOffset; eyeTexture.ViewportSize.Position = new OVR.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, 0.0f, 1.0f); this.hmdToEyeViewOffsets[eyeIndex] = eyeTexture.HmdToEyeViewOffset; // Specify the texture to show on the HMD. this.layerEyeFov.ColorTexture[eyeIndex] = this.eyeSwapTextureSet.SwapTextureSetPtr; this.layerEyeFov.Viewport[eyeIndex] = eyeTexture.ViewportSize; this.layerEyeFov.Fov[eyeIndex] = eyeTexture.FieldOfView; this.layerEyeFov.Header.Flags = OVR.LayerFlags.HighQuality; } // Define the texture used to display the rendered result on the computer monitor. Texture2DDescription mirrorTextureDescription = new Texture2DDescription(); mirrorTextureDescription.Width = this.Width; mirrorTextureDescription.Height = this.Height; mirrorTextureDescription.ArraySize = 1; mirrorTextureDescription.MipLevels = 1; mirrorTextureDescription.Format = Format.R8G8B8A8_UNorm_SRgb; mirrorTextureDescription.SampleDescription = new SampleDescription(1, 0); mirrorTextureDescription.Usage = ResourceUsage.Default; mirrorTextureDescription.CpuAccessFlags = CpuAccessFlags.None; mirrorTextureDescription.BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget; // Convert the SharpDX texture description to the native Direct3D texture description. OVR.D3D11.D3D11_TEXTURE2D_DESC mirrorTextureDescriptionD3D11 = OculusVRHelpers.CreateTexture2DDescription(mirrorTextureDescription); OculusWrap.D3D11.MirrorTexture mirrorTexture; // Create the texture used to display the rendered result on the computer monitor. result = this.Hmd.CreateMirrorTextureD3D11(device.NativePointer, ref mirrorTextureDescriptionD3D11, OVR.D3D11.SwapTextureSetD3D11Flags.None, out mirrorTexture); OculusVRHelpers.WriteErrorDetails(this.Oculus, result, "Failed to create mirror texture."); this.mirrorTexture = new Texture2D(mirrorTexture.Texture.Texture); this.HMDMirrorRenderTarget = renderTargetManager.CreateRenderTarget(this.mirrorTexture.NativePointer); WaveServices.RegisterService(new OculusVRService(this)); this.IsConnected = true; } catch (Exception e) { Console.WriteLine(e); } }
public void CloseD3D11() { CloseSharedResource(); if (_mainRenderTargerView != null) { _mainRenderTargerView.Dispose(); _mainRenderTargerView = null; } if (_vertexShaderConstansData != IntPtr.Zero) { Marshal.FreeHGlobal(_vertexShaderConstansData); _vertexShaderConstansData = IntPtr.Zero; } if (_swapChain != null) { _swapChain.Dispose(); _swapChain = null; } if (_dxgiFactory != null) { _dxgiFactory.Dispose(); _dxgiFactory = null; } if (_dxiAdapter != null) { _dxiAdapter.Dispose(); _dxiAdapter = null; } if (_d3d11Device != null) { _d3d11Device.Dispose(); _d3d11Device = null; } if (_dxgiDevice != null) { _dxgiDevice.Dispose(); _dxgiDevice = null; } if (_vertexShader != null) { _vertexShader.Dispose(); _vertexShader = null; } if (_pixelShader != null) { _pixelShader.Dispose(); _pixelShader = null; } if (_vertexShaderConstans != null) { _vertexShaderConstans.Dispose(); _vertexShaderConstans = null; } if (_samplerState != null) { _samplerState.Dispose(); _samplerState = null; } if (_rasterizerState != null) { _rasterizerState.Dispose(); _rasterizerState = null; } if (_inputLayout != null) { _inputLayout.Dispose(); _inputLayout = null; } }
public void InitializeD3D11(IntPtr wndHandle, int width, int height) { CloseD3D11(); _dxgiFactory = new Factory1(); _dxiAdapter = _dxgiFactory.Adapters[0]; _d3d11Device = new Device(_dxiAdapter, DeviceCreationFlags.BgraSupport, FeatureLevel.Level_11_0); _dxgiDevice = _d3d11Device.QueryInterface <DXGIDevice>(); _dxgiDevice.MaximumFrameLatency = 1; // Compile Vertex and Pixel shaders var vertexShaderByteCode = ShaderBytecode.CompileFromFile("VSShader.fx", "main", "vs_4_0", ShaderFlags.None, EffectFlags.None); _vertexShader = new VertexShader(_d3d11Device, vertexShaderByteCode); var pixelShaderByteCode = ShaderBytecode.CompileFromFile("PSShader.fx", "main", "ps_4_0", ShaderFlags.None, EffectFlags.None); _pixelShader = new PixelShader(_d3d11Device, pixelShaderByteCode); InputElement[] inputElements = new InputElement[3]; inputElements[0] = new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0, InputClassification.PerVertexData, 0); inputElements[1] = new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0, InputClassification.PerVertexData, 0); inputElements[2] = new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 20, 0, InputClassification.PerVertexData, 0); _inputLayout = new InputLayout(_d3d11Device, vertexShaderByteCode, inputElements); BufferDescription vertexShaderDesc = new BufferDescription(Matrix.SizeInBytes * 2, BindFlags.ConstantBuffer, ResourceUsage.Default); _vertexShaderConstans = new Buffer(_d3d11Device, vertexShaderDesc); SamplerStateDescription samplerStateDescription = new SamplerStateDescription(); samplerStateDescription.Filter = Filter.MinMagMipLinear; samplerStateDescription.AddressU = TextureAddressMode.Clamp; samplerStateDescription.AddressV = TextureAddressMode.Clamp; samplerStateDescription.AddressW = TextureAddressMode.Clamp; samplerStateDescription.MipLodBias = 0.0f; samplerStateDescription.MaximumAnisotropy = 1; samplerStateDescription.ComparisonFunction = Comparison.Always; samplerStateDescription.MinimumLod = 0.0f; samplerStateDescription.MaximumLod = float.MaxValue; _samplerState = new SamplerState(_d3d11Device, samplerStateDescription); RasterizerStateDescription rasterizerStateDescription = new RasterizerStateDescription(); rasterizerStateDescription.IsAntialiasedLineEnabled = false; rasterizerStateDescription.CullMode = CullMode.None; rasterizerStateDescription.DepthBias = 0; rasterizerStateDescription.DepthBiasClamp = 0.0f; rasterizerStateDescription.IsDepthClipEnabled = true; rasterizerStateDescription.FillMode = FillMode.Solid; rasterizerStateDescription.IsFrontCounterClockwise = false; rasterizerStateDescription.IsMultisampleEnabled = false; rasterizerStateDescription.IsScissorEnabled = false; rasterizerStateDescription.SlopeScaledDepthBias = 0.0f; _rasterizerState = new RasterizerState(_d3d11Device, rasterizerStateDescription); _d3d11Device.ImmediateContext.InputAssembler.InputLayout = _inputLayout; _d3d11Device.ImmediateContext.VertexShader.SetShader(_vertexShader, null, 0); _d3d11Device.ImmediateContext.VertexShader.SetConstantBuffers(0, 1, _vertexShaderConstans); SwapChainDescription swapChainDescription = new SwapChainDescription(); swapChainDescription.ModeDescription.Width = width; swapChainDescription.ModeDescription.Height = height; swapChainDescription.ModeDescription.Format = Format.B8G8R8A8_UNorm; swapChainDescription.ModeDescription.RefreshRate.Numerator = 1; //pretty ugly //its better to autodetect screen refresh rate swapChainDescription.ModeDescription.RefreshRate.Denominator = 60; swapChainDescription.SampleDescription.Count = 1; swapChainDescription.SampleDescription.Quality = 0; swapChainDescription.Usage = Usage.RenderTargetOutput; swapChainDescription.BufferCount = 2; swapChainDescription.ModeDescription.Scaling = DisplayModeScaling.Unspecified; swapChainDescription.SwapEffect = SwapEffect.FlipSequential; swapChainDescription.Flags = 0; swapChainDescription.IsWindowed = true; swapChainDescription.OutputHandle = wndHandle; _swapChain = new SwapChain(_dxgiFactory, _d3d11Device, swapChainDescription); _dxgiFactory.MakeWindowAssociation(wndHandle, WindowAssociationFlags.IgnoreAll); Texture2D backBuffer = _swapChain.GetBackBuffer <Texture2D>(0); _mainRenderTargerView = new RenderTargetView(_d3d11Device, backBuffer); backBuffer.Dispose(); backBuffer = null; Matrix projection = Matrix.Identity; Matrix view = new Matrix(); /* Update the view matrix */ view[0, 0] = 2.0f / (float)width; view[0, 1] = 0.0f; view[0, 2] = 0.0f; view[0, 3] = 0.0f; view[1, 0] = 0.0f; view[1, 1] = -2.0f / (float)height; view[1, 2] = 0.0f; view[1, 3] = 0.0f; view[2, 0] = 0.0f; view[2, 1] = 0.0f; view[2, 2] = 1.0f; view[2, 3] = 0.0f; view[3, 0] = -1.0f; view[3, 1] = 1.0f; view[3, 2] = 0.0f; view[3, 3] = 1.0f; VertexShaderConstants vertexShaderConstansData = new VertexShaderConstants(); vertexShaderConstansData.projectionAndView = Matrix.Multiply(view, projection); vertexShaderConstansData.model = Matrix.Identity; _vertexShaderConstansData = Marshal.AllocHGlobal(Marshal.SizeOf(vertexShaderConstansData)); Marshal.StructureToPtr(vertexShaderConstansData, _vertexShaderConstansData, false); _d3d11Device.ImmediateContext.UpdateSubresource(ref vertexShaderConstansData, _vertexShaderConstans); ViewPort viewPort = new ViewPort(); viewPort.X = 0; viewPort.Y = 0; viewPort.Width = width; viewPort.Height = height; viewPort.MinDepth = 0.0f; viewPort.MaxDepth = 1.0f; _d3d11Device.ImmediateContext.Rasterizer.SetViewport(viewPort); float minu, maxu, minv, maxv; minu = 0.0f; maxu = 1.0f; minv = 0.0f; maxv = 1.0f; // Instantiate Vertex buiffer from vertex data var vertices = Buffer.Create(_d3d11Device, BindFlags.VertexBuffer, new[] { //ul 0.0f, 0.0f, 0.0f, minu, minv, 1.0f, 1.0f, 1.0f, 1.0f, //dl 0.0f, (float)height, 0.0f, minu, maxv, 1.0f, 1.0f, 1.0f, 1.0f, //ur (float)width, 0.0f, 0.0f, maxu, minv, 1.0f, 1.0f, 1.0f, 1.0f, //dr (float)width, (float)height, 0.0f, maxu, maxv, 1.0f, 1.0f, 1.0f, 1.0f }); _d3d11Device.ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, 36, 0)); _d3d11Device.ImmediateContext.Rasterizer.State = _rasterizerState; _d3d11Device.ImmediateContext.PixelShader.SetShader(_pixelShader, null, 0); _d3d11Device.ImmediateContext.PixelShader.SetSamplers(0, 1, _samplerState); _d3d11Device.ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip; }
void InitializeDirect2D() { d3dDevice = new D3D.Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport); dxgiDevice = d3dDevice.QueryInterface<DXGI.Device1>(); var desc = new SwapChainDescription1() { Width = 0, Height = 0, Format = Format.B8G8R8A8_UNorm, Stereo = false, SampleDescription = new SampleDescription(1, 0), Usage = Usage.RenderTargetOutput, BufferCount = 3, Scaling = Scaling.None, SwapEffect = SwapEffect.FlipSequential, Flags = SwapChainFlags.None }; DXGI.Factory2 dxgiFactory = dxgiDevice.Adapter.GetParent<DXGI.Factory2>(); swapChain = new SwapChain1(dxgiFactory, d3dDevice, Child.Handle, ref desc); swapChain.BackgroundColor = Color4.White; dxgiFactory.Dispose(); d2dFactory = new D2D.Factory1(FactoryType.SingleThreaded); d2dDevice = new D2D.Device(d2dFactory, dxgiDevice); d2dDeviceContext = new D2D.DeviceContext(d2dDevice, DeviceContextOptions.None); d2dDeviceContext.TextAntialiasMode = TextAntialiasMode.Cleartype; //d2dDeviceContext.DotsPerInch = new Size2F(96, 96); var props = new BitmapProperties1(new PixelFormat(Format.B8G8R8A8_UNorm, D2D.AlphaMode.Ignore), d2dDeviceContext.DotsPerInch.Width, d2dDeviceContext.DotsPerInch.Height, BitmapOptions.Target | BitmapOptions.CannotDraw); Surface1 dxgiSurface = swapChain.GetBackBuffer<Surface1>(0); d2dSurface = new Bitmap1(d2dDeviceContext, dxgiSurface, props); dxgiSurface.Dispose(); d2dDeviceContext.Target = d2dSurface; VertexFillBrush = new SolidColorBrush(d2dDeviceContext, new Color4(1, 0.5f, 0, 1)); VertexDrawBrush = new SolidColorBrush(d2dDeviceContext, new Color4(0.2f, 0.2f, 0.2f, 1)); EdgeDrawBrush = new SolidColorBrush(d2dDeviceContext, Color4.Black); RasterDrawBrush = new SolidColorBrush(d2dDeviceContext, new Color4(0.5f, 0.5f, 0.5f, 1)); }