aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/SideChains/RealTimeGraphEx/DX2D/Direct2DControl.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/SideChains/RealTimeGraphEx/DX2D/Direct2DControl.cs')
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphEx/DX2D/Direct2DControl.cs261
1 files changed, 261 insertions, 0 deletions
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphEx/DX2D/Direct2DControl.cs b/Software/Visual_Studio/SideChains/RealTimeGraphEx/DX2D/Direct2DControl.cs
new file mode 100644
index 000000000..4ca6da35b
--- /dev/null
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphEx/DX2D/Direct2DControl.cs
@@ -0,0 +1,261 @@
+namespace RealTimeGraphEx.DX2D
+{
+ using SharpDX;
+ using SharpDX.Direct2D1;
+ using SharpDX.Direct3D10;
+ using SharpDX.DXGI;
+ using System;
+ using System.ComponentModel;
+ using System.Diagnostics;
+ using System.Threading;
+ using System.Windows;
+ using Device = SharpDX.Direct3D10.Device1;
+ using FeatureLevel = SharpDX.Direct3D10.FeatureLevel;
+
+ public abstract class Direct2DControl : System.Windows.Controls.Image
+ {
+ private Device Device;
+ private Texture2D RenderTarget;
+ private DX10ImageSource D3DSurface;
+ private readonly Stopwatch RenderTimer;
+ private RenderTarget m_d2dRenderTarget;
+ protected SharpDX.Direct2D1.Factory m_d2dFactory;
+ private bool enableRendering;
+ //private Stopwatch renderWatch;
+
+ //public int FrameRate { get; set; }
+
+ public Direct2DControl()
+ {
+ //renderWatch = new Stopwatch();
+ //FrameRate = 60;
+ this.RenderTimer = new Stopwatch();
+ this.Loaded += this.Window_Loaded;
+ this.Unloaded += this.Window_Closing;
+ this.Stretch = System.Windows.Media.Stretch.Fill;
+ }
+
+ public void EnableRendering()
+ {
+ enableRendering = true;
+ }
+
+ public void DisableRendering()
+ {
+ enableRendering = false;
+ }
+
+ private void Window_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (Direct2DControl.IsInDesignMode)
+ {
+ return;
+ }
+
+ this.StartD3D();
+ this.StartRendering();
+ }
+
+ private void Window_Closing(object sender, RoutedEventArgs e)
+ {
+ if (Direct2DControl.IsInDesignMode)
+ {
+ return;
+ }
+
+ this.StopRendering();
+ this.EndD3D();
+ }
+
+ private void StartD3D()
+ {
+ this.Device = new Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport, FeatureLevel.Level_10_0);
+
+ this.D3DSurface = new DX10ImageSource();
+ this.D3DSurface.IsFrontBufferAvailableChanged += OnIsFrontBufferAvailableChanged;
+
+ this.CreateAndBindTargets();
+
+ this.Source = this.D3DSurface;
+ }
+
+ private void EndD3D()
+ {
+ this.D3DSurface.IsFrontBufferAvailableChanged -= OnIsFrontBufferAvailableChanged;
+ this.Source = null;
+
+ Disposer.SafeDispose(ref this.m_d2dRenderTarget);
+ Disposer.SafeDispose(ref this.m_d2dFactory);
+ Disposer.SafeDispose(ref this.D3DSurface);
+ Disposer.SafeDispose(ref this.RenderTarget);
+ Disposer.SafeDispose(ref this.Device);
+ }
+
+ private void CreateAndBindTargets()
+ {
+ if (this.D3DSurface == null) return;
+
+ this.D3DSurface.SetRenderTargetDX10(null);
+
+ Disposer.SafeDispose(ref this.m_d2dRenderTarget);
+ Disposer.SafeDispose(ref this.m_d2dFactory);
+ Disposer.SafeDispose(ref this.RenderTarget);
+
+ var width = Math.Max((int)this.ActualWidth, 100);
+ var height = Math.Max((int)this.ActualHeight, 100);
+
+ var colordesc = new Texture2DDescription
+ {
+ BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
+ Format = Format.B8G8R8A8_UNorm,
+ Width = width,
+ Height = height,
+ MipLevels = 1,
+ SampleDescription = new SampleDescription(1, 0),
+ Usage = ResourceUsage.Default,
+ OptionFlags = ResourceOptionFlags.Shared,
+ CpuAccessFlags = CpuAccessFlags.None,
+ ArraySize = 1
+ };
+
+ this.RenderTarget = new Texture2D(this.Device, colordesc);
+
+ var surface = this.RenderTarget.QueryInterface<Surface>();
+
+ m_d2dFactory = new SharpDX.Direct2D1.Factory();
+ var rtp = new RenderTargetProperties(new PixelFormat(Format.Unknown, AlphaMode.Premultiplied));
+ m_d2dRenderTarget = new RenderTarget(m_d2dFactory, surface, rtp);
+
+ this.D3DSurface.SetRenderTargetDX10(this.RenderTarget);
+ }
+
+ private void StartRendering()
+ {
+ if (this.RenderTimer.IsRunning)
+ {
+ return;
+ }
+
+ System.Windows.Media.CompositionTarget.Rendering += OnRendering;
+ this.RenderTimer.Start();
+ //renderWatch.Start();
+ }
+
+ private void StopRendering()
+ {
+ if (!this.RenderTimer.IsRunning)
+ {
+ return;
+ }
+
+ System.Windows.Media.CompositionTarget.Rendering -= OnRendering;
+ this.RenderTimer.Stop();
+ RenderTimer.Stop();
+ }
+
+ private void OnRendering(object sender, EventArgs e)
+ {
+ if (!this.RenderTimer.IsRunning)
+ {
+ return;
+ }
+
+ //if (renderWatch.ElapsedMilliseconds >= (1000 / FrameRate))
+ //{
+ //renderWatch.Restart();
+ if (enableRendering)
+ {
+ this.PrepareAndCallRender();
+ this.D3DSurface.InvalidateD3DImage();
+ }
+ //}
+ }
+
+ protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
+ {
+ this.CreateAndBindTargets();
+ base.OnRenderSizeChanged(sizeInfo);
+ }
+
+ private void PrepareAndCallRender()
+ {
+ var device = this.Device;
+ if (device == null)
+ {
+ return;
+ }
+
+ var renderTarget = this.RenderTarget;
+ if (renderTarget == null)
+ {
+ return;
+ }
+
+ var targetWidth = renderTarget.Description.Width;
+ var targetHeight = renderTarget.Description.Height;
+
+ device.Rasterizer.SetViewports(new Viewport(0, 0, targetWidth, targetHeight, 0.0f, 1.0f));
+
+
+ // Does the actual rendering
+ m_d2dRenderTarget.BeginDraw();
+ this.Render(m_d2dRenderTarget);
+ m_d2dRenderTarget.EndDraw();
+ //this.ShowFramesPerSecondsOnDebug();
+
+ device.Flush();
+ }
+
+ /// <summary>
+ /// Does the actual rendering.
+ /// BeginDraw and EndDraw are already called by the caller.
+ /// </summary>
+ public abstract void Render(RenderTarget target);
+
+ /// <summary>
+ /// Shows the number of frames per seconds on the debug line
+ /// </summary>
+ private void ShowFramesPerSecondsOnDebug()
+ {
+ // Spits out the Frames per second
+ f++;
+ if ((DateTime.Now - last).TotalSeconds > 1)
+ {
+ System.Diagnostics.Debug.WriteLine(f);
+ f = 0;
+ last = DateTime.Now;
+ }
+ }
+
+ private DateTime last;
+ private int f;
+
+ private void OnIsFrontBufferAvailableChanged(object sender, DependencyPropertyChangedEventArgs e)
+ {
+ // this fires when the screensaver kicks in, the machine goes into sleep or hibernate
+ // and any other catastrophic losses of the d3d device from WPF's point of view
+ if (this.D3DSurface.IsFrontBufferAvailable)
+ {
+ this.StartRendering();
+ }
+ else
+ {
+ this.StopRendering();
+ }
+ }
+
+ /// <summary>
+ /// Gets f value indicating whether the control is in design mode
+ /// (running in Blend or Visual Studio).
+ /// </summary>
+ public static bool IsInDesignMode
+ {
+ get
+ {
+ var prop = DesignerProperties.IsInDesignModeProperty;
+ var isDesignMode = (bool)DependencyPropertyDescriptor.FromProperty(prop, typeof(FrameworkElement)).Metadata.DefaultValue;
+ return isDesignMode;
+ }
+ }
+ }
+} \ No newline at end of file