9

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

私の質問は、これをスピードアップする方法です。この画像のエンコード/デコードのすべてを常に行う必要はなく、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

3 に答える 3

6

SharpDX ツールキットは、Direct3D11 から Direct3D9 への共有テクスチャを介して WPF をサポートしています。SharpDXElementクラスに実装されています。

Direct2D(描画に使用)はDirect3D11.1またはDirect3D11と相互運用でき、SharpDXはWPFサポートにDirect3D11を使用するため、これをそのまま再利用できない場合があるため、ソリューションを少し調整する必要があります.

基本的に、次のことを行う必要があります。

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

レンダー ターゲットのコンテンツが更新されたら、 D3DImage.AddDirtyRectを呼び出すことを忘れないでください。

提供したコードからは、すべての初期化を 1 回だけ実行しているかどうかが明確ではないため、初期化コードを 1 回だけ呼び出して、レンダー ターゲットを再利用するようにしてください。すべてのフレームの開始時にクリアするだけです。これは、まともなパフォーマンスを得るために必須です。

更新: SharpDX.Toolkit は廃止され、メンテナンスされなくなりました。別のリポジトリに移動されます。

于 2013-10-31T15:57:04.873 に答える
5

Directx サーフェスを WPF と共有する場合、最適なオプションはWPF D3DImageを使用することです。適切なカラー形式を使用すれば、コピーせずに機能することが約束されています。

私は Directx9 でしか使用していませんが、Direct2D と互換性がある可能性もありますが、そうでない場合は D3d9 でも線を描画できます。

例を含む優れたcodeproject 記事があります。Slimdx または Sharpdx を使用するマネージ コードから、D3DImage が DirectX サーフェスへの参照カウントを保持しているため、d3d デバイスをリセットする場合はバックバッファを明示的に null にする必要があるという唯一の明らかでない注意事項があります。

于 2013-10-20T17:24:33.283 に答える