Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImGui DirectX11 Implementation #2409

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions Silk.NET.sln
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Assimp.Tests", "sr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Core.Tests", "src\Core\Silk.NET.Core.Tests\Silk.NET.Core.Tests.csproj", "{4D871493-0B88-477A-99A1-3E05561CFAD9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImGuiDX11", "src\Lab\Experiments\ImGuiDX11\ImGuiDX11.csproj", "{19EF071F-25D0-482D-9B81-31A2D037AD7A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Direct3D11 Demos", "Direct3D11 Demos", "{10CFA2B9-6453-42EB-A89E-796CED80EFA5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImGuiDX11Demo", "examples\CSharp\Direct3D11 Demos\ImGuiDX11Demo\ImGuiDX11Demo.csproj", "{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -3785,6 +3791,30 @@ Global
{4D871493-0B88-477A-99A1-3E05561CFAD9}.Release|x64.Build.0 = Release|Any CPU
{4D871493-0B88-477A-99A1-3E05561CFAD9}.Release|x86.ActiveCfg = Release|Any CPU
{4D871493-0B88-477A-99A1-3E05561CFAD9}.Release|x86.Build.0 = Release|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Debug|x64.ActiveCfg = Debug|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Debug|x64.Build.0 = Debug|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Debug|x86.ActiveCfg = Debug|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Debug|x86.Build.0 = Debug|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Release|Any CPU.Build.0 = Release|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Release|x64.ActiveCfg = Release|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Release|x64.Build.0 = Release|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Release|x86.ActiveCfg = Release|Any CPU
{19EF071F-25D0-482D-9B81-31A2D037AD7A}.Release|x86.Build.0 = Release|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Debug|x64.ActiveCfg = Debug|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Debug|x64.Build.0 = Debug|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Debug|x86.ActiveCfg = Debug|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Debug|x86.Build.0 = Debug|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Release|Any CPU.Build.0 = Release|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Release|x64.ActiveCfg = Release|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Release|x64.Build.0 = Release|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Release|x86.ActiveCfg = Release|Any CPU
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -4087,6 +4117,9 @@ Global
{01B6FFA0-5B37-44EA-ABDF-7BABD05874C5} = {90471225-AC23-424E-B62E-F6EC4C6ECAC0}
{12D0A556-7DDF-4902-8911-1DA3F6331149} = {6EADA376-E83F-40B7-9539-71DD17AEF7A4}
{4D871493-0B88-477A-99A1-3E05561CFAD9} = {0651C5EF-50AA-4598-8D9C-8F210ADD8490}
{19EF071F-25D0-482D-9B81-31A2D037AD7A} = {39B598E9-44BA-4A61-A1BB-7C543734DBA6}
{10CFA2B9-6453-42EB-A89E-796CED80EFA5} = {6842A2C6-5C7B-42DD-9825-0EDE91BFEBF7}
{2F97E314-5EC7-4FDF-9E89-E3BA19F64EA1} = {10CFA2B9-6453-42EB-A89E-796CED80EFA5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F5273D7F-3334-48DF-94E3-41AE6816CD4D}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>12</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ImGui.NET" Version="1.91.6.1" />
<ProjectReference Include="..\..\..\..\src\Input\Silk.NET.Input\Silk.NET.Input.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft\Silk.NET.Direct3D.Compilers\Silk.NET.Direct3D.Compilers.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft\Silk.NET.Direct3D11\Silk.NET.Direct3D11.csproj" />
<ProjectReference Include="..\..\..\..\src\Windowing\Silk.NET.Windowing\Silk.NET.Windowing.csproj" />
<ProjectReference Include="..\..\..\..\src\Lab\Experiments\ImGuiDX11\ImGuiDX11.csproj" />
</ItemGroup>

</Project>
196 changes: 196 additions & 0 deletions examples/CSharp/Direct3D11 Demos/ImGuiDX11Demo/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

/////////////////////////////////////////////////////// PLEASE READ! ///////////////////////////////////////////////////
// This provides a basic example of using our Direct3D 11 bindings in their current form. These bindings are still //
// improving over time, and as a result the content of this example may change. //
// Notably: //
// TODO remove Unsafe.NullRef once we've updated the bindings to not require it //
// TODO investigate making the D3DPrimitiveTopology enum more user friendly //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

using System.Runtime.CompilerServices;
using ImGuiNET;
using Silk.NET.Core.Native;
using Silk.NET.Direct3D11;
using Silk.NET.DXGI;
using Silk.NET.Input;
using Silk.NET.Lab.Experiments.ImGuiDX11;
using Silk.NET.Maths;
using Silk.NET.Windowing;

float[] backgroundColour = [0.0f, 0.0f, 0.0f, 1.0f];

// Load the DXGI and Direct3D11 libraries for later use.
// Given this is not tied to the window, this doesn't need to be done in the OnLoad event.
DXGI dxgi = null!;
D3D11 d3d11 = null!;

// These variables are initialized within the Load event.
ComPtr<IDXGIFactory2> factory = default;
ComPtr<IDXGISwapChain1> swapchain = default;
ComPtr<ID3D11Device> device = default;
ComPtr<ID3D11DeviceContext> deviceContext = default;

ImGuiDX11Controller controller = null;

// Create a window.
WindowOptions options = WindowOptions.Default with
{
Size = new Vector2D<int>(800, 600),
Title = "Learn Direct3D11 with Silk.NET",
API = GraphicsAPI.None, // <-- This bit is important, as your window will be configured for OpenGL by default.
};
var window = Window.Create(options);

// Assign events.
window.Load += OnLoad;
window.Render += OnRender;
window.FramebufferResize += OnFramebufferResize;

// Run the window.
window.Run();

// Dispose of the ImGui context.
controller?.Dispose();

// Clean up any resources.
factory.Dispose();
swapchain.Dispose();
device.Dispose();
deviceContext.Dispose();
d3d11.Dispose();
dxgi.Dispose();

//dispose the window, and its internal resources
window.Dispose();


unsafe void OnLoad()
{
//Whether or not to force use of DXVK on platforms where native DirectX implementations are available
const bool forceDxvk = false;

dxgi = DXGI.GetApi(window, forceDxvk);
d3d11 = D3D11.GetApi(window, forceDxvk);

// Set-up input context.
var input = window.CreateInput();
foreach (var keyboard in input.Keyboards)
{
keyboard.KeyDown += OnKeyDown;
}

// Create our D3D11 logical device.
SilkMarshal.ThrowHResult
(
d3d11.CreateDevice
(
default(ComPtr<IDXGIAdapter>),
D3DDriverType.Hardware,
Software: default,
(uint) CreateDeviceFlag.Debug,
null,
0,
D3D11.SdkVersion,
ref device,
null,
ref deviceContext
)
);

//This is not supported under DXVK
//TODO: PR a stub into DXVK for this maybe?
if (OperatingSystem.IsWindows())
{
// Log debug messages for this device (given that we've enabled the debug flag). Don't do this in release code!
device.SetInfoQueueCallback(msg => Console.WriteLine(SilkMarshal.PtrToString((nint) msg.PDescription)));
}

// Create our swapchain.
var swapChainDesc = new SwapChainDesc1
{
BufferCount = 2, // double buffered
Format = Format.FormatB8G8R8A8Unorm,
BufferUsage = DXGI.UsageRenderTargetOutput,
SwapEffect = SwapEffect.FlipDiscard,
SampleDesc = new SampleDesc(1, 0)
};

// Create our DXGI factory to allow us to create a swapchain.
factory = dxgi.CreateDXGIFactory<IDXGIFactory2>();

// Create the swapchain.
SilkMarshal.ThrowHResult
(
factory.CreateSwapChainForHwnd
(
device,
window.Native!.DXHandle!.Value,
in swapChainDesc,
null,
ref Unsafe.NullRef<IDXGIOutput>(),
ref swapchain
)
);

// Init ImGui.
// This is where you can set a custom font for ImGui.
//ImGuiFontConfig fontConfig = new ImGuiFontConfig("C:\\Windows\\Fonts\\arial.ttf", 16, ptr => ptr.Fonts.GetGlyphRangesDefault());
controller = new ImGuiDX11Controller(device, deviceContext, window, input/*, fontConfig*/);
}

void OnFramebufferResize(Vector2D<int> newSize)
{
// If the window resizes, we need to be sure to update the swapchain's back buffers.
// Good starting point for this function:
// https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/d3d10-graphics-programming-guide-dxgi#handling-window-resizing
SilkMarshal.ThrowHResult
(
swapchain.ResizeBuffers(0, (uint) newSize.X, (uint) newSize.Y, Format.FormatB8G8R8A8Unorm, 0)
);
}

unsafe void OnRender(double deltaSeconds)
{
// Update the ImGui controller.
controller.Update((float)deltaSeconds);

// Obtain the framebuffer for the swapchain's backbuffer.
using ComPtr<ID3D11Texture2D> framebuffer = swapchain.GetBuffer<ID3D11Texture2D>(0);

// Create a view over the render target.
ComPtr<ID3D11RenderTargetView> renderTargetView = default;
SilkMarshal.ThrowHResult(device.CreateRenderTargetView(framebuffer, null, ref renderTargetView));

// Clear the render target to be all black ahead of rendering.
deviceContext.ClearRenderTargetView(renderTargetView, ref backgroundColour[0]);

// Update the rasterizer state with the current viewport.
Viewport viewport = new Viewport(0, 0, window.FramebufferSize.X, window.FramebufferSize.Y, 0, 1);
deviceContext.RSSetViewports(1, in viewport);

// Tell the output merger about our render target view.
deviceContext.OMSetRenderTargets(1, ref renderTargetView, ref Unsafe.NullRef<ID3D11DepthStencilView>());

// Show everything you want before calling ImGui.Render().
ImGui.ShowDemoWindow();

// Then render ImGui.
controller.Render();

// Present the drawn image.
swapchain.Present(1, 0);

// Clean up any resources created in this method.
renderTargetView.Dispose();
}

void OnKeyDown(IKeyboard keyboard, Key key, int scancode)
{
// Check to close the window on escape.
if (key == Key.Escape)
{
window.Close();
}
}
22 changes: 22 additions & 0 deletions src/Lab/Experiments/ImGuiDX11/ImGuiDX11.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net5.0;net6.0</TargetFrameworks>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>12</LangVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\Core\Silk.NET.Core\Silk.NET.Core.csproj" />
<ProjectReference Include="..\..\..\Maths\Silk.NET.Maths\Silk.NET.Maths.csproj" />
<ProjectReference Include="..\..\..\Microsoft\Silk.NET.Direct3D11\Silk.NET.Direct3D11.csproj" />
<ProjectReference Include="..\..\..\Microsoft\Silk.NET.Direct3D.Compilers\Silk.NET.Direct3D.Compilers.csproj" />
<ProjectReference Include="..\..\..\Microsoft\Silk.NET.DXGI\Silk.NET.DXGI.csproj" />
<ProjectReference Include="..\..\..\Input\Silk.NET.Input\Silk.NET.Input.csproj" />
<ProjectReference Include="..\..\..\Windowing\Silk.NET.Windowing.Common\Silk.NET.Windowing.Common.csproj" />
<PackageReference Include="ImGui.NET" Version="1.90.8.1" />
</ItemGroup>

<Import Project="..\..\..\..\build\props\common.props" />
</Project>
Loading