diff --git a/ClickableTransparentOverlay.sln b/ClickableTransparentOverlay.sln
index 1a56a0c..3d8e324 100644
--- a/ClickableTransparentOverlay.sln
+++ b/ClickableTransparentOverlay.sln
@@ -1,31 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.28307.168
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30128.36
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClickableTransparentOverlay", "ClickableTransparentOverlay\ClickableTransparentOverlay.csproj", "{F5CF8972-D0DA-4FC0-8796-E7C60101C8EA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClickableTransparentOverlay", "ClickableTransparentOverlay\ClickableTransparentOverlay.csproj", "{210EB536-2C1F-48C0-BE59-6C945FC3E1F2}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DriverProgram", "DriverProgram\DriverProgram.csproj", "{370E1945-EF74-4618-A2DE-B5796AC3093E}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DriverProgram", "DriverProgram\DriverProgram.csproj", "{8F05BC9C-06E7-49F8-8417-E2E24F07726A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Release|x64 = Release|x64
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {F5CF8972-D0DA-4FC0-8796-E7C60101C8EA}.Debug|x64.ActiveCfg = Debug|x64
- {F5CF8972-D0DA-4FC0-8796-E7C60101C8EA}.Debug|x64.Build.0 = Debug|x64
- {F5CF8972-D0DA-4FC0-8796-E7C60101C8EA}.Release|x64.ActiveCfg = Release|x64
- {F5CF8972-D0DA-4FC0-8796-E7C60101C8EA}.Release|x64.Build.0 = Release|x64
- {370E1945-EF74-4618-A2DE-B5796AC3093E}.Debug|x64.ActiveCfg = Debug|x64
- {370E1945-EF74-4618-A2DE-B5796AC3093E}.Debug|x64.Build.0 = Debug|x64
- {370E1945-EF74-4618-A2DE-B5796AC3093E}.Release|x64.ActiveCfg = Release|x64
- {370E1945-EF74-4618-A2DE-B5796AC3093E}.Release|x64.Build.0 = Release|x64
+ {210EB536-2C1F-48C0-BE59-6C945FC3E1F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {210EB536-2C1F-48C0-BE59-6C945FC3E1F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {210EB536-2C1F-48C0-BE59-6C945FC3E1F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {210EB536-2C1F-48C0-BE59-6C945FC3E1F2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8F05BC9C-06E7-49F8-8417-E2E24F07726A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8F05BC9C-06E7-49F8-8417-E2E24F07726A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8F05BC9C-06E7-49F8-8417-E2E24F07726A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8F05BC9C-06E7-49F8-8417-E2E24F07726A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {CC9A7790-CFC1-4D4F-AE2C-177A80D122C8}
+ SolutionGuid = {0CA675A0-B7AC-4B41-9E79-BFD0DD4F8285}
EndGlobalSection
EndGlobal
diff --git a/ClickableTransparentOverlay/Shaders/HLSL/imgui-frag.hlsl.bytes b/ClickableTransparentOverlay/Assets/HLSL/imgui-frag.hlsl.bytes
similarity index 100%
rename from ClickableTransparentOverlay/Shaders/HLSL/imgui-frag.hlsl.bytes
rename to ClickableTransparentOverlay/Assets/HLSL/imgui-frag.hlsl.bytes
diff --git a/ClickableTransparentOverlay/Shaders/HLSL/imgui-vertex.hlsl.bytes b/ClickableTransparentOverlay/Assets/HLSL/imgui-vertex.hlsl.bytes
similarity index 100%
rename from ClickableTransparentOverlay/Shaders/HLSL/imgui-vertex.hlsl.bytes
rename to ClickableTransparentOverlay/Assets/HLSL/imgui-vertex.hlsl.bytes
diff --git a/ClickableTransparentOverlay/ClickableTransparentOverlay.csproj b/ClickableTransparentOverlay/ClickableTransparentOverlay.csproj
index 864da1d..9b12ffc 100644
--- a/ClickableTransparentOverlay/ClickableTransparentOverlay.csproj
+++ b/ClickableTransparentOverlay/ClickableTransparentOverlay.csproj
@@ -1,147 +1,26 @@
-
-
-
+
+
- Debug
- AnyCPU
- {F5CF8972-D0DA-4FC0-8796-E7C60101C8EA}
- Library
- Properties
- ClickableTransparentOverlay
- ClickableTransparentOverlay
- v4.7.2
- 512
- true
-
-
+ netstandard2.0
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- AnyCPU
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
- true
- bin\x64\Debug\
- DEBUG;TRACE
- full
- x64
- prompt
- MinimumRecommendedRules.ruleset
- true
- false
- false
- bin\x64\Debug\ClickableTransparentOverlay.xml
-
-
- bin\x64\Release\
-
-
- true
- none
- x64
- prompt
- MinimumRecommendedRules.ruleset
- true
-
-
- Off
- bin\x64\Release\ClickableTransparentOverlay.xml
-
-
-
- ..\packages\MouseKeyHook.5.6.0\lib\net40\Gma.System.MouseKeyHook.dll
-
-
- ..\packages\ImGui.NET.1.75.0\lib\netstandard2.0\ImGui.NET.dll
-
-
- ..\packages\NativeLibraryLoader.1.0.12\lib\netstandard2.0\NativeLibraryLoader.dll
-
-
- ..\packages\SharpDX.4.2.0\lib\net45\SharpDX.dll
-
-
- ..\packages\SharpDX.Direct3D11.4.2.0\lib\net45\SharpDX.Direct3D11.dll
-
-
- ..\packages\SharpDX.DXGI.4.2.0\lib\net45\SharpDX.DXGI.dll
-
-
- ..\packages\SixLabors.Core.1.0.0-beta0007\lib\netstandard2.0\SixLabors.Core.dll
-
-
- ..\packages\SixLabors.ImageSharp.1.0.0-beta0006\lib\net472\SixLabors.ImageSharp.dll
-
-
-
- ..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll
-
-
-
- ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll
-
-
-
- ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
-
-
- ..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
-
-
-
-
- ..\packages\Veldrid.4.7.0\lib\netstandard2.0\Veldrid.dll
-
-
- ..\packages\Veldrid.ImageSharp.4.7.0\lib\netstandard2.0\Veldrid.ImageSharp.dll
-
-
- ..\packages\Veldrid.SDL2.4.7.0\lib\netstandard2.0\Veldrid.SDL2.dll
-
-
- ..\packages\Veldrid.StartupUtilities.4.7.0\lib\netstandard2.0\Veldrid.StartupUtilities.dll
-
-
+
-
-
-
-
-
+
+
+
-
-
-
-
-
+
+
+
-
-
+
+
+
+
+
+
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
-
\ No newline at end of file
+
+
diff --git a/ClickableTransparentOverlay/HookController.cs b/ClickableTransparentOverlay/HookController.cs
deleted file mode 100644
index 1220e8b..0000000
--- a/ClickableTransparentOverlay/HookController.cs
+++ /dev/null
@@ -1,470 +0,0 @@
-//
-// Copyright (c) Zaafar Ahmed. All rights reserved.
-//
-
-namespace ClickableTransparentOverlay
-{
- using System;
- using System.Collections.Generic;
- using System.Numerics;
- using System.Windows.Forms;
- using Gma.System.MouseKeyHook;
- using ImGuiNET;
-
- ///
- /// This class Hooks the Global Window Keyboard/Mouse events
- /// and pass them into the ImGui Overlay.
- ///
- /// NOTE: This class might miss/skip a Keyboard/Mouse event
- /// if ImGui render function takes a lot of time. Report on GitHub
- /// if that happens.
- ///
- public class HookController
- {
- private readonly Queue messages;
- private IKeyboardMouseEvents myHook;
- private bool enable;
- private int windowX;
- private int windowY;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// Transparent SDL2Window top left corner X axis.
- ///
- ///
- /// Transparent SDL2Window top left corner Y axis.
- ///
- public HookController(int x, int y)
- {
- this.messages = new Queue();
- this.windowX = x;
- this.windowY = y;
- this.enable = true;
- this.myHook = Hook.GlobalEvents();
- }
-
- private enum HookControllerMessageType
- {
- MouseUpDown,
- MouseMove,
- MouseWheel,
- KeyUp,
- KeyDown,
- KeyPress,
- }
-
- ///
- /// Enable this class functionality ( only call it once ).
- ///
- public void EnableHooks()
- {
- this.myHook.KeyDown += this.HookKeyDown;
- this.myHook.KeyUp += this.HookKeyUp;
- this.myHook.KeyPress += this.HookKeyPress;
-
- this.myHook.MouseDownExt += this.HookMouseDownExt;
- this.myHook.MouseMove += this.HookMouseMove;
- this.myHook.MouseUpExt += this.HookMouseUpExt;
-
- this.myHook.MouseWheelExt += this.HookMouseWheelExt;
- }
-
- ///
- /// Update transparent SDL2Window top left position.
- ///
- ///
- /// X axis of the SDL2Window top left corner.
- ///
- ///
- /// Y axis of the SDL2Window top left corner.
- ///
- public void UpdateWindowPosition(int x, int y)
- {
- this.windowX = x;
- this.windowY = y;
- }
-
- ///
- /// Pause the hooks.
- ///
- public void PauseHooks()
- {
- this.enable = false;
- }
-
- ///
- /// Resume the hooks.
- ///
- public void ResumeHooks()
- {
- this.enable = true;
- }
-
- ///
- /// Dispose the resources acquired by this class.
- ///
- public void Dispose()
- {
- this.myHook.KeyDown -= this.HookKeyDown;
- this.myHook.KeyUp -= this.HookKeyUp;
- this.myHook.KeyPress -= this.HookKeyPress;
-
- this.myHook.MouseDownExt -= this.HookMouseDownExt;
- this.myHook.MouseMove -= this.HookMouseMove;
- this.myHook.MouseUpExt -= this.HookMouseUpExt;
-
- this.myHook.MouseWheelExt -= this.HookMouseWheelExt;
- this.myHook.Dispose();
- this.messages.Clear();
- }
-
- ///
- /// Consumes all (max limit 10 to avoid infinite loop) the
- /// keyboard/mouse messages from the message queue.
- ///
- public void PopMessages()
- {
- int counter = 0;
- int maxCounter = 20;
- while (counter < maxCounter && this.messages.Count > 0)
- {
- var message = this.messages.Dequeue();
- try
- {
- switch (message.Type)
- {
- case HookControllerMessageType.MouseUpDown:
- this.ProcessMouseUpDown((MouseEventExtArgs)message.E, message.MiscArg, true);
- break;
- case HookControllerMessageType.MouseMove:
- this.ProcessMouseMove((MouseEventArgs)message.E, true);
- break;
- case HookControllerMessageType.MouseWheel:
- this.ProcessMouseWheel((MouseEventExtArgs)message.E, true);
- break;
- case HookControllerMessageType.KeyUp:
- this.ProcessKeyUp((KeyEventArgs)message.E, true);
- break;
- case HookControllerMessageType.KeyDown:
- this.ProcessKeyDown((KeyEventArgs)message.E, true);
- break;
- case HookControllerMessageType.KeyPress:
- this.ProcessKeyPress((KeyPressEventArgs)message.E, true);
- break;
- default:
- break;
- }
- }
- catch (Exception e)
- {
- Console.WriteLine("Warning: Caught an exception while handling keyboard/mouse inputs." +
- "Report to the GitHub repository if this effects your work & it's reproduceable.");
- Console.WriteLine(e.Message);
- Console.WriteLine(e.StackTrace);
- }
-
- counter++;
- }
- }
-
- ///
- /// Push the keyboard/mouse message to the message queue.
- ///
- ///
- /// Message Type.
- ///
- ///
- /// Message details.
- ///
- ///
- /// Only Mouse Up/Down hook uses this param to pass isDownEvent param.
- ///
- private void PushMessage(HookControllerMessageType type, EventArgs e, bool miscArg = false)
- {
- var message = new HookControllerMessage()
- {
- Type = type,
- E = e,
- MiscArg = miscArg,
- };
-
- this.messages.Enqueue(message);
- }
-
- private void ProcessMouseUpDown(MouseEventExtArgs e, bool isDownEvent, bool shouldSendToImGui)
- {
- ImGuiIOPtr io = ImGui.GetIO();
- if (shouldSendToImGui)
- {
- switch (e.Button)
- {
- case MouseButtons.Left:
- io.MouseDown[0] = isDownEvent;
- break;
- case MouseButtons.Right:
- io.MouseDown[1] = isDownEvent;
- break;
- case MouseButtons.Middle:
- io.MouseDown[2] = isDownEvent;
- break;
- case MouseButtons.XButton1:
- io.MouseDown[3] = isDownEvent;
- break;
- case MouseButtons.XButton2:
- io.MouseDown[4] = isDownEvent;
- break;
- case MouseButtons.None:
- // TODO: Find out what does this None mean
- break;
- default:
- // TODO: Make a Logger for the whole Overlay
- break;
- }
- }
- else
- {
- this.PushMessage(HookControllerMessageType.MouseUpDown, e, isDownEvent);
- }
-
- if (io.WantCaptureMouse)
- {
- e.Handled = true;
- }
- }
-
- private void ProcessMouseMove(MouseEventArgs e, bool shouldSendToImGui)
- {
- if (shouldSendToImGui)
- {
- ImGuiIOPtr io = ImGui.GetIO();
- io.MousePos = new Vector2(e.X - this.windowX, e.Y - this.windowY);
-
- // TODO: Show ImGUI Cursor/Hide ImGui Cursor
- // ImGui.GetIO().MouseDrawCursor = true;
- // Window32 API ShowCursor(false)
- }
- else
- {
- this.PushMessage(HookControllerMessageType.MouseMove, e);
- }
- }
-
- private void ProcessMouseWheel(MouseEventExtArgs e, bool shouldSendToImGui)
- {
- ImGuiIOPtr io = ImGui.GetIO();
- if (io.WantCaptureMouse)
- {
- if (shouldSendToImGui)
- {
- io.MouseWheel = e.Delta / SystemInformation.MouseWheelScrollDelta;
- }
- else
- {
- this.PushMessage(HookControllerMessageType.MouseWheel, e);
- }
-
- e.Handled = true;
- }
- }
-
- private void ProcessKeyUp(KeyEventArgs e, bool shouldSendToImGui)
- {
- if (shouldSendToImGui)
- {
- var io = ImGui.GetIO();
- io.KeysDown[e.KeyValue] = false;
-
- switch (e.KeyCode)
- {
- case Keys.LWin:
- case Keys.RWin:
- io.KeySuper = false;
- break;
- case Keys.LControlKey:
- case Keys.RControlKey:
- io.KeyCtrl = false;
- break;
- case Keys.LMenu:
- case Keys.RMenu:
- io.KeyAlt = false;
- break;
- case Keys.LShiftKey:
- case Keys.RShiftKey:
- io.KeyShift = false;
- break;
- default:
- break;
- }
- }
- else
- {
- this.PushMessage(HookControllerMessageType.KeyUp, e);
- }
- }
-
- private void ProcessKeyDown(KeyEventArgs e, bool shouldSendToImGui)
- {
- var io = ImGui.GetIO();
- if (io.WantCaptureKeyboard)
- {
- if (shouldSendToImGui)
- {
- io.KeysDown[e.KeyValue] = true;
- }
- else
- {
- this.PushMessage(HookControllerMessageType.KeyDown, e);
- }
-
- switch (e.KeyCode)
- {
- case Keys.LWin:
- case Keys.RWin:
- if (shouldSendToImGui)
- {
- io.KeySuper = true;
- }
-
- break;
- case Keys.LControlKey:
- case Keys.RControlKey:
- if (shouldSendToImGui)
- {
- io.KeyCtrl = true;
- }
-
- e.Handled = true;
- break;
- case Keys.LMenu: // LAlt is LMenu
- case Keys.RMenu: // RAlt is RMenu
- if (shouldSendToImGui)
- {
- io.KeyAlt = true;
- }
-
- break;
- case Keys.LShiftKey:
- case Keys.RShiftKey:
- if (shouldSendToImGui)
- {
- io.KeyShift = true;
- }
-
- break;
- default:
- // Ignoring ALT key so we can do ALT+TAB or ALT+F4 etc.
- // Not sure if ImGUI needs to use ALT+XXX key for anything.
- // Ignoring Capital/NumLock key so Windows can use it.
- // Ignoring Win/Super key so we can do Win+D or other stuff.
- // Create a new issue on the repo if I miss any important key.
- if (!io.KeyAlt && e.KeyCode != Keys.Capital && e.KeyCode != Keys.NumLock && !io.KeySuper &&
- e.KeyCode != Keys.PrintScreen && e.KeyCode != Keys.Print)
- {
- e.Handled = true;
- }
-
- break;
- }
- }
- }
-
- private void ProcessKeyPress(KeyPressEventArgs e, bool shouldSendToImGui)
- {
- var io = ImGui.GetIO();
-
- // Ignoring Win/Super key so we can do Win+D or other stuff
- // Ignoring ALT key so we can do ALT+TAB or ALT+F4 etc.
- // Not sure if ImGUI needs to use ALT+XXX or Super+XXX key for anything.
- if (io.KeySuper || io.KeyAlt)
- {
- return;
- }
-
- if (io.WantTextInput || io.WantCaptureKeyboard)
- {
- if (shouldSendToImGui)
- {
- io.AddInputCharacter(e.KeyChar);
- }
- else
- {
- this.PushMessage(HookControllerMessageType.KeyPress, e);
- }
-
- e.Handled = true;
- }
- }
-
- private void HookMouseUpExt(object sender, MouseEventExtArgs e)
- {
- if (this.enable)
- {
- this.ProcessMouseUpDown(e, false, false);
- }
- }
-
- private void HookMouseDownExt(object sender, MouseEventExtArgs e)
- {
- if (this.enable)
- {
- this.ProcessMouseUpDown(e, true, false);
- }
- }
-
- private void HookMouseMove(object sender, MouseEventArgs e)
- {
- if (!this.enable)
- {
- return;
- }
-
- this.ProcessMouseMove(e, false);
- }
-
- private void HookMouseWheelExt(object sender, MouseEventExtArgs e)
- {
- if (!this.enable)
- {
- return;
- }
-
- this.ProcessMouseWheel(e, false);
- }
-
- private void HookKeyUp(object sender, KeyEventArgs e)
- {
- this.ProcessKeyUp(e, true);
- }
-
- private void HookKeyDown(object sender, KeyEventArgs e)
- {
- if (!this.enable)
- {
- return;
- }
-
- this.ProcessKeyDown(e, true);
- }
-
- private void HookKeyPress(object sender, KeyPressEventArgs e)
- {
- if (!this.enable)
- {
- return;
- }
-
- this.ProcessKeyPress(e, false);
- }
-
- private struct HookControllerMessage
- {
- public HookControllerMessageType Type { get; set; }
-
- public EventArgs E { get; set; }
-
- public bool MiscArg { get; set; }
- }
- }
-}
diff --git a/ClickableTransparentOverlay/ImGuiController.cs b/ClickableTransparentOverlay/ImGuiController.cs
index 813eab6..8ac8482 100644
--- a/ClickableTransparentOverlay/ImGuiController.cs
+++ b/ClickableTransparentOverlay/ImGuiController.cs
@@ -1,151 +1,108 @@
-//
+using System;
+using System.Collections.Generic;
+using System.Numerics;
+using System.Reflection;
+using System.IO;
+using Veldrid;
+using System.Runtime.CompilerServices;
+using ImGuiNET;
+
namespace ClickableTransparentOverlay
{
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Numerics;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using ImGuiNET;
- using NativeLibraryLoader;
- using Veldrid;
-
///
- /// A modified version of ImGui.NET.SampleProgram's ImGuiController.
+ /// A modified version of Veldrid.ImGui's ImGuiRenderer.
/// Manages input for ImGui and handles rendering ImGui's DrawLists with Veldrid.
///
- public sealed class ImGuiController : IDisposable
+ public class ImGuiController : IDisposable
{
-#pragma warning disable CS0169 // Force Copy this DLL
- private readonly DefaultPathResolver useless;
-#pragma warning restore CS0169
+ private GraphicsDevice _gd;
+ private bool _frameBegun;
- private readonly IntPtr fontAtlasID = (IntPtr)1;
+ // Veldrid objects
+ private DeviceBuffer _vertexBuffer;
+ private DeviceBuffer _indexBuffer;
+ private DeviceBuffer _projMatrixBuffer;
+ private Texture _fontTexture;
+ private TextureView _fontTextureView;
+ private Shader _vertexShader;
+ private Shader _fragmentShader;
+ private ResourceLayout _layout;
+ private ResourceLayout _textureLayout;
+ private Pipeline _pipeline;
+ private ResourceSet _mainResourceSet;
+ private ResourceSet _fontTextureResourceSet;
+
+ private readonly IntPtr _fontAtlasID = (IntPtr)1;
+ private bool _controlDown;
+ private bool _shiftDown;
+ private bool _altDown;
+ private bool _winKeyDown;
+
+ private int _windowWidth;
+ private int _windowHeight;
+ private Vector2 _scaleFactor = Vector2.One;
// Image trackers
- private readonly Dictionary setsByView
+ private readonly Dictionary _setsByView
= new Dictionary();
-
- private readonly Dictionary autoViewsByTexture
+ private readonly Dictionary _autoViewsByTexture
= new Dictionary();
-
- private readonly Dictionary viewsById
- = new Dictionary();
-
- private readonly List ownedResources
- = new List();
-
- private int lastAssignedID = 100;
-
- private GraphicsDevice gd;
- private bool frameBegun;
-
- // Veldrid objects
- private DeviceBuffer vertexBuffer;
- private DeviceBuffer indexBuffer;
- private DeviceBuffer projMatrixBuffer;
- private Texture fontTexture;
- private TextureView fontTextureView;
- private Shader vertexShader;
- private Shader fragmentShader;
- private ResourceLayout layout;
- private ResourceLayout textureLayout;
- private Pipeline pipeline;
- private ResourceSet mainResourceSet;
- private ResourceSet fontTextureResourceSet;
-
- private int windowWidth;
- private int windowHeight;
- private Vector2 scaleFactor = Vector2.One;
+ private readonly Dictionary _viewsById = new Dictionary();
+ private readonly List _ownedResources = new List();
+ private int _lastAssignedID = 100;
///
- /// Initializes a new instance of the class.
+ /// Constructs a new ImGuiController.
///
- ///
- /// Graphic Device
- ///
- ///
- /// Output Description
- ///
- ///
- /// SDL2Window Window width
- ///
- ///
- /// SDL2Window Window height
- ///
- ///
- /// desired FPS of the ImGui Overlay
- ///
- public ImGuiController(GraphicsDevice gd, OutputDescription outputDescription, int width, int height, int fps)
+ public ImGuiController(GraphicsDevice gd, OutputDescription outputDescription, int width, int height)
{
- this.gd = gd;
- this.windowWidth = width;
- this.windowHeight = height;
+ _gd = gd;
+ _windowWidth = width;
+ _windowHeight = height;
IntPtr context = ImGui.CreateContext();
ImGui.SetCurrentContext(context);
-
ImGui.GetIO().Fonts.AddFontDefault();
- this.CreateDeviceResources(gd, outputDescription);
+ CreateDeviceResources(gd, outputDescription);
SetKeyMappings();
- this.SetPerFrameImGuiData(1f / fps);
+ SetPerFrameImGuiData(1f / 60f);
ImGui.NewFrame();
- this.frameBegun = true;
+ _frameBegun = true;
}
- ///
- /// Updates the ImGui about the SDL2Window Size
- ///
- ///
- /// Width of the SDL2Window
- ///
- ///
- /// Height of the SDL2Window
- ///
public void WindowResized(int width, int height)
{
- this.windowWidth = width;
- this.windowHeight = height;
+ _windowWidth = width;
+ _windowHeight = height;
}
- ///
- /// Disposes the resources acquired by the ImGuiController class.
- ///
public void DestroyDeviceObjects()
{
- this.Dispose();
+ Dispose();
}
- ///
- /// Initializes different resources for ImGui Controller class.
- ///
- ///
- /// Graphic Device
- ///
- ///
- /// Output Description
- ///
public void CreateDeviceResources(GraphicsDevice gd, OutputDescription outputDescription)
{
- this.gd = gd;
+ _gd = gd;
ResourceFactory factory = gd.ResourceFactory;
- this.vertexBuffer = factory.CreateBuffer(new BufferDescription(10000, BufferUsage.VertexBuffer | BufferUsage.Dynamic));
- this.vertexBuffer.Name = "ImGui.NET Vertex Buffer";
- this.indexBuffer = factory.CreateBuffer(new BufferDescription(2000, BufferUsage.IndexBuffer | BufferUsage.Dynamic));
- this.indexBuffer.Name = "ImGui.NET Index Buffer";
- this.RecreateFontDeviceTexture(gd);
-
- this.projMatrixBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
- this.projMatrixBuffer.Name = "ImGui.NET Projection Buffer";
-
- byte[] vertexShaderBytes = this.LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-vertex", ShaderStages.Vertex);
- byte[] fragmentShaderBytes = this.LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-frag", ShaderStages.Fragment);
- this.vertexShader = factory.CreateShader(new ShaderDescription(ShaderStages.Vertex, vertexShaderBytes, "VS"));
- this.fragmentShader = factory.CreateShader(new ShaderDescription(ShaderStages.Fragment, fragmentShaderBytes, "FS"));
+ _vertexBuffer = factory.CreateBuffer(new BufferDescription(10000, BufferUsage.VertexBuffer | BufferUsage.Dynamic));
+ _vertexBuffer.Name = "ImGui.NET Vertex Buffer";
+ _indexBuffer = factory.CreateBuffer(new BufferDescription(2000, BufferUsage.IndexBuffer | BufferUsage.Dynamic));
+ _indexBuffer.Name = "ImGui.NET Index Buffer";
+ RecreateFontDeviceTexture(gd);
+
+ _projMatrixBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
+ _projMatrixBuffer.Name = "ImGui.NET Projection Buffer";
+
+ byte[] vertexShaderBytes = LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-vertex", ShaderStages.Vertex);
+ byte[] fragmentShaderBytes = LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-frag", ShaderStages.Fragment);
+ _vertexShader = factory.CreateShader(new ShaderDescription(
+ ShaderStages.Vertex, vertexShaderBytes, _gd.BackendType == GraphicsBackend.Vulkan ? "main" : "VS"));
+ _fragmentShader = factory.CreateShader(new ShaderDescription(
+ ShaderStages.Fragment, fragmentShaderBytes, _gd.BackendType == GraphicsBackend.Vulkan ? "main" : "FS"));
VertexLayoutDescription[] vertexLayouts = new VertexLayoutDescription[]
{
@@ -155,10 +112,10 @@ namespace ClickableTransparentOverlay
new VertexElementDescription("in_color", VertexElementSemantic.Color, VertexElementFormat.Byte4_Norm))
};
- this.layout = factory.CreateResourceLayout(new ResourceLayoutDescription(
+ _layout = factory.CreateResourceLayout(new ResourceLayoutDescription(
new ResourceLayoutElementDescription("ProjectionMatrixBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex),
new ResourceLayoutElementDescription("MainSampler", ResourceKind.Sampler, ShaderStages.Fragment)));
- this.textureLayout = factory.CreateResourceLayout(new ResourceLayoutDescription(
+ _textureLayout = factory.CreateResourceLayout(new ResourceLayoutDescription(
new ResourceLayoutElementDescription("MainTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment)));
GraphicsPipelineDescription pd = new GraphicsPipelineDescription(
@@ -166,85 +123,96 @@ namespace ClickableTransparentOverlay
new DepthStencilStateDescription(false, false, ComparisonKind.Always),
new RasterizerStateDescription(FaceCullMode.None, PolygonFillMode.Solid, FrontFace.Clockwise, false, true),
PrimitiveTopology.TriangleList,
- new ShaderSetDescription(vertexLayouts, new[] { this.vertexShader, this.fragmentShader }),
- new ResourceLayout[] { this.layout, this.textureLayout },
- outputDescription);
- this.pipeline = factory.CreateGraphicsPipeline(ref pd);
+ new ShaderSetDescription(vertexLayouts, new[] { _vertexShader, _fragmentShader }),
+ new ResourceLayout[] { _layout, _textureLayout },
+ outputDescription,
+ ResourceBindingModel.Default);
+ _pipeline = factory.CreateGraphicsPipeline(ref pd);
- this.mainResourceSet = factory.CreateResourceSet(new ResourceSetDescription(
- this.layout, this.projMatrixBuffer, gd.PointSampler));
+ _mainResourceSet = factory.CreateResourceSet(new ResourceSetDescription(_layout,
+ _projMatrixBuffer,
+ gd.PointSampler));
- this.fontTextureResourceSet = factory.CreateResourceSet(
- new ResourceSetDescription(this.textureLayout, this.fontTextureView));
+ _fontTextureResourceSet = factory.CreateResourceSet(new ResourceSetDescription(_textureLayout, _fontTextureView));
}
///
/// Gets or creates a handle for a texture to be drawn with ImGui.
- /// Pass the returned handle to Image() or ImageButton().
+ /// E.G. Pass the returned handle to Image() or ImageButton().
///
- ///
- /// Resource Factory
- ///
- ///
- /// Texture View
- ///
- ///
- /// Creates ImGui Binding
- ///
public IntPtr GetOrCreateImGuiBinding(ResourceFactory factory, TextureView textureView)
{
- if (!this.setsByView.TryGetValue(textureView, out ResourceSetInfo rsi))
+ if (!_setsByView.TryGetValue(textureView, out ResourceSetInfo rsi))
{
- ResourceSet resourceSet = factory.CreateResourceSet(
- new ResourceSetDescription(this.textureLayout, textureView));
-
- rsi = new ResourceSetInfo(this.GetNextImGuiBindingID(), resourceSet);
+ ResourceSet resourceSet = factory.CreateResourceSet(new ResourceSetDescription(_textureLayout, textureView));
+ rsi = new ResourceSetInfo(GetNextImGuiBindingID(), resourceSet);
- this.setsByView.Add(textureView, rsi);
- this.viewsById.Add(rsi.ImGuiBinding, rsi);
- this.ownedResources.Add(resourceSet);
+ _setsByView.Add(textureView, rsi);
+ _viewsById.Add(rsi.ImGuiBinding, rsi);
+ _ownedResources.Add(resourceSet);
}
return rsi.ImGuiBinding;
}
+ ///
+ /// Removes the texture from the resources.
+ ///
+ /// texture to remove
+ public void RemoveImGuiBinding(TextureView textureView)
+ {
+ if (_setsByView.TryGetValue(textureView, out ResourceSetInfo rsi))
+ {
+ _setsByView.Remove(textureView);
+ _viewsById.Remove(rsi.ImGuiBinding);
+ _ownedResources.Remove(rsi.ResourceSet);
+ rsi.ResourceSet.Dispose();
+ }
+ }
+
+ ///
+ /// Removes the texture from the resources.
+ ///
+ /// texture to remove
+ public void RemoveImGuiBinding(Texture texture)
+ {
+ if (_autoViewsByTexture.TryGetValue(texture, out TextureView textureView))
+ {
+ _autoViewsByTexture.Remove(texture);
+ _ownedResources.Remove(textureView);
+ textureView.Dispose();
+ RemoveImGuiBinding(textureView);
+ }
+ }
+
+ private IntPtr GetNextImGuiBindingID()
+ {
+ int newID = _lastAssignedID++;
+ return (IntPtr)newID;
+ }
+
///
/// Gets or creates a handle for a texture to be drawn with ImGui.
/// Pass the returned handle to Image() or ImageButton().
///
- ///
- /// Resource Factory
- ///
- ///
- /// Texture information
- ///
- ///
- /// Pointer to the resource
- ///
public IntPtr GetOrCreateImGuiBinding(ResourceFactory factory, Texture texture)
{
- if (!this.autoViewsByTexture.TryGetValue(texture, out TextureView textureView))
+ if (!_autoViewsByTexture.TryGetValue(texture, out TextureView textureView))
{
textureView = factory.CreateTextureView(texture);
- this.autoViewsByTexture.Add(texture, textureView);
- this.ownedResources.Add(textureView);
+ _autoViewsByTexture.Add(texture, textureView);
+ _ownedResources.Add(textureView);
}
- return this.GetOrCreateImGuiBinding(factory, textureView);
+ return GetOrCreateImGuiBinding(factory, textureView);
}
///
/// Retrieves the shader texture binding for the given helper handle.
///
- ///
- /// ImGui Binding resource pointer.
- ///
- ///
- /// Resource
- ///
public ResourceSet GetImageResourceSet(IntPtr imGuiBinding)
{
- if (!this.viewsById.TryGetValue(imGuiBinding, out ResourceSetInfo tvi))
+ if (!_viewsById.TryGetValue(imGuiBinding, out ResourceSetInfo tvi))
{
throw new InvalidOperationException("No registered ImGui binding with id " + imGuiBinding.ToString());
}
@@ -252,52 +220,71 @@ namespace ClickableTransparentOverlay
return tvi.ResourceSet;
}
- ///
- /// Clears the cache images.
- ///
public void ClearCachedImageResources()
{
- foreach (IDisposable resource in this.ownedResources)
+ foreach (IDisposable resource in _ownedResources)
{
resource.Dispose();
}
- this.ownedResources.Clear();
- this.setsByView.Clear();
- this.viewsById.Clear();
- this.autoViewsByTexture.Clear();
- this.lastAssignedID = 100;
+ _ownedResources.Clear();
+ _setsByView.Clear();
+ _viewsById.Clear();
+ _autoViewsByTexture.Clear();
+ _lastAssignedID = 100;
+ }
+
+ private byte[] LoadEmbeddedShaderCode(ResourceFactory factory, string name, ShaderStages _)
+ {
+ switch (factory.BackendType)
+ {
+ case GraphicsBackend.Direct3D11:
+ {
+ string resourceName = name + ".hlsl.bytes";
+ return GetEmbeddedResourceBytes(resourceName);
+ }
+ default:
+ throw new NotImplementedException();
+ }
+ }
+
+ private byte[] GetEmbeddedResourceBytes(string resourceName)
+ {
+ Assembly assembly = typeof(ImGuiController).Assembly;
+ using (Stream s = assembly.GetManifestResourceStream(resourceName))
+ {
+ byte[] ret = new byte[s.Length];
+ s.Read(ret, 0, (int)s.Length);
+ return ret;
+ }
}
///
/// Recreates the device texture used to render text.
///
- ///
- /// Graphic Device
- ///
- public unsafe void RecreateFontDeviceTexture(GraphicsDevice gd)
+ public void RecreateFontDeviceTexture(GraphicsDevice gd)
{
ImGuiIOPtr io = ImGui.GetIO();
-
// Build
- byte* pixels;
- int width, height, bytesPerPixel;
- io.Fonts.GetTexDataAsRGBA32(out pixels, out width, out height, out bytesPerPixel);
-
+ io.Fonts.GetTexDataAsRGBA32(
+ out IntPtr pixels,
+ out int width,
+ out int height,
+ out int bytesPerPixel);
// Store our identifier
- io.Fonts.SetTexID(this.fontAtlasID);
+ io.Fonts.SetTexID(_fontAtlasID);
- this.fontTexture = gd.ResourceFactory.CreateTexture(TextureDescription.Texture2D(
+ _fontTexture = gd.ResourceFactory.CreateTexture(TextureDescription.Texture2D(
(uint)width,
(uint)height,
1,
1,
PixelFormat.R8_G8_B8_A8_UNorm,
TextureUsage.Sampled));
- this.fontTexture.Name = "ImGui.NET Font Texture";
+ _fontTexture.Name = "ImGui.NET Font Texture";
gd.UpdateTexture(
- this.fontTexture,
- (IntPtr)pixels,
+ _fontTexture,
+ pixels,
(uint)(bytesPerPixel * width * height),
0,
0,
@@ -307,7 +294,7 @@ namespace ClickableTransparentOverlay
1,
0,
0);
- this.fontTextureView = gd.ResourceFactory.CreateTextureView(this.fontTexture);
+ _fontTextureView = gd.ResourceFactory.CreateTextureView(_fontTexture);
io.Fonts.ClearTexData();
}
@@ -318,180 +305,150 @@ namespace ClickableTransparentOverlay
/// or index data has increased beyond the capacity of the existing buffers.
/// A is needed to submit drawing and resource update commands.
///
- ///
- /// Graphic Device
- ///
- ///
- /// Command List
- ///
public void Render(GraphicsDevice gd, CommandList cl)
{
- if (this.frameBegun)
+ if (_frameBegun)
{
- this.frameBegun = false;
+ _frameBegun = false;
ImGui.Render();
- this.RenderImDrawData(ImGui.GetDrawData(), gd, cl);
+ RenderImDrawData(ImGui.GetDrawData(), gd, cl);
}
}
///
- /// Initilizes a new frame
+ /// Updates ImGui input and IO configuration state.
///
- ///
- /// FPS delay
- ///
- public void InitlizeFrame(float deltaSeconds)
+ public void Update(float deltaSeconds, InputSnapshot snapshot, IntPtr handle)
{
- if (this.frameBegun)
+ if (_frameBegun)
{
ImGui.Render();
}
- this.SetPerFrameImGuiData(deltaSeconds);
+ SetPerFrameImGuiData(deltaSeconds);
+ UpdateImGuiInput(snapshot, handle);
- this.frameBegun = true;
+ _frameBegun = true;
ImGui.NewFrame();
}
///
- /// Frees all graphics resources used by the renderer.
+ /// Sets per-frame data based on the associated window.
+ /// This is called by Update(float).
///
- public void Dispose()
+ private void SetPerFrameImGuiData(float deltaSeconds)
{
- this.vertexBuffer.Dispose();
- this.indexBuffer.Dispose();
- this.projMatrixBuffer.Dispose();
- this.fontTexture.Dispose();
- this.fontTextureView.Dispose();
- this.vertexShader.Dispose();
- this.fragmentShader.Dispose();
- this.layout.Dispose();
- this.textureLayout.Dispose();
- this.pipeline.Dispose();
- this.mainResourceSet.Dispose();
- this.fontTextureResourceSet.Dispose();
- this.ClearCachedImageResources();
+ ImGuiIOPtr io = ImGui.GetIO();
+ io.DisplaySize = new Vector2(
+ _windowWidth / _scaleFactor.X,
+ _windowHeight / _scaleFactor.Y);
+ io.DisplayFramebufferScale = _scaleFactor;
+ io.DeltaTime = deltaSeconds; // DeltaTime is in seconds.
}
- ///
- /// Allows ImGui to identify the Keys
- ///
- private static void SetKeyMappings()
+ private void UpdateImGuiInput(InputSnapshot snapshot, IntPtr handle)
{
ImGuiIOPtr io = ImGui.GetIO();
- io.KeyMap[(int)ImGuiKey.Tab] = (int)System.Windows.Forms.Keys.Tab;
- io.KeyMap[(int)ImGuiKey.LeftArrow] = (int)System.Windows.Forms.Keys.Left;
- io.KeyMap[(int)ImGuiKey.RightArrow] = (int)System.Windows.Forms.Keys.Right;
- io.KeyMap[(int)ImGuiKey.UpArrow] = (int)System.Windows.Forms.Keys.Up;
- io.KeyMap[(int)ImGuiKey.DownArrow] = (int)System.Windows.Forms.Keys.Down;
- io.KeyMap[(int)ImGuiKey.PageUp] = (int)System.Windows.Forms.Keys.PageUp;
- io.KeyMap[(int)ImGuiKey.PageDown] = (int)System.Windows.Forms.Keys.PageDown;
- io.KeyMap[(int)ImGuiKey.Home] = (int)System.Windows.Forms.Keys.Home;
- io.KeyMap[(int)ImGuiKey.End] = (int)System.Windows.Forms.Keys.End;
- io.KeyMap[(int)ImGuiKey.Delete] = (int)System.Windows.Forms.Keys.Delete;
- io.KeyMap[(int)ImGuiKey.Backspace] = (int)System.Windows.Forms.Keys.Back;
- io.KeyMap[(int)ImGuiKey.Enter] = (int)System.Windows.Forms.Keys.Enter;
- io.KeyMap[(int)ImGuiKey.Escape] = (int)System.Windows.Forms.Keys.Escape;
-
- // io.KeyMap[(int)ImGuiKey.COUNT] = (int)System.Windows.Forms.Keys.un;
- io.KeyMap[(int)ImGuiKey.Insert] = (int)System.Windows.Forms.Keys.Insert;
- io.KeyMap[(int)ImGuiKey.Space] = (int)System.Windows.Forms.Keys.Space;
- io.KeyMap[(int)ImGuiKey.A] = (int)System.Windows.Forms.Keys.A;
- io.KeyMap[(int)ImGuiKey.C] = (int)System.Windows.Forms.Keys.C;
- io.KeyMap[(int)ImGuiKey.V] = (int)System.Windows.Forms.Keys.V;
- io.KeyMap[(int)ImGuiKey.X] = (int)System.Windows.Forms.Keys.X;
- io.KeyMap[(int)ImGuiKey.Y] = (int)System.Windows.Forms.Keys.Y;
- io.KeyMap[(int)ImGuiKey.Z] = (int)System.Windows.Forms.Keys.Z;
- }
- ///
- /// Get the Next ImGui Binding ID.
- ///
- ///
- /// ImGui next binding ID.
- ///
- private IntPtr GetNextImGuiBindingID()
- {
- int newID = this.lastAssignedID++;
- return (IntPtr)newID;
- }
+ // Determine if any of the mouse buttons were pressed during this snapshot period, even if they are no longer held.
+ bool leftPressed = false;
+ bool middlePressed = false;
+ bool rightPressed = false;
+ for (int i = 0; i < snapshot.MouseEvents.Count; i++)
+ {
+ MouseEvent me = snapshot.MouseEvents[i];
+ if (me.Down)
+ {
+ switch (me.MouseButton)
+ {
+ case MouseButton.Left:
+ leftPressed = true;
+ break;
+ case MouseButton.Middle:
+ middlePressed = true;
+ break;
+ case MouseButton.Right:
+ rightPressed = true;
+ break;
+ }
+ }
+ }
- ///
- /// Loading Shader Code
- ///
- ///
- /// Resource Factory
- ///
- ///
- /// Shader file name
- ///
- ///
- /// Shader stage
- ///
- ///
- /// Returns shader byte code
- ///
- private byte[] LoadEmbeddedShaderCode(ResourceFactory factory, string name, ShaderStages stage)
- {
- switch (factory.BackendType)
+ io.MouseDown[0] = leftPressed || snapshot.IsMouseDown(MouseButton.Left);
+ io.MouseDown[1] = rightPressed || snapshot.IsMouseDown(MouseButton.Right);
+ io.MouseDown[2] = middlePressed || snapshot.IsMouseDown(MouseButton.Middle);
+ io.MousePos = NativeMethods.GetCursorPosition(handle);
+ io.MouseWheel = snapshot.WheelDelta;
+
+ IReadOnlyList keyCharPresses = snapshot.KeyCharPresses;
+ for (int i = 0; i < keyCharPresses.Count; i++)
{
- case GraphicsBackend.Direct3D11:
- string resourceName = name + ".hlsl.bytes";
- return this.GetEmbeddedResourceBytes(resourceName);
- default:
- throw new NotImplementedException();
+ char c = keyCharPresses[i];
+ io.AddInputCharacter(c);
}
- }
- ///
- /// Get embedded resource file in bytes
- ///
- ///
- /// Name of the resource file
- ///
- ///
- /// Byte code of the resource file
- ///
- private byte[] GetEmbeddedResourceBytes(string resourceName)
- {
- Assembly assembly = typeof(ImGuiController).Assembly;
- using (Stream s = assembly.GetManifestResourceStream(resourceName))
+ IReadOnlyList keyEvents = snapshot.KeyEvents;
+ for (int i = 0; i < keyEvents.Count; i++)
{
- byte[] ret = new byte[s.Length];
- s.Read(ret, 0, (int)s.Length);
- return ret;
+ KeyEvent keyEvent = keyEvents[i];
+ io.KeysDown[(int)keyEvent.Key] = keyEvent.Down;
+ if (keyEvent.Key == Key.ControlLeft)
+ {
+ _controlDown = keyEvent.Down;
+ }
+ if (keyEvent.Key == Key.ShiftLeft)
+ {
+ _shiftDown = keyEvent.Down;
+ }
+ if (keyEvent.Key == Key.AltLeft)
+ {
+ _altDown = keyEvent.Down;
+ }
+ if (keyEvent.Key == Key.WinLeft)
+ {
+ _winKeyDown = keyEvent.Down;
+ }
+ }
+
+ io.KeyCtrl = _controlDown;
+ io.KeyAlt = _altDown;
+ io.KeyShift = _shiftDown;
+ io.KeySuper = _winKeyDown;
+
+ if (io.WantCaptureKeyboard || io.WantCaptureMouse)
+ {
+ NativeMethods.SetOverlayClickable(handle, true);
+ }
+ else
+ {
+ NativeMethods.SetOverlayClickable(handle, false);
}
}
- ///
- /// Sets per-frame data based on the associated window.
- /// This is called by Update(float).
- ///
- ///
- /// FPS delay
- ///
- private void SetPerFrameImGuiData(float deltaSeconds)
+ private static void SetKeyMappings()
{
ImGuiIOPtr io = ImGui.GetIO();
- io.DisplaySize = new Vector2(
- this.windowWidth / this.scaleFactor.X,
- this.windowHeight / this.scaleFactor.Y);
- io.DisplayFramebufferScale = this.scaleFactor;
- io.DeltaTime = deltaSeconds; // DeltaTime is in seconds.
+ 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;
}
- ///
- /// Draw the ImGui graphic data
- ///
- ///
- /// ImGui data to draw
- ///
- ///
- /// Graphic Device
- ///
- ///
- /// Command List
- ///
private void RenderImDrawData(ImDrawDataPtr draw_data, GraphicsDevice gd, CommandList cl)
{
uint vertexOffsetInVertices = 0;
@@ -503,19 +460,17 @@ namespace ClickableTransparentOverlay
}
uint totalVBSize = (uint)(draw_data.TotalVtxCount * Unsafe.SizeOf());
- if (totalVBSize > this.vertexBuffer.SizeInBytes)
+ if (totalVBSize > _vertexBuffer.SizeInBytes)
{
- gd.DisposeWhenIdle(this.vertexBuffer);
- this.vertexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription(
- (uint)(totalVBSize * 1.5f), BufferUsage.VertexBuffer | BufferUsage.Dynamic));
+ _vertexBuffer.Dispose();
+ _vertexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalVBSize * 1.5f), BufferUsage.VertexBuffer | BufferUsage.Dynamic));
}
uint totalIBSize = (uint)(draw_data.TotalIdxCount * sizeof(ushort));
- if (totalIBSize > this.indexBuffer.SizeInBytes)
+ if (totalIBSize > _indexBuffer.SizeInBytes)
{
- gd.DisposeWhenIdle(this.indexBuffer);
- this.indexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription(
- (uint)(totalIBSize * 1.5f), BufferUsage.IndexBuffer | BufferUsage.Dynamic));
+ _indexBuffer.Dispose();
+ _indexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalIBSize * 1.5f), BufferUsage.IndexBuffer | BufferUsage.Dynamic));
}
for (int i = 0; i < draw_data.CmdListsCount; i++)
@@ -523,13 +478,13 @@ namespace ClickableTransparentOverlay
ImDrawListPtr cmd_list = draw_data.CmdListsRange[i];
cl.UpdateBuffer(
- this.vertexBuffer,
+ _vertexBuffer,
vertexOffsetInVertices * (uint)Unsafe.SizeOf(),
cmd_list.VtxBuffer.Data,
(uint)(cmd_list.VtxBuffer.Size * Unsafe.SizeOf()));
cl.UpdateBuffer(
- this.indexBuffer,
+ _indexBuffer,
indexOffsetInElements * sizeof(ushort),
cmd_list.IdxBuffer.Data,
(uint)(cmd_list.IdxBuffer.Size * sizeof(ushort)));
@@ -548,12 +503,12 @@ namespace ClickableTransparentOverlay
-1.0f,
1.0f);
- this.gd.UpdateBuffer(this.projMatrixBuffer, 0, ref mvp);
+ _gd.UpdateBuffer(_projMatrixBuffer, 0, ref mvp);
- cl.SetVertexBuffer(0, this.vertexBuffer);
- cl.SetIndexBuffer(this.indexBuffer, IndexFormat.UInt16);
- cl.SetPipeline(this.pipeline);
- cl.SetGraphicsResourceSet(0, this.mainResourceSet);
+ cl.SetVertexBuffer(0, _vertexBuffer);
+ cl.SetIndexBuffer(_indexBuffer, IndexFormat.UInt16);
+ cl.SetPipeline(_pipeline);
+ cl.SetGraphicsResourceSet(0, _mainResourceSet);
draw_data.ScaleClipRects(io.DisplayFramebufferScale);
@@ -574,15 +529,13 @@ namespace ClickableTransparentOverlay
{
if (pcmd.TextureId != IntPtr.Zero)
{
- if (pcmd.TextureId == this.fontAtlasID)
+ if (pcmd.TextureId == _fontAtlasID)
{
- cl.SetGraphicsResourceSet(
- 1, this.fontTextureResourceSet);
+ cl.SetGraphicsResourceSet(1, _fontTextureResourceSet);
}
else
{
- cl.SetGraphicsResourceSet(
- 1, this.GetImageResourceSet(pcmd.TextureId));
+ cl.SetGraphicsResourceSet(1, GetImageResourceSet(pcmd.TextureId));
}
}
@@ -598,14 +551,30 @@ namespace ClickableTransparentOverlay
idx_offset += (int)pcmd.ElemCount;
}
-
vtx_offset += cmd_list.VtxBuffer.Size;
}
}
///
- /// ResourceSetInfo
+ /// Frees all graphics resources used by the renderer.
///
+ public void Dispose()
+ {
+ _vertexBuffer.Dispose();
+ _indexBuffer.Dispose();
+ _projMatrixBuffer.Dispose();
+ _fontTexture.Dispose();
+ _fontTextureView.Dispose();
+ _vertexShader.Dispose();
+ _fragmentShader.Dispose();
+ _layout.Dispose();
+ _textureLayout.Dispose();
+ _pipeline.Dispose();
+ _mainResourceSet.Dispose();
+ ClearCachedImageResources();
+ _fontTextureResourceSet.Dispose();
+ }
+
private struct ResourceSetInfo
{
public readonly IntPtr ImGuiBinding;
@@ -613,8 +582,8 @@ namespace ClickableTransparentOverlay
public ResourceSetInfo(IntPtr imGuiBinding, ResourceSet resourceSet)
{
- this.ImGuiBinding = imGuiBinding;
- this.ResourceSet = resourceSet;
+ ImGuiBinding = imGuiBinding;
+ ResourceSet = resourceSet;
}
}
}
diff --git a/ClickableTransparentOverlay/NativeMethods.cs b/ClickableTransparentOverlay/NativeMethods.cs
index 8f80b14..b410533 100644
--- a/ClickableTransparentOverlay/NativeMethods.cs
+++ b/ClickableTransparentOverlay/NativeMethods.cs
@@ -1,13 +1,10 @@
-//
-// Copyright (c) Zaafar Ahmed. All rights reserved.
-//
+using System;
+using System.Drawing;
+using System.Numerics;
+using System.Runtime.InteropServices;
namespace ClickableTransparentOverlay
{
- using System;
- using System.Drawing;
- using System.Runtime.InteropServices;
-
///
/// This class allow user to access Win32 API functions.
///
@@ -20,39 +17,107 @@ namespace ClickableTransparentOverlay
private const int SW_HIDE = 0x00;
private const int SW_SHOW = 0x05;
+ public static bool IsClickable = true;
+ private static IntPtr GWL_EXSTYLE_CLICKABLE = IntPtr.Zero;
+ private static IntPtr GWL_EXSTYLE_NOT_CLICKABLE = IntPtr.Zero;
+
+ private const int KEY_PRESSED = 0x8000;
+
///
/// Allows the SDL2Window to become transparent.
///
///
/// Veldrid window handle in IntPtr format.
///
- public static void EnableTransparent(IntPtr handle)
+ public static void InitTransparency(IntPtr handle)
{
- IntPtr windowLong = GetWindowLongPtr(handle, GWL_EXSTYLE);
- windowLong = new IntPtr(windowLong.ToInt64() | WS_EX_LAYERED | WS_EX_TRANSPARENT);
- SetWindowLongPtr(handle, GWL_EXSTYLE, windowLong);
+ GWL_EXSTYLE_CLICKABLE = GetWindowLongPtr(handle, GWL_EXSTYLE);
+ GWL_EXSTYLE_NOT_CLICKABLE = new IntPtr(
+ GWL_EXSTYLE_CLICKABLE.ToInt64() | WS_EX_LAYERED | WS_EX_TRANSPARENT);
+
Margins margins = Margins.FromRectangle(new Rectangle(-1, -1, -1, -1));
DwmExtendFrameIntoClientArea(handle, ref margins);
}
///
- /// Allows hiding the console window.
+ /// Enables (clickable) / Disables (not clickable) the SDL2Window keyboard/mouse inputs.
+ /// NOTE: This function depends on InitTransparency being called when the SDL2Winhdow was created.
+ ///
+ /// Veldrid window handle in IntPtr format.
+ /// Set to true if you want to make the window clickable otherwise false.
+ public static void SetOverlayClickable(IntPtr handle, bool WantClickable)
+ {
+ if (!IsClickable && WantClickable)
+ {
+ SetWindowLongPtr(handle, GWL_EXSTYLE, GWL_EXSTYLE_CLICKABLE);
+ SetFocus(handle);
+ IsClickable = true;
+ }
+ else if(IsClickable && !WantClickable)
+ {
+ SetWindowLongPtr(handle, GWL_EXSTYLE, GWL_EXSTYLE_NOT_CLICKABLE);
+ IsClickable = false;
+ }
+ }
+
+ ///
+ /// Allows showing/hiding the console window.
+ ///
+ public static void SetConsoleWindow(bool visiable)
+ {
+ if (visiable)
+ {
+ var handle = GetConsoleWindow();
+ ShowWindow(handle, SW_SHOW);
+ }
+ else
+ {
+ var handle = GetConsoleWindow();
+ ShowWindow(handle, SW_HIDE);
+ }
+ }
+
+ ///
+ /// Returns the current mouse position w.r.t the window in Vector2 format.
+ /// Also, returns Zero in case of any errors.
///
- public static void HideConsoleWindow()
+ ///
+ ///
+ public static Vector2 GetCursorPosition(IntPtr hWnd)
{
- var handle = GetConsoleWindow();
- ShowWindow(handle, SW_HIDE);
+ if (GetCursorPos(out var lpPoint))
+ {
+ ScreenToClient(hWnd, ref lpPoint);
+ return lpPoint;
+ }
+
+ return Vector2.Zero;
}
///
- /// Allows displaying the console window.
+ /// Returns true if the key is pressed.
+ /// For keycode information visit: https://www.pinvoke.net/default.aspx/user32.getkeystate
///
- public static void ShowConsoleWindow()
+ /// key to look for.
+ /// weather the key is pressed or not.
+ public static bool isKeyPressed(int nVirtKey)
{
- var handle = GetConsoleWindow();
- ShowWindow(handle, SW_SHOW);
+ return Convert.ToBoolean(GetKeyState(nVirtKey) & KEY_PRESSED);
}
+ [DllImport("USER32.dll")]
+ static extern short GetKeyState(int nVirtKey);
+
+ [DllImport("user32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ static extern bool GetCursorPos(out POINT lpPoint);
+
+ [DllImport("user32.dll")]
+ static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
+
+ [DllImport("user32.dll", SetLastError = true)]
+ static extern IntPtr SetFocus(IntPtr hWnd);
+
[DllImport("dwmapi.dll")]
private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMarInset);
@@ -88,5 +153,28 @@ namespace ClickableTransparentOverlay
return margins;
}
}
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct POINT
+ {
+ public int X;
+ public int Y;
+
+ public POINT(int x, int y)
+ {
+ this.X = x;
+ this.Y = y;
+ }
+
+ public static implicit operator Point(POINT p)
+ {
+ return new Point(p.X, p.Y);
+ }
+
+ public static implicit operator Vector2(POINT p)
+ {
+ return new Vector2(p.X, p.Y);
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/ClickableTransparentOverlay/Overlay.cs b/ClickableTransparentOverlay/Overlay.cs
index e91c95a..716d619 100644
--- a/ClickableTransparentOverlay/Overlay.cs
+++ b/ClickableTransparentOverlay/Overlay.cs
@@ -1,42 +1,28 @@
-//
-// Copyright (c) Zaafar Ahmed. All rights reserved.
-//
+using System;
+using System.Collections.Generic;
+using System.Numerics;
+using System.Threading;
+using Coroutine;
+using Veldrid;
+using Veldrid.ImageSharp;
+using Veldrid.Sdl2;
+using Veldrid.StartupUtilities;
namespace ClickableTransparentOverlay
{
- using System;
- using System.Collections.Generic;
- using System.Numerics;
- using System.Threading;
- using System.Windows.Forms;
- using Veldrid;
- using Veldrid.ImageSharp;
- using Veldrid.Sdl2;
- using Veldrid.StartupUtilities;
-
+ // TODO: Implement overlay info, warn, error logger.
///
/// A class to create clickable transparent overlay.
///
- public class Overlay
+ public static class Overlay
{
- private static Sdl2Window window;
- private static GraphicsDevice graphicsDevice;
- private static CommandList commandList;
- private static ImGuiController imController;
- private static HookController hookController;
- private static Thread uiThread;
-
- // UI State
- private static Vector4 clearColor;
- private static int myFps;
- private static bool isClosed;
- private static Dictionary loadedImages;
-
- // For Resizing SDL2Window
- private static Vector2 futurePos;
- private static Vector2 futureSize;
- private static bool requireResize;
- private static bool debugMode;
+ private readonly static Sdl2Window window;
+ private readonly static GraphicsDevice graphicsDevice;
+ private readonly static CommandList commandList;
+ private readonly static ImGuiController imController;
+ private readonly static Vector4 clearColor;
+ private readonly static Dictionary loadedImages;
+ private static bool terminal = true;
///
/// Initializes a new instance of the class.
@@ -59,149 +45,139 @@ namespace ClickableTransparentOverlay
///
/// In this mode, overlay will not hide the Console.
///
- public Overlay(int x, int y, int width, int height, int fps, bool debug)
+ static Overlay()
{
- loadedImages = new Dictionary();
clearColor = new Vector4(0.00f, 0.00f, 0.00f, 0.00f);
- myFps = fps;
- isClosed = false;
- debugMode = debug;
-
- // Stuff related to (thread safe) resizing of SDL2Window
- requireResize = false;
- futureSize = Vector2.Zero;
- futurePos = Vector2.Zero;
-
- window = new Sdl2Window("Overlay", x, y, width, height, SDL_WindowFlags.Borderless | SDL_WindowFlags.AlwaysOnTop | SDL_WindowFlags.SkipTaskbar, false);
- graphicsDevice = VeldridStartup.CreateGraphicsDevice(window, new GraphicsDeviceOptions(true, null, true), GraphicsBackend.Direct3D11);
-
- // graphicsDevice = VeldridStartup.CreateDefaultD3D11GraphicsDevice(new GraphicsDeviceOptions(true, null, true), window);
- NativeMethods.EnableTransparent(window.Handle);
+ loadedImages = new Dictionary();
+ window = new Sdl2Window(
+ "Overlay",
+ 0,
+ 0,
+ 2560,
+ 1440,
+ SDL_WindowFlags.Borderless |
+ SDL_WindowFlags.AlwaysOnTop |
+ SDL_WindowFlags.SkipTaskbar,
+ false);
+ graphicsDevice = VeldridStartup.CreateDefaultD3D11GraphicsDevice(
+ new GraphicsDeviceOptions(false, null, true),
+ window);
+ commandList = graphicsDevice.ResourceFactory.CreateCommandList();
+ imController = new ImGuiController(
+ graphicsDevice,
+ graphicsDevice.MainSwapchain.Framebuffer.OutputDescription,
+ window.Width,
+ window.Height);
window.Resized += () =>
{
graphicsDevice.MainSwapchain.Resize((uint)window.Width, (uint)window.Height);
imController.WindowResized(window.Width, window.Height);
- futureSize = Vector2.Zero;
- futurePos = Vector2.Zero;
- requireResize = false;
- };
- window.Closed += () =>
- {
- isClosed = true;
};
- commandList = graphicsDevice.ResourceFactory.CreateCommandList();
- imController = new ImGuiController(graphicsDevice, graphicsDevice.MainSwapchain.Framebuffer.OutputDescription, window.Width, window.Height, myFps);
- uiThread = new Thread(this.WhileLoop);
- hookController = new HookController(window.X, window.Y);
+ NativeMethods.InitTransparency(window.Handle);
+ NativeMethods.SetOverlayClickable(window.Handle, false);
}
- ///
- /// To submit ImGui code for generating the UI.
- ///
- public event EventHandler SubmitUI;
-
- ///
- /// Starts the overlay.
- ///
- public void Run()
+ public static void RunInfiniteLoop()
{
- uiThread.Start();
- hookController.EnableHooks();
- if (!debugMode)
+ DateTime previous = DateTime.Now;
+ DateTime current;
+ TimeSpan interval;
+ float sec;
+ while (window.Exists && !Close)
{
- NativeMethods.HideConsoleWindow();
+ InputSnapshot snapshot = window.PumpEvents();
+ if (!window.Exists) { break; }
+ current = DateTime.Now;
+ interval = current - previous;
+ sec = (float)interval.TotalSeconds;
+ previous = current;
+ imController.Update(sec > 0 ? sec : 0.001f, snapshot, window.Handle);
+ CoroutineHandler.Tick(interval.TotalSeconds);
+ if (Visible)
+ {
+ CoroutineHandler.RaiseEvent(OnRender);
+ }
+
+ commandList.Begin();
+ commandList.SetFramebuffer(graphicsDevice.MainSwapchain.Framebuffer);
+ commandList.ClearColorTarget(0, new RgbaFloat(clearColor.X, clearColor.Y, clearColor.Z, clearColor.W));
+ imController.Render(graphicsDevice, commandList);
+ commandList.End();
+ graphicsDevice.SubmitCommands(commandList);
+ graphicsDevice.SwapBuffers(graphicsDevice.MainSwapchain);
}
- Application.Run(new ApplicationContext());
+ Dispose();
}
///
- /// Set the overlay FPS.
+ /// To submit ImGui code for generating the UI.
///
- ///
- /// FPS to set.
- ///
- public void SetFps(int fps)
- {
- myFps = fps;
- }
+ public static Event OnRender = new Event();
///
- /// Resizes the overlay.
+ /// Safely Closes the Overlay.
+ /// Doesn't matter if you set it to true multiple times.
///
- ///
- /// x axis of the overlay.
- ///
- ///
- /// y axis of the overlay.
- ///
- ///
- /// width of the overlay.
- ///
- ///
- /// height of the overlay.
- ///
- public void Resize(int x, int y, int width, int height)
- {
- futurePos.X = x;
- futurePos.Y = y;
- futureSize.X = width;
- futureSize.Y = height;
-
- // TODO: move following two lines to _window.Moved
- hookController.UpdateWindowPosition(x, y);
- NativeMethods.EnableTransparent(window.Handle);
- requireResize = true;
- }
+ public static bool Close { get; set; } = false;
///
- /// Shows the overlay.
+ /// Makes the overlay visible or invisible. Invisible Overlay
+ /// will not call OnRender coroutines, however time based
+ /// coroutines are still called.
///
- public void Show()
+ public static bool Visible { get; set; } = true;
+
+ public static bool TerminalWindow
{
- hookController.ResumeHooks();
- window.Visible = true;
+ get => terminal;
+ set
+ {
+ if (value != terminal)
+ {
+ NativeMethods.SetConsoleWindow(value);
+ }
+
+ terminal = value;
+ }
}
///
- /// hides the overlay.
+ /// Gets or sets the position of the overlay window.
///
- public void Hide()
+ public static Point Position
{
- hookController.PauseHooks();
- window.Visible = false;
+ get
+ {
+ return new Point(window.X, window.Y);
+ }
+ set
+ {
+ Sdl2Native.SDL_SetWindowPosition(window.SdlWindowHandle, value.X, value.Y);
+ }
}
///
- /// Free all resources acquired by the overlay.
+ /// Gets or sets the size of the overlay window.
///
- public void Dispose()
+ public static Point Size
{
- window.Close();
- while (!isClosed)
+ get
{
- Thread.Sleep(10);
+ return new Point(window.Width, window.Height);
+ }
+ set
+ {
+ Sdl2Native.SDL_SetWindowSize(window.SdlWindowHandle, value.X, value.Y);
}
-
- uiThread.Join();
- graphicsDevice.WaitForIdle();
- imController.Dispose();
- commandList.Dispose();
- graphicsDevice.Dispose();
- hookController.Dispose();
- NativeMethods.ShowConsoleWindow();
- this.SubmitUI = null;
- loadedImages.Clear();
- Console.WriteLine("All Overlay resources are cleared.");
- Application.Exit();
}
///
/// Adds the image to the Graphic Device as a texture.
/// Then returns the pointer of the added texture. It also
/// cache the image internally rather than creating a new texture on every call,
- /// so this function can be called multiple times per image (per FPS).
+ /// so this function can be called multiple times per frame.
///
///
/// Path to the image on disk. If the image is loaded in the memory
@@ -211,7 +187,7 @@ namespace ClickableTransparentOverlay
///
/// A pointer to the Texture in the Graphic Device.
///
- public IntPtr AddOrGetImagePointer(string filePath)
+ public static IntPtr AddOrGetImagePointer(string filePath)
{
if (!loadedImages.TryGetValue(filePath, out Texture texture))
{
@@ -224,43 +200,34 @@ namespace ClickableTransparentOverlay
}
///
- /// Infinite While Loop to render the ImGui.
+ /// Gets or sets the overlay clickable feature.
///
- private void WhileLoop()
+ public static bool Clickable
{
- while (window.Exists)
+ get => NativeMethods.IsClickable;
+ set
{
- if (requireResize)
- {
- Sdl2Native.SDL_SetWindowPosition(window.SdlWindowHandle, (int)futurePos.X, (int)futurePos.Y);
- Sdl2Native.SDL_SetWindowSize(window.SdlWindowHandle, (int)futureSize.X, (int)futureSize.Y);
- window.PumpEvents();
- continue;
- }
-
- if (!window.Visible)
- {
- window.PumpEvents();
- Thread.Sleep(10);
- continue;
- }
-
- hookController.PopMessages();
- if (!window.Exists)
- {
- break;
- }
+ NativeMethods.SetOverlayClickable(window.Handle, value);
+ }
+ }
- imController.InitlizeFrame(1f / myFps);
- this.SubmitUI?.Invoke(this, new EventArgs());
- commandList.Begin();
- commandList.SetFramebuffer(graphicsDevice.MainSwapchain.Framebuffer);
- commandList.ClearColorTarget(0, new RgbaFloat(clearColor.X, clearColor.Y, clearColor.Z, clearColor.W));
- imController.Render(graphicsDevice, commandList);
- commandList.End();
- graphicsDevice.SubmitCommands(commandList);
- graphicsDevice.SwapBuffers(graphicsDevice.MainSwapchain);
+ ///
+ /// Free all resources acquired by the overlay.
+ ///
+ private static void Dispose()
+ {
+ window.Close();
+ while (window.Exists)
+ {
+ Thread.Sleep(1);
}
+
+ graphicsDevice.WaitForIdle();
+ imController.Dispose();
+ commandList.Dispose();
+ graphicsDevice.Dispose();
+ loadedImages.Clear();
+ NativeMethods.SetConsoleWindow(true);
}
}
}
diff --git a/ClickableTransparentOverlay/Properties/AssemblyInfo.cs b/ClickableTransparentOverlay/Properties/AssemblyInfo.cs
deleted file mode 100644
index 42b9748..0000000
--- a/ClickableTransparentOverlay/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// Copyright (c) Zaafar Ahmed. All rights reserved.
-//
-
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ClickableTransparentOverlay")]
-[assembly: AssemblyDescription("A library for creating clickable transparent overlay")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ClickableTransparentOverlay")]
-[assembly: AssemblyCopyright("Copyright © 2019")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(true)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("f5cf8972-d0da-4fc0-8796-e7c60101c8ea")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/ClickableTransparentOverlay/Shaders/HLSL/imgui-frag.hlsl b/ClickableTransparentOverlay/Shaders/HLSL/imgui-frag.hlsl
deleted file mode 100644
index 63d175f..0000000
--- a/ClickableTransparentOverlay/Shaders/HLSL/imgui-frag.hlsl
+++ /dev/null
@@ -1,15 +0,0 @@
-struct PS_INPUT
-{
- float4 pos : SV_POSITION;
- float4 col : COLOR0;
- float2 uv : TEXCOORD0;
-};
-
-Texture2D FontTexture : register(t0);
-sampler FontSampler : register(s0);
-
-float4 FS(PS_INPUT input) : SV_Target
-{
- float4 out_col = input.col * FontTexture.Sample(FontSampler, input.uv);
- return out_col;
-}
\ No newline at end of file
diff --git a/ClickableTransparentOverlay/Shaders/HLSL/imgui-vertex.hlsl b/ClickableTransparentOverlay/Shaders/HLSL/imgui-vertex.hlsl
deleted file mode 100644
index 55793c1..0000000
--- a/ClickableTransparentOverlay/Shaders/HLSL/imgui-vertex.hlsl
+++ /dev/null
@@ -1,27 +0,0 @@
-cbuffer ProjectionMatrixBuffer : register(b0)
-{
- float4x4 ProjectionMatrix;
-};
-
-struct VS_INPUT
-{
- float2 pos : POSITION;
- float2 uv : TEXCOORD0;
- float4 col : COLOR0;
-};
-
-struct PS_INPUT
-{
- float4 pos : SV_POSITION;
- float4 col : COLOR0;
- float2 uv : TEXCOORD0;
-};
-
-PS_INPUT VS(VS_INPUT input)
-{
- PS_INPUT output;
- output.pos = mul(ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));
- output.col = input.col;
- output.uv = input.uv;
- return output;
-}
\ No newline at end of file
diff --git a/ClickableTransparentOverlay/app.config b/ClickableTransparentOverlay/app.config
deleted file mode 100644
index a89fbba..0000000
--- a/ClickableTransparentOverlay/app.config
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ClickableTransparentOverlay/packages.config b/ClickableTransparentOverlay/packages.config
deleted file mode 100644
index 076e1c5..0000000
--- a/ClickableTransparentOverlay/packages.config
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ClickableTransparentOverlay/stylecop.json b/ClickableTransparentOverlay/stylecop.json
deleted file mode 100644
index 81fde14..0000000
--- a/ClickableTransparentOverlay/stylecop.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- // ACTION REQUIRED: This file was automatically added to your project, but it
- // will not take effect until additional steps are taken to enable it. See the
- // following page for additional information:
- //
- // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
-
- "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
- "settings": {
- "documentationRules": {
- "companyName": "Zaafar Ahmed"
- }
- }
-}
diff --git a/DriverProgram/App.config b/DriverProgram/App.config
deleted file mode 100644
index 962ed6c..0000000
--- a/DriverProgram/App.config
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/DriverProgram/DriverProgram.csproj b/DriverProgram/DriverProgram.csproj
index fbfceb0..054d916 100644
--- a/DriverProgram/DriverProgram.csproj
+++ b/DriverProgram/DriverProgram.csproj
@@ -1,104 +1,18 @@
-
-
-
+
+
- Debug
- AnyCPU
- {370E1945-EF74-4618-A2DE-B5796AC3093E}
Exe
- DriverProgram
- OverlayDemo
- v4.7.2
- 512
- true
- true
-
-
+ netcoreapp3.1
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- false
-
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
- true
- bin\x64\Debug\
- DEBUG;TRACE
- full
- x64
- prompt
- MinimumRecommendedRules.ruleset
- true
- false
-
-
- bin\x64\Release\
-
-
- true
- none
- x64
- prompt
- MinimumRecommendedRules.ruleset
- false
- true
-
-
- Off
-
-
-
-
-
+
-
-
+
+
-
- {f5cf8972-d0da-4fc0-8796-e7c60101c8ea}
- ClickableTransparentOverlay
-
-
-
-
- ..\packages\ImGui.NET.1.75.0\lib\netstandard2.0\ImGui.NET.dll
-
-
-
- ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
-
-
-
-
+
PreserveNewest
-
-
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
\ No newline at end of file
+
+
diff --git a/DriverProgram/Program.cs b/DriverProgram/Program.cs
index 1420f6e..bf4f42a 100644
--- a/DriverProgram/Program.cs
+++ b/DriverProgram/Program.cs
@@ -1,123 +1,167 @@
-namespace DriverProgram
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Numerics;
+using ClickableTransparentOverlay;
+using Coroutine;
+using ImGuiNET;
+
+namespace DriverProgram
{
- using ClickableTransparentOverlay;
- using ImGuiNET;
- using System;
- using System.IO;
- using System.Numerics;
- using System.Threading;
-
class Program
{
- private static bool isRunning = true;
- private static bool showImGuiDemo = false;
-
- private static bool drawOnScreen = false;
- private static Random randomGen = new Random();
- private static int totalCircles = 10;
- private static Vector2[] circleCenters = new Vector2[totalCircles];
+ public static bool showClickableMenu = true;
+ public static bool showOverlaySample1 = true;
+ public static bool showOverlaySample2 = false;
+ public static bool showImGuiDemo = false;
- private static int Fps = 144;
private static int[] resizeHelper = new int[4] { 0, 0, 2560, 1440 };
- private static int seconds = 5;
- private static Overlay overlay = new Overlay(0, 0, 2560, 1440, Fps, true);
- private static void MainApplicationLogic()
- {
- while (isRunning)
- {
- for (int i = 0; i < circleCenters.Length; i++)
- {
- circleCenters[i].X = randomGen.Next(0, 2560);
- circleCenters[i].Y = randomGen.Next(0, 1440);
- }
- Thread.Sleep(600);
- }
+ private static int seconds = 5;
- overlay.Dispose();
- }
+ private static Random randomGen = new Random();
+ private static Vector2[] circleCenters = new Vector2[200];
- static void Main(string[] args)
+ static void Main()
{
- overlay.SubmitUI += RenderUi;
- Thread p = new Thread(MainApplicationLogic);
- p.Start();
- overlay.Run();
- p.Join();
+ CoroutineHandler.Start(UpdateOverlaySample2());
+ CoroutineHandler.Start(SubmitRenderLogic());
+ Overlay.RunInfiniteLoop();
}
- private static void RenderUi(object sender, System.EventArgs e)
+ private static IEnumerator SubmitRenderLogic()
{
- if(isRunning)
+ while (true)
{
- ImGui.Begin("Overlay Config", ref isRunning, ImGuiWindowFlags.NoResize | ImGuiWindowFlags.AlwaysAutoResize);
-
- if (ImGui.SliderInt("Set FPS", ref Fps, 30, 144))
- {
- overlay.SetFps(Fps);
- }
+ yield return new WaitEvent(Overlay.OnRender);
- ImGui.NewLine();
- ImGui.SliderInt2("Set Position", ref resizeHelper[0], 0, 3840);
- ImGui.SliderInt2("Set Size", ref resizeHelper[2], 0, 3840);
- if (ImGui.Button("Resize"))
+ if (NativeMethods.isKeyPressed(0x7B)) //F12.
{
- overlay.Resize(resizeHelper[0], resizeHelper[1], resizeHelper[2], resizeHelper[3]);
+ showClickableMenu = !showClickableMenu;
}
- ImGui.NewLine();
- ImGui.SliderInt("###time(sec)", ref seconds, 1, 30);
- if (ImGui.Button($"Hide for {seconds} seconds"))
+ if (showImGuiDemo)
{
- new Thread(() => { Thread.Sleep(seconds * 1000); overlay.Show(); }).Start();
- overlay.Hide();
+ ImGui.ShowDemoWindow(ref showImGuiDemo);
}
- ImGui.NewLine();
- if(ImGui.Button("Show ImGui Demo"))
+ if (showOverlaySample1)
{
- showImGuiDemo = true;
+ ImGui.SetNextWindowPos(new Vector2(0f, 0f));
+ ImGui.SetNextWindowBgAlpha(0.9f);
+ ImGui.Begin(
+ "Sample Overlay",
+ ImGuiWindowFlags.NoInputs |
+ ImGuiWindowFlags.NoCollapse |
+ ImGuiWindowFlags.NoTitleBar |
+ ImGuiWindowFlags.AlwaysAutoResize |
+ ImGuiWindowFlags.NoResize);
+
+ ImGui.Text("I am sample Overlay");
+ ImGui.Text("You can not click me");
+ ImGui.Text("I am here just to display stuff");
+ ImGui.Text($"Current Date: {DateTime.Now.Date}");
+ ImGui.Text($"Current Time: {DateTime.Now.TimeOfDay}");
+ ImGui.End();
}
- ImGui.NewLine();
- if(ImGui.Button("Draw on Screen"))
+ if (showOverlaySample2)
{
- drawOnScreen = true;
+ ImGui.SetNextWindowContentSize(ImGui.GetIO().DisplaySize);
+ ImGui.SetNextWindowPos(new Vector2(0, 0));
+ ImGui.Begin(
+ "Background Screen",
+ ref showOverlaySample2,
+ ImGuiWindowFlags.NoInputs |
+ ImGuiWindowFlags.NoBackground |
+ ImGuiWindowFlags.NoBringToFrontOnFocus |
+ ImGuiWindowFlags.NoCollapse |
+ ImGuiWindowFlags.NoMove |
+ ImGuiWindowFlags.NoScrollbar |
+ ImGuiWindowFlags.NoSavedSettings |
+ ImGuiWindowFlags.NoResize |
+ ImGuiWindowFlags.NoTitleBar);
+ var windowPtr = ImGui.GetWindowDrawList();
+ for (int i = 0; i < circleCenters.Length; i++)
+ {
+ windowPtr.AddCircleFilled(circleCenters[i], 10.0f, (uint)(((255 << 24) | (00 << 16) | (00 << 8) | 255) & 0xffffffffL));
+ }
+ ImGui.End();
}
- ImGui.NewLine();
- if (File.Exists("image.png"))
+ if (showClickableMenu)
{
- ImGui.Image(overlay.AddOrGetImagePointer("image.png"), new Vector2(256, 256));
+ bool isRunning = true;
+ if (!ImGui.Begin("Overlay Main Menu", ref isRunning, ImGuiWindowFlags.NoResize | ImGuiWindowFlags.AlwaysAutoResize))
+ {
+ Overlay.Close = !isRunning;
+ ImGui.End();
+ continue;
+ }
+
+ Overlay.Close = !isRunning;
+ ImGui.Text("Try pressing F12 button to show/hide this menu.");
+ ImGui.Text("Click X on top right of this menu to close the overlay.");
+ ImGui.Checkbox("Show non-clickable transparent overlay Sample 1.", ref showOverlaySample1);
+ ImGui.Checkbox("Show full-screen non-clickable transparent overlay sample 2.", ref showOverlaySample2);
+ ImGui.NewLine();
+
+ ImGui.SliderInt2("Set Position", ref resizeHelper[0], 0, 3840);
+ ImGui.SliderInt2("Set Size", ref resizeHelper[2], 0, 3840);
+ if (ImGui.Button("Resize"))
+ {
+ Overlay.Position = new Veldrid.Point(resizeHelper[0], resizeHelper[1]);
+ Overlay.Size = new Veldrid.Point(resizeHelper[2], resizeHelper[3]);
+ }
+
+ ImGui.NewLine();
+ ImGui.SliderInt("###time(sec)", ref seconds, 1, 30);
+ if (ImGui.Button($"Hide for {seconds} seconds"))
+ {
+ Overlay.Visible = false;
+ // Time Based Coroutines are executed even when the Overlay is invisible.
+ // So in case there is a reason you want to hide the overlay, u can use timebased
+ // coroutines to bring it back.
+ CoroutineHandler.InvokeLater(new WaitSeconds(seconds), () => { Overlay.Visible = true; });
+ }
+
+ ImGui.NewLine();
+ if (ImGui.Button("Toggle ImGui Demo"))
+ {
+ showImGuiDemo = !showImGuiDemo;
+ }
+
+ if (ImGui.Button("Toggle Terminal"))
+ {
+ Overlay.TerminalWindow = !Overlay.TerminalWindow;
+ }
+
+ ImGui.NewLine();
+ if (File.Exists("image.png"))
+ {
+ ImGui.Image(Overlay.AddOrGetImagePointer("image.png"), new Vector2(256, 256));
+ }
+ else
+ {
+ ImGui.Text("Put any image where the exe is, name is 'image.png'");
+ }
+
+ ImGui.End();
}
- else
- {
- ImGui.Text("Put any image where the exe is, name is 'image.png'");
- }
-
- ImGui.End();
- }
-
- if (showImGuiDemo)
- {
- ImGui.ShowDemoWindow(ref showImGuiDemo);
}
+ }
- if(drawOnScreen)
+ private static IEnumerator UpdateOverlaySample2()
+ {
+ while (true)
{
- ImGui.SetNextWindowContentSize(ImGui.GetIO().DisplaySize);
- ImGui.SetNextWindowPos(new Vector2(0, 0));
- ImGui.Begin("Background Screen", ref drawOnScreen, ImGuiWindowFlags.NoInputs |
- ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.NoBringToFrontOnFocus |
- ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoScrollbar |
- ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoTitleBar);
- var windowPtr = ImGui.GetWindowDrawList();
+ yield return new WaitSeconds(1);
for (int i = 0; i < circleCenters.Length; i++)
{
- windowPtr.AddCircleFilled(circleCenters[i], 10.0f, (uint)(((255 << 24) | (00 << 16) | (00 << 8) | 255) & 0xffffffffL));
+ circleCenters[i].X = randomGen.Next(0, 2560);
+ circleCenters[i].Y = randomGen.Next(0, 1440);
}
- ImGui.End();
}
}
}
-}
\ No newline at end of file
+}
diff --git a/DriverProgram/Properties/AssemblyInfo.cs b/DriverProgram/Properties/AssemblyInfo.cs
deleted file mode 100644
index 77f1968..0000000
--- a/DriverProgram/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("OverlayDemo")]
-[assembly: AssemblyDescription("Overlay Demo with ImGui")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("DriverProgram")]
-[assembly: AssemblyCopyright("Copyright © 2019")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("370e1945-ef74-4618-a2de-b5796ac3093e")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/DriverProgram/packages.config b/DriverProgram/packages.config
deleted file mode 100644
index b89d42a..0000000
--- a/DriverProgram/packages.config
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file