2013-10-20 145 views
7

我想盡可能快地畫線。出於這個原因,我實現了一個使用InteropBitmap的方法。這工作很好。下一步是與ShardDX進行比較。基本上我想要做的是: 在BackgroundWorker中運行以下代碼。這通知WPF有關WIC的更新。我發現這個代碼(創建ShapeDX和繪製線所需的全部代碼)比使用InteropBitmap做同樣的工作要花費大約10ms的時間。SharpDX在WPF中渲染

我現在的問題很簡單,如何加快速度?我可以以某種方式更改代碼,我只需要調用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(); 
     } 
    } 

和:

<StackPanel> 
    <Image Name="huhu1" Source="{Binding WIC}" /> 
</StackPanel> 

回答

4

SharpDX Toolkit通過Direct3D11到Direct3D9共享紋理支持WPF。它在SharpDXElement類中實現。

您可能無法按原樣重複使用,因爲Direct2D(用於繪製)可以與Direct3D11.1或Direct3D10互操作,SharpDX使用Direct3D11來支持WPF,因此您需要調整解決方案一點點。

基本上你需要做到以下幾點:

  • 初始化的Direct3D(10或11.1)。
  • 初始化Direct2D。
  • 使用Direct2D支持和Shared標誌創建D3D渲染目標(here是在SharpDX中如何完成的)。
  • 初始化Direct3D9
  • 創建共享texture
  • 將紋理綁定到D3DImage

當更新渲染目標的內容時,不要忘記調用D3DImage.AddDirtyRect

從你提供的代碼來看,如果你只做了一次所有的初始化並不清楚,所以試着只調用一次初始化代碼並重新使用渲染目標 - 只需在每幀的開頭清除它。這是獲得體面表現的必備條件。

更新:SharpDX。Toolkit已被棄用,不再被維護。它被移動到一個單獨的存儲庫。

+0

SharpDXElement的鏈接已損壞。請更新它。 – BrainSlugs83

+0

@ BrainSlugs83 - 鏈接已更新。 –

+0

截至2017年,他們表示:「該倉庫中Toolkit的當前代碼不再適用於SharpDX的最新分支。」 – vines

4

如果你想與大家分享一個WPF的DirectX表面,最好的選擇是使用WPF D3DImage。如果您使用正確的顏色格式,它承諾無需複製即可使用。

我只用它與Directx9,但它也可能與Direct2D兼容,但如果它不是D3d9也可以畫線。

有很多codeproject article的例子。從使用slimdx或sharpdx的託管代碼中,唯一不明顯的警告是D3DImage保留了DirectX表面的引用計數,因此當您要重置d3d設備時,需要明確地清空backbuffer。

+0

這聽起來像一個更好的方法,也許你可以分享一個小例子?符合上面的代碼?我對這個DirectX的東西很陌生。我已經開始搜索,但也許你可以幫助更快。 – user2799180

+0

感謝這個例子。我已經看過這個例子,但對我來說這並不明顯。 DirectX對我來說確實很新,所以我更喜歡不需要C++庫的示例,具體取決於DirectX SDK。不幸的是,我看不出如何在這個例子中應用sharpdx。 – user2799180