2013-10-20 3 views
7

가능한 한 빨리 선을 그립니다. 이러한 이유로 InteropBitmap을 사용하는 메소드를 구현했습니다. 이것은 꽤 잘 작동합니다. 다음 단계는 ShardDX와 비교하는 것이 었습니다. 기본적으로 내가하고 싶은 일은 다음과 같습니다. BackgroundWorker에서 다음 코드를 실행합니다. WPF에 WIC 업데이트에 대한 정보를 제공합니다. 이 코드 (ShapeDX에 필요한 모든 것을 작성하고 선을 그리는 코드)는 InteropBitmap을 사용하여 동일한 작업을 수행하는 것보다 약 10ms 더 오래 걸립니다.WPF에서 SharpDX 렌더링

내 질문은 이제 간단합니다. 어떻게 속도를 향상시킬 수 있습니까? 어떻게 든 BeginDraw를 호출하고, 라인과 EndDraw를 생성하며, 항상이 이미지 인코딩/디코딩 작업을 수행하지 않고 코드를 변경할 수 있습니까? 아니면 더 나은 방법이 있습니까?

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

와 :와

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(); 

당신이 WPF와 다이렉트 표면을 공유하려는 경우

<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으로 전화하는 것을 잊지 마십시오.

제공 한 코드에서 모든 초기화를 한 번만 수행했는지 여부는 확실하지 않으므로 초기화 코드를 한 번만 호출하고 렌더링 대상을 다시 사용하십시오. 모든 프레임의 시작 부분에서 초기화하십시오. 적절한 성능을 얻으려면 필수입니다.

업데이트 : SharpDX.Toolkit은 더 이상 사용되지 않으며 더 이상 유지 관리되지 않습니다. 별도의 저장소로 이동됩니다.

+0

SharpDXElement에 대한 링크가 끊어졌습니다. 업데이트하십시오. – BrainSlugs83

+0

@ BrainSlugs83 - 링크가 업데이트되었습니다. –

+0

2017 년 현재 그들은 다음과 같이 말하고 있습니다. "이 저장소에있는 툴킷의 현재 코드는 더 이상 최신 SharpDX 브랜치에서 작동하지 않습니다." – vines

4

은 최선의 선택은 WPF D3DImage을 사용하고 있습니다. 올바른 색상 형식을 사용하면 복사하지 않고 작업 할 수 있습니다.

나는 Directx9에서만 사용했지만 Direct2D 와도 호환 될 수 있지만 D3d9와 호환되지 않는 경우에도 선을 그릴 수 있습니다.

예제가있는 codeproject article이 좋습니다. slimdx 또는 sharpdx를 사용하는 관리 코드에서 D3DImage가 DirectX 표면에 대한 참조 카운트를 유지하므로 독점적으로 d3d 장치를 재설정하려는 경우 백 버퍼를 null로 지정해야합니다.

+0

더 나은 접근 방식처럼 들리 겠지만, 어쩌면 작은 예제를 공유 할 수 있을까요? 위의 코드에 맞습니까? 나는이 DirectX와 관련된 새로운 것들이다. 이미 검색을 시작했는데 훨씬 더 빨리 도움을 줄 수 있습니다. – user2799180

+0

예를 들어 주셔서 감사합니다. 나는이 예를 이미 보았지만 그것이 나에게는 분명하지 않다. DirectX는 정말 새로운 것이므로 DirectX SDK에 따라 C++ 라이브러리가 필요없는 예제를 선호합니다. 불행히도이 예제에서 sharpdx를 어떻게 적용 할 수 있는지 알 수 없습니다. – user2799180