SharpDX在WPF中渲染

我想尽快画出线条。 出于这个原因,我使用InteropBitmap实现了一个方法。 这非常有效。 下一步是与ShardDX进行比较。 基本上我想要做的是:在BackgroundWorker中运行以下代码。 这确实告知WPF有关WIC的更新。 我发现这个代码(创建ShapeDX和绘制线所需的所有代码)比使用InteropBitmap做同样的时间长约10ms。

我现在的问题很简单,如何加快速度? 我可以以某种方式更改代码,我只需要调用BeginDraw,创建行和EndDraw,而不是总是执行所有这些图像编码/解码的东西吗? 还是有更好的方法?

var wicFactory = new ImagingFactory(); var d2dFactory = new SharpDX.Direct2D1.Factory(); const int width = 800; const int height = 200; var wicBitmap = new Bitmap(wicFactory, width, height, SharpDX.WIC.PixelFormat.Format32bppBGR, BitmapCreateCacheOption.CacheOnLoad); var renderTargetProperties = new RenderTargetProperties(RenderTargetType.Default, new PixelFormat(Format.Unknown, AlphaMode.Unknown), 0, 0, RenderTargetUsage.None, FeatureLevel.Level_DEFAULT); var d2dRenderTarget = new WicRenderTarget(d2dFactory, wicBitmap, renderTargetProperties); var solidColorBrush = new SharpDX.Direct2D1.SolidColorBrush(d2dRenderTarget, SharpDX.Color.White); d2dRenderTarget.BeginDraw(); //draw whatever you want d2dRenderTarget.EndDraw(); // Memorystream. MemoryStream ms = new MemoryStream(); var stream = new WICStream(wicFactory, ms); // JPEG encoder var encoder = new SharpDX.WIC.JpegBitmapEncoder(wicFactory); encoder.Initialize(stream); // Frame encoder var bitmapFrameEncode = new BitmapFrameEncode(encoder); bitmapFrameEncode.Initialize(); bitmapFrameEncode.SetSize(width, height); var pixelFormatGuid = SharpDX.WIC.PixelFormat.FormatDontCare; bitmapFrameEncode.SetPixelFormat(ref pixelFormatGuid); bitmapFrameEncode.WriteSource(wicBitmap); bitmapFrameEncode.Commit(); encoder.Commit(); ms.Seek(0, SeekOrigin.Begin); // JPEG decoder var decoder = new System.Windows.Media.Imaging.JpegBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); // Write to wpf image _WIC = decoder.Frames[0]; // Tell WPF to update RaisePropertyChanged("WIC"); bitmapFrameEncode.Dispose(); encoder.Dispose(); stream.Dispose(); 

附:

 System.Windows.Media.Imaging.BitmapFrame _WIC; public System.Windows.Media.Imaging.BitmapSource WIC { get { return (System.Windows.Media.Imaging.BitmapSource)_WIC.GetAsFrozen(); } } 

和:

    

SharpDX Toolkit通过Direct3D11到Direct3D9共享纹理支持WPF。 它在SharpDXElement类中实现。

你可能无法重复使用它,因为Direct2D(你用来绘制)可以与Direct3D11.1或Direct3D10互操作,SharpDX使用Direct3D11支持WPF,所以你需要稍微调整一下解决方案。

基本上你需要做以下事情:

  • 初始化Direct3D(10或11.1)。
  • 初始化Direct2D。
  • 使用Direct2D支持和共享标志创建D3D渲染目标(这是在SharpDX中完成的方式)。
  • 初始化Direct3D9 。
  • 创建共享纹理 。
  • 将纹理绑定到D3DImage 。

当渲染目标的内容更新时,不要忘记调用D3DImage.AddDirtyRect 。

从您提供的代码中不清楚您是否只进行了一次所有初始化,因此请尝试仅调用任何初始化代码一次并重用渲染目标 – 只需在每个帧的开头清除它。 这是获得体面表现的必要条件。

更新:SharpDX.Toolkit已被弃用,不再维护。 它被移动到一个单独的存储库。

如果你想与WPF共享一个directx表面,最好的选择是使用WPF D3DImage 。 如果使用正确的颜色格式,它可以在不复制的情况下工作。

我只使用它与Directx9,但它也可能与Direct2D兼容,但如果它不是D3d9也可以画线。

有一个很棒的代码项目文章和示例。 从使用slimdx或sharpdx的托管代码中,唯一不明显的警告是D3DImage保留了DirectX表面的引用计数,因此当您想要重置d3d设备时,需要显式地使后备缓冲区为空。

您可以使用Smartrak / WpfSharpDxControl:提供WPF控件来托管SharpDx内容。

它在WPF中使用sharpDx,而wpf可以将Win32HwndControl添加到HwndHost。