2016-08-30 8 views
1

3D 장면을 보여주는 WPF 응용 프로그램을 개발 중입니다. 해당 장면 내에서 Viewport3D 컨트롤을 사용하여 2D WPF 컨트롤을 표시하는 동안 복잡한 애니메이션 3D 지오메트리의 투명 오버레이 창에서 기본 Direct3D 11을 사용합니다. 이것은 잘 작동합니다.Direct3D 11 오버레이를 WPF Viewport3D와 동기화하는 방법은 무엇입니까?

유일한 단점은 Direct3D 오버레이 창이 WPF Viewport3D과 동기화되지 않아 현재 상당한 지연이있을 수 있다는 점입니다. DirectShow 렌더링과 마찬가지로 Viewport3D 렌더링을 업데이트해야하기 때문에 카메라를 이동할 때만 표시됩니다. 이상적으로, Direct3D 버퍼는 WPF 버퍼 바로 다음에 바꿔야합니다.

내 질문 : Viewport3D가 내용을 표시 한 직후에 코드를 실행할 수있는 방법이 있습니까? 아니면 적어도 그 순간에 가깝습니까?

내가 (내부) Viewport3DVisual 클래스의 RenderContent에서 호출되는 방법을 만들기 위해 관리 ... 나는 또한 더러운 기본 해킹 살 수 있지만,이보다 더 자주 실행 - 깨끗한 해결책이 될 필요는 없다 화면에 표시 할 실제 현재 및 아마도 렌더링 스레드에 없습니다.

+1

당신은 당신이 당신의 문제를 해결하기 위해 노력 코드를 공유해야합니다. 문제가있는 경우 여기에서 제안/대답을 얻을 수 있습니다. –

+0

D3D에서 무언가를 변경 한 후에 Viewport3D를 업데이트 할 수 있습니다. 왜 안돼? –

+0

@sergey 글쎄, 내가 그렇게하는 경우 문제는 Viewport3D가 렌더링을 끝내고 마지막으로 업데이트를 제공 할 때까지 약간의 시간이 걸린다는 것입니다. 실제로 WPF는 아무 것도 제시하지 않고 여러 번 렌더링하기 시작할 수도 있습니다 완충기. 따라서 Viewport3D는 오래된 장면을 계속 표시하지만 업데이트 된 Direct3D 오버레이는 이미 표시됩니다. 그 이유는'RenderContent'에 대한 나의 훅이 좋은 해결책이 아니기 때문에 렌더링이 반드시 WPF의 프론트 버퍼에 대한 다음 현재에 근접하지는 않습니다. –

답변

0

좋아, 해결책을 찾았습니다. 내부 MediaContext 클래스 사용하여 반사의 내부 RenderComplete 이벤트에 이벤트 처리기를 추가 할 수 있습니다 :

Assembly oAssemblyPresentationCore = typeof(Visual).Assembly; 
Type oTypeMediaContext = oAssemblyPresentationCore.GetType("System.Windows.Media.MediaContext"); 
MethodInfo oMethodInfoGetMediaContextFromDispatcher = oTypeMediaContext.GetMethod("From", BindingFlags.Static | BindingFlags.NonPublic); 
object oMediaContext = oMethodInfoGetMediaContextFromDispatcher.Invoke(null, new object[] { oViewport3D.Dispatcher }); 
EventInfo oEventInfoRenderComplete = oMediaContext.GetType().GetEvent("RenderComplete", BindingFlags.NonPublic | BindingFlags.Instance); 
oEventInfoRenderComplete.GetAddMethod(true).Invoke(oMediaContext, new object[] { new EventHandler(EventHandlerRendered) });