-
Notifications
You must be signed in to change notification settings - Fork 0
/
D3dViewer.cs
121 lines (106 loc) · 3.97 KB
/
D3dViewer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Interop;
using System.Runtime.InteropServices;
namespace OccView
{
//Tools object for output OCCT rendering with Direct3D
public class D3dViewer
{
private D3DImage mD3dImg = new D3DImage();
private IntPtr mColorSurf;
public OCCViewer Viewer;
public D3dViewer()
{
//register OnIsFrontBufferAvailabelChanged as DependencyPropertyChangedEventHandler to
//D3DImage.IsFrontBufferAvailableChanged which is an event(an instaniate delegate)
mD3dImg.IsFrontBufferAvailableChanged
+= new DependencyPropertyChangedEventHandler(OnIsFrontBufferAvailableChanged);
//once D3DViewer be initialized, attach FrontBuffer method to D3DImage
//thus D3DImage Front Buffer changed it will notice OnIsFrontBufferAvailableChanged
BeginRenderingScene();
}
private void OnIsFrontBufferAvailableChanged(object sender, DependencyPropertyChangedEventArgs e)
{
// If the front buffer is available, then WPF has just created a new
// Direct3D device, thus we need to start rendering our custom scene
if (mD3dImg.IsFrontBufferAvailable)
{
BeginRenderingScene();
}
else
{
// If the front buffer is no longer available, then WPF has lost Direct3D
// device, thus we need to stop rendering until the new device is created
StopRenderingScene();
}
}
private bool mIsFailed = false;
private void BeginRenderingScene()
{
if (mIsFailed)
{
return;
}
if (mD3dImg.IsFrontBufferAvailable)
{
Viewer = new OCCViewer();
if (!Viewer.InitViewer())
{
MessageBox.Show("Failed to initialize OpenGL-Direct3D interoperability!",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
mIsFailed = true;
return;
}
// Leverage the Rendering event of WPF composition
// target to update the our custom Direct3D scene
CompositionTarget.Rendering += OnRendering;
}
}
public void StopRenderingScene()
{
CompositionTarget.Rendering -= OnRendering;
mColorSurf = IntPtr.Zero;
}
private void OnRendering(object sender, EventArgs e)
{
UpdateScene();
}
private void UpdateScene()
{
if (!mIsFailed
&& mD3dImg.IsFrontBufferAvailable
&& mColorSurf != IntPtr.Zero
&& (mD3dImg.PixelWidth != 0 && mD3dImg.PixelHeight != 0))
{
mD3dImg.Lock();
{
// Update the scene (via a call into our custom library)
Viewer.View.RedrawView();
// Invalidate the updated region of the D3DImage
mD3dImg.AddDirtyRect(new Int32Rect(0, 0, mD3dImg.PixelWidth, mD3dImg.PixelHeight));
}
mD3dImg.Unlock();
}
}
public void Resize(int theSizeX, int theSizeY)
{
if (!mIsFailed && mD3dImg.IsFrontBufferAvailable)
{
// Set the back buffer for Direct3D WPF image
mD3dImg.Lock();
{
mD3dImg.SetBackBuffer(D3DResourceType.IDirect3DSurface9, IntPtr.Zero);
mColorSurf = Viewer.View.ResizeBridgeFBO(theSizeX, theSizeY);
mD3dImg.SetBackBuffer(D3DResourceType.IDirect3DSurface9, mColorSurf);
}
mD3dImg.Unlock();
}
}
public D3DImage Image
{
get => mD3dImg;
}
}
}