1+ // See https://aka.ms/new-console-template for more information
2+
3+ using Example ;
4+ using Hexa . NET . D3D11 ;
5+ using Hexa . NET . D3DCommon ;
6+ using Hexa . NET . D3DCompiler ;
7+ using Hexa . NET . DXGI ;
8+ using Hexa . NET . GLFW ;
9+ using HexaGen . Runtime ;
10+ using HexaGen . Runtime . COM ;
11+ using System . Numerics ;
12+ using System . Runtime . CompilerServices ;
13+
14+ GLFW . Init ( ) ;
15+
16+ GLFW . WindowHint ( GLFW . GLFW_CLIENT_API , GLFW . GLFW_NO_API ) ;
17+
18+ GLFW . WindowHint ( GLFW . GLFW_FOCUSED , 1 ) ; // Make window focused on start
19+ GLFW . WindowHint ( GLFW . GLFW_RESIZABLE , 1 ) ; // Make window resizable
20+
21+ GLFWwindowPtr window = GLFW . CreateWindow ( 800 , 600 , "D3D11 Example" , null , null ) ;
22+ if ( window . IsNull )
23+ {
24+ Console . WriteLine ( "Failed to create GLFW window." ) ;
25+ GLFW . Terminate ( ) ;
26+ return ;
27+ }
28+
29+ unsafe IDXGIAdapter1 * GetHardwareAdapter ( ComPtr < IDXGIFactory2 > dxgiFactory )
30+ {
31+ ComPtr < IDXGIAdapter1 > adapter = null ;
32+ dxgiFactory . QueryInterface ( out ComPtr < IDXGIFactory6 > factory6 ) ;
33+
34+ if ( factory6 . Handle != null )
35+ {
36+ for ( uint adapterIndex = 0 ;
37+ ( ResultCode ) factory6 . EnumAdapterByGpuPreference ( adapterIndex , DxgiGpuPreference . HighPerformance , out adapter ) !=
38+ ResultCode . DXGI_ERROR_NOT_FOUND ;
39+ adapterIndex ++ )
40+ {
41+ DxgiAdapterDesc1 desc ;
42+ adapter . GetDesc1 ( & desc ) ;
43+ if ( ( ( DxgiAdapterFlag ) desc . Flags & DxgiAdapterFlag . Software ) != DxgiAdapterFlag . None )
44+ {
45+ // Don't select the Basic Render Driver adapter.
46+ adapter . Release ( ) ;
47+ continue ;
48+ }
49+
50+ return adapter ;
51+ }
52+
53+ factory6 . Release ( ) ;
54+ }
55+
56+ if ( adapter . Handle == null )
57+ {
58+ for ( uint adapterIndex = 0 ;
59+ ( ResultCode ) dxgiFactory . EnumAdapters1 ( adapterIndex , & adapter . Handle ) != ResultCode . DXGI_ERROR_NOT_FOUND ;
60+ adapterIndex ++ )
61+ {
62+ DxgiAdapterDesc1 desc ;
63+ adapter . GetDesc1 ( & desc ) ;
64+ string name = new ( & desc . Description_0 ) ;
65+
66+ Console . WriteLine ( $ "Found Adapter { name } ") ;
67+
68+ if ( ( ( DxgiAdapterFlag ) desc . Flags & DxgiAdapterFlag . Software ) != DxgiAdapterFlag . None )
69+ {
70+ // Don't select the Basic Render Driver adapter.
71+ adapter . Release ( ) ;
72+ continue ;
73+ }
74+
75+ return adapter ;
76+ }
77+ }
78+
79+ return adapter ;
80+ }
81+
82+ unsafe
83+ {
84+ ComPtr < IDXGIFactory2 > dxgiFactory ;
85+ ComPtr < IDXGIAdapter1 > dxgiAdapter ;
86+
87+ ComPtr < ID3D11Device1 > device ;
88+ ComPtr < ID3D11DeviceContext1 > deviceContext ;
89+
90+ D3DFeatureLevel level ;
91+
92+ DXGI . CreateDXGIFactory2 ( 0 , out dxgiFactory ) ;
93+
94+ dxgiAdapter = GetHardwareAdapter ( dxgiFactory ) ;
95+
96+ D3DFeatureLevel [ ] levelsArr =
97+ [
98+ D3DFeatureLevel . Level111 ,
99+ D3DFeatureLevel . Level110
100+ ] ;
101+
102+ D3D11CreateDeviceFlag flags = D3D11CreateDeviceFlag . BgraSupport ;
103+ bool debug = true ;
104+ if ( debug )
105+ {
106+ flags |= D3D11CreateDeviceFlag . Debug ;
107+ }
108+
109+ ID3D11Device * tempDevice ;
110+ ID3D11DeviceContext * tempContext ;
111+
112+ D3DFeatureLevel * levels = ( D3DFeatureLevel * ) Unsafe . AsPointer ( ref levelsArr [ 0 ] ) ;
113+
114+ D3D11 . CreateDevice ( ( IDXGIAdapter * ) dxgiAdapter . Handle , D3DDriverType . Unknown , nint . Zero , ( uint ) flags , levels , ( uint ) levelsArr . Length , D3D11 . D3D11_SDK_VERSION , & tempDevice , & level , & tempContext ) ;
115+
116+ tempDevice ->QueryInterface ( out device ) ;
117+ tempContext ->QueryInterface ( out deviceContext ) ;
118+
119+ tempDevice ->Release ( ) ;
120+ tempContext ->Release ( ) ;
121+
122+ ComPtr < IDXGISwapChain1 > swapChain = default ;
123+ DxgiSwapChainDesc1 swapChainDesc ;
124+
125+ ComPtr < ID3D11RenderTargetView > swapChainRTV ;
126+
127+ int width = 0 ;
128+ int height = 0 ;
129+ D3D11Viewport Viewport ;
130+
131+ GLFW . GetWindowSize ( window , ref width , ref height ) ;
132+
133+ var Hwnd = GLFW . GetWin32Window ( window ) ;
134+
135+ DxgiSwapChainDesc1 desc = new ( )
136+ {
137+ Width = ( uint ) width ,
138+ Height = ( uint ) height ,
139+ Format = DxgiFormat . B8G8R8A8Unorm ,
140+ BufferCount = 3 ,
141+ BufferUsage = ( uint ) DXGI . DXGI_USAGE_RENDER_TARGET_OUTPUT ,
142+ SampleDesc = new ( 1 , 0 ) ,
143+ Scaling = DxgiScaling . Stretch ,
144+ SwapEffect = DxgiSwapEffect . FlipSequential ,
145+ Flags = ( uint ) ( DxgiSwapChainFlag . AllowModeSwitch | DxgiSwapChainFlag . AllowTearing )
146+ } ;
147+
148+ DxgiSwapChainFullscreenDesc fullscreenDesc = new ( )
149+ {
150+ Windowed = 1 ,
151+ RefreshRate = new DxgiRational ( 0 , 1 ) ,
152+ Scaling = DxgiModeScaling . Unspecified ,
153+ ScanlineOrdering = DxgiModeScanlineOrder . Unspecified ,
154+ } ;
155+
156+ dxgiFactory . CreateSwapChainForHwnd ( ( IUnknown * ) device . Handle , Hwnd , & desc , & fullscreenDesc , ( IDXGIOutput * ) null , out swapChain ) ;
157+ // IDXGIFactory.MakeWindowAssociation(Hwnd, 1 << 0);
158+
159+ {
160+ swapChainDesc = desc ;
161+ swapChain . GetBuffer ( 0 , out ComPtr < ID3D11Texture2D > swapChainBackbuffer ) ;
162+ ID3D11RenderTargetView * rtv ;
163+ device . CreateRenderTargetView ( ( ID3D11Resource * ) swapChainBackbuffer . Handle , ( D3D11RenderTargetViewDesc * ) null , & rtv ) ;
164+ swapChainRTV . Handle = rtv ;
165+ swapChainBackbuffer . Release ( ) ;
166+ }
167+
168+ Viewport = new ( 0 , 0 , width , height , maxDepth : 1 ) ;
169+
170+ // Vertex and Pixel Shader source code
171+ string vertexShaderSource = @"
172+ struct VSInput {
173+ float3 position : POSITION;
174+ float4 color : COLOR;
175+ };
176+
177+ struct VSOutput {
178+ float4 position : SV_POSITION;
179+ float4 color : COLOR;
180+ };
181+
182+ VSOutput main(VSInput input) {
183+ VSOutput output;
184+ output.position = float4(input.position, 1.0);
185+ output.color = input.color;
186+ return output;
187+ }
188+ " ;
189+ string pixelShaderSource = @"
190+ struct VSOutput {
191+ float4 position : SV_POSITION;
192+ float4 color : COLOR;
193+ };
194+ float4 main(VSOutput input) : SV_TARGET {
195+ return input.color;
196+ }
197+ " ;
198+
199+ CompileShader ( vertexShaderSource , "main" , "vs_5_0" , out var vsBlob ) ;
200+ CompileShader ( pixelShaderSource , "main" , "ps_5_0" , out var psBlob ) ;
201+
202+ ComPtr < ID3D11VertexShader > vertexShader = default ;
203+ ComPtr < ID3D11PixelShader > pixelShader = default ;
204+
205+ device . CreateVertexShader ( vsBlob . GetBufferPointer ( ) , vsBlob . GetBufferSize ( ) , ( ID3D11ClassLinkage * ) null , vertexShader . GetAddressOf ( ) ) ;
206+ device . CreatePixelShader ( psBlob . GetBufferPointer ( ) , psBlob . GetBufferSize ( ) , ( ID3D11ClassLinkage * ) null , pixelShader . GetAddressOf ( ) ) ;
207+
208+ static unsafe void CompileShader ( string vertexShaderSource , string entrypoint , string profile , out ComPtr < ID3D10Blob > blob )
209+ {
210+ blob = default ;
211+ nuint size = ( nuint ) Utils . GetByteCountUTF8 ( vertexShaderSource ) ;
212+ byte * pData = Utils . StringToUTF8Ptr ( vertexShaderSource ) ;
213+ byte * pProfile = Utils . StringToUTF8Ptr ( profile ) ;
214+ byte * pEntrypoint = Utils . StringToUTF8Ptr ( entrypoint ) ;
215+ int pixelShaderBlob = D3DCompiler . Compile ( pData , size , ( byte * ) null , ( D3DShaderMacro * ) null , ( ID3DInclude * ) null , pEntrypoint , pProfile , 0 , 0 , blob . GetAddressOf ( ) , null ) ;
216+ Utils . Free ( pEntrypoint ) ;
217+ Utils . Free ( pProfile ) ;
218+ Utils . Free ( pData ) ;
219+ }
220+
221+ ComPtr < ID3D11InputLayout > inputLayout ;
222+
223+ D3D11InputElementDesc [ ] inputLayoutDesc =
224+ [
225+ new D3D11InputElementDesc
226+ {
227+ SemanticName = Utils . StringToUTF8Ptr ( "POSITION" ) ,
228+ SemanticIndex = 0 ,
229+ Format = DxgiFormat . R32G32B32Float ,
230+ InputSlot = 0 ,
231+ AlignedByteOffset = 0 ,
232+ InputSlotClass = D3D11InputClassification . PerVertexData ,
233+ InstanceDataStepRate = 0
234+ } ,
235+ new D3D11InputElementDesc
236+ {
237+ SemanticName = Utils . StringToUTF8Ptr ( "COLOR" ) ,
238+ SemanticIndex = 0 ,
239+ Format = DxgiFormat . R32G32B32A32Float ,
240+ InputSlot = 0 ,
241+ AlignedByteOffset = 12 ,
242+ InputSlotClass = D3D11InputClassification . PerVertexData ,
243+ InstanceDataStepRate = 0
244+ }
245+ ] ;
246+
247+ device . CreateInputLayout ( ref inputLayoutDesc [ 0 ] , 2 , vsBlob . GetBufferPointer ( ) , vsBlob . GetBufferSize ( ) , & inputLayout . Handle ) ;
248+
249+ vsBlob . Release ( ) ;
250+ psBlob . Release ( ) ;
251+
252+ Vertex [ ] vertices =
253+ [
254+ new Vertex ( new ( 0.0f , 0.5f , 0.0f ) , new ( 0 , 0 , 1 , 1 ) ) ,
255+ new Vertex ( new ( 0.5f , - 0.5f , 0.0f ) , new ( 0 , 1 , 0 , 1 ) ) ,
256+ new Vertex ( new ( - 0.5f , - 0.5f , 0.0f ) , new ( 1 , 0 , 0 , 1 ) )
257+ ] ;
258+ ComPtr < ID3D11Buffer > vertexBuffer ;
259+
260+ D3D11BufferDesc bufferDesc = new ( )
261+ {
262+ BindFlags = ( uint ) ( D3D11BindFlag . VertexBuffer ) ,
263+ CPUAccessFlags = 0 ,
264+ ByteWidth = ( uint ) ( sizeof ( Vertex ) * vertices . Length ) ,
265+ Usage = D3D11Usage . Immutable ,
266+ } ;
267+
268+ fixed ( Vertex * pVerts = vertices )
269+ {
270+ D3D11SubresourceData subresourceData = new ( pVerts , ( uint ) sizeof ( Vertex ) ) ;
271+ device . CreateBuffer ( & bufferDesc , & subresourceData , out vertexBuffer ) ;
272+ }
273+
274+ GLFW . SetFramebufferSizeCallback ( window , Resized ) ;
275+
276+ void Resized ( GLFWwindow * window , int wwidth , int wheight )
277+ {
278+ swapChainRTV . Dispose ( ) ;
279+
280+ swapChain . ResizeBuffers ( swapChainDesc . BufferCount , ( uint ) wwidth , ( uint ) wheight , swapChainDesc . Format , swapChainDesc . Flags ) ;
281+ width = wwidth ;
282+ height = wheight ;
283+ Viewport = new ( 0 , 0 , wwidth , wheight ) ;
284+
285+ swapChain . GetBuffer ( 0 , out ComPtr < ID3D11Texture2D > swapChainBackbuffer ) ;
286+
287+ ID3D11RenderTargetView * rtv ;
288+ device . CreateRenderTargetView ( ( ID3D11Resource * ) swapChainBackbuffer . Handle , ( D3D11RenderTargetViewDesc * ) null , & rtv ) ;
289+ swapChainRTV . Handle = rtv ;
290+ swapChainBackbuffer . Release ( ) ;
291+ }
292+
293+ // Main loop
294+ while ( GLFW . WindowShouldClose ( window ) == 0 )
295+ {
296+ // Poll for and process events
297+ GLFW . PollEvents ( ) ;
298+
299+ if ( GLFW . GetKey ( window , ( int ) GlfwKey . Escape ) == GLFW . GLFW_PRESS )
300+ {
301+ GLFW . SetWindowShouldClose ( window , 1 ) ; // Request to close the window
302+ }
303+
304+ Vector4 color = new ( 1 , 0.8f , 0.75f , 1 ) ;
305+ deviceContext . ClearRenderTargetView ( swapChainRTV . Handle , ( float * ) & color ) ;
306+
307+ ID3D11RenderTargetView * rtv = swapChainRTV . Handle ;
308+ deviceContext . OMSetRenderTargets ( 1 , & rtv , ( ID3D11DepthStencilView * ) null ) ;
309+ D3D11Viewport viewport = Viewport ;
310+ deviceContext . RSSetViewports ( 1 , & viewport ) ;
311+
312+ deviceContext . IASetInputLayout ( inputLayout ) ;
313+ uint stride = ( uint ) sizeof ( Vertex ) ;
314+ uint offset = 0 ;
315+ deviceContext . IASetVertexBuffers ( 0 , 1 , & vertexBuffer . Handle , & stride , & offset ) ;
316+ deviceContext . IASetPrimitiveTopology ( D3D11PrimitiveTopology . Trianglelist ) ;
317+
318+ deviceContext . VSSetShader ( vertexShader , ( ID3D11ClassInstance * * ) null , 0 ) ;
319+ deviceContext . PSSetShader ( pixelShader , ( ID3D11ClassInstance * * ) null , 0 ) ;
320+
321+ deviceContext . Draw ( 3 , 0 ) ;
322+
323+ swapChain . Present ( 1 , 0 ) ;
324+ }
325+
326+ vertexBuffer . Release ( ) ;
327+ pixelShader . Release ( ) ;
328+ vertexShader . Release ( ) ;
329+ inputLayout . Release ( ) ;
330+ swapChainRTV . Release ( ) ;
331+ swapChain . Release ( ) ;
332+ device . Release ( ) ;
333+ deviceContext . Release ( ) ;
334+ dxgiAdapter . Release ( ) ;
335+ dxgiFactory . Release ( ) ;
336+ }
337+
338+ // Clean up and terminate GLFW
339+ GLFW . DestroyWindow ( window ) ;
340+ GLFW . Terminate ( ) ;
0 commit comments