2013-10-20 33 views
7

できるだけ早く線を描きたい。そのため、私はInteropBitmapを使ってメソッドを実装しました。これはかなりうまくいく。次のステップは、ShardDXと比較することでした。基本的に私がしたいのは: BackgroundWorkerで次のコードを実行します。これにより、WICの更新についてWPFに通知されます。私はこのコード(ShapeDXに必要なものをすべて作成して線を引く)がInteropBitmapを使って同じコードを実行するよりも約10ms長くかかることを知りました。WPFのSharpDXレンダリング

私の質問は今簡単にどのようにこれをスピードアップするのですか?コードを何とか変更して、BeginDrawを呼び出して、ラインとEndDrawを作成するだけで、このImage Encoding/Decodingのすべての処理を常に行う必要はありませんか?それとも良い方法がありますか?

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がWP3サポートのためにDirect3D11を使用しているため、解決策aを調整する必要があるため、これをそのまま使用することはできません。若干。

基本的には、以下を実行する必要があります。

  • 初期のDirect3D(10または11.1)。
  • Direct2Dを初期化します。
  • Direct2Dをサポートし、Sharedフラグ(hereはSharpDXでの処理方法)を使用してD3Dレンダーターゲットを作成します。
  • Direct3D9を初期化します。
  • 共有番号textureを作成します。
  • テクスチャをD3DImageにバインドします。

D3DImage.AddDirtyRectレンダーターゲットの内容が更新されたときに、忘れずにD3DImage.AddDirtyRectに電話してください。

すべての初期化を1回だけ行うかどうかは分かりませんので、初期化コードを一度しか呼び出しずにレンダリングターゲットを再利用してみてください。すべてのフレームの先頭でクリアしてください。これは、まともなパフォーマンスを得るために必須です。

更新:SharpDX。ツールキットは推奨されず、もはや維持されません。別のリポジトリに移動されます。

+0

SharpDXElementへのリンクが壊れています。それを更新してください。 – BrainSlugs83

+0

@ BrainSlugs83 - リンクが更新されました。 –

+0

2017年現在、彼らはこう言っています。「このリポジトリ内のツールキットの現在のコードは、SharpDXの最新のブランチではもはや動作していません。 – vines

4

あなたがWPFでDirectXの表面を共有したい場合は、最良のオプションは、WPF D3DImageを使用しています。適切なカラーフォーマットを使用すると、コピーせずに作業することができます。

私はDirectX9でしか使用していませんが、Direct2Dと互換性がある可能性もありますが、そうでなければD3d9も線を引くことができます。

例があります。codeproject articleがあります。 slimdxやsharpdxを使用したマネージコードからは、D3DImageがDirectXサーフェスへの参照カウントを保持していることを唯一の覚えていないので、d3dデバイスをリセットするときにバックバッファを空白にする必要があります。

+0

これは良いアプローチのように聞こえますが、おそらくあなたはリトルの例を共有できますか?上のコードに当てはまる?私はこのDirectXのものにはかなり新しいです。私はすでに検索を始めましたが、もっと速く助けてくれるかもしれません。 – user2799180

+0

この例をありがとう。私はすでにこの例を見てきましたが、それは私には明らかではありません。 DirectXは本当に新しく、DirectX SDKによってはC++ライブラリが不要な例が好きです。残念ながら、私はこの例でsharpdxをどのように適用することができないのか分かりません。 – user2799180

関連する問題