1+ // See https://aka.ms/new-console-template for more information
2+ using ExampleWin32D3D9 ;
3+ using Hexa . NET . ImGui ;
4+ using Hexa . NET . ImGui . Backends . D3D9 ;
5+ using Hexa . NET . ImGui . Backends . Win32 ;
6+ using HexaGen . Runtime ;
7+ using Silk . NET . Core . Native ;
8+ using Silk . NET . Direct3D9 ;
9+ using Silk . NET . Maths ;
10+ using System . Diagnostics ;
11+ using System . Numerics ;
12+ using System . Runtime . InteropServices ;
13+ using IDirect3DDevice9 = Silk . NET . Direct3D9 . IDirect3DDevice9 ;
14+
15+ nint hInstance = Win32 . GetModuleHandle ( null ) ;
16+ nint hWnd ;
17+ unsafe
18+ {
19+ WNDCLASS wndClass = new ( )
20+ {
21+ style = 0x0040 ,
22+ lpfnWndProc = Marshal . GetFunctionPointerForDelegate < WindowProcCallback > ( WindowProc ) ,
23+ cbClsExtra = 0 ,
24+ cbWndExtra = 0 ,
25+ hInstance = hInstance ,
26+ hIcon = nint . Zero ,
27+ hCursor = nint . Zero ,
28+ hbrBackground = 1 ,
29+ lpszMenuName = null ,
30+ lpszClassName = Utils . StringToUTF16Ptr ( "ImGui Example" )
31+ } ;
32+
33+ if ( Win32 . RegisterClassA ( ref wndClass ) == 0 )
34+ {
35+ Console . WriteLine ( "Failed to register window class. Error: " + Marshal . GetLastWin32Error ( ) ) ;
36+ return ;
37+ }
38+
39+ byte * title = Utils . StringToUTF8Ptr ( "Dear ImGui DirectX9 Example" ) ;
40+
41+ hWnd = Win32 . CreateWindowEx (
42+ 0 ,
43+ wndClass . lpszClassName ,
44+ title ,
45+ Win32 . WS_OVERLAPPEDWINDOW ,
46+ 100 , 100 ,
47+ 1200 , 800 ,
48+ nint . Zero ,
49+ nint . Zero ,
50+ hInstance ,
51+ nint . Zero ) ;
52+
53+ Utils . Free ( title ) ;
54+ Utils . Free ( wndClass . lpszClassName ) ;
55+
56+ if ( hWnd == nint . Zero )
57+ {
58+ int error = Marshal . GetLastWin32Error ( ) ;
59+ Console . WriteLine ( "Failed to create window. Error code: " + error ) ;
60+ return ;
61+ }
62+ }
63+
64+ Win32 . ShowWindow ( hWnd , Win32 . SW_SHOW ) ;
65+ Win32 . UpdateWindow ( hWnd ) ;
66+
67+ var D3D9 = Silk . NET . Direct3D9 . D3D9 . GetApi ( ) ;
68+
69+ var context = ImGui . CreateContext ( ) ;
70+
71+ var io = ImGui . GetIO ( ) ;
72+
73+ ImGuiImplWin32 . SetCurrentContext ( context ) ;
74+ ImGuiImplWin32 . Init ( hWnd ) ;
75+ PresentParameters d3dpp = default ;
76+ ComPtr < IDirect3D9 > pD3D = null ;
77+ ComPtr < IDirect3DDevice9 > pD3DDevice = null ;
78+ unsafe
79+ {
80+ pD3D = D3D9 . Direct3DCreate9 ( Silk . NET . Direct3D9 . D3D9 . SdkVersion ) ;
81+
82+ d3dpp . Windowed = true ; // Run in windowed mode
83+ d3dpp . SwapEffect = Swapeffect . Discard ; // Discard old frames
84+ d3dpp . BackBufferFormat = Format . Unknown ; // Use current display format
85+ d3dpp . EnableAutoDepthStencil = true ;
86+ d3dpp . AutoDepthStencilFormat = Format . D16 ;
87+ d3dpp . PresentationInterval = Silk . NET . Direct3D9 . D3D9 . PresentIntervalOne ;
88+
89+ // Create the Direct3D device
90+
91+ HResult hr = pD3D . CreateDevice (
92+ Silk . NET . Direct3D9 . D3D9 . AdapterDefault , // Use the primary display adapter
93+ Devtype . Hal , // Use hardware rasterization
94+ hWnd , // Handle to the window
95+ Silk . NET . Direct3D9 . D3D9 . CreateHardwareVertexprocessing , // Use software vertex processing
96+ ref d3dpp , // Presentation parameters
97+ ref pD3DDevice // Pointer to the created device
98+ ) ;
99+
100+ ImGuiImplD3D9 . SetCurrentContext ( context ) ;
101+ ImGuiImplD3D9 . Init ( new ( ( Hexa . NET . ImGui . Backends . D3D9 . IDirect3DDevice9 * ) pD3DDevice . Handle ) ) ;
102+ }
103+
104+ bool running = true ;
105+
106+ bool g_DeviceLost = false ;
107+ uint g_ResizeWidth = 0 , g_ResizeHeight = 0 ;
108+ MSG msg = default ;
109+
110+ Vector4 clear_color = new ( 1 , 0.8f , 0.75f , 1 ) ;
111+ unsafe
112+ {
113+ while ( running )
114+ {
115+ while ( Win32 . PeekMessage ( ref msg , 0 , 0U , 0U , Win32 . PM_REMOVE ) )
116+ {
117+ Win32 . TranslateMessage ( ref msg ) ;
118+ Win32 . DispatchMessage ( ref msg ) ;
119+ if ( msg . message == Win32 . WM_QUIT )
120+ running = false ;
121+ }
122+
123+ if ( g_DeviceLost )
124+ {
125+ ResultCode hr = ( ResultCode ) pD3DDevice . TestCooperativeLevel ( ) ;
126+ if ( hr == ResultCode . D3DERR_DEVICELOST )
127+ {
128+ Thread . Sleep ( 10 ) ;
129+ continue ;
130+ }
131+ if ( hr == ResultCode . D3DERR_DEVICENOTRESET )
132+ ResetDevice ( ) ;
133+ g_DeviceLost = false ;
134+ }
135+
136+ if ( g_ResizeWidth != 0 && g_ResizeHeight != 0 )
137+ {
138+ d3dpp . BackBufferWidth = g_ResizeWidth ;
139+ d3dpp . BackBufferHeight = g_ResizeHeight ;
140+ g_ResizeWidth = g_ResizeHeight = 0 ;
141+ ResetDevice ( ) ;
142+ }
143+
144+ ImGuiImplD3D9 . NewFrame ( ) ;
145+ ImGuiImplWin32 . NewFrame ( ) ;
146+ ImGui . NewFrame ( ) ;
147+
148+ ImGui . ShowDemoWindow ( ) ;
149+
150+ ImGui . EndFrame ( ) ;
151+
152+ pD3DDevice . SetRenderState ( Renderstatetype . Zenable , 0 ) ;
153+ pD3DDevice . SetRenderState ( Renderstatetype . Alphablendenable , 0 ) ;
154+ pD3DDevice . SetRenderState ( Renderstatetype . Scissortestenable , 0 ) ;
155+ uint clear_col_dx = ( uint ) (
156+ ( ( int ) ( clear_color . W * 255.0f ) << 24 ) | // Alpha
157+ ( ( int ) ( clear_color . X * clear_color . W * 255.0f ) << 16 ) | // Red
158+ ( ( int ) ( clear_color . Y * clear_color . W * 255.0f ) << 8 ) | // Green
159+ ( ( int ) ( clear_color . Z * clear_color . W * 255.0f ) ) // Blue
160+ ) ;
161+ pD3DDevice . Clear ( 0 , ( Rect * ) null , Silk . NET . Direct3D9 . D3D9 . ClearTarget | Silk . NET . Direct3D9 . D3D9 . ClearZbuffer , clear_col_dx , 1.0f , 0 ) ;
162+ if ( pD3DDevice . BeginScene ( ) >= 0 )
163+ {
164+ ImGui . Render ( ) ;
165+ ImGuiImplD3D9 . RenderDrawData ( ImGui . GetDrawData ( ) ) ;
166+ pD3DDevice . EndScene ( ) ;
167+ }
168+
169+ ResultCode result = ( ResultCode ) pD3DDevice . Present ( ( Box2D < int > * ) null , ( Box2D < int > * ) null , 0 , ( RGNData * ) null ) ;
170+ if ( result == ResultCode . D3DERR_DEVICELOST )
171+ g_DeviceLost = true ;
172+ }
173+ }
174+
175+ ImGuiImplD3D9 . Shutdown ( ) ;
176+ ImGuiImplWin32 . Shutdown ( ) ;
177+ ImGui . DestroyContext ( ) ;
178+
179+ pD3DDevice . Release ( ) ;
180+ pD3D . Release ( ) ;
181+
182+ Win32 . DestroyWindow ( hWnd ) ;
183+
184+ nint WindowProc ( nint hWnd , uint msg , nuint wParam , nint lParam )
185+ {
186+ if ( ImGuiImplWin32 . WndProcHandler ( hWnd , msg , wParam , lParam ) != 0 )
187+ {
188+ return 1 ;
189+ }
190+
191+ const uint WM_SIZE = 0x0005 ;
192+ const uint SIZE_MINIMIZED = 1 ;
193+ const uint WM_SYSCOMMAND = 0x0112 ;
194+ const uint SC_KEYMENU = 0xF100 ;
195+ const uint WM_DESTROY = 0x0002 ;
196+
197+ switch ( msg )
198+ {
199+ case WM_SIZE :
200+ if ( wParam == SIZE_MINIMIZED )
201+ return 0 ;
202+ g_ResizeWidth = ( uint ) ( lParam & 0xFFFF ) ; // Queue resize
203+ g_ResizeHeight = ( uint ) ( ( lParam >> 16 ) & 0xFFFF ) ;
204+ return 0 ;
205+
206+ case WM_SYSCOMMAND :
207+ if ( ( wParam & 0xfff0 ) == SC_KEYMENU ) // Disable ALT application menu
208+ return 0 ;
209+ break ;
210+
211+ case WM_DESTROY :
212+ Environment . Exit ( 0 ) ;
213+ return 0 ;
214+ }
215+
216+ return Win32 . DefWindowProc ( hWnd , msg , wParam , lParam ) ;
217+ }
218+
219+ unsafe void ResetDevice ( )
220+ {
221+ ImGuiImplD3D9 . InvalidateDeviceObjects ( ) ;
222+ ResultCode hr = ( ResultCode ) pD3DDevice . Reset ( ref d3dpp ) ;
223+ if ( hr == ResultCode . D3DERR_INVALIDCALL )
224+ Trace . Assert ( false ) ;
225+ ImGuiImplD3D9 . CreateDeviceObjects ( ) ;
226+ }
0 commit comments