pkdawson / imgui-godot Goto Github PK
View Code? Open in Web Editor NEWDear ImGui plugin for Godot 4
License: MIT License
Dear ImGui plugin for Godot 4
License: MIT License
I am currently working on an application that involves multiple windows: a main program window and a newly created secondary window. My issue is that ImGui seems to render its content in the main window by default. I'm looking to have ImGui content rendered in the secondary window instead.
Unfortunately, I'm not fully familiar with the rendering process of ImGui and how it decides the target window for rendering. My apologies for reaching out without a deep understanding of the system's internals – I haven't had the chance to delve into the implementation details of ImGui's window handling.
Could someone guide me on how to direct ImGui to render in a specific window that is not the main program window? Any insights or references to documentation/examples that explain how ImGui interacts with multiple window contexts would be greatly appreciated.
It's possible to also use ImGui from outside C# by sharing the context pointer and using the exact same version of ImGui. I should document this, and add a method for getting the current context. That could be done on ImGuiLayer, but I'll probably wait and use GDExtension instead, which should be available for C# soon.
I'd also like to provide an optional C++ implementation of the renderer, but viewports make that more complicated.
I get this error on my laptop (Radeon RX Vega 10 graphics). Here's the callstack (none is my code). I get this with any simple ImGui.Begin("blah")/ImGui.End() in a single node's _Process function (I'm using the 4.1.2 dotnet)
E 0:00:02:0871 Godot.NativeInterop.NativeFuncs.generated.cs:345 @ void Godot.NativeInterop.NativeFuncs.godotsharp_method_bind_ptrcall(IntPtr , IntPtr , System.Void** , System.Void* ): Error (-3) creating shader module for stage: Vertex
<C++ Error> Method/function failed. Returning: RID()
<C++ Source> drivers/vulkan/rendering_device_vulkan.cpp:5131 @ shader_create_from_bytecode()
<Stack Trace> Godot.NativeInterop.NativeFuncs.generated.cs:345 @ void Godot.NativeInterop.NativeFuncs.godotsharp_method_bind_ptrcall(IntPtr , IntPtr , System.Void** , System.Void* )
NativeCalls.cs:7393 @ Godot.Rid Godot.NativeCalls.godot_icall_2_814(IntPtr , IntPtr , IntPtr , System.String )
RenderingDevice.cs:2381 @ Godot.Rid Godot.RenderingDevice.ShaderCreateFromSpirV(Godot.RDShaderSpirV , System.String )
RdRenderer.cs:56 @ ImGuiGodot.Internal.RdRenderer..ctor()
ImGuiGD.cs:79 @ void ImGuiGodot.ImGuiGD.Init(Godot.Window , Godot.Rid , System.Nullable`1[System.Single] , ImGuiGodot.RendererType )
ImGuiLayer.cs:83 @ void ImGuiGodot.ImGuiLayer._EnterTree()
Node.cs:2057 @ Boolean Godot.Node.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
CanvasLayer.cs:379 @ Boolean Godot.CanvasLayer.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
ImGuiGodot.ImGuiLayer_ScriptMethods.generated.cs:82 @ Boolean ImGuiGodot.ImGuiLayer.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
CSharpInstanceBridge.cs:24 @ Godot.NativeInterop.godot_bool Godot.Bridge.CSharpInstanceBridge.Call(IntPtr , Godot.NativeInterop.godot_string_name* , Godot.NativeInterop.godot_variant** , Int32 , Godot.NativeInterop.godot_variant_call_error* , Godot.NativeInterop.godot_variant* )
https://github.com/ocornut/imgui/wiki/Multi-Viewports
https://docs.godotengine.org/en/latest/classes/class_window.html
The remaining work required seems to be converting between local (window) coordinates and global (screen) coordinates in the right places. Mouse input and rendering.
Stretch change bisected to godotengine/godot@3cae980
https://github.com/ocornut/imgui/releases/tag/v1.89.8
Changes to CmdLists
should make it possible to move the draw data without copying it, but will certainly break the existing code in RdRendererThreadSafe
.
Waiting for ImGui.NET 1.89.8
Restore support for configurable Actions, but fall back on defaults wherever possible.
Node processing priority seems currently unimplemented in 4.1-dev3 because of ongoing refactoring for threading support. No satisfactory alternatives.
To reproduce, just open Help in the demo window and scroll around.
Might have messed up the indices while refactoring
Currently, if you run any ImGuiNET code in the editor Godot will crash, and you will have to delete the offending code and rebuild to stop the crashing.
I'm not 100% sure if the issue is with this plugin or ImGuiNET generally, but I thought it was worth bringing to this project's attention.
Minimal example (and attach to a Node in the scene):
using Godot;
using ImGuiNET;
namespace Example;
[Tool]
public sealed partial class MyTool : Node
{
public override void _Process(double delta)
{
ImGui.Text("Hello from the editor!");
}
}
Not obvious how to do this correctly. Viewport::_gui_input_event
seems responsible for updating the mouse cursor. OS::set_cursor_shape
is not available from scripts. Generate fake input events to update the cursor?
I think a large performance improvement is possible by using RenderingDevice instead of canvas items, so the vertex buffer can be shared and a lot of allocations and copying can be avoided.
This is probably relatively straightforward if you're comfortable with Vulkan, but I'm definitely not.
https://docs.godotengine.org/en/latest/classes/class_renderingdevice.html
https://github.com/ocornut/imgui/wiki/Integrating-with-Vulkan
Wonder if this Imgui could be used in 3D Gui?
Howdy, I was wondering if you had any advice on making an imgui panel that renders in 3D space (similar to the 3D Gui example in the godot examples repo).
I've done this before in another game engine by modifying the imgui renderer to render the frame to an FBO, and then I can use that framebuffer as the source for a texture. In my experience it works really well, and I can just give each panel its own context if needed. Maybe multi-viewports is better though, but I have not used it before. I also am not super familiar with godot's rendering abstraction, it's a little different from directly calling OpenGL to make framebuffers.
Another approach might be to render imgui in another scene, and then render that scene to texture to display in-game? I don't know how this would affect performance (I have not done this before), would it be the easiest solution?
My usecase is that a) I like using imgui :D and b) it makes it easy to implement dynamic UI for in-game panels. I think this would also be very useful for debugging in VR/XR setups, similar to how Desktop+ uses imgui for its settings menu.
Would it be better to wait until the GDExtension work has progressed more? I'd be interested in contributing to docs and other things if needed.
Trying to either load a SPIR-V resource or compile SPIR-V source in C# causes a crash in beta 16. I'll see if I can help fix this upstream, but beta 16 is probably unusable.
The plugin is great, but there is a small memory leak.
I noticed that my static memory graph was going up. I had some footage of the game before I installed the plugin and the graph didn't go up.
Then I disabled the plugin and the memory leak is gone.
Here is a short video:
https://github.com/pkdawson/imgui-godot/assets/96019707/8ccfc1a1-3677-4192-b363-4f13719fe902
Need a new solution for rendering at the correct size with canvas_items
scaling.
The Image widget appears not working correctly when using AtlasTextures. It will display the whole AtlasTexture and not just the specified region of the AtlasTexture e.g. The whole TileSet is shown instead of the a single tile.
Regression from Godot 4.2.1. Resizing the main window causes an offset in the mouse position seen by a SubViewport widget.
When moving a window with the gamepad (hold X button), at least one texture is wrong. Most obvious in the second demo scene, where the Godot icon changes to the font texture.
Not sure if this is my bug or ImGui's.
Figure out which Godot scaling option(s) we can support.
https://docs.godotengine.org/en/latest/tutorials/rendering/multiple_resolutions.html
https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#q-how-should-i-handle-dpi-in-my-application
We need to save the full font configuration so it can be changed and reloaded if the scale changes. AddFont should just build a configuration, RebuildFontAtlas should actually load everything.
Stretch mode disabled
is simple enough. We should optionally auto-detect "retina" displays, and have configurable scaling on top of that.
canvas_items
may require a SubViewport to override the scaling and do our own custom scaling?
https://github.com/godotengine/godot-demo-projects/tree/4.0-dev/viewport/3d_scaling
I like my projects to run with Nullable reference types: Enabled to allow me as a developer to notice obvious issues with nullable types.
Fixing 3-4 issues with the with lack of ?
on some types, it shows 35 warrnings. I would love to have this fixed.
It doesn't break anything to use this in your project. It's just ignored when someone has this Disabled (as it is by default)
Example of the warning:
Project\addons\imgui-godot\ImGuiGodot\Internal\Fonts.cs(15,25): warning CS8618: Non-nullable property 'Font' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
Originally posted by amroc-dev October 20, 2023
First off this is amazing and thanks so much for it. I recently tried an iOS export in the new Godot 4.2 beta that brings back (experimental) C#/iOS support and an error is thrown in XCode using this library, due to iOS disallowing code generation (I think it was Reflection.Emit specifically). I don't know much about the inner workings of imgui-godot but just thought I'd ask to see if there was a way around this. Thanks :)
Looks simple with Font.GetSupportedChars(). Not sure how best to handle font sizes with different glyph ranges.
For better quality and consistency, we could draw the font atlases ourselves using Godot's Font APIs.
Low priority.
https://github.com/ocornut/imgui/tree/master/misc/freetype
https://github.com/ocornut/imgui/blob/master/docs/FONTS.md#using-custom-colorful-icons
This will also let us support .woff2 files, and FontVariation, and SystemFont. We can (optionally) render the whole font atlas once and cache it as an image in the user data directory.
Instead of requiring the user to add an ImGuiNode to every scene, it may be easier to have one global node as an option.
Something changed with SubViewport or SubViewportContainer sizes. I need to find the commit/PR which made that change, because I don't have a quick fix that still works correctly with content scaling enabled.
Bisected to godotengine/godot@00b5222
Title says all, it is possible to get a usable version for GDScript?
Thanks
The io.Fonts.Fonts
data structure is not being correctly updated after adding a font. This is an upstream issue with the ImGui.NET NuGet package, just don't use 1.89.3.
See this commit: godotengine/godot@a968e51
Currently the addon code will not compile against the latest version of GodotSharp because the naming conventions for many Godot objects was updated to match .NET conventions.
Docking doesn't seem to work
public override void _Process(double delta)
{
base._Process(delta);
if(ImGui.BeginMainMenuBar())
{
if (ImGui.BeginMenu("File" ))
{
if (ImGui.MenuItem("New" )) EmitSignal(SignalName.FileNew);
ImGui.Separator();
if (ImGui.MenuItem("Open" )) EmitSignal(SignalName.FileOpen);
if (ImGui.MenuItem("Save" )) EmitSignal(SignalName.FileSave);
if (ImGui.MenuItem("SaveAs..")) EmitSignal(SignalName.FileSaveAs);
ImGui.Separator();
if (ImGui.MenuItem("Exit" )) EmitSignal(SignalName.FileExit);
ImGui.EndMenu();
}
if (ImGui.BeginMenu("Tools"))
{
if (ImGui.MenuItem("Screen" )) EmitSignal(SignalName.ToolsScreen);
ImGui.EndMenu();
}
ImGui.EndMainMenuBar();
}
ImGui.DockSpaceOverViewport();
}
Hello,
I'm currently using your plugin to create a level editor and I'm currently facing an issue with input processing.
I created a godot viewport to bind the texture to an imgui window, and it works perfectly fine.
Inside that godot viewport I have a meshInstance, with an Area node and a collisionshape, that allow to select the mesh with my mouse by using the signal input_event from godot.
The issue I'm facing is that your imguinode is stopping the input event propagation, to handle it directly with imgui.
I tried to recreate a new custom event that I forward to my viewport (after handling it through imgui), but that input event doesn't get to the collisionshape input_event.
Do you know how I could forward an input from imgui back to the collisionshape input_event?
Thanks in advance for your help.
dynamic set "ImGuiGd.Scale" will raising error.
imgui-godot seems to have ~2x more input latency than SDL2 and GLFW implementations of imgui, despite running at the same framerates (see below videos).
If a window is created as the mouse leaves the frame of the main window, and the “mouse button up” event isn’t received, then the main window will stop responding to all inputs.
Drag the new window back into the main window. You may need to repeat this once or twice (drag it out, then back in).
This bug is easy to reproduce (depending on the input handling code), but it’s been frustratingly difficult to find the root cause, so I’m documenting it here.
All I know is that in this situation, the main window stops receiving window messages at all, and it’s not caused by WS_EX_NOACTIVATE
or MA_NOACTIVATEANDEAT
. Destroying the new window usually fixes it, at least temporarily.
I’ve been unable to make an MRP. I’m not entirely convinced it’s a Godot bug, but I also don’t know how my code or ImGui could break the main window like that.
TODO: Examine the following scenario
Reproduce the issue, then ctrl+tab to a window within the main window. This fixes the main window. Then click the new window, which breaks it again. This can be repeated. Ctrl+tab to the new window does not break it.
When using the "Multi-Threaded" thread model in Godot (4.0.3.stable), Vulkan fails to submit its graphics queue and fails to create the swapchain.
OS: Windows 11 22H2, build 22621.1702
Error messages:
E 0:00:09:0012 swap_buffers: Vulkan: Cannot submit graphics queue. Error code: VK_ERROR_DEVICE_LOST
<C++ Error> Condition "err" is true. Returning: ERR_CANT_CREATE
<C++ Source> drivers/vulkan/vulkan_context.cpp:2357 @ swap_buffers()
E 0:00:09:0013 prepare_buffers: Vulkan: Did not create swapchain successfully. Error code: VK_NOT_READY
<C++ Error> Condition "err != VK_SUCCESS" is true. Breaking.
<C++ Source> drivers/vulkan/vulkan_context.cpp:2280 @ prepare_buffers()
To reproduce, just try to use imgui-godot with the "Multi-Threaded" thread model.
(This appears to only happen sometimes, but should be reproduceable after a couple of restarts)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.