From 9b12fbeb69f2b29c9b48b36033f0953d6db17c8c Mon Sep 17 00:00:00 2001 From: Matthew Edmondson Date: Thu, 20 Jun 2024 08:41:50 +1000 Subject: [PATCH] ImGui.NET 1.90.8.1 (#2230) * start of ImGui.NET 1.90.8.1 * Add TranslateInputKeyToImGuiKey() to translate Silk.NET.Input.Key to ImGuiKey. Reference: https://github.com/ocornut/imgui/commit/fe646ea59131fb9bd792de8843173b7e6f6b9e51 * Clean up keyboard input in ImGuiController Use the `_keyboard` field rather than retrieving the first keyboard from the input context in `UpdateImGuiInput()` as it gets reset every frame to `_input.Keyboards[0]` in `BeginFrame()`. * Upgrade ImGui.NET and remove `io.KeysDown` and `io.KeyMap` calls, and replace with the new `io.AddKeyEvent()` API. Also implemented `io.SetKeyEventNativeData()` to preserve legacy user code. * Minor formatting and code style improvements * Uncomment F13-F24 keycode translations now that ImGui.NET package has been upgraded. * Update ImGui.NET package in `Silk.NET.OpenGL.Legacy.Extensions.ImGui` and `Silk.NET.OpenGLES.Extensions.ImGui`. --- .../ImGuiController.cs | 211 ++++++++++++++---- .../Silk.NET.OpenGL.Extensions.ImGui.csproj | 2 +- ....NET.OpenGL.Legacy.Extensions.ImGui.csproj | 2 +- .../Silk.NET.OpenGLES.Extensions.ImGui.csproj | 2 +- 4 files changed, 173 insertions(+), 44 deletions(-) diff --git a/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs b/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs index be4251eb9c..ad1125287b 100644 --- a/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs +++ b/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs @@ -18,7 +18,6 @@ #endif using Silk.NET.Windowing; - #if GL namespace Silk.NET.OpenGL.Extensions.ImGui #elif GLES @@ -33,7 +32,7 @@ public class ImGuiController : IDisposable private IView _view; private IInputContext _input; private bool _frameBegun; - private readonly List _pressedChars = new List(); + private readonly List _pressedChars = new(); private IKeyboard _keyboard; private int _attribLocationTex; @@ -84,7 +83,7 @@ public ImGuiController(GL gl, IView view, IInputContext input, ImGuiFontConfig? var io = ImGuiNET.ImGui.GetIO(); if (imGuiFontConfig is not null) { - var glyphRange = imGuiFontConfig.Value.GetGlyphRange?.Invoke(io) ?? default(IntPtr); + var glyphRange = imGuiFontConfig.Value.GetGlyphRange?.Invoke(io) ?? default; io.Fonts.AddFontFromFileTTF(imGuiFontConfig.Value.FontPath, imGuiFontConfig.Value.FontSize, null, glyphRange); } @@ -94,7 +93,6 @@ public ImGuiController(GL gl, IView view, IInputContext input, ImGuiFontConfig? io.BackendFlags |= ImGuiBackendFlags.RendererHasVtxOffset; CreateDeviceResources(); - SetKeyMappings(); SetPerFrameImGuiData(1f / 60f); @@ -125,9 +123,44 @@ private void BeginFrame() _frameBegun = true; _keyboard = _input.Keyboards[0]; _view.Resize += WindowResized; + _keyboard.KeyDown += OnKeyDown; + _keyboard.KeyUp += OnKeyUp; _keyboard.KeyChar += OnKeyChar; } + /// + /// Delegate to receive keyboard key down events. + /// + /// The keyboard context generating the event. + /// The native keycode of the pressed key. + /// The native scancode of the pressed key. + private static void OnKeyDown(IKeyboard keyboard, Key keycode, int scancode) => + OnKeyEvent(keyboard, keycode, scancode, down: true); + + /// + /// Delegate to receive keyboard key up events. + /// + /// The keyboard context generating the event. + /// The native keycode of the released key. + /// The native scancode of the released key. + private static void OnKeyUp(IKeyboard keyboard, Key keycode, int scancode) => + OnKeyEvent(keyboard, keycode, scancode, down: false); + + /// + /// Delegate to receive keyboard key events. + /// + /// The keyboard context generating the event. + /// The native keycode of the key generating the event. + /// The native scancode of the key generating the event. + /// True if the event is a key down event, otherwise False + private static void OnKeyEvent(IKeyboard keyboard, Key keycode, int scancode, bool down) + { + var io = ImGuiNET.ImGui.GetIO(); + var imGuiKey = TranslateInputKeyToImGuiKey(keycode); + io.AddKeyEvent(imGuiKey, down); + io.SetKeyEventNativeData(imGuiKey, (int) keycode, scancode); + } + private void OnKeyChar(IKeyboard arg1, char arg2) { _pressedChars.Add(arg2); @@ -214,13 +247,11 @@ private void SetPerFrameImGuiData(float deltaSeconds) io.DeltaTime = deltaSeconds; // DeltaTime is in seconds. } - private static Key[] keyEnumArr = (Key[]) Enum.GetValues(typeof(Key)); private void UpdateImGuiInput() { var io = ImGuiNET.ImGui.GetIO(); var mouseState = _input.Mice[0].CaptureState(); - var keyboardState = _input.Keyboards[0]; io.MouseDown[0] = mouseState.IsButtonPressed(MouseButton.Left); io.MouseDown[1] = mouseState.IsButtonPressed(MouseButton.Right); @@ -233,15 +264,6 @@ private void UpdateImGuiInput() io.MouseWheel = wheel.Y; io.MouseWheelH = wheel.X; - foreach (var key in keyEnumArr) - { - if (key == Key.Unknown) - { - continue; - } - io.KeysDown[(int) key] = keyboardState.IsKeyPressed(key); - } - foreach (var c in _pressedChars) { io.AddInputCharacter(c); @@ -249,10 +271,10 @@ private void UpdateImGuiInput() _pressedChars.Clear(); - io.KeyCtrl = keyboardState.IsKeyPressed(Key.ControlLeft) || keyboardState.IsKeyPressed(Key.ControlRight); - io.KeyAlt = keyboardState.IsKeyPressed(Key.AltLeft) || keyboardState.IsKeyPressed(Key.AltRight); - io.KeyShift = keyboardState.IsKeyPressed(Key.ShiftLeft) || keyboardState.IsKeyPressed(Key.ShiftRight); - io.KeySuper = keyboardState.IsKeyPressed(Key.SuperLeft) || keyboardState.IsKeyPressed(Key.SuperRight); + io.KeyCtrl = _keyboard.IsKeyPressed(Key.ControlLeft) || _keyboard.IsKeyPressed(Key.ControlRight); + io.KeyAlt = _keyboard.IsKeyPressed(Key.AltLeft) || _keyboard.IsKeyPressed(Key.AltRight); + io.KeyShift = _keyboard.IsKeyPressed(Key.ShiftLeft) || _keyboard.IsKeyPressed(Key.ShiftRight); + io.KeySuper = _keyboard.IsKeyPressed(Key.SuperLeft) || _keyboard.IsKeyPressed(Key.SuperRight); } internal void PressChar(char keyChar) @@ -260,28 +282,135 @@ internal void PressChar(char keyChar) _pressedChars.Add(keyChar); } - private static void SetKeyMappings() + /// + /// Translates a Silk.NET.Input.Key to an ImGuiKey. + /// + /// The Silk.NET.Input.Key to translate. + /// The corresponding ImGuiKey. + /// When the key has not been implemented yet. + private static ImGuiKey TranslateInputKeyToImGuiKey(Key key) { - var io = ImGuiNET.ImGui.GetIO(); - io.KeyMap[(int) ImGuiKey.Tab] = (int) Key.Tab; - io.KeyMap[(int) ImGuiKey.LeftArrow] = (int) Key.Left; - io.KeyMap[(int) ImGuiKey.RightArrow] = (int) Key.Right; - io.KeyMap[(int) ImGuiKey.UpArrow] = (int) Key.Up; - io.KeyMap[(int) ImGuiKey.DownArrow] = (int) Key.Down; - io.KeyMap[(int) ImGuiKey.PageUp] = (int) Key.PageUp; - io.KeyMap[(int) ImGuiKey.PageDown] = (int) Key.PageDown; - io.KeyMap[(int) ImGuiKey.Home] = (int) Key.Home; - io.KeyMap[(int) ImGuiKey.End] = (int) Key.End; - io.KeyMap[(int) ImGuiKey.Delete] = (int) Key.Delete; - io.KeyMap[(int) ImGuiKey.Backspace] = (int) Key.Backspace; - io.KeyMap[(int) ImGuiKey.Enter] = (int) Key.Enter; - io.KeyMap[(int) ImGuiKey.Escape] = (int) Key.Escape; - io.KeyMap[(int) ImGuiKey.A] = (int) Key.A; - io.KeyMap[(int) ImGuiKey.C] = (int) Key.C; - io.KeyMap[(int) ImGuiKey.V] = (int) Key.V; - io.KeyMap[(int) ImGuiKey.X] = (int) Key.X; - io.KeyMap[(int) ImGuiKey.Y] = (int) Key.Y; - io.KeyMap[(int) ImGuiKey.Z] = (int) Key.Z; + return key switch + { + Key.Tab => ImGuiKey.Tab, + Key.Left => ImGuiKey.LeftArrow, + Key.Right => ImGuiKey.RightArrow, + Key.Up => ImGuiKey.UpArrow, + Key.Down => ImGuiKey.DownArrow, + Key.PageUp => ImGuiKey.PageUp, + Key.PageDown => ImGuiKey.PageDown, + Key.Home => ImGuiKey.Home, + Key.End => ImGuiKey.End, + Key.Insert => ImGuiKey.Insert, + Key.Delete => ImGuiKey.Delete, + Key.Backspace => ImGuiKey.Backspace, + Key.Space => ImGuiKey.Space, + Key.Enter => ImGuiKey.Enter, + Key.Escape => ImGuiKey.Escape, + Key.Apostrophe => ImGuiKey.Apostrophe, + Key.Comma => ImGuiKey.Comma, + Key.Minus => ImGuiKey.Minus, + Key.Period => ImGuiKey.Period, + Key.Slash => ImGuiKey.Slash, + Key.Semicolon => ImGuiKey.Semicolon, + Key.Equal => ImGuiKey.Equal, + Key.LeftBracket => ImGuiKey.LeftBracket, + Key.BackSlash => ImGuiKey.Backslash, + Key.RightBracket => ImGuiKey.RightBracket, + Key.GraveAccent => ImGuiKey.GraveAccent, + Key.CapsLock => ImGuiKey.CapsLock, + Key.ScrollLock => ImGuiKey.ScrollLock, + Key.NumLock => ImGuiKey.NumLock, + Key.PrintScreen => ImGuiKey.PrintScreen, + Key.Pause => ImGuiKey.Pause, + Key.Keypad0 => ImGuiKey.Keypad0, + Key.Keypad1 => ImGuiKey.Keypad1, + Key.Keypad2 => ImGuiKey.Keypad2, + Key.Keypad3 => ImGuiKey.Keypad3, + Key.Keypad4 => ImGuiKey.Keypad4, + Key.Keypad5 => ImGuiKey.Keypad5, + Key.Keypad6 => ImGuiKey.Keypad6, + Key.Keypad7 => ImGuiKey.Keypad7, + Key.Keypad8 => ImGuiKey.Keypad8, + Key.Keypad9 => ImGuiKey.Keypad9, + Key.KeypadDecimal => ImGuiKey.KeypadDecimal, + Key.KeypadDivide => ImGuiKey.KeypadDivide, + Key.KeypadMultiply => ImGuiKey.KeypadMultiply, + Key.KeypadSubtract => ImGuiKey.KeypadSubtract, + Key.KeypadAdd => ImGuiKey.KeypadAdd, + Key.KeypadEnter => ImGuiKey.KeypadEnter, + Key.KeypadEqual => ImGuiKey.KeypadEqual, + Key.ShiftLeft => ImGuiKey.LeftShift, + Key.ControlLeft => ImGuiKey.LeftCtrl, + Key.AltLeft => ImGuiKey.LeftAlt, + Key.SuperLeft => ImGuiKey.LeftSuper, + Key.ShiftRight => ImGuiKey.RightShift, + Key.ControlRight => ImGuiKey.RightCtrl, + Key.AltRight => ImGuiKey.RightAlt, + Key.SuperRight => ImGuiKey.RightSuper, + Key.Menu => ImGuiKey.Menu, + Key.Number0 => ImGuiKey._0, + Key.Number1 => ImGuiKey._1, + Key.Number2 => ImGuiKey._2, + Key.Number3 => ImGuiKey._3, + Key.Number4 => ImGuiKey._4, + Key.Number5 => ImGuiKey._5, + Key.Number6 => ImGuiKey._6, + Key.Number7 => ImGuiKey._7, + Key.Number8 => ImGuiKey._8, + Key.Number9 => ImGuiKey._9, + Key.A => ImGuiKey.A, + Key.B => ImGuiKey.B, + Key.C => ImGuiKey.C, + Key.D => ImGuiKey.D, + Key.E => ImGuiKey.E, + Key.F => ImGuiKey.F, + Key.G => ImGuiKey.G, + Key.H => ImGuiKey.H, + Key.I => ImGuiKey.I, + Key.J => ImGuiKey.J, + Key.K => ImGuiKey.K, + Key.L => ImGuiKey.L, + Key.M => ImGuiKey.M, + Key.N => ImGuiKey.N, + Key.O => ImGuiKey.O, + Key.P => ImGuiKey.P, + Key.Q => ImGuiKey.Q, + Key.R => ImGuiKey.R, + Key.S => ImGuiKey.S, + Key.T => ImGuiKey.T, + Key.U => ImGuiKey.U, + Key.V => ImGuiKey.V, + Key.W => ImGuiKey.W, + Key.X => ImGuiKey.X, + Key.Y => ImGuiKey.Y, + Key.Z => ImGuiKey.Z, + Key.F1 => ImGuiKey.F1, + Key.F2 => ImGuiKey.F2, + Key.F3 => ImGuiKey.F3, + Key.F4 => ImGuiKey.F4, + Key.F5 => ImGuiKey.F5, + Key.F6 => ImGuiKey.F6, + Key.F7 => ImGuiKey.F7, + Key.F8 => ImGuiKey.F8, + Key.F9 => ImGuiKey.F9, + Key.F10 => ImGuiKey.F10, + Key.F11 => ImGuiKey.F11, + Key.F12 => ImGuiKey.F12, + Key.F13 => ImGuiKey.F13, + Key.F14 => ImGuiKey.F14, + Key.F15 => ImGuiKey.F15, + Key.F16 => ImGuiKey.F16, + Key.F17 => ImGuiKey.F17, + Key.F18 => ImGuiKey.F18, + Key.F19 => ImGuiKey.F19, + Key.F20 => ImGuiKey.F20, + Key.F21 => ImGuiKey.F21, + Key.F22 => ImGuiKey.F22, + Key.F23 => ImGuiKey.F23, + Key.F24 => ImGuiKey.F24, + _ => throw new NotImplementedException(), + }; } private unsafe void SetupRenderState(ImDrawDataPtr drawDataPtr, int framebufferWidth, int framebufferHeight) @@ -477,6 +606,7 @@ private unsafe void RenderImDrawData(ImDrawDataPtr drawDataPtr) { _gl.Disable(GLEnum.DepthTest); } + if (lastEnableStencilTest) { _gl.Enable(GLEnum.StencilTest); @@ -569,7 +699,6 @@ void main() }"; #endif - string fragmentSource = #if GLES @"#version 300 es diff --git a/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/Silk.NET.OpenGL.Extensions.ImGui.csproj b/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/Silk.NET.OpenGL.Extensions.ImGui.csproj index 7ae70188b3..61860e993f 100644 --- a/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/Silk.NET.OpenGL.Extensions.ImGui.csproj +++ b/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/Silk.NET.OpenGL.Extensions.ImGui.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/OpenGL/Extensions/Silk.NET.OpenGL.Legacy.Extensions.ImGui/Silk.NET.OpenGL.Legacy.Extensions.ImGui.csproj b/src/OpenGL/Extensions/Silk.NET.OpenGL.Legacy.Extensions.ImGui/Silk.NET.OpenGL.Legacy.Extensions.ImGui.csproj index f8b1e4c5b3..2fb4d8c08f 100644 --- a/src/OpenGL/Extensions/Silk.NET.OpenGL.Legacy.Extensions.ImGui/Silk.NET.OpenGL.Legacy.Extensions.ImGui.csproj +++ b/src/OpenGL/Extensions/Silk.NET.OpenGL.Legacy.Extensions.ImGui/Silk.NET.OpenGL.Legacy.Extensions.ImGui.csproj @@ -24,7 +24,7 @@ - + diff --git a/src/OpenGL/Extensions/Silk.NET.OpenGLES.Extensions.ImGui/Silk.NET.OpenGLES.Extensions.ImGui.csproj b/src/OpenGL/Extensions/Silk.NET.OpenGLES.Extensions.ImGui/Silk.NET.OpenGLES.Extensions.ImGui.csproj index 8ccb5d35c6..c072ec26e7 100644 --- a/src/OpenGL/Extensions/Silk.NET.OpenGLES.Extensions.ImGui/Silk.NET.OpenGLES.Extensions.ImGui.csproj +++ b/src/OpenGL/Extensions/Silk.NET.OpenGLES.Extensions.ImGui/Silk.NET.OpenGLES.Extensions.ImGui.csproj @@ -23,7 +23,7 @@ - +