1
+ using System ;
2
+ using System . Runtime . InteropServices ;
3
+ using DearImGuiInjection . Windows ;
4
+ using ImGuiNET ;
5
+ using SharpDX . Direct3D11 ;
6
+ using SharpDX . DXGI ;
7
+ using Device = SharpDX . Direct3D11 . Device ;
8
+
9
+ namespace DearImGuiInjection . Backends ;
10
+
11
+ internal static class ImGuiDX11
12
+ {
13
+ private static IntPtr _windowHandle ;
14
+
15
+ private static RenderTargetView _renderTargetView ;
16
+ private static User32 . WndProcDelegate _myWindowProc ;
17
+ private static IntPtr _originalWindowProc ;
18
+ private const int GWL_WNDPROC = - 4 ;
19
+
20
+ internal static void Init ( )
21
+ {
22
+ RendererFinder . Renderers . DX11Renderer . OnPresent += InitImGui ;
23
+
24
+ RendererFinder . Renderers . DX11Renderer . OnPresent += RenderImGui ;
25
+ RendererFinder . Renderers . DX11Renderer . PreResizeBuffers += PreResizeBuffers ;
26
+ RendererFinder . Renderers . DX11Renderer . PostResizeBuffers += PostResizeBuffers ;
27
+ }
28
+
29
+ internal static void Dispose ( )
30
+ {
31
+ if ( ! DearImGuiInjection . Initialized )
32
+ {
33
+ return ;
34
+ }
35
+
36
+ RendererFinder . Renderers . DX11Renderer . PostResizeBuffers -= PostResizeBuffers ;
37
+ RendererFinder . Renderers . DX11Renderer . PreResizeBuffers -= PreResizeBuffers ;
38
+ RendererFinder . Renderers . DX11Renderer . OnPresent -= RenderImGui ;
39
+
40
+ User32 . SetWindowLong ( _windowHandle , GWL_WNDPROC , _originalWindowProc ) ;
41
+
42
+ ImGuiWin32Impl . Shutdown ( ) ;
43
+
44
+ _renderTargetView = null ;
45
+
46
+ Log . Info ( "ImGui.ImGuiImplDX11Shutdown()" ) ;
47
+ ImGuiDX11Impl . Shutdown ( ) ;
48
+
49
+ _windowHandle = IntPtr . Zero ;
50
+ }
51
+
52
+ private static unsafe void InitImGui ( SwapChain swapChain , uint syncInterval , uint flags )
53
+ {
54
+ var windowHandle = swapChain . Description . OutputHandle ;
55
+
56
+ if ( ! DearImGuiInjection . Initialized )
57
+ {
58
+ DearImGuiInjection . InitImGui ( ) ;
59
+
60
+ InitImGuiWin32 ( windowHandle ) ;
61
+
62
+ InitImGuiDX11 ( swapChain ) ;
63
+
64
+ DearImGuiInjection . Initialized = true ;
65
+ }
66
+
67
+ RendererFinder . Renderers . DX11Renderer . OnPresent -= InitImGui ;
68
+ }
69
+
70
+ private static unsafe void InitImGuiWin32 ( IntPtr windowHandle )
71
+ {
72
+ if ( ! DearImGuiInjection . Initialized )
73
+ {
74
+ _windowHandle = windowHandle ;
75
+ if ( _windowHandle == IntPtr . Zero )
76
+ return ;
77
+
78
+ Log . Info ( $ "ImGuiImplWin32Init, Window Handle: { windowHandle : X} ") ;
79
+ ImGuiWin32Impl . Init ( _windowHandle ) ;
80
+
81
+ _myWindowProc = new User32 . WndProcDelegate ( WndProcHandler ) ;
82
+ _originalWindowProc = User32 . SetWindowLong ( windowHandle , GWL_WNDPROC , Marshal . GetFunctionPointerForDelegate ( _myWindowProc ) ) ;
83
+ }
84
+ }
85
+
86
+ private static unsafe void InitImGuiDX11 ( SwapChain swapChain )
87
+ {
88
+ using var device = InitImGuiDX11Internal ( swapChain ) ;
89
+
90
+ ImGuiDX11Impl . Init ( ( void * ) device . NativePointer , ( void * ) device . ImmediateContext . NativePointer ) ;
91
+ }
92
+
93
+ private static unsafe Device InitImGuiDX11Internal ( SwapChain swapChain )
94
+ {
95
+ var device = swapChain . GetDevice < Device > ( ) ;
96
+ using var backBuffer = swapChain . GetBackBuffer < Texture2D > ( 0 ) ;
97
+ _renderTargetView = new RenderTargetView ( device , backBuffer ) ;
98
+
99
+ return device ;
100
+ }
101
+
102
+ private static unsafe IntPtr WndProcHandler ( IntPtr windowHandle , WindowMessage message , IntPtr wParam , IntPtr lParam )
103
+ {
104
+ if ( DearImGuiInjection . IsCursorVisible && ImGuiWin32Impl . WndProcHandler ( windowHandle , message , wParam , lParam ) )
105
+ return IntPtr . Zero ;
106
+
107
+ return User32 . CallWindowProc ( _originalWindowProc , windowHandle , message , wParam , lParam ) ;
108
+ }
109
+
110
+ private static unsafe void RenderImGui ( SwapChain swapChain , uint syncInterval , uint flags )
111
+ {
112
+ var windowHandle = swapChain . Description . OutputHandle ;
113
+
114
+ if ( ! IsTargetWindowHandle ( windowHandle ) )
115
+ {
116
+ // Log.Info($"[DX11] Discarding window handle {windowHandle:X} due to mismatch");
117
+ return ;
118
+ }
119
+
120
+ ImGuiDX11Impl . NewFrame ( ) ;
121
+
122
+ NewFrame ( ) ;
123
+
124
+ using var device = swapChain . GetDevice < Device > ( ) ;
125
+ device . ImmediateContext . OutputMerger . SetRenderTargets ( _renderTargetView ) ;
126
+
127
+ var drawData = ImGui . GetDrawData ( ) ;
128
+ ImGuiDX11Impl . RenderDrawData ( drawData . NativePtr ) ;
129
+ }
130
+
131
+ private static bool IsTargetWindowHandle ( IntPtr windowHandle )
132
+ {
133
+ if ( windowHandle != IntPtr . Zero )
134
+ {
135
+ return windowHandle == _windowHandle || ! DearImGuiInjection . Initialized ;
136
+ }
137
+
138
+ return false ;
139
+ }
140
+
141
+ private static unsafe void NewFrame ( )
142
+ {
143
+ ImGuiWin32Impl . NewFrame ( ) ;
144
+ ImGui . NewFrame ( ) ;
145
+
146
+ if ( DearImGuiInjection . RenderAction != null )
147
+ {
148
+ foreach ( Action item in DearImGuiInjection . RenderAction . GetInvocationList ( ) )
149
+ {
150
+ try
151
+ {
152
+ item ( ) ;
153
+ }
154
+ catch ( Exception e )
155
+ {
156
+ Log . Error ( e ) ;
157
+ }
158
+ }
159
+ }
160
+
161
+ ImGui . EndFrame ( ) ;
162
+ ImGui . Render ( ) ;
163
+
164
+ /*if ((DearImGuiInjection.IO.ConfigFlags & ImGuiConfigFlags.ViewportsEnable) > 0)
165
+ {
166
+ ImGui.UpdatePlatformWindows();
167
+ ImGui.RenderPlatformWindowsDefault(IntPtr.Zero, IntPtr.Zero);
168
+ }*/
169
+ }
170
+
171
+ private static void PreResizeBuffers ( SwapChain swapChain , uint bufferCount , uint width , uint height , Format newFormat , uint swapchainFlags )
172
+ {
173
+ if ( ! DearImGuiInjection . Initialized )
174
+ {
175
+ return ;
176
+ }
177
+
178
+ var windowHandle = swapChain . Description . OutputHandle ;
179
+
180
+ Log . Info ( $ "[DX11 ResizeBuffers] Window Handle { windowHandle : X} ") ;
181
+
182
+ if ( ! IsTargetWindowHandle ( windowHandle ) )
183
+ {
184
+ Log . Info ( $ "[DX11 ResizeBuffers] Discarding window handle { windowHandle : X} due to mismatch") ;
185
+ return ;
186
+ }
187
+
188
+ _renderTargetView ? . Dispose ( ) ;
189
+ _renderTargetView = null ;
190
+ ImGuiDX11Impl . InvalidateDeviceObjects ( ) ;
191
+ }
192
+
193
+ private static void PostResizeBuffers ( SwapChain swapChain , uint bufferCount , uint width , uint height , Format newFormat , uint swapchainFlags )
194
+ {
195
+ if ( ! DearImGuiInjection . Initialized )
196
+ {
197
+ return ;
198
+ }
199
+
200
+ var windowHandle = swapChain . Description . OutputHandle ;
201
+
202
+ if ( ! IsTargetWindowHandle ( windowHandle ) )
203
+ {
204
+ Log . Info ( $ "[DX11 ResizeBuffers] Discarding window handle { windowHandle : X} due to mismatch") ;
205
+ return ;
206
+ }
207
+
208
+ ImGuiDX11Impl . CreateDeviceObjects ( ) ;
209
+
210
+ using var device = swapChain . GetDevice < Device > ( ) ;
211
+ using var backBuffer = swapChain . GetBackBuffer < Texture2D > ( 0 ) ;
212
+ _renderTargetView = new RenderTargetView ( device , backBuffer ) ;
213
+ }
214
+ }
0 commit comments