2016-08-30 62 views
1

我正在開發一個顯示3D場景的WPF應用程序。雖然我使用Viewport3D控件在該場景中顯示2D WPF控件,但我在透明覆蓋窗口中使用本機Direct3D 11,以獲得複雜的動畫3D幾何圖形。這工作正常。如何使Direct3D 11覆蓋與WPF Viewport3D同步?

唯一的問題是,由於Direct3D覆蓋窗口未與WPF Viewport3D同步,所以目前可能會出現明顯的延遲。它只有在相機移動時纔可見,因爲必須像Direct3D渲染一樣更新渲染。理想情況下,Direct3D緩衝區應該在WPF緩衝區之後立即交換。

我的問題:有什麼方法可以在Viewport3D顯示其內容後立即執行代碼嗎?或者至少接近那一刻? 不必成爲一個乾淨的解決方案 - 我也可以生活在一個骯髒的本土黑客...

我成功地創建一個該被從(內部)Viewport3DVisual類的RenderContent調用的方法,但是這往往比執行實際存在的屏幕可能不在渲染線程上。

+1

你應該分享你的努力來解決問題的代碼。如果它有任何問題,你會在這裏得到建議/答案。 –

+0

在更改D3D中的某些內容後,您可能需要更新Viewport3D。爲什麼不? –

+0

@sergey那麼,如果我這樣做的問題是,它需要一段時間,直到Viewport3D完成渲染並最終呈現更新 - 實際上,WPF可能會開始多次渲染,而不會在前端展示任何東西緩衝。因此,Viewport3D仍然顯示過時的場景,而更新的Direct3D覆蓋圖已經可見。 這也是爲什麼我在'RenderContent'上的鉤子不是一個好的解決方案,渲染不一定接近WPF中前端緩衝區的下一個存在。 –

回答

0

好的,我自己找到了解決方案。這是可能的事件處理程序添加到內部RenderComplete事件的內部MediaContext類使用反射的:

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