├── .clang-format
├── .editorconfig
├── .gitattributes
├── .github
├── actions
│ ├── import
│ │ └── action.yml
│ └── run-test-project
│ │ └── action.yml
└── workflows
│ ├── dotnet.yml
│ ├── gdext.yml
│ └── godot.yml
├── .gitignore
├── .gitmodules
├── Dear ImGui for Godot Demo.csproj
├── Dear ImGui for Godot Demo.sln
├── LICENSE
├── README.md
├── addons
└── imgui-godot
│ ├── ImGuiGodot
│ ├── ImGuiController.cs
│ ├── ImGuiExtensions.cs
│ ├── ImGuiGD.cs
│ ├── ImGuiLayer.cs
│ ├── ImGuiSync.cs
│ ├── Internal
│ │ ├── BackendNative.cs
│ │ ├── BackendNet.cs
│ │ ├── CanvasRenderer.cs
│ │ ├── DummyRenderer.cs
│ │ ├── Fonts.cs
│ │ ├── IBackend.cs
│ │ ├── IRenderer.cs
│ │ ├── Input.cs
│ │ ├── InputLocal.cs
│ │ ├── RdRenderer.cs
│ │ ├── RdRendererThreadSafe.cs
│ │ ├── State.cs
│ │ ├── Util.cs
│ │ └── Viewports.cs
│ └── Widgets.cs
│ ├── data
│ ├── ImGuiRoot.tscn
│ ├── ImGuiShader.glsl
│ └── ImGuiShader.glsl.import
│ ├── plugin.cfg
│ └── scripts
│ ├── ImGuiConfig.gd
│ ├── ImGuiFont.gd
│ ├── ImGuiPlugin.gd
│ └── ImGuiRoot.gd
├── data
├── Hack-Regular.ttf
├── Hack-Regular.ttf.import
├── MPLUS2-Regular.ttf
├── MPLUS2-Regular.ttf.import
├── buttongroup.tres
├── default_env.tres
├── demo.tscn
├── demo2.tscn
├── gui_in_3d.tscn
├── gui_panel_3d.tscn
├── icon.svg
├── icon.svg.import
├── robot_eye.tres
└── sample_config.tres
├── doc
├── .gdignore
├── examples
│ ├── CSharpGameProject
│ │ ├── CSharpGameProject.csproj
│ │ ├── CSharpGameProject.sln
│ │ ├── Globals.cs
│ │ ├── Main.cs
│ │ ├── README.md
│ │ ├── Sprite.cs
│ │ ├── addons.json
│ │ ├── export_presets.cfg
│ │ ├── icon.svg
│ │ ├── icon.svg.import
│ │ ├── main.tscn
│ │ └── project.godot
│ ├── GDExt
│ │ ├── CMakeLists.txt
│ │ ├── README.md
│ │ ├── SConstruct
│ │ ├── project
│ │ │ ├── Hack-Bold.ttf
│ │ │ ├── Hack-Bold.ttf.import
│ │ │ ├── Hack-Italic.ttf
│ │ │ ├── Hack-Italic.ttf.import
│ │ │ ├── Hack-Regular.ttf
│ │ │ ├── Hack-Regular.ttf.import
│ │ │ ├── addons.json
│ │ │ ├── example.gdextension
│ │ │ ├── icon.svg
│ │ │ ├── icon.svg.import
│ │ │ ├── imgui_config.tres
│ │ │ ├── main.tscn
│ │ │ ├── project.godot
│ │ │ └── robot_eye.tres
│ │ └── src
│ │ │ ├── example.cpp
│ │ │ ├── example.h
│ │ │ ├── gdmarkdown.cpp
│ │ │ ├── gdmarkdown.h
│ │ │ ├── register_types.cpp
│ │ │ └── register_types.h
│ ├── GdsDemo
│ │ ├── README.md
│ │ ├── addons.json
│ │ ├── demo.gd
│ │ ├── icon.svg
│ │ ├── icon.svg.import
│ │ ├── main.tscn
│ │ └── project.godot
│ ├── GdsGameProject
│ │ ├── README.md
│ │ ├── addons.json
│ │ ├── export
│ │ │ └── .gdignore
│ │ ├── export_presets.cfg
│ │ ├── icon.svg
│ │ ├── icon.svg.import
│ │ ├── main.gd
│ │ ├── main.tscn
│ │ ├── project.godot
│ │ └── sprite.gd
│ ├── Module
│ │ ├── README.md
│ │ ├── modules
│ │ │ └── mymod
│ │ │ │ ├── SCsub
│ │ │ │ ├── config.py
│ │ │ │ ├── mynode.cpp
│ │ │ │ ├── mynode.h
│ │ │ │ ├── register_types.cpp
│ │ │ │ └── register_types.h
│ │ └── project
│ │ │ ├── addons.json
│ │ │ ├── icon.svg
│ │ │ ├── icon.svg.import
│ │ │ ├── main.tscn
│ │ │ └── project.godot
│ ├── ToolCSharp
│ │ ├── README.md
│ │ ├── SpriteTool.cs
│ │ ├── ToolCSharp.csproj
│ │ ├── ToolCSharp.sln
│ │ ├── addons.json
│ │ ├── icon.svg
│ │ ├── icon.svg.import
│ │ ├── main.tscn
│ │ └── project.godot
│ └── ToolScript
│ │ ├── README.md
│ │ ├── addons.json
│ │ ├── icon.svg
│ │ ├── icon.svg.import
│ │ ├── main.tscn
│ │ ├── project.godot
│ │ └── sprite_tool.gd
├── icon.png
├── screenshot.png
└── test
│ ├── addons
│ └── TestData
│ │ └── config_scale2x.tres
│ ├── csbench
│ ├── BenchCanvas.cs
│ ├── BenchRid.cs
│ ├── Program.cs
│ ├── csbench.csproj
│ └── csbench.sln
│ ├── csharp
│ ├── Main.cs
│ ├── addons.json
│ ├── export
│ │ └── .gdignore
│ ├── export_presets.cfg
│ ├── icon.svg
│ ├── icon.svg.import
│ ├── main.tscn
│ ├── project.godot
│ ├── test.csproj
│ └── test.sln
│ └── gdscript
│ ├── addons.json
│ ├── export
│ └── .gdignore
│ ├── export_presets.cfg
│ ├── icon.svg
│ ├── icon.svg.import
│ ├── main.gd
│ ├── main.tscn
│ ├── project.godot
│ └── test_base.gd
├── export_presets.cfg
├── gdext
├── .gdignore
├── CMakeLists.txt
├── SConstruct
├── imgui-godot-native.gdextension
├── include
│ ├── .gdignore
│ ├── imconfig-godot.h
│ └── imgui-godot.h
├── scripts
│ ├── gds_bindings.py
│ └── vcpkg-macos.sh
├── src
│ ├── CMakeLists.txt
│ ├── CanvasRenderer.cpp
│ ├── CanvasRenderer.h
│ ├── Context.cpp
│ ├── Context.h
│ ├── DummyRenderer.h
│ ├── Fonts.cpp
│ ├── Fonts.h
│ ├── GdsCache.cpp
│ ├── GdsCache.h
│ ├── ImGuiAPI.cpp
│ ├── ImGuiAPI.h
│ ├── ImGuiController.cpp
│ ├── ImGuiController.h
│ ├── ImGuiControllerHelper.cpp
│ ├── ImGuiControllerHelper.h
│ ├── ImGuiGD.cpp
│ ├── ImGuiGD.h
│ ├── ImGuiLayer.cpp
│ ├── ImGuiLayer.h
│ ├── ImGuiSync.cpp
│ ├── ImGuiSync.h
│ ├── Input.cpp
│ ├── Input.h
│ ├── InputLocal.cpp
│ ├── InputLocal.h
│ ├── RdRenderer.cpp
│ ├── RdRenderer.h
│ ├── RdRendererThreadSafe.cpp
│ ├── RdRendererThreadSafe.h
│ ├── Renderer.h
│ ├── Viewports.cpp
│ ├── Viewports.h
│ ├── common.h
│ └── main.cpp
└── vcpkg.json
├── project.godot
└── src
├── MyNode.cs
├── MySecondNode.cs
├── ThirdNode.cs
├── ViewportArea.cs
└── gui_3d.gd
/.clang-format:
--------------------------------------------------------------------------------
1 | Language: Cpp
2 | BasedOnStyle: Microsoft
3 | AccessModifierOffset: -4
4 | AllowAllArgumentsOnNextLine: false
5 | AlignEscapedNewlines: Left
6 | AlwaysBreakTemplateDeclarations: Yes
7 | BinPackArguments: false
8 | BinPackParameters: true
9 | PointerAlignment: Left
10 | AllowShortFunctionsOnASingleLine: InlineOnly
11 |
12 | BreakBeforeBraces: Custom
13 | BraceWrapping:
14 | AfterNamespace: false
15 | AfterExternBlock: false
16 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | insert_final_newline = true
7 | trim_trailing_whitespace = true
8 | end_of_line = lf
9 | charset = utf-8
10 |
11 | [*.cs]
12 | csharp_style_var_when_type_is_apparent = true
13 | csharp_prefer_braces = when_multiline
14 | csharp_style_namespace_declarations = file_scoped
15 | dotnet_style_allow_multiple_blank_lines_experimental = false
16 | csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
17 |
18 | dotnet_analyzer_diagnostic.severity = warning
19 |
20 | # don't add _ discards for return values
21 | dotnet_diagnostic.IDE0058.severity = none
22 |
23 | # don't change var to explicit type
24 | dotnet_diagnostic.IDE0008.severity = none
25 |
26 | # use expression bodies for methods: when i feel like it
27 | dotnet_diagnostic.IDE0022.severity = none
28 |
29 | # incomplete switch statements are fine
30 | dotnet_diagnostic.IDE0010.severity = none
31 | dotnet_diagnostic.IDE0072.severity = none
32 |
33 | dotnet_diagnostic.CA1805.severity = none
34 | dotnet_diagnostic.CA1051.severity = none
35 | dotnet_diagnostic.CA1001.severity = none
36 | dotnet_diagnostic.CA1725.severity = none
37 | dotnet_diagnostic.CA1707.severity = none
38 | dotnet_diagnostic.CA1711.severity = none
39 |
40 | # Roslynator
41 | dotnet_diagnostic.rcs0056.severity = warning
42 | roslynator_max_line_length = 100
43 |
44 | dotnet_diagnostic.rcs1194.severity = none
45 | dotnet_diagnostic.rcs1129.severity = none
46 | dotnet_diagnostic.rcs1061.severity = none
47 | dotnet_diagnostic.rcs1006.severity = none
48 | dotnet_diagnostic.rcs1141.severity = none
49 | dotnet_diagnostic.rcs1161.severity = none
50 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto eol=lf
2 |
--------------------------------------------------------------------------------
/.github/actions/import/action.yml:
--------------------------------------------------------------------------------
1 | name: Import
2 | description: Import
3 | inputs:
4 | path:
5 | description: Path
6 | required: true
7 |
8 | runs:
9 | using: composite
10 | steps:
11 | - uses: actions/setup-dotnet@v4
12 | with:
13 | dotnet-version: 8.0.x
14 |
15 | - name: Install GodotEnv
16 | shell: bash
17 | run: |
18 | dotnet tool install --global Chickensoft.GodotEnv
19 |
20 | - name: Prep
21 | shell: bash
22 | run: |
23 | cd imgui-godot-* || true
24 | cd ${{ inputs.path }}
25 | godotenv addons install
26 | if [[ -f addons/imgui-godot/imgui-godot-native.gdextension ]]; then
27 | mkdir .godot
28 | echo "res://addons/imgui-godot/imgui-godot-native.gdextension" > .godot/extension_list.cfg
29 | fi
30 | $GODOT --headless --import || true
31 | echo "GAMEDIR=$(pwd)" >> $GITHUB_ENV
32 |
--------------------------------------------------------------------------------
/.github/actions/run-test-project/action.yml:
--------------------------------------------------------------------------------
1 | name: Run test project
2 | description: Run test project
3 | inputs:
4 | exe:
5 | description: Executable
6 | required: true
7 |
8 | runs:
9 | using: composite
10 | steps:
11 | - name: Run tests
12 | shell: bash
13 | run: |
14 | cd $GAMEDIR
15 | $GODOT --headless --debug
16 |
17 | - name: Export debug
18 | shell: bash
19 | run: |
20 | cd $GAMEDIR
21 | $GODOT --headless --export-debug $RUNNER_OS
22 | cd export
23 | ./${{ inputs.exe }} --headless
24 | rm -rf *
25 |
26 | - name: Export release
27 | shell: bash
28 | run: |
29 | cd $GAMEDIR
30 | $GODOT --headless --export-release $RUNNER_OS
31 | cd export
32 | ./${{ inputs.exe }} --headless
33 | rm -rf *
34 |
--------------------------------------------------------------------------------
/.github/workflows/dotnet.yml:
--------------------------------------------------------------------------------
1 | name: 🦖 .NET Checks
2 |
3 | on:
4 | push:
5 | branches-ignore:
6 | - godot3
7 | pull_request:
8 | branches-ignore:
9 | - godot3
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-latest
14 | strategy:
15 | matrix:
16 | dotnet: ["8.0.x", "9.0.x"]
17 |
18 | name: .NET ${{ matrix.dotnet }}
19 |
20 | env:
21 | DemoProj: Dear ImGui for Godot Demo.csproj
22 |
23 | steps:
24 | - uses: actions/checkout@v4
25 |
26 | - name: Setup .NET
27 | uses: actions/setup-dotnet@v4
28 | with:
29 | dotnet-version: ${{ matrix.dotnet }}
30 |
31 | - name: Modify .editorconfig
32 | run: |
33 | sed -i "s:dotnet_analyzer_diagnostic.severity = warning:dotnet_analyzer_diagnostic.severity = error:" .editorconfig
34 |
35 | - name: Restore dependencies
36 | run: dotnet restore
37 |
38 | - name: Format
39 | run: dotnet format --no-restore --verify-no-changes --verbosity detailed "${{ env.DemoProj }}" || (dotnet format --no-restore "${{ env.DemoProj }}" && git diff --color && exit 1)
40 |
41 | - name: Build
42 | run: dotnet build --no-restore
43 |
44 | - name: Test
45 | run: dotnet test --no-build --verbosity normal
46 |
--------------------------------------------------------------------------------
/.github/workflows/godot.yml:
--------------------------------------------------------------------------------
1 | name: 🤖 Godot Checks
2 |
3 | on:
4 | - push
5 | - pull_request
6 |
7 | jobs:
8 | test_csharp_only:
9 | strategy:
10 | fail-fast: false
11 | matrix:
12 | os: [ubuntu-latest, macos-latest, windows-latest]
13 | gdver: ["4.2.2", "4.3.0", "4.4.1", "4.5.0-dev.2"]
14 | include:
15 | - os: ubuntu-latest
16 | name: 🐧🧪C# Only
17 | exe: test.x86_64
18 | - os: macos-latest
19 | name: 🍎🧪C# Only
20 | exe: test.app/Contents/MacOS/test
21 | - os: windows-latest
22 | name: 🪟🧪C# Only
23 | exe: test.exe
24 |
25 | name: ${{ matrix.name }} (${{ matrix.gdver }})
26 | runs-on: ${{ matrix.os }}
27 | steps:
28 | - uses: actions/checkout@v4
29 |
30 | - uses: chickensoft-games/setup-godot@v2
31 | with:
32 | version: ${{ matrix.gdver }}
33 | use-dotnet: true
34 | include-templates: true
35 | cache: false
36 |
37 | - name: Import
38 | uses: ./.github/actions/import
39 | with:
40 | path: doc/test/csharp
41 |
42 | - name: Build
43 | shell: bash
44 | run: |
45 | cd $GAMEDIR
46 | dotnet build
47 |
48 | - name: Run tests
49 | uses: ./.github/actions/run-test-project
50 | with:
51 | exe: ${{ matrix.exe }}
52 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .import/
2 | .mono/
3 | .vs/
4 | .vscode/
5 | *.old
6 | imgui.ini
7 | .godot/
8 | *.user
9 | Properties/
10 | build/
11 | build.*/
12 | msvc.*/
13 | *.so
14 | *.dylib
15 | *.framework
16 | *.dll
17 | *.pdb
18 | doc/cpp-demo/MyGame/addons
19 | *.old.*
20 | gdext/vcpkg_installed/
21 | .sconsign.dblite
22 | gdext/x64/
23 | *.exp
24 | *.obj
25 | *.lib
26 | *.os
27 | gdext/proj/addons/imgui-godot-native/include/*.h
28 | gdext/gen/
29 | *.o
30 | *.pyc
31 | gdext/proj/doc/
32 | gdext/proj/modules/
33 | gdext/proj/platform/
34 |
35 | addons/imgui-godot-native/
36 | gdext/proj/addons/imgui-godot/
37 | gdext/samples/project/addons/
38 | addons/imgui-godot/imgui-godot-native.gdextension
39 | addons/imgui-godot/include/
40 | scons_cache
41 | doc/**/addons/
42 | addons/imgui-godot/include/imgui-version.txt
43 | export/
44 | **/bin/Debug/
45 | **/bin/Release/
46 | **/obj/
47 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "gdext/dear_bindings"]
2 | path = gdext/dear_bindings
3 | url = https://github.com/dearimgui/dear_bindings
4 | [submodule "gdext/imgui"]
5 | path = gdext/imgui
6 | url = https://github.com/ocornut/imgui
7 | [submodule "gdext/godot-cpp"]
8 | path = gdext/godot-cpp
9 | url = https://github.com/godotengine/godot-cpp
10 |
--------------------------------------------------------------------------------
/Dear ImGui for Godot Demo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net8.0
4 | true
5 | DemoProject
6 | True
7 | enable
8 |
9 |
10 | True
11 | True
12 |
13 |
14 | True
15 | True
16 |
17 |
18 | True
19 | True
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | all
31 | runtime; build; native; contentfiles; analyzers; buildtransitive
32 |
33 |
34 | all
35 | runtime; build; native; contentfiles; analyzers; buildtransitive
36 |
37 |
38 | all
39 | runtime; build; native; contentfiles; analyzers; buildtransitive
40 |
41 |
42 | all
43 | runtime; build; native; contentfiles; analyzers; buildtransitive
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Dear ImGui for Godot Demo.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2012
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dear ImGui for Godot Demo", "Dear ImGui for Godot Demo.csproj", "{D939DAF9-46BC-4305-9D69-D920E185BDC7}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Any CPU = Debug|Any CPU
8 | ExportDebug|Any CPU = ExportDebug|Any CPU
9 | ExportRelease|Any CPU = ExportRelease|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {D939DAF9-46BC-4305-9D69-D920E185BDC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {D939DAF9-46BC-4305-9D69-D920E185BDC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {D939DAF9-46BC-4305-9D69-D920E185BDC7}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
15 | {D939DAF9-46BC-4305-9D69-D920E185BDC7}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
16 | {D939DAF9-46BC-4305-9D69-D920E185BDC7}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
17 | {D939DAF9-46BC-4305-9D69-D920E185BDC7}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
18 | EndGlobalSection
19 | EndGlobal
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Patrick Dawson and contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/ImGuiController.cs:
--------------------------------------------------------------------------------
1 | #if GODOT_PC
2 | #nullable enable
3 | using Godot;
4 | using ImGuiNET;
5 |
6 | namespace ImGuiGodot;
7 |
8 | public partial class ImGuiController : Node
9 | {
10 | private Window _window = null!;
11 | public static ImGuiController Instance { get; private set; } = null!;
12 | private ImGuiControllerHelper _helper = null!;
13 | public Node Signaler { get; private set; } = null!;
14 | private readonly StringName _signalName = "imgui_layout";
15 |
16 | private sealed partial class ImGuiControllerHelper : Node
17 | {
18 | public override void _Ready()
19 | {
20 | Name = "ImGuiControllerHelper";
21 | ProcessPriority = int.MinValue;
22 | ProcessMode = ProcessModeEnum.Always;
23 | }
24 |
25 | public override void _Process(double delta)
26 | {
27 | Internal.State.Instance.InProcessFrame = true;
28 | var vpSize = Internal.State.Instance.Layer.UpdateViewport();
29 | Internal.State.Instance.Update(delta, new(vpSize.X, vpSize.Y));
30 | }
31 | }
32 |
33 | public override void _EnterTree()
34 | {
35 | Instance = this;
36 | _window = GetWindow();
37 |
38 | CheckContentScale();
39 |
40 | string cfgPath = (string)ProjectSettings.GetSetting("addons/imgui/config", "");
41 | Resource? cfg = null;
42 | if (ResourceLoader.Exists(cfgPath))
43 | {
44 | cfg = ResourceLoader.Load(cfgPath);
45 | float scale = (float)cfg.Get("Scale");
46 | bool cfgok = scale > 0.0f;
47 |
48 | if (!cfgok)
49 | {
50 | GD.PushError($"imgui-godot: config not a valid ImGuiConfig resource: {cfgPath}");
51 | cfg = null;
52 | }
53 | }
54 | else if (cfgPath.Length > 0)
55 | {
56 | GD.PushError($"imgui-godot: config does not exist: {cfgPath}");
57 | }
58 |
59 | Internal.State.Init(cfg ?? (Resource)((GDScript)GD.Load(
60 | "res://addons/imgui-godot/scripts/ImGuiConfig.gd")).New());
61 |
62 | _helper = new ImGuiControllerHelper();
63 | AddChild(_helper);
64 |
65 | Signaler = GetParent();
66 | SetMainViewport(_window);
67 | }
68 |
69 | public override void _Ready()
70 | {
71 | ProcessPriority = int.MaxValue;
72 | ProcessMode = ProcessModeEnum.Always;
73 | }
74 |
75 | public override void _ExitTree()
76 | {
77 | Internal.State.Instance.Dispose();
78 | }
79 |
80 | public override void _Process(double delta)
81 | {
82 | Signaler.EmitSignal(_signalName);
83 | Internal.State.Instance.Render();
84 | Internal.State.Instance.InProcessFrame = false;
85 | }
86 |
87 | public override void _Notification(int what)
88 | {
89 | Internal.Input.ProcessNotification(what);
90 | }
91 |
92 | public void OnLayerExiting()
93 | {
94 | // an ImGuiLayer is being destroyed without calling SetMainViewport
95 | if (Internal.State.Instance.Layer.GetViewport() != _window)
96 | {
97 | // revert to main window
98 | SetMainViewport(_window);
99 | }
100 | }
101 |
102 | public void SetMainViewport(Viewport vp)
103 | {
104 | ImGuiLayer? oldLayer = Internal.State.Instance.Layer;
105 | if (oldLayer != null)
106 | {
107 | oldLayer.TreeExiting -= OnLayerExiting;
108 | oldLayer.QueueFree();
109 | }
110 |
111 | var newLayer = new ImGuiLayer();
112 | newLayer.TreeExiting += OnLayerExiting;
113 |
114 | if (vp is Window window)
115 | {
116 | Internal.State.Instance.Input = new Internal.Input();
117 | if (window == _window)
118 | AddChild(newLayer);
119 | else
120 | window.AddChild(newLayer);
121 | ImGui.GetIO().BackendFlags |= ImGuiBackendFlags.PlatformHasViewports
122 | | ImGuiBackendFlags.HasMouseHoveredViewport;
123 | }
124 | else if (vp is SubViewport svp)
125 | {
126 | Internal.State.Instance.Input = new Internal.InputLocal();
127 | svp.AddChild(newLayer);
128 | ImGui.GetIO().BackendFlags &= ~ImGuiBackendFlags.PlatformHasViewports;
129 | ImGui.GetIO().BackendFlags &= ~ImGuiBackendFlags.HasMouseHoveredViewport;
130 | }
131 | else
132 | {
133 | throw new System.ArgumentException("secret third kind of viewport??", nameof(vp));
134 | }
135 | Internal.State.Instance.Layer = newLayer;
136 | }
137 |
138 | private void CheckContentScale()
139 | {
140 | if (_window.ContentScaleMode == Window.ContentScaleModeEnum.Viewport)
141 | {
142 | GD.PrintErr("imgui-godot: scale mode `viewport` is unsupported");
143 | }
144 | }
145 |
146 | public static void WindowInputCallback(InputEvent evt)
147 | {
148 | Internal.State.Instance.Input.ProcessInput(evt);
149 | }
150 | }
151 | #endif
152 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/ImGuiExtensions.cs:
--------------------------------------------------------------------------------
1 | #if GODOT_PC
2 | using Godot;
3 | using ImGuiNET;
4 | using Vector3 = System.Numerics.Vector3;
5 | using Vector4 = System.Numerics.Vector4;
6 |
7 | namespace ImGuiGodot;
8 |
9 | public static class ImGuiExtensions
10 | {
11 | ///
12 | /// Extension method to translate between and
13 | ///
14 | public static ImGuiKey ToImGuiKey(this Key key)
15 | {
16 | return Internal.Input.ConvertKey(key);
17 | }
18 |
19 | ///
20 | /// Extension method to translate between and
21 | ///
22 | public static ImGuiKey ToImGuiKey(this JoyButton button)
23 | {
24 | return Internal.Input.ConvertJoyButton(button);
25 | }
26 |
27 | ///
28 | /// Convert to ImGui color RGBA
29 | ///
30 | public static Vector4 ToVector4(this Color color)
31 | {
32 | return new Vector4(color.R, color.G, color.B, color.A);
33 | }
34 |
35 | ///
36 | /// Convert to ImGui color RGB
37 | ///
38 | public static Vector3 ToVector3(this Color color)
39 | {
40 | return new Vector3(color.R, color.G, color.B);
41 | }
42 |
43 | ///
44 | /// Convert RGB to
45 | ///
46 | public static Color ToColor(this Vector3 vec)
47 | {
48 | return new Color(vec.X, vec.Y, vec.Z);
49 | }
50 |
51 | ///
52 | /// Convert RGBA to
53 | ///
54 | public static Color ToColor(this Vector4 vec)
55 | {
56 | return new Color(vec.X, vec.Y, vec.Z, vec.W);
57 | }
58 |
59 | ///
60 | /// Set IniFilename, converting Godot path to native
61 | ///
62 | public static void SetIniFilename(this ImGuiIOPtr io, string fileName)
63 | {
64 | _ = io;
65 | ImGuiGD.SetIniFilename(fileName);
66 | }
67 | }
68 | #endif
69 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/ImGuiGD.cs:
--------------------------------------------------------------------------------
1 | #if GODOT_PC
2 | #nullable enable
3 | using Godot;
4 | using System;
5 |
6 | namespace ImGuiGodot;
7 |
8 | public static partial class ImGuiGD
9 | {
10 | private static readonly Internal.IBackend _backend;
11 |
12 | ///
13 | /// Deadzone for all axes
14 | ///
15 | public static float JoyAxisDeadZone
16 | {
17 | get => _backend.JoyAxisDeadZone;
18 | set => _backend.JoyAxisDeadZone = value;
19 | }
20 |
21 | ///
22 | /// Setting this property will reload fonts and modify the ImGuiStyle.
23 | /// Can only be set outside of a process frame (eg, use CallDeferred)
24 | ///
25 | public static float Scale
26 | {
27 | get => _backend.Scale;
28 | set
29 | {
30 | if (_backend.Scale != value && value >= 0.25f)
31 | {
32 | _backend.Scale = value;
33 | RebuildFontAtlas();
34 | }
35 | }
36 | }
37 |
38 | public static bool Visible
39 | {
40 | get => _backend.Visible;
41 | set => _backend.Visible = value;
42 | }
43 |
44 | static ImGuiGD()
45 | {
46 | _backend = ClassDB.ClassExists("ImGuiGD")
47 | ? new Internal.BackendNative()
48 | : new Internal.BackendNet();
49 | }
50 |
51 | public static IntPtr BindTexture(Texture2D tex)
52 | {
53 | return (IntPtr)tex.GetRid().Id;
54 | }
55 |
56 | public static void ResetFonts()
57 | {
58 | _backend.ResetFonts();
59 | }
60 |
61 | public static void AddFont(
62 | FontFile fontData,
63 | int fontSize,
64 | bool merge = false,
65 | ushort[]? glyphRanges = null)
66 | {
67 | _backend.AddFont(fontData, fontSize, merge, glyphRanges);
68 | }
69 |
70 | ///
71 | /// Add a font using glyph ranges from ImGui.GetIO().Fonts.GetGlyphRanges*()
72 | ///
73 | /// pointer to an array of ushorts terminated by 0
74 | public static unsafe void AddFont(FontFile fontData, int fontSize, bool merge, nint glyphRanges)
75 | {
76 | ushort* p = (ushort*)glyphRanges;
77 | int len = 1;
78 | while (p[len++] != 0) ;
79 | ushort[] gr = new ushort[len];
80 | for (int i = 0; i < len; ++i)
81 | gr[i] = p[i];
82 | _backend.AddFont(fontData, fontSize, merge, gr);
83 | }
84 |
85 | public static void AddFontDefault()
86 | {
87 | _backend.AddFontDefault();
88 | }
89 |
90 | public static void RebuildFontAtlas()
91 | {
92 | _backend.RebuildFontAtlas();
93 | }
94 |
95 | public static void Connect(Callable callable)
96 | {
97 | _backend.Connect(callable);
98 | }
99 |
100 | public static void Connect(Action action)
101 | {
102 | Connect(Callable.From(action));
103 | }
104 |
105 | ///
106 | /// Changes the main viewport to either a new
107 | /// or a .
108 | ///
109 | public static void SetMainViewport(Viewport vp)
110 | {
111 | _backend.SetMainViewport(vp);
112 | }
113 |
114 | ///
115 | /// Must call from a tool script before doing anything else
116 | ///
117 | public static bool ToolInit()
118 | {
119 | if (_backend is Internal.BackendNative nbe)
120 | {
121 | nbe.ToolInit();
122 | return true;
123 | }
124 |
125 | return false;
126 | }
127 |
128 | public static void SetIniFilename(string filename)
129 | {
130 | _backend.SetIniFilename(filename);
131 | }
132 | }
133 | #endif
134 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/ImGuiLayer.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | #if GODOT_PC
3 | #nullable enable
4 |
5 | namespace ImGuiGodot;
6 |
7 | public partial class ImGuiLayer : CanvasLayer
8 | {
9 | private Rid _subViewportRid;
10 | private Vector2I _subViewportSize = Vector2I.Zero;
11 | private Rid _canvasItem;
12 | private Transform2D _finalTransform = Transform2D.Identity;
13 | private bool _visible = true;
14 | private Viewport _parentViewport = null!;
15 |
16 | public override void _EnterTree()
17 | {
18 | Name = "ImGuiLayer";
19 | Layer = Internal.State.Instance.LayerNum;
20 |
21 | _parentViewport = GetViewport();
22 | _subViewportRid = AddLayerSubViewport(this);
23 | _canvasItem = RenderingServer.CanvasItemCreate();
24 | RenderingServer.CanvasItemSetParent(_canvasItem, GetCanvas());
25 |
26 | Internal.State.Instance.Renderer.InitViewport(_subViewportRid);
27 | Internal.State.Instance.Viewports.SetMainWindow(GetWindow(), _subViewportRid);
28 | }
29 |
30 | public override void _Ready()
31 | {
32 | VisibilityChanged += OnChangeVisibility;
33 | OnChangeVisibility();
34 | }
35 |
36 | public override void _ExitTree()
37 | {
38 | RenderingServer.FreeRid(_canvasItem);
39 | RenderingServer.FreeRid(_subViewportRid);
40 | }
41 |
42 | private void OnChangeVisibility()
43 | {
44 | _visible = Visible;
45 | if (_visible)
46 | {
47 | SetProcessInput(true);
48 | }
49 | else
50 | {
51 | SetProcessInput(false);
52 | Internal.State.Instance.Renderer.OnHide();
53 | _subViewportSize = Vector2I.Zero;
54 | RenderingServer.CanvasItemClear(_canvasItem);
55 | }
56 | }
57 |
58 | public override void _Input(InputEvent @event)
59 | {
60 | if (Internal.State.Instance.Input.ProcessInput(@event))
61 | {
62 | _parentViewport.SetInputAsHandled();
63 | }
64 | }
65 |
66 | public Vector2I UpdateViewport()
67 | {
68 | Vector2I vpSize = _parentViewport is Window w ? w.Size
69 | : (_parentViewport as SubViewport)?.Size
70 | ?? throw new System.InvalidOperationException();
71 |
72 | if (_visible)
73 | {
74 | var ft = _parentViewport.GetFinalTransform();
75 | if (_subViewportSize != vpSize || _finalTransform != ft)
76 | {
77 | // this is more or less how SubViewportContainer works
78 | _subViewportSize = vpSize;
79 | _finalTransform = ft;
80 | RenderingServer.ViewportSetSize(
81 | _subViewportRid,
82 | _subViewportSize.X,
83 | _subViewportSize.Y);
84 | Rid vptex = RenderingServer.ViewportGetTexture(_subViewportRid);
85 | RenderingServer.CanvasItemClear(_canvasItem);
86 | RenderingServer.CanvasItemSetTransform(_canvasItem, ft.AffineInverse());
87 | RenderingServer.CanvasItemAddTextureRect(
88 | _canvasItem,
89 | new(0, 0, _subViewportSize.X, _subViewportSize.Y),
90 | vptex);
91 | }
92 | }
93 |
94 | return vpSize;
95 | }
96 |
97 | private static Rid AddLayerSubViewport(Node parent)
98 | {
99 | Rid svp = RenderingServer.ViewportCreate();
100 | RenderingServer.ViewportSetTransparentBackground(svp, true);
101 | RenderingServer.ViewportSetUpdateMode(svp, RenderingServer.ViewportUpdateMode.Always);
102 | RenderingServer.ViewportSetClearMode(svp, RenderingServer.ViewportClearMode.Always);
103 | RenderingServer.ViewportSetActive(svp, true);
104 | RenderingServer.ViewportSetParentViewport(svp, parent.GetWindow().GetViewportRid());
105 | return svp;
106 | }
107 | }
108 | #else
109 | namespace ImGuiNET
110 | {
111 | }
112 |
113 | namespace ImGuiGodot
114 | {
115 | }
116 | #endif
117 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/ImGuiSync.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | #if GODOT_PC
3 | using ImGuiNET;
4 | using System.Runtime.InteropServices;
5 | using System;
6 |
7 | namespace ImGuiGodot;
8 |
9 | public partial class ImGuiSync : GodotObject
10 | {
11 | public static readonly StringName GetImGuiPtrs = "GetImGuiPtrs";
12 |
13 | public static void SyncPtrs()
14 | {
15 | GodotObject gd = Engine.GetSingleton("ImGuiGD");
16 | long[] ptrs = (long[])gd.Call(GetImGuiPtrs,
17 | ImGui.GetVersion(),
18 | Marshal.SizeOf(),
19 | Marshal.SizeOf(),
20 | sizeof(ushort),
21 | sizeof(ushort)
22 | );
23 |
24 | if (ptrs.Length != 3)
25 | {
26 | throw new NotSupportedException("ImGui version mismatch");
27 | }
28 |
29 | checked
30 | {
31 | ImGui.SetCurrentContext((IntPtr)ptrs[0]);
32 | ImGui.SetAllocatorFunctions((IntPtr)ptrs[1], (IntPtr)ptrs[2]);
33 | }
34 | }
35 | }
36 | #endif
37 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/Internal/BackendNative.cs:
--------------------------------------------------------------------------------
1 | #if GODOT_PC
2 | #nullable enable
3 | using Godot;
4 |
5 | namespace ImGuiGodot.Internal;
6 |
7 | internal sealed class BackendNative : IBackend
8 | {
9 | private readonly GodotObject _gd = Engine.GetSingleton("ImGuiGD");
10 |
11 | private sealed class MethodName
12 | {
13 | public static readonly StringName AddFont = "AddFont";
14 | public static readonly StringName AddFontDefault = "AddFontDefault";
15 | public static readonly StringName Connect = "Connect";
16 | public static readonly StringName RebuildFontAtlas = "RebuildFontAtlas";
17 | public static readonly StringName ResetFonts = "ResetFonts";
18 | public static readonly StringName SetMainViewport = "SetMainViewport";
19 | public static readonly StringName SubViewport = "SubViewport";
20 | public static readonly StringName ToolInit = "ToolInit";
21 | public static readonly StringName SetIniFilename = "SetIniFilename";
22 | }
23 |
24 | private sealed class PropertyName
25 | {
26 | public static readonly StringName JoyAxisDeadZone = "JoyAxisDeadZone";
27 | public static readonly StringName Scale = "Scale";
28 | public static readonly StringName Visible = "Visible";
29 | }
30 |
31 | public float JoyAxisDeadZone
32 | {
33 | get => (float)_gd.Get(PropertyName.JoyAxisDeadZone);
34 | set => _gd.Set(PropertyName.JoyAxisDeadZone, value);
35 | }
36 |
37 | public float Scale
38 | {
39 | get => (float)_gd.Get(PropertyName.Scale);
40 | set => _gd.Set(PropertyName.Scale, value);
41 | }
42 |
43 | public bool Visible
44 | {
45 | get => (bool)_gd.Get(PropertyName.Visible);
46 | set => _gd.Set(PropertyName.Visible, value);
47 | }
48 |
49 | public void AddFont(FontFile fontData, int fontSize, bool merge, ushort[]? glyphRanges)
50 | {
51 | if (glyphRanges != null)
52 | {
53 | int[] gr = new int[glyphRanges.Length];
54 | for (int i = 0; i < glyphRanges.Length; ++i)
55 | gr[i] = glyphRanges[i];
56 | _gd.Call(MethodName.AddFont, fontData, fontSize, merge, gr);
57 | }
58 | else
59 | {
60 | _gd.Call(MethodName.AddFont, fontData, fontSize, merge);
61 | }
62 | }
63 |
64 | public void AddFontDefault()
65 | {
66 | _gd.Call(MethodName.AddFontDefault);
67 | }
68 |
69 | public void Connect(Callable callable)
70 | {
71 | _gd.Call(MethodName.Connect, callable);
72 | }
73 |
74 | public void RebuildFontAtlas()
75 | {
76 | _gd.Call(MethodName.RebuildFontAtlas);
77 | }
78 |
79 | public void ResetFonts()
80 | {
81 | _gd.Call(MethodName.ResetFonts);
82 | }
83 | public void SetMainViewport(Viewport vp)
84 | {
85 | _gd.Call(MethodName.SetMainViewport, vp);
86 | }
87 |
88 | public bool SubViewportWidget(SubViewport svp)
89 | {
90 | return (bool)_gd.Call(MethodName.SubViewport, svp);
91 | }
92 |
93 | public void ToolInit()
94 | {
95 | _gd.Call(MethodName.ToolInit);
96 | ImGuiSync.SyncPtrs();
97 | }
98 |
99 | public void SetIniFilename(string filename)
100 | {
101 | _gd.Call(MethodName.SetIniFilename, filename);
102 | }
103 | }
104 | #endif
105 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/Internal/BackendNet.cs:
--------------------------------------------------------------------------------
1 | #if GODOT_PC
2 | #nullable enable
3 | using Godot;
4 | using ImGuiNET;
5 | using System;
6 | using Vector2 = System.Numerics.Vector2;
7 |
8 | namespace ImGuiGodot.Internal;
9 |
10 | internal sealed class BackendNet : IBackend
11 | {
12 | public float JoyAxisDeadZone
13 | {
14 | get => State.Instance.JoyAxisDeadZone;
15 | set => State.Instance.JoyAxisDeadZone = value;
16 | }
17 |
18 | public float Scale
19 | {
20 | get => State.Instance.Scale;
21 | set => State.Instance.Scale = value;
22 | }
23 |
24 | public bool Visible
25 | {
26 | get => State.Instance.Layer.Visible;
27 | set => State.Instance.Layer.Visible = value;
28 | }
29 |
30 | public void AddFont(FontFile fontData, int fontSize, bool merge, ushort[]? glyphRanges)
31 | {
32 | State.Instance.Fonts.AddFont(fontData, fontSize, merge, glyphRanges);
33 | }
34 |
35 | public void AddFontDefault()
36 | {
37 | State.Instance.Fonts.AddFont(null, 13, false, null);
38 | }
39 |
40 | public void Connect(Callable callable)
41 | {
42 | ImGuiController.Instance?.Signaler.Connect("imgui_layout", callable);
43 | }
44 |
45 | public void RebuildFontAtlas()
46 | {
47 | if (State.Instance.InProcessFrame)
48 | throw new InvalidOperationException("fonts can't be changed during process");
49 |
50 | bool scaleToDpi = (bool)ProjectSettings.GetSetting("display/window/dpi/allow_hidpi");
51 | int dpiFactor = Math.Max(1, DisplayServer.ScreenGetDpi() / 96);
52 | State.Instance.Fonts.RebuildFontAtlas(scaleToDpi ? dpiFactor * Scale : Scale);
53 | }
54 |
55 | public void ResetFonts()
56 | {
57 | State.Instance.Fonts.ResetFonts();
58 | }
59 |
60 | public void SetIniFilename(string filename)
61 | {
62 | State.Instance.SetIniFilename(filename);
63 | }
64 |
65 | public void SetMainViewport(Viewport vp)
66 | {
67 | ImGuiController.Instance.SetMainViewport(vp);
68 | }
69 |
70 | public bool SubViewportWidget(SubViewport svp)
71 | {
72 | Vector2 vpSize = new(svp.Size.X, svp.Size.Y);
73 | var pos = ImGui.GetCursorScreenPos();
74 | var pos_max = new Vector2(pos.X + vpSize.X, pos.Y + vpSize.Y);
75 | ImGui.GetWindowDrawList().AddImage((IntPtr)svp.GetTexture().GetRid().Id, pos, pos_max);
76 |
77 | ImGui.PushID(svp.NativeInstance);
78 | ImGui.InvisibleButton("godot_subviewport", vpSize);
79 | ImGui.PopID();
80 |
81 | if (ImGui.IsItemHovered())
82 | {
83 | State.Instance.Input.CurrentSubViewport = svp;
84 | State.Instance.Input.CurrentSubViewportPos = pos;
85 | return true;
86 | }
87 | return false;
88 | }
89 | }
90 | #endif
91 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/Internal/DummyRenderer.cs:
--------------------------------------------------------------------------------
1 | #if GODOT_PC
2 | using Godot;
3 |
4 | namespace ImGuiGodot.Internal;
5 |
6 | internal sealed class DummyRenderer : IRenderer
7 | {
8 | public string Name => "godot4_net_dummy";
9 |
10 | public void InitViewport(Rid vprid)
11 | {
12 | }
13 |
14 | public void CloseViewport(Rid vprid)
15 | {
16 | }
17 |
18 | public void OnHide()
19 | {
20 | }
21 |
22 | public void Render()
23 | {
24 | }
25 |
26 | public void Dispose()
27 | {
28 | }
29 | }
30 | #endif
31 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/Internal/IBackend.cs:
--------------------------------------------------------------------------------
1 | #if GODOT_PC
2 | #nullable enable
3 | using Godot;
4 |
5 | namespace ImGuiGodot.Internal;
6 |
7 | internal interface IBackend
8 | {
9 | bool Visible { get; set; }
10 | float JoyAxisDeadZone { get; set; }
11 | float Scale { get; set; }
12 | void ResetFonts();
13 | void AddFont(FontFile fontData, int fontSize, bool merge, ushort[]? glyphRanges);
14 | void AddFontDefault();
15 | void RebuildFontAtlas();
16 | void Connect(Callable callable);
17 | void SetMainViewport(Viewport vp);
18 | bool SubViewportWidget(SubViewport svp);
19 | void SetIniFilename(string filename);
20 | }
21 | #endif
22 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/Internal/IRenderer.cs:
--------------------------------------------------------------------------------
1 | #if GODOT_PC
2 | using Godot;
3 | using System;
4 |
5 | namespace ImGuiGodot.Internal;
6 |
7 | internal interface IRenderer : IDisposable
8 | {
9 | string Name { get; }
10 | void InitViewport(Rid vprid);
11 | void CloseViewport(Rid vprid);
12 | void Render();
13 | void OnHide();
14 | }
15 | #endif
16 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/Internal/InputLocal.cs:
--------------------------------------------------------------------------------
1 | #if GODOT_PC
2 | using Godot;
3 | using ImGuiNET;
4 |
5 | namespace ImGuiGodot.Internal;
6 |
7 | internal sealed class InputLocal : Input
8 | {
9 | protected override void UpdateMousePos(ImGuiIOPtr io)
10 | {
11 | // do not use global mouse position
12 | }
13 |
14 | public override bool ProcessInput(InputEvent evt)
15 | {
16 | // no support for SubViewport widgets
17 |
18 | if (evt is InputEventMouseMotion mm)
19 | {
20 | var io = ImGui.GetIO();
21 | var mousePos = mm.Position;
22 | #pragma warning disable IDE0004 // Remove Unnecessary Cast
23 | io.AddMousePosEvent((float)mousePos.X, (float)mousePos.Y);
24 | #pragma warning restore IDE0004 // Remove Unnecessary Cast
25 | mm.Dispose();
26 | return io.WantCaptureMouse;
27 | }
28 | return HandleEvent(evt);
29 | }
30 | }
31 | #endif
32 |
--------------------------------------------------------------------------------
/addons/imgui-godot/ImGuiGodot/Internal/Util.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System.Runtime.CompilerServices;
3 |
4 | namespace ImGuiGodot.Internal;
5 |
6 | internal static class Util
7 | {
8 | [UnsafeAccessor(UnsafeAccessorKind.Constructor)]
9 | public static extern Rid ConstructRid(ulong id);
10 | }
11 |
--------------------------------------------------------------------------------
/addons/imgui-godot/data/ImGuiRoot.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://dugmpnsxaagba"]
2 |
3 | [ext_resource type="Script" path="res://addons/imgui-godot/scripts/ImGuiRoot.gd" id="1_lney5"]
4 |
5 | [node name="ImGuiRoot" type="Node"]
6 | script = ExtResource("1_lney5")
7 |
--------------------------------------------------------------------------------
/addons/imgui-godot/data/ImGuiShader.glsl:
--------------------------------------------------------------------------------
1 | // shader source borrowed from imgui_impl_vulkan.cpp
2 |
3 | #[vertex]
4 | #version 450 core
5 | layout(location = 0) in vec2 aPos;
6 | layout(location = 1) in vec2 aUV;
7 | layout(location = 2) in vec4 aColor;
8 | layout(push_constant) uniform uPushConstant { vec2 uScale; vec2 uTranslate; } pc;
9 |
10 | out gl_PerVertex { vec4 gl_Position; };
11 | layout(location = 0) out struct { vec4 Color; vec2 UV; } Out;
12 |
13 | void main()
14 | {
15 | Out.Color = aColor;
16 | Out.UV = aUV;
17 | gl_Position = vec4(aPos * pc.uScale + pc.uTranslate, 0, 1);
18 | }
19 |
20 | #[fragment]
21 | #version 450 core
22 | layout(location = 0) out vec4 fColor;
23 | layout(set=0, binding=0) uniform sampler2D sTexture;
24 | layout(location = 0) in struct { vec4 Color; vec2 UV; } In;
25 |
26 | void main()
27 | {
28 | fColor = In.Color * texture(sTexture, In.UV.st);
29 | }
30 |
--------------------------------------------------------------------------------
/addons/imgui-godot/data/ImGuiShader.glsl.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="glsl"
4 | type="RDShaderFile"
5 | uid="uid://belucuvjtb04o"
6 | path="res://.godot/imported/ImGuiShader.glsl-2f8c9595e5031ef8022ed7e6f565729e.res"
7 |
8 | [deps]
9 |
10 | source_file="res://addons/imgui-godot/data/ImGuiShader.glsl"
11 | dest_files=["res://.godot/imported/ImGuiShader.glsl-2f8c9595e5031ef8022ed7e6f565729e.res"]
12 |
13 | [params]
14 |
15 |
--------------------------------------------------------------------------------
/addons/imgui-godot/plugin.cfg:
--------------------------------------------------------------------------------
1 | [plugin]
2 |
3 | name="imgui-godot"
4 | description="Dear ImGui for Godot"
5 | author="Patrick Dawson"
6 | version="6.3.2"
7 | script="scripts/ImGuiPlugin.gd"
8 |
--------------------------------------------------------------------------------
/addons/imgui-godot/scripts/ImGuiConfig.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | class_name ImGuiConfig extends Resource
3 |
4 | @export_range(0.25, 4.0, 0.001, "or_greater") var Scale: float = 1.0
5 | @export var IniFilename: String = "user://imgui.ini"
6 | @export_enum("RenderingDevice", "Canvas", "Dummy") var Renderer: String = "RenderingDevice"
7 | @export_range(-128, 128) var Layer: int = 128
8 |
9 | @export_category("Font Settings")
10 | #@export var Fonts: Array[ImGuiFont]
11 | @export var AddDefaultFont: bool = true
12 |
13 | # HACK: workaround for intermittent Godot bug
14 | var _fonts: Array
15 |
16 | func _get_property_list() -> Array[Dictionary]:
17 | return [
18 | {
19 | "name": "Fonts",
20 | "class_name": &"",
21 | "type": TYPE_ARRAY,
22 | "hint": PROPERTY_HINT_TYPE_STRING,
23 | "hint_string": "24/17:ImGuiFont",
24 | "usage": PROPERTY_USAGE_SCRIPT_VARIABLE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE
25 | }
26 | ]
27 |
28 | func _get(property: StringName) -> Variant:
29 | if property == &"Fonts":
30 | return _fonts
31 | return null
32 |
33 | func _set(property: StringName, value: Variant) -> bool:
34 | if property == &"Fonts":
35 | _fonts = value
36 | return true
37 | return false
38 |
--------------------------------------------------------------------------------
/addons/imgui-godot/scripts/ImGuiFont.gd:
--------------------------------------------------------------------------------
1 | class_name ImGuiFont extends Resource
2 |
3 | @export var FontData: FontFile
4 | @export var FontSize: int = 16
5 | @export var Merge: bool = true
6 |
--------------------------------------------------------------------------------
/addons/imgui-godot/scripts/ImGuiRoot.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 |
3 | signal imgui_layout
4 |
5 | const csharp_controller := "res://addons/imgui-godot/ImGuiGodot/ImGuiController.cs"
6 | const csharp_sync := "res://addons/imgui-godot/ImGuiGodot/ImGuiSync.cs"
7 |
8 | func _enter_tree():
9 | var has_csharp := false
10 | if ClassDB.class_exists("CSharpScript"):
11 | var script := load(csharp_sync)
12 | has_csharp = script.get_instance_base_type() == "Object"
13 |
14 | if ClassDB.class_exists("ImGuiController"):
15 | # native
16 | add_child(ClassDB.instantiate("ImGuiController"))
17 | if has_csharp:
18 | var obj: Object = load(csharp_sync).new()
19 | obj.SyncPtrs()
20 | obj.free()
21 | else:
22 | # C# only
23 | if has_csharp:
24 | add_child(load(csharp_controller).new())
25 |
--------------------------------------------------------------------------------
/data/Hack-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/data/Hack-Regular.ttf
--------------------------------------------------------------------------------
/data/Hack-Regular.ttf.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="font_data_dynamic"
4 | type="FontFile"
5 | uid="uid://c2o4vx2jik43e"
6 | path="res://.godot/imported/Hack-Regular.ttf-3d6007156cf38336f0685ad871feaf05.fontdata"
7 |
8 | [deps]
9 |
10 | source_file="res://data/Hack-Regular.ttf"
11 | dest_files=["res://.godot/imported/Hack-Regular.ttf-3d6007156cf38336f0685ad871feaf05.fontdata"]
12 |
13 | [params]
14 |
15 | Rendering=null
16 | antialiasing=1
17 | generate_mipmaps=false
18 | disable_embedded_bitmaps=true
19 | multichannel_signed_distance_field=false
20 | msdf_pixel_range=8
21 | msdf_size=48
22 | allow_system_fallback=true
23 | force_autohinter=false
24 | hinting=1
25 | subpixel_positioning=1
26 | oversampling=0.0
27 | Fallbacks=null
28 | fallbacks=[]
29 | Compress=null
30 | compress=true
31 | preload=[]
32 | language_support={}
33 | script_support={}
34 | opentype_features={}
35 |
--------------------------------------------------------------------------------
/data/MPLUS2-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/data/MPLUS2-Regular.ttf
--------------------------------------------------------------------------------
/data/MPLUS2-Regular.ttf.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="font_data_dynamic"
4 | type="FontFile"
5 | uid="uid://bk0s2hduow46m"
6 | path="res://.godot/imported/MPLUS2-Regular.ttf-7fe86ccd65e167ffa0da418b024bf3c5.fontdata"
7 |
8 | [deps]
9 |
10 | source_file="res://data/MPLUS2-Regular.ttf"
11 | dest_files=["res://.godot/imported/MPLUS2-Regular.ttf-7fe86ccd65e167ffa0da418b024bf3c5.fontdata"]
12 |
13 | [params]
14 |
15 | Rendering=null
16 | antialiasing=1
17 | generate_mipmaps=false
18 | disable_embedded_bitmaps=true
19 | multichannel_signed_distance_field=false
20 | msdf_pixel_range=8
21 | msdf_size=48
22 | allow_system_fallback=true
23 | force_autohinter=false
24 | hinting=1
25 | subpixel_positioning=1
26 | oversampling=0.0
27 | Fallbacks=null
28 | fallbacks=[]
29 | Compress=null
30 | compress=true
31 | preload=[]
32 | language_support={}
33 | script_support={}
34 | opentype_features={}
35 |
--------------------------------------------------------------------------------
/data/buttongroup.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="ButtonGroup" format=3 uid="uid://ucf261yyiwkq"]
2 |
3 | [resource]
4 |
--------------------------------------------------------------------------------
/data/default_env.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Environment" load_steps=2 format=2]
2 |
3 | [sub_resource type="Sky" id=1]
4 |
5 | [resource]
6 | background_mode = 2
7 | background_sky = SubResource( 1 )
8 |
--------------------------------------------------------------------------------
/data/demo.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=3 uid="uid://sdgew7sm2686"]
2 |
3 | [ext_resource type="Texture2D" uid="uid://2cvgmt2fmpao" path="res://data/icon.svg" id="1_c7hdb"]
4 | [ext_resource type="FontFile" uid="uid://c2o4vx2jik43e" path="res://data/Hack-Regular.ttf" id="3_fjiyg"]
5 | [ext_resource type="Script" path="res://src/MyNode.cs" id="3_qvd0t"]
6 | [ext_resource type="ButtonGroup" uid="uid://ucf261yyiwkq" path="res://data/buttongroup.tres" id="4_7oj01"]
7 |
8 | [node name="Control" type="Control"]
9 | layout_mode = 3
10 | anchors_preset = 15
11 | anchor_right = 1.0
12 | anchor_bottom = 1.0
13 | grow_horizontal = 2
14 | grow_vertical = 2
15 |
16 | [node name="MyNode" type="Node" parent="."]
17 | script = ExtResource("3_qvd0t")
18 |
19 | [node name="TextureRect" type="TextureRect" parent="."]
20 | layout_mode = 1
21 | anchors_preset = 8
22 | anchor_left = 0.5
23 | anchor_top = 0.5
24 | anchor_right = 0.5
25 | anchor_bottom = 0.5
26 | offset_left = -128.0
27 | offset_top = -128.0
28 | offset_right = 128.0
29 | offset_bottom = 128.0
30 | grow_horizontal = 2
31 | grow_vertical = 2
32 | texture = ExtResource("1_c7hdb")
33 |
34 | [node name="PanelContainer" type="PanelContainer" parent="."]
35 | layout_mode = 1
36 | anchors_preset = 2
37 | anchor_top = 1.0
38 | anchor_bottom = 1.0
39 | offset_top = -143.0
40 | offset_right = 256.0
41 | grow_vertical = 0
42 |
43 | [node name="CenterContainer" type="CenterContainer" parent="PanelContainer"]
44 | layout_mode = 2
45 |
46 | [node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/CenterContainer"]
47 | layout_mode = 2
48 |
49 | [node name="Label" type="Label" parent="PanelContainer/CenterContainer/VBoxContainer"]
50 | layout_mode = 2
51 | text = "Content scale mode"
52 | horizontal_alignment = 1
53 |
54 | [node name="ButtonCIE" type="Button" parent="PanelContainer/CenterContainer/VBoxContainer"]
55 | layout_mode = 2
56 | focus_mode = 0
57 | toggle_mode = true
58 | button_pressed = true
59 | button_group = ExtResource("4_7oj01")
60 | text = "canvas_items/expand"
61 |
62 | [node name="ButtonD" type="Button" parent="PanelContainer/CenterContainer/VBoxContainer"]
63 | layout_mode = 2
64 | focus_mode = 0
65 | toggle_mode = true
66 | button_group = ExtResource("4_7oj01")
67 | text = "disabled"
68 |
69 | [node name="CanvasLayer" type="CanvasLayer" parent="."]
70 | layer = 120
71 |
72 | [node name="TextureRect2" type="TextureRect" parent="CanvasLayer"]
73 | anchors_preset = 3
74 | anchor_left = 1.0
75 | anchor_top = 1.0
76 | anchor_right = 1.0
77 | anchor_bottom = 1.0
78 | offset_left = -64.0
79 | offset_top = -64.0
80 | grow_horizontal = 0
81 | grow_vertical = 0
82 | texture = ExtResource("1_c7hdb")
83 | expand_mode = 1
84 |
85 | [node name="CenterContainer" type="CenterContainer" parent="."]
86 | layout_mode = 0
87 | offset_right = 209.0
88 | offset_bottom = 173.0
89 |
90 | [node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
91 | custom_minimum_size = Vector2(180, 0)
92 | layout_mode = 2
93 |
94 | [node name="Button1" type="Button" parent="CenterContainer/VBoxContainer"]
95 | unique_name_in_owner = true
96 | layout_mode = 2
97 | focus_mode = 0
98 | theme_override_fonts/font = ExtResource("3_fjiyg")
99 | theme_override_font_sizes/font_size = 24
100 | text = "Widgets"
101 |
102 | [node name="Button2" type="Button" parent="CenterContainer/VBoxContainer"]
103 | unique_name_in_owner = true
104 | layout_mode = 2
105 | focus_mode = 0
106 | theme_override_fonts/font = ExtResource("3_fjiyg")
107 | theme_override_font_sizes/font_size = 24
108 | text = "New Window"
109 |
110 | [node name="Button3" type="Button" parent="CenterContainer/VBoxContainer"]
111 | unique_name_in_owner = true
112 | layout_mode = 2
113 | focus_mode = 0
114 | theme_override_fonts/font = ExtResource("3_fjiyg")
115 | theme_override_font_sizes/font_size = 24
116 | text = "3D Scene"
117 |
118 | [node name="CheckBox" type="CheckBox" parent="CenterContainer/VBoxContainer"]
119 | unique_name_in_owner = true
120 | layout_mode = 2
121 | focus_mode = 0
122 | text = "ImGui Viewports"
123 |
124 | [connection signal="pressed" from="PanelContainer/CenterContainer/VBoxContainer/ButtonCIE" to="MyNode" method="OnContentScaleCIE"]
125 | [connection signal="pressed" from="PanelContainer/CenterContainer/VBoxContainer/ButtonD" to="MyNode" method="OnContentScaleDisabled"]
126 |
--------------------------------------------------------------------------------
/data/demo2.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=7 format=3 uid="uid://dr8hy6iu5hk8a"]
2 |
3 | [ext_resource type="Script" path="res://src/ViewportArea.cs" id="2_btjlu"]
4 | [ext_resource type="Script" path="res://src/MySecondNode.cs" id="2_gnjei"]
5 |
6 | [sub_resource type="PlaneMesh" id="PlaneMesh_dsg5q"]
7 | size = Vector2(250, 250)
8 |
9 | [sub_resource type="CylinderMesh" id="CylinderMesh_kek8d"]
10 | top_radius = 2.0
11 | bottom_radius = 10.0
12 | height = 30.0
13 |
14 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_eanfn"]
15 | albedo_color = Color(0.615686, 0.556863, 0.968627, 1)
16 |
17 | [sub_resource type="BoxShape3D" id="BoxShape3D_6s853"]
18 | size = Vector3(230, 1, 230)
19 |
20 | [node name="Background" type="ColorRect"]
21 | anchors_preset = 15
22 | anchor_right = 1.0
23 | anchor_bottom = 1.0
24 | grow_horizontal = 2
25 | grow_vertical = 2
26 | color = Color(0.0784314, 0, 0.117647, 1)
27 |
28 | [node name="MySecondNode" type="Node" parent="."]
29 | script = ExtResource("2_gnjei")
30 |
31 | [node name="ShowHideButton" type="Button" parent="."]
32 | unique_name_in_owner = true
33 | layout_mode = 1
34 | anchors_preset = 3
35 | anchor_left = 1.0
36 | anchor_top = 1.0
37 | anchor_right = 1.0
38 | anchor_bottom = 1.0
39 | offset_left = -96.0
40 | offset_top = -48.0
41 | offset_right = -7.0
42 | offset_bottom = -8.0
43 | grow_horizontal = 0
44 | grow_vertical = 0
45 | focus_mode = 0
46 | toggle_mode = true
47 | text = "hide"
48 |
49 | [node name="SubViewport" type="SubViewport" parent="."]
50 | unique_name_in_owner = true
51 | physics_object_picking = true
52 | render_target_update_mode = 4
53 |
54 | [node name="Board" type="MeshInstance3D" parent="SubViewport"]
55 | unique_name_in_owner = true
56 | mesh = SubResource("PlaneMesh_dsg5q")
57 |
58 | [node name="Piece" type="MeshInstance3D" parent="SubViewport"]
59 | unique_name_in_owner = true
60 | layers = 2
61 | mesh = SubResource("CylinderMesh_kek8d")
62 | surface_material_override/0 = SubResource("StandardMaterial3D_eanfn")
63 |
64 | [node name="Camera3d" type="Camera3D" parent="SubViewport"]
65 | transform = Transform3D(1, 0, 0, 0, 0.422618, 0.906308, 0, -0.906308, 0.422618, 0, 150, 100)
66 | current = true
67 |
68 | [node name="Area3d" type="Area3D" parent="SubViewport"]
69 | script = ExtResource("2_btjlu")
70 |
71 | [node name="CollisionShape3d" type="CollisionShape3D" parent="SubViewport/Area3d"]
72 | shape = SubResource("BoxShape3D_6s853")
73 |
--------------------------------------------------------------------------------
/data/gui_in_3d.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=12 format=3 uid="uid://0iek6ri88gkb"]
2 |
3 | [ext_resource type="PackedScene" uid="uid://dvl383ispakmn" path="res://data/gui_panel_3d.tscn" id="1"]
4 | [ext_resource type="Script" path="res://src/ThirdNode.cs" id="2_xsiun"]
5 |
6 | [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_1lgdv"]
7 | sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
8 | ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
9 |
10 | [sub_resource type="Sky" id="Sky_pq42j"]
11 | sky_material = SubResource("ProceduralSkyMaterial_1lgdv")
12 |
13 | [sub_resource type="Environment" id="Environment_niyks"]
14 | background_mode = 2
15 | sky = SubResource("Sky_pq42j")
16 | tonemap_mode = 2
17 | tonemap_white = 2.0
18 |
19 | [sub_resource type="Animation" id="1"]
20 | length = 6.0
21 | loop_mode = 1
22 | tracks/0/type = "value"
23 | tracks/0/imported = false
24 | tracks/0/enabled = true
25 | tracks/0/path = NodePath("Camera3D:transform")
26 | tracks/0/interp = 1
27 | tracks/0/loop_wrap = true
28 | tracks/0/keys = {
29 | "times": PackedFloat32Array(0, 2, 4, 6),
30 | "transitions": PackedFloat32Array(-2, -2, -2, -2),
31 | "update": 0,
32 | "values": [Transform3D(0.994592, 0, 0.103856, 0, 1, 0, -0.103856, 0, 0.994592, 0.465682, 0, 1.78523), Transform3D(0.962984, 0, -0.269557, 0, 1, 0, 0.269557, 0, 0.962984, -0.462237, 0, 2.41934), Transform3D(0.806599, 0, -0.591098, 0, 1, 0, 0.591098, 0, 0.806599, -1.59502, 0, 2.05358), Transform3D(0.994592, 0, 0.103856, 0, 1, 0, -0.103856, 0, 0.994592, 0.465682, 0, 1.78523)]
33 | }
34 |
35 | [sub_resource type="AnimationLibrary" id="AnimationLibrary_uw4n0"]
36 | _data = {
37 | "Move_camera": SubResource("1")
38 | }
39 |
40 | [sub_resource type="PlaneMesh" id="2"]
41 |
42 | [sub_resource type="BoxMesh" id="3"]
43 |
44 | [sub_resource type="StandardMaterial3D" id="4"]
45 | albedo_color = Color(0.722656, 0.791992, 1, 1)
46 | roughness = 0.0
47 |
48 | [sub_resource type="SphereMesh" id="SphereMesh_ecs3k"]
49 |
50 | [node name="GUIin3D" type="Node3D"]
51 |
52 | [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
53 | transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0)
54 | visible = false
55 | shadow_enabled = true
56 |
57 | [node name="WorldEnvironment" type="WorldEnvironment" parent="."]
58 | environment = SubResource("Environment_niyks")
59 |
60 | [node name="GUIPanel3D" parent="." instance=ExtResource("1")]
61 |
62 | [node name="Camera3D" type="Camera3D" parent="."]
63 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 0.999999, 0, 0, 3)
64 | fov = 74.0
65 | near = 0.1
66 |
67 | [node name="OmniLight3D" type="OmniLight3D" parent="."]
68 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.38866, 1.2413, 2.72141)
69 | shadow_enabled = true
70 | shadow_blur = 3.0
71 | omni_range = 10.0
72 |
73 | [node name="Camera_Move" type="AnimationPlayer" parent="."]
74 | libraries = {
75 | "": SubResource("AnimationLibrary_uw4n0")
76 | }
77 | autoplay = "Move_camera"
78 |
79 | [node name="Background" type="Node3D" parent="."]
80 |
81 | [node name="Wall" type="MeshInstance3D" parent="Background"]
82 | transform = Transform3D(4, 0, 0, 0, -1.74846e-07, -4, 0, 4, -1.74846e-07, -2.60819, 0.589247, -2.08943)
83 | mesh = SubResource("2")
84 |
85 | [node name="Wall2" type="MeshInstance3D" parent="Background"]
86 | transform = Transform3D(4, 0, 0, 0, -1.74846e-07, -4, 0, 4, -1.74846e-07, 5.08055, 0.589247, -2.08943)
87 | mesh = SubResource("2")
88 |
89 | [node name="Wall3" type="MeshInstance3D" parent="Background"]
90 | transform = Transform3D(-1.74846e-07, -4, 0, -1.74846e-07, 7.64274e-15, -4, 4, -1.74846e-07, -1.74846e-07, 9.04446, 0.589247, 1.62058)
91 | mesh = SubResource("2")
92 |
93 | [node name="Floor" type="MeshInstance3D" parent="Background"]
94 | transform = Transform3D(4, 0, 0, 0, 4, 0, 0, 0, 4, -2.60819, -2.68765, 1.46502)
95 | mesh = SubResource("2")
96 |
97 | [node name="Floor2" type="MeshInstance3D" parent="Background"]
98 | transform = Transform3D(4, 0, 0, 0, 4, 0, 0, 0, 4, 5.08055, -2.68765, 1.46502)
99 | mesh = SubResource("2")
100 |
101 | [node name="Cube" type="MeshInstance3D" parent="Background"]
102 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.25901, -0.598608, 0.374871)
103 | mesh = SubResource("3")
104 | surface_material_override/0 = SubResource("4")
105 |
106 | [node name="Sphere" type="MeshInstance3D" parent="Background"]
107 | transform = Transform3D(2, 0, 0, 0, 2, 0, 0, 0, 2, 2.88761, 2.01326, 0.374871)
108 | mesh = SubResource("SphereMesh_ecs3k")
109 | surface_material_override/0 = SubResource("4")
110 |
111 | [node name="ThirdNode" type="Node" parent="."]
112 | script = ExtResource("2_xsiun")
113 |
--------------------------------------------------------------------------------
/data/gui_panel_3d.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=6 format=3 uid="uid://dvl383ispakmn"]
2 |
3 | [ext_resource type="Script" path="res://src/gui_3d.gd" id="1_lsoqm"]
4 |
5 | [sub_resource type="QuadMesh" id="1"]
6 | size = Vector2(3, 2)
7 |
8 | [sub_resource type="ViewportTexture" id="2"]
9 | viewport_path = NodePath("SubViewport")
10 |
11 | [sub_resource type="StandardMaterial3D" id="3"]
12 | resource_local_to_scene = true
13 | transparency = 1
14 | shading_mode = 0
15 | albedo_texture = SubResource("2")
16 |
17 | [sub_resource type="BoxShape3D" id="4"]
18 | size = Vector3(3, 2, 0.1)
19 |
20 | [node name="GUIPanel3D" type="Node3D"]
21 | process_mode = 3
22 | script = ExtResource("1_lsoqm")
23 |
24 | [node name="SubViewport" type="SubViewport" parent="."]
25 | gui_embed_subwindows = true
26 | size = Vector2i(560, 360)
27 | render_target_update_mode = 4
28 |
29 | [node name="GUI" type="Control" parent="SubViewport"]
30 | layout_mode = 3
31 | anchors_preset = 0
32 | offset_right = 560.0
33 | offset_bottom = 360.0
34 | mouse_filter = 1
35 |
36 | [node name="Panel" type="Panel" parent="SubViewport/GUI"]
37 | layout_mode = 0
38 | anchor_right = 1.0
39 | anchor_bottom = 1.0
40 |
41 | [node name="VBoxContainer" type="VBoxContainer" parent="SubViewport/GUI/Panel"]
42 | layout_mode = 1
43 | anchors_preset = 9
44 | anchor_bottom = 1.0
45 | offset_left = 20.0
46 | offset_top = 20.0
47 | offset_right = 319.0
48 | offset_bottom = -20.0
49 | grow_vertical = 2
50 | theme_override_constants/separation = 13
51 |
52 | [node name="Label" type="Label" parent="SubViewport/GUI/Panel/VBoxContainer"]
53 | layout_mode = 2
54 | text = "Hello world!"
55 | horizontal_alignment = 1
56 |
57 | [node name="Quad" type="MeshInstance3D" parent="."]
58 | mesh = SubResource("1")
59 | surface_material_override/0 = SubResource("3")
60 |
61 | [node name="Area3D" type="Area3D" parent="Quad"]
62 | collision_layer = 2
63 | input_capture_on_drag = true
64 |
65 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Quad/Area3D"]
66 | shape = SubResource("4")
67 |
--------------------------------------------------------------------------------
/data/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/data/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://2cvgmt2fmpao"
6 | path="res://.godot/imported/icon.svg-7967cc08d22e46b525e9855c7e0ca0ca.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://data/icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-7967cc08d22e46b525e9855c7e0ca0ca.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=true
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=4.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/data/robot_eye.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="AtlasTexture" load_steps=2 format=3 uid="uid://cqelg04ohkgm5"]
2 |
3 | [ext_resource type="Texture2D" uid="uid://2cvgmt2fmpao" path="res://data/icon.svg" id="1_ofydq"]
4 |
5 | [resource]
6 | atlas = ExtResource("1_ofydq")
7 | region = Rect2(142, 228, 64, 64)
8 |
--------------------------------------------------------------------------------
/data/sample_config.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Resource" script_class="ImGuiConfig" load_steps=7 format=3 uid="uid://bm0qxspuntbpl"]
2 |
3 | [ext_resource type="FontFile" uid="uid://c2o4vx2jik43e" path="res://data/Hack-Regular.ttf" id="1_0g12f"]
4 | [ext_resource type="Script" path="res://addons/imgui-godot/scripts/ImGuiConfig.gd" id="1_n8f18"]
5 | [ext_resource type="Script" path="res://addons/imgui-godot/scripts/ImGuiFont.gd" id="2_etwwr"]
6 | [ext_resource type="FontFile" uid="uid://bk0s2hduow46m" path="res://data/MPLUS2-Regular.ttf" id="3_qqkxo"]
7 |
8 | [sub_resource type="Resource" id="Resource_df4vj"]
9 | script = ExtResource("2_etwwr")
10 | FontData = ExtResource("1_0g12f")
11 | FontSize = 18
12 | Merge = true
13 |
14 | [sub_resource type="Resource" id="Resource_kiahq"]
15 | script = ExtResource("2_etwwr")
16 | FontData = ExtResource("3_qqkxo")
17 | FontSize = 22
18 | Merge = true
19 |
20 | [resource]
21 | script = ExtResource("1_n8f18")
22 | Fonts = Array[ExtResource("2_etwwr")]([SubResource("Resource_df4vj"), SubResource("Resource_kiahq")])
23 | AddDefaultFont = true
24 | Scale = 1.0
25 | IniFilename = "user://imgui.ini"
26 | Renderer = "RenderingDevice"
27 | Layer = 100
28 |
--------------------------------------------------------------------------------
/doc/.gdignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/doc/.gdignore
--------------------------------------------------------------------------------
/doc/examples/CSharpGameProject/CSharpGameProject.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net8.0
4 | true
5 | True
6 | enable
7 |
8 |
9 | $(DefineConstants);IMGUI
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/doc/examples/CSharpGameProject/CSharpGameProject.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2012
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpGameProject", "CSharpGameProject.csproj", "{86EC619D-62C6-466E-9415-95CB700470B1}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Any CPU = Debug|Any CPU
8 | ExportDebug|Any CPU = ExportDebug|Any CPU
9 | ExportRelease|Any CPU = ExportRelease|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {86EC619D-62C6-466E-9415-95CB700470B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {86EC619D-62C6-466E-9415-95CB700470B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {86EC619D-62C6-466E-9415-95CB700470B1}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
15 | {86EC619D-62C6-466E-9415-95CB700470B1}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
16 | {86EC619D-62C6-466E-9415-95CB700470B1}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
17 | {86EC619D-62C6-466E-9415-95CB700470B1}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
18 | EndGlobalSection
19 | EndGlobal
20 |
--------------------------------------------------------------------------------
/doc/examples/CSharpGameProject/Globals.cs:
--------------------------------------------------------------------------------
1 | #if !IMGUI
2 | namespace ImGuiNET { }
3 | namespace ImGuiGodot { }
4 | #endif
5 |
--------------------------------------------------------------------------------
/doc/examples/CSharpGameProject/Main.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using ImGuiNET;
3 |
4 | namespace CSharpGameProject;
5 |
6 | public partial class Main : Node
7 | {
8 | public override void _Ready()
9 | {
10 | if (DisplayServer.WindowGetVsyncMode() == DisplayServer.VSyncMode.Disabled)
11 | {
12 | int refreshRate = (int)DisplayServer.ScreenGetRefreshRate();
13 | Engine.MaxFps = refreshRate > 0 ? refreshRate : 60;
14 | }
15 |
16 | #if IMGUI
17 | var io = ImGui.GetIO();
18 | io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable;
19 | #endif
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/doc/examples/CSharpGameProject/README.md:
--------------------------------------------------------------------------------
1 | # C# Game Project
2 |
3 | Run:
4 |
5 | ```
6 | godotenv addons install
7 | ```
8 |
9 | (or install from AssetLib)
10 |
11 | See the .csproj and Globals.cs for recommended changes to support exports with ImGui disabled.
12 |
--------------------------------------------------------------------------------
/doc/examples/CSharpGameProject/Sprite.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using ImGuiNET;
3 |
4 | namespace CSharpGameProject;
5 |
6 | public partial class Sprite : Sprite2D
7 | {
8 | public override void _Process(double delta)
9 | {
10 | Position = new((float)(Position.X + (delta * 10.0)), Position.Y);
11 |
12 | #if IMGUI
13 | ImGui.Begin($"SpriteTool: {Name}", ImGuiWindowFlags.AlwaysAutoResize);
14 | int[] pos = [(int)Position.X, (int)Position.Y];
15 | if (ImGui.DragInt2("position", ref pos[0]))
16 | {
17 | Position = new(pos[0], pos[1]);
18 | }
19 | ImGui.End();
20 | #endif
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/doc/examples/CSharpGameProject/addons.json:
--------------------------------------------------------------------------------
1 | {
2 | "addons": {
3 | "imgui-godot": {
4 | "url": "../../../addons/imgui-godot",
5 | "source": "symlink"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/doc/examples/CSharpGameProject/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/doc/examples/CSharpGameProject/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://cq5t7s1jnaiuj"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/doc/examples/CSharpGameProject/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=3 uid="uid://cyqi1opwbrjvr"]
2 |
3 | [ext_resource type="Script" path="res://Main.cs" id="1_taldx"]
4 | [ext_resource type="Texture2D" uid="uid://cq5t7s1jnaiuj" path="res://icon.svg" id="2_e48e3"]
5 | [ext_resource type="Script" path="res://Sprite.cs" id="3_wp2si"]
6 |
7 | [node name="Node2D" type="Node2D"]
8 | script = ExtResource("1_taldx")
9 |
10 | [node name="Icon" type="Sprite2D" parent="."]
11 | position = Vector2(450, 244)
12 | texture = ExtResource("2_e48e3")
13 | script = ExtResource("3_wp2si")
14 |
--------------------------------------------------------------------------------
/doc/examples/CSharpGameProject/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="CSharpGameProject"
14 | run/main_scene="res://main.tscn"
15 | config/features=PackedStringArray("4.2", "C#", "Forward Plus")
16 | config/icon="res://icon.svg"
17 |
18 | [autoload]
19 |
20 | ImGuiRoot="*res://addons/imgui-godot/data/ImGuiRoot.tscn"
21 |
22 | [display]
23 |
24 | window/subwindows/embed_subwindows=false
25 | window/vsync/vsync_mode=0
26 |
27 | [dotnet]
28 |
29 | project/assembly_name="CSharpGameProject"
30 |
31 | [editor_plugins]
32 |
33 | enabled=PackedStringArray("res://addons/imgui-godot/plugin.cfg")
34 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.26)
2 |
3 | # Windows only
4 |
5 | set(IMGUI_GODOT_INCLUDE "../../../addons/imgui-godot/include")
6 |
7 | project(gdexample CXX)
8 |
9 | include(FetchContent)
10 | FetchContent_Declare(
11 | godot-cpp
12 | GIT_REPOSITORY https://github.com/godotengine/godot-cpp
13 | GIT_TAG 4.2
14 | )
15 | FetchContent_MakeAvailable(godot-cpp)
16 |
17 | FetchContent_Declare(
18 | imgui
19 | GIT_REPOSITORY https://github.com/ocornut/imgui
20 | GIT_TAG v1.91.6-docking
21 | )
22 | FetchContent_MakeAvailable(imgui)
23 |
24 | FetchContent_Declare(
25 | implot
26 | GIT_REPOSITORY https://github.com/epezent/implot
27 | GIT_TAG master
28 | )
29 | FetchContent_MakeAvailable(implot)
30 |
31 | FetchContent_Declare(
32 | imgui_markdown
33 | GIT_REPOSITORY https://github.com/enkisoftware/imgui_markdown
34 | GIT_TAG main
35 | )
36 | FetchContent_MakeAvailable(imgui_markdown)
37 |
38 | add_library(gdexample SHARED)
39 | target_compile_features(gdexample PRIVATE cxx_std_20)
40 | target_compile_definitions(gdexample PUBLIC
41 | IMGUI_USER_CONFIG="imconfig-godot.h"
42 | )
43 | if (MSVC)
44 | target_compile_options(godot-cpp PRIVATE "/MP")
45 | target_compile_options(gdexample PRIVATE "/MP")
46 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD ON)
47 | endif()
48 |
49 | target_sources(gdexample PRIVATE
50 | ${imgui_SOURCE_DIR}/imgui.cpp
51 | ${imgui_SOURCE_DIR}/imgui_demo.cpp
52 | ${imgui_SOURCE_DIR}/imgui_draw.cpp
53 | ${imgui_SOURCE_DIR}/imgui_tables.cpp
54 | ${imgui_SOURCE_DIR}/imgui_widgets.cpp
55 | ${imgui_SOURCE_DIR}/imgui.h
56 | ${implot_SOURCE_DIR}/implot.cpp
57 | ${implot_SOURCE_DIR}/implot_demo.cpp
58 | ${implot_SOURCE_DIR}/implot_items.cpp
59 | ${implot_SOURCE_DIR}/implot.h
60 | ${imgui_markdown_SOURCE_DIR}/imgui_markdown.h
61 | src/example.cpp
62 | src/example.h
63 | src/register_types.cpp
64 | src/register_types.h
65 | src/gdmarkdown.cpp
66 | src/gdmarkdown.h
67 | )
68 |
69 | target_link_libraries(gdexample PUBLIC godot-cpp)
70 |
71 | target_include_directories(gdexample PRIVATE
72 | src
73 | ${IMGUI_GODOT_INCLUDE}
74 | ${imgui_SOURCE_DIR}
75 | ${implot_SOURCE_DIR}
76 | ${imgui_markdown_SOURCE_DIR}
77 | )
78 |
79 | set_property(TARGET gdexample
80 | PROPERTY OUTPUT_NAME "libgdexample.windows.template_$,debug,release>.x86_64")
81 |
82 | set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/project")
83 |
84 | install(TARGETS gdexample
85 | RUNTIME DESTINATION bin
86 | )
87 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/README.md:
--------------------------------------------------------------------------------
1 | Run:
2 |
3 | ```
4 | scons
5 | cd project
6 | godotenv addons install
7 | ```
8 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/SConstruct:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | IMGUI_GODOT_INCLUDE = "../../../addons/imgui-godot/include"
4 | IMGUI_TAG = "v1.91.6-docking"
5 |
6 | import os
7 | import subprocess
8 |
9 | if not os.path.exists("godot-cpp"):
10 | subprocess.call(
11 | "git clone -b 4.2 https://github.com/godotengine/godot-cpp", shell=True
12 | )
13 |
14 | if not os.path.exists("imgui"):
15 | subprocess.call("git clone -b docking https://github.com/ocornut/imgui", shell=True)
16 | subprocess.call(f"git -C imgui checkout {IMGUI_TAG}", shell=True)
17 |
18 | if not os.path.exists("implot"):
19 | subprocess.call("git clone https://github.com/epezent/implot", shell=True)
20 |
21 | if not os.path.exists("imgui_markdown"):
22 | subprocess.call(
23 | "git clone https://github.com/enkisoftware/imgui_markdown", shell=True
24 | )
25 |
26 | env = SConscript("godot-cpp/SConstruct")
27 | env = env.Clone()
28 |
29 | env.Append(CPPPATH=["src/"])
30 | sources = Glob("src/*.cpp")
31 |
32 | # Dear ImGui
33 | sources += Glob(f"imgui/*.cpp")
34 | env.Append(CPPDEFINES=['IMGUI_USER_CONFIG="\\"imconfig-godot.h\\""'])
35 | env.Append(CPPPATH=["imgui", IMGUI_GODOT_INCLUDE])
36 |
37 | # ImPlot
38 | sources += Glob(f"implot/*.cpp")
39 | env.Append(CPPPATH=["implot"])
40 |
41 | # imgui_markdown
42 | env.Append(CPPPATH=["imgui_markdown"])
43 |
44 | if env["platform"] == "macos":
45 | library = env.SharedLibrary(
46 | "project/bin/libgdexample.{}.{}.framework/libgdexample.{}.{}".format(
47 | env["platform"], env["target"], env["platform"], env["target"]
48 | ),
49 | source=sources,
50 | )
51 | else:
52 | library = env.SharedLibrary(
53 | "project/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
54 | source=sources,
55 | )
56 |
57 | Default(library)
58 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/Hack-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/doc/examples/GDExt/project/Hack-Bold.ttf
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/Hack-Bold.ttf.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="font_data_dynamic"
4 | type="FontFile"
5 | uid="uid://geey1pyskdev"
6 | path="res://.godot/imported/Hack-Bold.ttf-691cdc24fdde9142fc0f47c007a581d0.fontdata"
7 |
8 | [deps]
9 |
10 | source_file="res://Hack-Bold.ttf"
11 | dest_files=["res://.godot/imported/Hack-Bold.ttf-691cdc24fdde9142fc0f47c007a581d0.fontdata"]
12 |
13 | [params]
14 |
15 | Rendering=null
16 | antialiasing=1
17 | generate_mipmaps=false
18 | multichannel_signed_distance_field=false
19 | msdf_pixel_range=8
20 | msdf_size=48
21 | allow_system_fallback=true
22 | force_autohinter=false
23 | hinting=1
24 | subpixel_positioning=1
25 | oversampling=0.0
26 | Fallbacks=null
27 | fallbacks=[]
28 | Compress=null
29 | compress=true
30 | preload=[]
31 | language_support={}
32 | script_support={}
33 | opentype_features={}
34 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/Hack-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/doc/examples/GDExt/project/Hack-Italic.ttf
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/Hack-Italic.ttf.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="font_data_dynamic"
4 | type="FontFile"
5 | uid="uid://ccn210ltcrs6i"
6 | path="res://.godot/imported/Hack-Italic.ttf-da10696e2f4be4192574d1c950d4085f.fontdata"
7 |
8 | [deps]
9 |
10 | source_file="res://Hack-Italic.ttf"
11 | dest_files=["res://.godot/imported/Hack-Italic.ttf-da10696e2f4be4192574d1c950d4085f.fontdata"]
12 |
13 | [params]
14 |
15 | Rendering=null
16 | antialiasing=1
17 | generate_mipmaps=false
18 | multichannel_signed_distance_field=false
19 | msdf_pixel_range=8
20 | msdf_size=48
21 | allow_system_fallback=true
22 | force_autohinter=false
23 | hinting=1
24 | subpixel_positioning=1
25 | oversampling=0.0
26 | Fallbacks=null
27 | fallbacks=[]
28 | Compress=null
29 | compress=true
30 | preload=[]
31 | language_support={}
32 | script_support={}
33 | opentype_features={}
34 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/Hack-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/doc/examples/GDExt/project/Hack-Regular.ttf
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/Hack-Regular.ttf.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="font_data_dynamic"
4 | type="FontFile"
5 | uid="uid://2se0brkpdxhs"
6 | path="res://.godot/imported/Hack-Regular.ttf-4957220eed9c50075bb4de8b4fadc317.fontdata"
7 |
8 | [deps]
9 |
10 | source_file="res://Hack-Regular.ttf"
11 | dest_files=["res://.godot/imported/Hack-Regular.ttf-4957220eed9c50075bb4de8b4fadc317.fontdata"]
12 |
13 | [params]
14 |
15 | Rendering=null
16 | antialiasing=1
17 | generate_mipmaps=false
18 | multichannel_signed_distance_field=false
19 | msdf_pixel_range=8
20 | msdf_size=48
21 | allow_system_fallback=true
22 | force_autohinter=false
23 | hinting=1
24 | subpixel_positioning=1
25 | oversampling=0.0
26 | Fallbacks=null
27 | fallbacks=[]
28 | Compress=null
29 | compress=true
30 | preload=[]
31 | language_support={}
32 | script_support={}
33 | opentype_features={}
34 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/addons.json:
--------------------------------------------------------------------------------
1 | {
2 | "addons": {
3 | "imgui-godot": {
4 | "url": "../../../../addons/imgui-godot",
5 | "source": "symlink"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/example.gdextension:
--------------------------------------------------------------------------------
1 | [configuration]
2 |
3 | entry_symbol = "example_library_init"
4 | compatibility_minimum = "4.2"
5 |
6 | [libraries]
7 |
8 | macos.debug = "res://bin/libgdexample.macos.template_debug.framework"
9 | macos.release = "res://bin/libgdexample.macos.template_release.framework"
10 | windows.debug.x86_64 = "res://bin/libgdexample.windows.template_debug.x86_64.dll"
11 | windows.release.x86_64 = "res://bin/libgdexample.windows.template_release.x86_64.dll"
12 | linux.debug.x86_64 = "res://bin/libgdexample.linux.template_debug.x86_64.so"
13 | linux.release.x86_64 = "res://bin/libgdexample.linux.template_release.x86_64.so"
14 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://cr045l23wjmqc"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=true
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=4.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/imgui_config.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Resource" script_class="ImGuiConfig" load_steps=11 format=3 uid="uid://c58buectmbwmf"]
2 |
3 | [ext_resource type="Script" path="res://addons/imgui-godot/scripts/ImGuiFont.gd" id="1_0saup"]
4 | [ext_resource type="FontFile" uid="uid://2se0brkpdxhs" path="res://Hack-Regular.ttf" id="1_7tey3"]
5 | [ext_resource type="Script" path="res://addons/imgui-godot/scripts/ImGuiConfig.gd" id="1_nq4e5"]
6 | [ext_resource type="FontFile" uid="uid://geey1pyskdev" path="res://Hack-Bold.ttf" id="3_5fv0r"]
7 | [ext_resource type="FontFile" uid="uid://ccn210ltcrs6i" path="res://Hack-Italic.ttf" id="4_34el5"]
8 |
9 | [sub_resource type="Resource" id="Resource_57j4v"]
10 | script = ExtResource("1_0saup")
11 | FontData = ExtResource("1_7tey3")
12 | FontSize = 16
13 | Merge = false
14 |
15 | [sub_resource type="Resource" id="Resource_4trot"]
16 | script = ExtResource("1_0saup")
17 | FontData = ExtResource("3_5fv0r")
18 | FontSize = 32
19 | Merge = false
20 |
21 | [sub_resource type="Resource" id="Resource_okot8"]
22 | script = ExtResource("1_0saup")
23 | FontData = ExtResource("3_5fv0r")
24 | FontSize = 24
25 | Merge = false
26 |
27 | [sub_resource type="Resource" id="Resource_3knfi"]
28 | script = ExtResource("1_0saup")
29 | FontData = ExtResource("3_5fv0r")
30 | FontSize = 16
31 | Merge = false
32 |
33 | [sub_resource type="Resource" id="Resource_2wpqv"]
34 | script = ExtResource("1_0saup")
35 | FontData = ExtResource("4_34el5")
36 | FontSize = 16
37 | Merge = false
38 |
39 | [resource]
40 | script = ExtResource("1_nq4e5")
41 | Fonts = Array[ExtResource("1_0saup")]([SubResource("Resource_57j4v"), SubResource("Resource_4trot"), SubResource("Resource_okot8"), SubResource("Resource_3knfi"), SubResource("Resource_2wpqv")])
42 | AddDefaultFont = false
43 | Scale = 1.0
44 | IniFilename = "user://imgui.ini"
45 | Renderer = "RenderingDevice"
46 | Layer = 128
47 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene format=3 uid="uid://c08lt0b17jqog"]
2 |
3 | [node name="Node2D" type="Node2D"]
4 |
5 | [node name="Example" type="Example" parent="."]
6 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [addons]
12 |
13 | imgui/config="res://imgui_config.tres"
14 |
15 | [application]
16 |
17 | config/name="GDExt"
18 | run/main_scene="res://main.tscn"
19 | config/features=PackedStringArray("4.2", "Forward Plus")
20 | run/max_fps=144
21 | config/icon="res://icon.svg"
22 |
23 | [autoload]
24 |
25 | ImGuiRoot="*res://addons/imgui-godot/data/ImGuiRoot.tscn"
26 |
27 | [display]
28 |
29 | window/subwindows/embed_subwindows=false
30 | window/vsync/vsync_mode=0
31 |
32 | [editor_plugins]
33 |
34 | enabled=PackedStringArray("res://addons/imgui-godot/plugin.cfg")
35 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/project/robot_eye.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="AtlasTexture" load_steps=2 format=3 uid="uid://cqelg04ohkgm5"]
2 |
3 | [ext_resource type="Texture2D" uid="uid://cr045l23wjmqc" path="res://icon.svg" id="1_d7u5w"]
4 |
5 | [resource]
6 | atlas = ExtResource("1_d7u5w")
7 | region = Rect2(142, 228, 64, 64)
8 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/src/example.cpp:
--------------------------------------------------------------------------------
1 | #include "example.h"
2 | #include "gdmarkdown.h"
3 | #include
4 | #include
5 | #include
6 |
7 | using godot::Engine;
8 | using godot::ResourceLoader;
9 |
10 | static const std::string markdownText = R"(# H1 Header
11 |
12 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
13 |
14 | ## H2 Header
15 |
16 | Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
17 |
18 | ### H3 Header
19 |
20 | * Item 1
21 | * Item 2
22 | * Item 3
23 |
24 | *Emphasis* and **strong emphasis** change the appearance of the text.
25 |
26 | Link: [Godot Engine](https://godotengine.org)
27 |
28 | robot eye 
29 |
30 | ___
31 |
32 | big robot
33 | 
34 | )";
35 |
36 | void Example::_bind_methods()
37 | {
38 | }
39 |
40 | Example::Example()
41 | {
42 | }
43 |
44 | Example::~Example()
45 | {
46 | }
47 |
48 | void Example::_ready()
49 | {
50 | #ifdef DEBUG_ENABLED
51 | if (Engine::get_singleton()->is_editor_hint())
52 | return;
53 | #endif
54 |
55 | _img = ResourceLoader::get_singleton()->load("res://robot_eye.tres");
56 | ImGui::InitMarkdown();
57 | }
58 |
59 | void Example::_process(double delta)
60 | {
61 | #ifdef DEBUG_ENABLED
62 | if (Engine::get_singleton()->is_editor_hint())
63 | return;
64 | #endif
65 |
66 | static int x = 0;
67 |
68 | ImGui::SetNextWindowSize({200, 200}, ImGuiCond_Once);
69 | ImGui::Begin("GDExtension Example");
70 | ImGui::DragInt("x", &x);
71 | ImGui::Text("x = %d", x);
72 | ImGui::Separator();
73 | ImGui::Image(_img, {64, 64});
74 | ImGui::End();
75 |
76 | ImGui::ShowDemoWindow();
77 |
78 | ImPlot::ShowDemoWindow();
79 |
80 | ImGui::Begin("Markdown example");
81 | ImGui::Markdown(markdownText);
82 | ImGui::End();
83 | }
84 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/src/example.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | using godot::Node;
6 | using godot::Ref;
7 | using godot::AtlasTexture;
8 |
9 | class Example : public Node
10 | {
11 | GDCLASS(Example, Node);
12 |
13 | protected:
14 | static void _bind_methods();
15 |
16 | public:
17 | Example();
18 | ~Example();
19 |
20 | void _ready() override;
21 | void _process(double delta) override;
22 |
23 | private:
24 | Ref _img;
25 | };
26 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/src/gdmarkdown.cpp:
--------------------------------------------------------------------------------
1 | #include "gdmarkdown.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | namespace {
10 | using godot::AtlasTexture;
11 | using godot::OS;
12 | using godot::Ref;
13 | using godot::ResourceLoader;
14 | using godot::String;
15 | using godot::Texture2D;
16 |
17 | ImGui::MarkdownConfig mdConfig;
18 | ImFont* italicFont = nullptr;
19 |
20 | void MdLinkCallback(ImGui::MarkdownLinkCallbackData data)
21 | {
22 | if (!data.isImage)
23 | {
24 | String link = String::utf8(data.link, data.linkLength);
25 | OS::get_singleton()->shell_open(link);
26 | }
27 | }
28 |
29 | ImGui::MarkdownImageData MdImageCallback(ImGui::MarkdownLinkCallbackData data)
30 | {
31 | ImGui::MarkdownImageData imageData;
32 |
33 | String link = String::utf8(data.link, data.linkLength);
34 | Ref tex = ResourceLoader::get_singleton()->load(link);
35 |
36 | if (tex.is_valid())
37 | {
38 | imageData.isValid = true;
39 | imageData.useLinkCallback = false;
40 | imageData.user_texture_id = (ImTextureID)tex->get_rid().get_id();
41 |
42 | if (Ref atex = tex; atex.is_valid())
43 | {
44 | imageData.size = atex->get_size();
45 |
46 | Vector2 atlasSize = atex->get_atlas()->get_size();
47 | imageData.uv0 = atex->get_region().get_position() / atlasSize;
48 | imageData.uv1 = atex->get_region().get_end() / atlasSize;
49 | }
50 | else
51 | {
52 | imageData.size = tex->get_size();
53 | }
54 | }
55 |
56 | return imageData;
57 | }
58 |
59 | void MdFormatCallback(const ImGui::MarkdownFormatInfo& fmt, bool start)
60 | {
61 | if (fmt.type == ImGui::MarkdownFormatType::EMPHASIS && fmt.level == 1)
62 | {
63 | if (start)
64 | ImGui::PushFont(italicFont);
65 | else
66 | ImGui::PopFont();
67 | }
68 | else if (fmt.type == ImGui::MarkdownFormatType::HEADING)
69 | {
70 | // default has excessive whitespace
71 |
72 | int32_t level = std::min(fmt.level, ImGui::MarkdownConfig::NUMHEADINGS);
73 | ImGui::MarkdownHeadingFormat hfmt = fmt.config->headingFormats[level - 1];
74 |
75 | if (start)
76 | {
77 | ImGui::NewLine();
78 | if (hfmt.font)
79 | ImGui::PushFont(hfmt.font);
80 | }
81 | else
82 | {
83 | if (hfmt.separator)
84 | ImGui::Separator();
85 | if (hfmt.font)
86 | ImGui::PopFont();
87 | }
88 | }
89 | else
90 | {
91 | ImGui::defaultMarkdownFormatCallback(fmt, start);
92 | }
93 | }
94 |
95 | void MdTooltipCallback(ImGui::MarkdownTooltipCallbackData data)
96 | {
97 | if (data.linkData.isImage)
98 | {
99 | if (data.linkData.textLength > 0)
100 | {
101 | ImGui::SetTooltip("%.*s", data.linkData.textLength, data.linkData.text);
102 | }
103 | }
104 | else
105 | {
106 | ImGui::SetTooltip("%s Open in browser\n%.*s", data.linkIcon, data.linkData.linkLength, data.linkData.link);
107 | }
108 | }
109 | } // namespace
110 |
111 | void ImGui::InitMarkdown()
112 | {
113 | const auto& io = ImGui::GetIO();
114 | const auto& fonts = io.Fonts->Fonts;
115 |
116 | mdConfig.linkCallback = MdLinkCallback;
117 | mdConfig.tooltipCallback = MdTooltipCallback;
118 | mdConfig.imageCallback = MdImageCallback;
119 | mdConfig.formatCallback = MdFormatCallback;
120 | mdConfig.headingFormats[0] = {fonts[1], true};
121 | mdConfig.headingFormats[1] = {fonts[2], true};
122 | mdConfig.headingFormats[2] = {fonts[3], false};
123 |
124 | italicFont = fonts[4];
125 | }
126 |
127 | void ImGui::Markdown(std::string_view text)
128 | {
129 | ImGui::Markdown(text.data(), text.length(), mdConfig);
130 | }
131 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/src/gdmarkdown.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | namespace ImGui {
4 | void InitMarkdown();
5 | void Markdown(std::string_view text);
6 | } // namespace ImGui
7 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/src/register_types.cpp:
--------------------------------------------------------------------------------
1 | #include "register_types.h"
2 | #include "example.h"
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | using godot::MODULE_INITIALIZATION_LEVEL_SCENE;
12 |
13 | void initialize_example_module(ModuleInitializationLevel p_level)
14 | {
15 | if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE)
16 | return;
17 |
18 | ImGui::Godot::SyncImGuiPtrs();
19 | ImPlot::CreateContext();
20 |
21 | godot::ClassDB::register_class();
22 | }
23 |
24 | void uninitialize_example_module(ModuleInitializationLevel p_level)
25 | {
26 | if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE)
27 | return;
28 |
29 | ImPlot::DestroyContext();
30 | }
31 |
32 | extern "C" {
33 | GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address,
34 | GDExtensionClassLibraryPtr p_library,
35 | GDExtensionInitialization* r_initialization)
36 | {
37 | godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
38 |
39 | init_obj.register_initializer(initialize_example_module);
40 | init_obj.register_terminator(uninitialize_example_module);
41 | init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);
42 |
43 | return init_obj.init();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/doc/examples/GDExt/src/register_types.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | using godot::ModuleInitializationLevel;
5 |
6 | void initialize_example_module(ModuleInitializationLevel p_level);
7 | void uninitialize_example_module(ModuleInitializationLevel p_level);
8 |
--------------------------------------------------------------------------------
/doc/examples/GdsDemo/README.md:
--------------------------------------------------------------------------------
1 | Run:
2 |
3 | ```
4 | godotenv addons install
5 | ```
6 |
--------------------------------------------------------------------------------
/doc/examples/GdsDemo/addons.json:
--------------------------------------------------------------------------------
1 | {
2 | "addons": {
3 | "imgui-godot": {
4 | "url": "../../../addons/imgui-godot",
5 | "source": "symlink"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/doc/examples/GdsDemo/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/doc/examples/GdsDemo/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://p5eschom80xn"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/doc/examples/GdsDemo/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://dcv44scldjibq"]
2 |
3 | [ext_resource type="Script" path="res://demo.gd" id="1_dqw6r"]
4 |
5 | [node name="Control" type="Control"]
6 | layout_mode = 3
7 | anchors_preset = 15
8 | anchor_right = 1.0
9 | anchor_bottom = 1.0
10 | grow_horizontal = 2
11 | grow_vertical = 2
12 | script = ExtResource("1_dqw6r")
13 |
--------------------------------------------------------------------------------
/doc/examples/GdsDemo/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="GdsDemo"
14 | run/main_scene="res://main.tscn"
15 | config/features=PackedStringArray("4.3", "Forward Plus")
16 | config/icon="res://icon.svg"
17 |
18 | [autoload]
19 |
20 | ImGuiRoot="*res://addons/imgui-godot/data/ImGuiRoot.tscn"
21 |
22 | [display]
23 |
24 | window/subwindows/embed_subwindows=false
25 | window/vsync/vsync_mode=0
26 |
27 | [editor_plugins]
28 |
29 | enabled=PackedStringArray("res://addons/imgui-godot/plugin.cfg")
30 |
--------------------------------------------------------------------------------
/doc/examples/GdsGameProject/README.md:
--------------------------------------------------------------------------------
1 | # GDScript Game Project
2 |
3 | Run:
4 |
5 | ```
6 | godotenv addons install
7 | ```
8 |
9 | (or install from AssetLib)
10 |
11 | This project demonstrates how to use ImGui in a way that makes it safe to export your project with
12 | imgui-godot disabled.
13 |
--------------------------------------------------------------------------------
/doc/examples/GdsGameProject/addons.json:
--------------------------------------------------------------------------------
1 | {
2 | "addons": {
3 | "imgui-godot": {
4 | "url": "../../../addons/imgui-godot",
5 | "source": "symlink"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/doc/examples/GdsGameProject/export/.gdignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/doc/examples/GdsGameProject/export/.gdignore
--------------------------------------------------------------------------------
/doc/examples/GdsGameProject/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/doc/examples/GdsGameProject/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://bwwgygwkoe4ei"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/doc/examples/GdsGameProject/main.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 |
3 | func _ready() -> void:
4 | # disabling vsync reduces input lag
5 | if DisplayServer.window_get_vsync_mode() == DisplayServer.VSYNC_DISABLED:
6 | var refreshRate := DisplayServer.screen_get_refresh_rate()
7 | Engine.max_fps = int(refreshRate) if refreshRate > 0.0 else 60
8 |
9 | if Engine.has_singleton("ImGuiAPI"):
10 | var ImGui: Object = Engine.get_singleton("ImGuiAPI")
11 | var io: Object = ImGui.GetIO()
12 | io.ConfigFlags |= ImGui.ConfigFlags_ViewportsEnable
13 |
14 | func _process(_delta: float) -> void:
15 | pass
16 |
--------------------------------------------------------------------------------
/doc/examples/GdsGameProject/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=3 uid="uid://cmvrg5mco0rv7"]
2 |
3 | [ext_resource type="Script" path="res://main.gd" id="1_a75q1"]
4 | [ext_resource type="Texture2D" uid="uid://bwwgygwkoe4ei" path="res://icon.svg" id="1_v7ads"]
5 | [ext_resource type="Script" path="res://sprite.gd" id="3_ngin8"]
6 |
7 | [node name="Node2D" type="Node2D"]
8 | script = ExtResource("1_a75q1")
9 |
10 | [node name="Sprite1" type="Sprite2D" parent="."]
11 | position = Vector2(275, 236)
12 | texture = ExtResource("1_v7ads")
13 | script = ExtResource("3_ngin8")
14 |
--------------------------------------------------------------------------------
/doc/examples/GdsGameProject/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="GdsGameProject"
14 | run/main_scene="res://main.tscn"
15 | config/features=PackedStringArray("4.2", "Forward Plus")
16 | config/icon="res://icon.svg"
17 |
18 | [autoload]
19 |
20 | ImGuiRoot="*res://addons/imgui-godot/data/ImGuiRoot.tscn"
21 |
22 | [debug]
23 |
24 | gdscript/warnings/shadowed_global_identifier=0
25 | gdscript/warnings/untyped_declaration=1
26 |
27 | [display]
28 |
29 | window/subwindows/embed_subwindows=false
30 | window/vsync/vsync_mode=0
31 |
32 | [editor_plugins]
33 |
34 | enabled=PackedStringArray("res://addons/imgui-godot/plugin.cfg")
35 |
36 | [rendering]
37 |
38 | textures/vram_compression/import_etc2_astc=true
39 |
--------------------------------------------------------------------------------
/doc/examples/GdsGameProject/sprite.gd:
--------------------------------------------------------------------------------
1 | extends Sprite2D
2 |
3 | func _ready() -> void:
4 | pass
5 |
6 | func _process(delta: float) -> void:
7 | position.x += delta * 10.0
8 |
9 | if Engine.has_singleton("ImGuiAPI"):
10 | var ImGui: Object = Engine.get_singleton("ImGuiAPI")
11 | ImGui.Begin("SpriteTool: %s" % name, [], ImGui.WindowFlags_AlwaysAutoResize)
12 | var pos: Array = [position.x, position.y]
13 | if ImGui.DragInt2("position", pos):
14 | position = Vector2(pos[0], pos[1])
15 | ImGui.End()
16 |
--------------------------------------------------------------------------------
/doc/examples/Module/README.md:
--------------------------------------------------------------------------------
1 | Run, for example:
2 |
3 | ```
4 | git clone https://github.com/ocornut/imgui
5 | git -C imgui checkout v1.91.6-docking
6 | git clone https://github.com/godotengine/godot
7 | cd godot
8 | scons custom_modules=../modules
9 | cd ../project
10 | godotenv addons install
11 | ../godot/bin/godot.* -e
12 | ```
13 |
--------------------------------------------------------------------------------
/doc/examples/Module/modules/mymod/SCsub:
--------------------------------------------------------------------------------
1 | Import('env')
2 |
3 | IMGUI_PATH = "../../imgui"
4 | IMGUI_GODOT_INCLUDE = "../../../../../addons/imgui-godot/include"
5 |
6 | env.Append(CPPPATH=[IMGUI_PATH, IMGUI_GODOT_INCLUDE])
7 | env.Append(CPPDEFINES=['IMGUI_USER_CONFIG="\\"imconfig-godot.h\\""'])
8 | env.add_source_files(env.modules_sources, f"{IMGUI_PATH}/*.cpp")
9 |
10 | env.add_source_files(env.modules_sources, "*.cpp")
11 |
--------------------------------------------------------------------------------
/doc/examples/Module/modules/mymod/config.py:
--------------------------------------------------------------------------------
1 | def can_build(env, platform):
2 | return True
3 |
4 | def configure(env):
5 | pass
6 |
--------------------------------------------------------------------------------
/doc/examples/Module/modules/mymod/mynode.cpp:
--------------------------------------------------------------------------------
1 | #include "mynode.h"
2 | #include "core/config/engine.h"
3 | #include "core/io/resource_loader.h"
4 | #include
5 |
6 | MyNode::MyNode()
7 | {
8 | #ifdef DEBUG_ENABLED
9 | if (Engine::get_singleton()->is_editor_hint())
10 | return;
11 | #endif
12 | set_process(true);
13 | }
14 |
15 | MyNode::~MyNode()
16 | {
17 | }
18 |
19 | void MyNode::_bind_methods()
20 | {
21 | }
22 |
23 | void MyNode::_notification(int what)
24 | {
25 | #ifdef DEBUG_ENABLED
26 | if (Engine::get_singleton()->is_editor_hint())
27 | return;
28 | #endif
29 |
30 | switch (what)
31 | {
32 | case NOTIFICATION_PROCESS:
33 | ImGui::Begin("C++ module", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
34 | ImGui::Text("hello");
35 | ImGui::Image(_img, {_iconSize, _iconSize});
36 | ImGui::DragFloat("size", &_iconSize, 1.f, 32.f, 512.f);
37 | ImGui::End();
38 | break;
39 |
40 | case NOTIFICATION_READY:
41 | _img = ResourceLoader::load("res://icon.svg");
42 | break;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/doc/examples/Module/modules/mymod/mynode.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "scene/main/node.h"
3 | #include "scene/resources/texture.h"
4 |
5 | class MyNode : public Node
6 | {
7 | GDCLASS(MyNode, Node);
8 |
9 | protected:
10 | static void _bind_methods();
11 |
12 | void _notification(int what);
13 |
14 | public:
15 | MyNode();
16 | ~MyNode();
17 |
18 | private:
19 | Ref _img;
20 | float _iconSize = 64.f;
21 | };
22 |
--------------------------------------------------------------------------------
/doc/examples/Module/modules/mymod/register_types.cpp:
--------------------------------------------------------------------------------
1 | #include "register_types.h"
2 | #include "core/object/class_db.h"
3 | #include "mynode.h"
4 | #include
5 |
6 | // use this macro once in any module
7 | IMGUI_GODOT_MODULE_INIT()
8 |
9 | void initialize_mymod_module(ModuleInitializationLevel p_level)
10 | {
11 | if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE)
12 | return;
13 | ClassDB::register_class();
14 | }
15 |
16 | void uninitialize_mymod_module(ModuleInitializationLevel p_level)
17 | {
18 | if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE)
19 | return;
20 | }
21 |
--------------------------------------------------------------------------------
/doc/examples/Module/modules/mymod/register_types.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "modules/register_module_types.h"
4 |
5 | void initialize_mymod_module(ModuleInitializationLevel p_level);
6 | void uninitialize_mymod_module(ModuleInitializationLevel p_level);
7 |
--------------------------------------------------------------------------------
/doc/examples/Module/project/addons.json:
--------------------------------------------------------------------------------
1 | {
2 | "addons": {
3 | "imgui-godot": {
4 | "url": "../../../../addons/imgui-godot",
5 | "source": "symlink"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/doc/examples/Module/project/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/doc/examples/Module/project/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://c4q3xqtrta6bs"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=true
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=4.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/doc/examples/Module/project/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene format=3 uid="uid://bgkdofvtxk6qx"]
2 |
3 | [node name="Node2D" type="Node2D"]
4 |
5 | [node name="MyNode" type="MyNode" parent="."]
6 |
--------------------------------------------------------------------------------
/doc/examples/Module/project/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="Module"
14 | run/main_scene="res://main.tscn"
15 | config/features=PackedStringArray("4.2", "Forward Plus")
16 | config/icon="res://icon.svg"
17 |
18 | [autoload]
19 |
20 | ImGuiRoot="*res://addons/imgui-godot/data/ImGuiRoot.tscn"
21 |
22 | [editor_plugins]
23 |
24 | enabled=PackedStringArray("res://addons/imgui-godot/plugin.cfg")
25 |
--------------------------------------------------------------------------------
/doc/examples/ToolCSharp/README.md:
--------------------------------------------------------------------------------
1 | Run:
2 |
3 | ```
4 | godotenv addons install
5 | ```
6 |
7 | Open the project, then restart the editor.
8 |
--------------------------------------------------------------------------------
/doc/examples/ToolCSharp/SpriteTool.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using ImGuiNET;
3 | using ImGuiGodot;
4 |
5 | [Tool]
6 | public partial class SpriteTool : Sprite2D
7 | {
8 | private bool _showImGui = false;
9 |
10 | public override void _Ready()
11 | {
12 | if (Engine.IsEditorHint())
13 | {
14 | _showImGui = ImGuiGD.ToolInit();
15 | var io = ImGui.GetIO();
16 | io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable;
17 | io.ConfigViewportsNoAutoMerge = true;
18 | }
19 | }
20 |
21 | public override void _Process(double delta)
22 | {
23 | if (_showImGui)
24 | {
25 | ImGui.Begin($"SpriteTool: {Name}");
26 | float scale = Scale.X;
27 | if (ImGui.DragFloat("scale", ref scale, 0.1f))
28 | {
29 | Scale = new(scale, scale);
30 | }
31 | ImGui.End();
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/doc/examples/ToolCSharp/ToolCSharp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net8.0
4 | true
5 | True
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/doc/examples/ToolCSharp/ToolCSharp.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2012
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ToolCSharp", "ToolCSharp.csproj", "{E08468D9-B6AE-4EBA-BE2B-B18B0194FEAF}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Any CPU = Debug|Any CPU
8 | ExportDebug|Any CPU = ExportDebug|Any CPU
9 | ExportRelease|Any CPU = ExportRelease|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {E08468D9-B6AE-4EBA-BE2B-B18B0194FEAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {E08468D9-B6AE-4EBA-BE2B-B18B0194FEAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {E08468D9-B6AE-4EBA-BE2B-B18B0194FEAF}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
15 | {E08468D9-B6AE-4EBA-BE2B-B18B0194FEAF}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
16 | {E08468D9-B6AE-4EBA-BE2B-B18B0194FEAF}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
17 | {E08468D9-B6AE-4EBA-BE2B-B18B0194FEAF}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
18 | EndGlobalSection
19 | EndGlobal
20 |
--------------------------------------------------------------------------------
/doc/examples/ToolCSharp/addons.json:
--------------------------------------------------------------------------------
1 | {
2 | "addons": {
3 | "imgui-godot": {
4 | "url": "../../../addons/imgui-godot",
5 | "source": "symlink"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/doc/examples/ToolCSharp/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/doc/examples/ToolCSharp/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://g0surar1un43"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/doc/examples/ToolCSharp/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=3 uid="uid://ceybxiw6agvb2"]
2 |
3 | [ext_resource type="Texture2D" uid="uid://g0surar1un43" path="res://icon.svg" id="1_vsk0a"]
4 | [ext_resource type="Script" path="res://SpriteTool.cs" id="2_a7b6t"]
5 |
6 | [node name="Node2D" type="Node2D"]
7 |
8 | [node name="Icon" type="Sprite2D" parent="."]
9 | position = Vector2(470, 223)
10 | texture = ExtResource("1_vsk0a")
11 | script = ExtResource("2_a7b6t")
12 |
--------------------------------------------------------------------------------
/doc/examples/ToolCSharp/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="ToolCSharp"
14 | run/main_scene="res://main.tscn"
15 | config/features=PackedStringArray("4.2", "C#", "Forward Plus")
16 | config/icon="res://icon.svg"
17 |
18 | [autoload]
19 |
20 | ImGuiRoot="*res://addons/imgui-godot/data/ImGuiRoot.tscn"
21 |
22 | [dotnet]
23 |
24 | project/assembly_name="ToolCSharp"
25 |
26 | [editor_plugins]
27 |
28 | enabled=PackedStringArray("res://addons/imgui-godot/plugin.cfg")
29 |
--------------------------------------------------------------------------------
/doc/examples/ToolScript/README.md:
--------------------------------------------------------------------------------
1 | Run:
2 |
3 | ```
4 | godotenv addons install
5 | ```
6 |
7 | Open the project, then restart the editor.
8 |
--------------------------------------------------------------------------------
/doc/examples/ToolScript/addons.json:
--------------------------------------------------------------------------------
1 | {
2 | "addons": {
3 | "imgui-godot": {
4 | "url": "../../../addons/imgui-godot",
5 | "source": "symlink"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/doc/examples/ToolScript/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/doc/examples/ToolScript/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://nhty36dbhwyw"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/doc/examples/ToolScript/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=3 uid="uid://cc1o2vsbuo1u8"]
2 |
3 | [ext_resource type="Texture2D" uid="uid://nhty36dbhwyw" path="res://icon.svg" id="1_refmf"]
4 | [ext_resource type="Script" path="res://sprite_tool.gd" id="2_e8mp5"]
5 |
6 | [node name="Node2D" type="Node2D"]
7 |
8 | [node name="Sprite 1" type="Sprite2D" parent="."]
9 | position = Vector2(264, 176)
10 | texture = ExtResource("1_refmf")
11 | script = ExtResource("2_e8mp5")
12 |
13 | [node name="Sprite 2" type="Sprite2D" parent="."]
14 | position = Vector2(790, 348)
15 | rotation = 0.785398
16 | scale = Vector2(2, 2)
17 | texture = ExtResource("1_refmf")
18 | script = ExtResource("2_e8mp5")
19 |
--------------------------------------------------------------------------------
/doc/examples/ToolScript/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="ToolScript"
14 | run/main_scene="res://main.tscn"
15 | config/features=PackedStringArray("4.2", "Forward Plus")
16 | config/icon="res://icon.svg"
17 |
18 | [autoload]
19 |
20 | ImGuiRoot="*res://addons/imgui-godot/data/ImGuiRoot.tscn"
21 |
22 | [editor_plugins]
23 |
24 | enabled=PackedStringArray("res://addons/imgui-godot/plugin.cfg")
25 |
--------------------------------------------------------------------------------
/doc/examples/ToolScript/sprite_tool.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Node2D
3 |
4 | var show_tool_gui := ImGuiGD.ToolInit()
5 | var myscale := [scale.x]
6 | var myrot := [0]
7 | var auto_rotate := [false]
8 |
9 | func _ready():
10 | if show_tool_gui:
11 | var io = ImGui.GetIO()
12 | io.ConfigFlags |= ImGui.ConfigFlags_ViewportsEnable
13 | io.ConfigViewportsNoAutoMerge = true
14 |
15 |
16 | func _process(_delta):
17 | if show_tool_gui:
18 | ImGui.Begin("tool: " + name)
19 | if ImGui.DragFloatEx("scale", myscale, 0.1, 0.25, 8.0):
20 | scale.x = myscale[0]
21 | scale.y = myscale[0]
22 |
23 | myrot[0] = rad_to_deg(rotation)
24 | if ImGui.DragInt("rotation", myrot):
25 | rotation = deg_to_rad(myrot[0])
26 |
27 | ImGui.Checkbox("auto rotate", auto_rotate)
28 | if auto_rotate[0]:
29 | if rotation >= 2 * PI:
30 | rotation = 0
31 | rotation += deg_to_rad(1)
32 | ImGui.End()
33 |
--------------------------------------------------------------------------------
/doc/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/doc/icon.png
--------------------------------------------------------------------------------
/doc/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/doc/screenshot.png
--------------------------------------------------------------------------------
/doc/test/addons/TestData/config_scale2x.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Resource" script_class="ImGuiConfig" load_steps=2 format=3 uid="uid://su0bdciskixm"]
2 |
3 | [ext_resource type="Script" path="res://addons/imgui-godot/scripts/ImGuiConfig.gd" id="1_o27t7"]
4 |
5 | [resource]
6 | script = ExtResource("1_o27t7")
7 | Fonts = Array[Resource("res://addons/imgui-godot/scripts/ImGuiFont.gd")]([])
8 | AddDefaultFont = true
9 | Scale = 2.0
10 | IniFilename = "user://imgui.ini"
11 | Renderer = "RenderingDevice"
12 | Layer = 128
13 |
--------------------------------------------------------------------------------
/doc/test/csbench/BenchCanvas.cs:
--------------------------------------------------------------------------------
1 | using ImGuiNET;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace csbench;
5 |
6 | [MemoryDiagnoser]
7 | public class BenchCanvas
8 | {
9 | private readonly ImDrawVertPtr v;
10 | private readonly Godot.Vector2[] points = new Godot.Vector2[1];
11 | private readonly Godot.Color[] colors = new Godot.Color[1];
12 | private readonly Godot.Vector2[] uvs = new Godot.Vector2[1];
13 |
14 | public unsafe BenchCanvas()
15 | {
16 | nint ptr = Marshal.AllocHGlobal(sizeof(ImDrawVert));
17 | v = new(ptr)
18 | {
19 | col = 0x12345678,
20 | uv = new(0.1f, 0.2f),
21 | pos = new(0.3f, 0.4f)
22 | };
23 | }
24 |
25 | [Benchmark(Baseline = true)]
26 | public void ConvertVertex1()
27 | {
28 | points[0] = new(v.pos.X, v.pos.Y);
29 | uint rgba = v.col;
30 | float r = (rgba & 0xFFu) / 255f;
31 | rgba >>= 8;
32 | float g = (rgba & 0xFFu) / 255f;
33 | rgba >>= 8;
34 | float b = (rgba & 0xFFu) / 255f;
35 | rgba >>= 8;
36 | float a = (rgba & 0xFFu) / 255f;
37 | colors[0] = new(r, g, b, a);
38 | uvs[0] = new(v.uv.X, v.uv.Y);
39 | }
40 |
41 | // same as #1
42 | [Benchmark]
43 | public void ConvertVertex2()
44 | {
45 | ref var out_pos = ref points[0];
46 | ref var out_color = ref colors[0];
47 | ref var out_uv = ref uvs[0];
48 |
49 | out_pos.X = v.pos.X;
50 | out_pos.Y = v.pos.Y;
51 | uint rgba = v.col;
52 | out_color.R = (rgba & 0xFFu) / 255f;
53 | rgba >>= 8;
54 | out_color.G = (rgba & 0xFFu) / 255f;
55 | rgba >>= 8;
56 | out_color.B = (rgba & 0xFFu) / 255f;
57 | rgba >>= 8;
58 | out_color.A = (rgba & 0xFFu) / 255f;
59 | out_uv.X = v.uv.X;
60 | out_uv.Y = v.uv.Y;
61 | }
62 |
63 | // this is a bit faster
64 | [Benchmark]
65 | public unsafe void ConvertVertex3()
66 | {
67 | ref var out_pos = ref points[0];
68 | ref var out_color = ref colors[0];
69 | ref var out_uv = ref uvs[0];
70 |
71 | ImDrawVert* p = v;
72 |
73 | out_pos.X = p->pos.X;
74 | out_pos.Y = p->pos.Y;
75 | uint rgba = p->col;
76 | out_color.R = (rgba & 0xFFu) / 255f;
77 | rgba >>= 8;
78 | out_color.G = (rgba & 0xFFu) / 255f;
79 | rgba >>= 8;
80 | out_color.B = (rgba & 0xFFu) / 255f;
81 | rgba >>= 8;
82 | out_color.A = (rgba & 0xFFu) / 255f;
83 | out_uv.X = p->uv.X;
84 | out_uv.Y = p->uv.Y;
85 | }
86 |
87 | // same as #3
88 | [Benchmark]
89 | public unsafe void ConvertVertex4()
90 | {
91 | ImDrawVert* p = v;
92 |
93 | points[0] = new(p->pos.X, p->pos.Y);
94 | uint rgba = p->col;
95 | float r = (rgba & 0xFFu) / 255f;
96 | rgba >>= 8;
97 | float g = (rgba & 0xFFu) / 255f;
98 | rgba >>= 8;
99 | float b = (rgba & 0xFFu) / 255f;
100 | rgba >>= 8;
101 | float a = (rgba & 0xFFu) / 255f;
102 | colors[0] = new(r, g, b, a);
103 | uvs[0] = new(p->uv.X, p->uv.Y);
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/doc/test/csbench/BenchRid.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System.Reflection.Emit;
3 | using System.Reflection;
4 | using System.Runtime.InteropServices;
5 | using System.Runtime.CompilerServices;
6 |
7 | namespace csbench;
8 |
9 | [MemoryDiagnoser]
10 | public class BenchRid
11 | {
12 | private readonly Func _constructRid;
13 | private readonly ulong _id = 12345;
14 |
15 | public BenchRid()
16 | {
17 | ConstructorInfo cinfo = typeof(Rid).GetConstructor(
18 | BindingFlags.NonPublic | BindingFlags.Instance,
19 | [typeof(ulong)]) ??
20 | throw new PlatformNotSupportedException("failed to get Rid constructor");
21 | DynamicMethod dm = new("ConstructRid", typeof(Rid), [typeof(ulong)]);
22 | ILGenerator il = dm.GetILGenerator();
23 | il.Emit(OpCodes.Ldarg_0);
24 | il.Emit(OpCodes.Newobj, cinfo);
25 | il.Emit(OpCodes.Ret);
26 | _constructRid = dm.CreateDelegate>();
27 | }
28 |
29 | [Benchmark]
30 | public Rid ConstructRid_Emitted()
31 | {
32 | return _constructRid(_id);
33 | }
34 |
35 | [Benchmark]
36 | public Rid ConstructRid_Marshal()
37 | {
38 | nint ptr = Marshal.AllocHGlobal(Marshal.SizeOf());
39 | byte[] bytes = BitConverter.GetBytes(_id);
40 | Marshal.Copy(bytes, 0, ptr, bytes.Length);
41 | Rid rv = Marshal.PtrToStructure(ptr);
42 | Marshal.FreeHGlobal(ptr);
43 | return rv;
44 | }
45 |
46 | [Benchmark]
47 | public Rid ConstructRid_MemoryMarshal_WriteRead()
48 | {
49 | Span bytes = stackalloc byte[sizeof(ulong)];
50 | MemoryMarshal.TryWrite(bytes, in _id);
51 | return MemoryMarshal.Read(bytes);
52 | }
53 |
54 | [Benchmark]
55 | public Rid ConstructRid_MemoryMarshal_SpanCast()
56 | {
57 | ReadOnlySpan uspan = new(in _id);
58 | ReadOnlySpan bytes = MemoryMarshal.Cast(uspan);
59 | return MemoryMarshal.Read(bytes);
60 | }
61 |
62 | [Benchmark]
63 | public Rid ConstructRid_UnsafeAccessor()
64 | {
65 | return RidConstructor(_id);
66 | }
67 |
68 | [UnsafeAccessor(UnsafeAccessorKind.Constructor)]
69 | private static extern Rid RidConstructor(ulong id);
70 |
71 | [Benchmark(Baseline = true)]
72 | public unsafe Rid ConstructRid_Unsafe_DirectCopy()
73 | {
74 | Rid rv;
75 | fixed (ulong* p = &_id)
76 | {
77 | Buffer.MemoryCopy(p, &rv, sizeof(Rid), sizeof(ulong));
78 | }
79 | return rv;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/doc/test/csbench/Program.cs:
--------------------------------------------------------------------------------
1 | using csbench;
2 |
3 | //BenchmarkRunner.Run();
4 | BenchmarkRunner.Run();
5 |
--------------------------------------------------------------------------------
/doc/test/csbench/csbench.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 | True
9 | False
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/doc/test/csbench/csbench.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.11.35222.181
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csbench", "csbench.csproj", "{D37BA677-C36A-4F7A-9E87-72D5CF034A7B}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {D37BA677-C36A-4F7A-9E87-72D5CF034A7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {D37BA677-C36A-4F7A-9E87-72D5CF034A7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {D37BA677-C36A-4F7A-9E87-72D5CF034A7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {D37BA677-C36A-4F7A-9E87-72D5CF034A7B}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {21D11FF2-8E04-4538-B85D-36C1B5758C37}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/doc/test/csharp/Main.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 | using Xunit;
4 | using ImGuiGodot;
5 | using ImGuiNET;
6 |
7 | namespace test;
8 |
9 | public partial class Main : Node
10 | {
11 | [Signal]
12 | public delegate void WithinProcessEventHandler();
13 |
14 | public override async void _Ready()
15 | {
16 | try
17 | {
18 | var io = ImGui.GetIO();
19 | io.SetIniFilename("");
20 |
21 | await ToSignal(this, SignalName.WithinProcess);
22 |
23 | Assert.Equal(ImGuiGD.Scale, 2);
24 | Assert.Equal(ImGui.GetFontSize(), 26.0f);
25 |
26 | // just for comparison with GDScript test
27 | Assert.Equal(ImGui.GetID("test_id"), 3584119329u);
28 |
29 | CallDeferred(nameof(ChangeScale));
30 |
31 | await ToSignal(this, SignalName.WithinProcess);
32 |
33 | Assert.Equal(ImGuiGD.Scale, 4);
34 | Assert.Equal(ImGui.GetFontSize(), 52.0f);
35 |
36 | // IniSavingRate
37 | GetTree().CreateTimer(5.1).Timeout += OnTimeout;
38 | }
39 | catch (Exception e)
40 | {
41 | GD.Print(e);
42 | GetTree().Quit(1);
43 | }
44 | }
45 |
46 | public async void OnTimeout()
47 | {
48 | try
49 | {
50 | await ToSignal(this, SignalName.WithinProcess);
51 |
52 | Assert.False(FileAccess.FileExists("user://imgui.ini"));
53 |
54 | GD.Print("All tests passed.");
55 | GetTree().Quit(0);
56 | }
57 | catch (Exception e)
58 | {
59 | GD.Print(e);
60 | GetTree().Quit(1);
61 | }
62 | }
63 |
64 | public override void _Process(double delta)
65 | {
66 | EmitSignal(SignalName.WithinProcess);
67 | }
68 |
69 | private static void ChangeScale()
70 | {
71 | ImGuiGD.Scale = 4;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/doc/test/csharp/addons.json:
--------------------------------------------------------------------------------
1 | {
2 | "addons": {
3 | "imgui-godot": {
4 | "url": "../../../addons/imgui-godot",
5 | "source": "symlink"
6 | },
7 | "TestData": {
8 | "url": "../addons/TestData",
9 | "source": "symlink"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/doc/test/csharp/export/.gdignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/doc/test/csharp/export/.gdignore
--------------------------------------------------------------------------------
/doc/test/csharp/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/doc/test/csharp/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://kfs316jt1ha0"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/doc/test/csharp/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://b4sq25vkasfoy"]
2 |
3 | [ext_resource type="Script" path="res://Main.cs" id="1_sm0lr"]
4 |
5 | [node name="Node2D" type="Node2D"]
6 | script = ExtResource("1_sm0lr")
7 |
--------------------------------------------------------------------------------
/doc/test/csharp/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [addons]
12 |
13 | imgui/config="res://addons/TestData/config_scale2x.tres"
14 |
15 | [application]
16 |
17 | config/name="test"
18 | run/main_scene="res://main.tscn"
19 | config/features=PackedStringArray("4.3", "C#", "Forward Plus")
20 | config/icon="res://icon.svg"
21 |
22 | [autoload]
23 |
24 | ImGuiRoot="*res://addons/imgui-godot/data/ImGuiRoot.tscn"
25 |
26 | [dotnet]
27 |
28 | project/assembly_name="test"
29 |
30 | [editor_plugins]
31 |
32 | enabled=PackedStringArray("res://addons/imgui-godot/plugin.cfg")
33 |
34 | [rendering]
35 |
36 | textures/vram_compression/import_etc2_astc=true
37 |
--------------------------------------------------------------------------------
/doc/test/csharp/test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net8.0
4 | net7.0
5 | net8.0
6 | true
7 | True
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/doc/test/csharp/test.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2012
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test.csproj", "{67604B9A-7DDB-4C26-8C73-5ACE0DD01BFD}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Any CPU = Debug|Any CPU
8 | ExportDebug|Any CPU = ExportDebug|Any CPU
9 | ExportRelease|Any CPU = ExportRelease|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {67604B9A-7DDB-4C26-8C73-5ACE0DD01BFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {67604B9A-7DDB-4C26-8C73-5ACE0DD01BFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {67604B9A-7DDB-4C26-8C73-5ACE0DD01BFD}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
15 | {67604B9A-7DDB-4C26-8C73-5ACE0DD01BFD}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
16 | {67604B9A-7DDB-4C26-8C73-5ACE0DD01BFD}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
17 | {67604B9A-7DDB-4C26-8C73-5ACE0DD01BFD}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
18 | EndGlobalSection
19 | EndGlobal
20 |
--------------------------------------------------------------------------------
/doc/test/gdscript/addons.json:
--------------------------------------------------------------------------------
1 | {
2 | "addons": {
3 | "imgui-godot": {
4 | "url": "../../../addons/imgui-godot",
5 | "source": "symlink"
6 | },
7 | "TestData": {
8 | "url": "../addons/TestData",
9 | "source": "symlink"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/doc/test/gdscript/export/.gdignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/doc/test/gdscript/export/.gdignore
--------------------------------------------------------------------------------
/doc/test/gdscript/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/doc/test/gdscript/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://kfs316jt1ha0"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/doc/test/gdscript/main.gd:
--------------------------------------------------------------------------------
1 | extends "res://test_base.gd"
2 |
3 | signal within_process
4 |
5 | func _ready() -> void:
6 | ImGuiGD.SetIniFilename("")
7 |
8 | await within_process
9 |
10 | # ImGuiConfig loads properly
11 | assert_equal(ImGuiGD.Scale, 2)
12 | assert_equal(ImGui.GetFontSize(), 26)
13 |
14 | # StringName conversion
15 | assert_equal(ImGui.GetID("test_id"), 3584119329)
16 |
17 | # rescale
18 | call_deferred("change_scale")
19 |
20 | await within_process
21 |
22 | assert_equal(ImGuiGD.Scale, 4)
23 | assert_equal(ImGui.GetFontSize(), 52)
24 |
25 | # IniSavingRate
26 | get_tree().create_timer(5.1).timeout.connect(on_timeout)
27 |
28 | func on_timeout():
29 | await within_process
30 |
31 | assert_false(FileAccess.file_exists("user://imgui.ini"))
32 |
33 | exit_with_status()
34 |
35 | func _process(_delta: float) -> void:
36 | within_process.emit()
37 |
38 | func change_scale() -> void:
39 | ImGuiGD.Scale = 4
40 | ImGuiGD.RebuildFontAtlas()
41 |
--------------------------------------------------------------------------------
/doc/test/gdscript/main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://b4sq25vkasfoy"]
2 |
3 | [ext_resource type="Script" path="res://main.gd" id="1_4lpr7"]
4 |
5 | [node name="Node2D" type="Node2D"]
6 | script = ExtResource("1_4lpr7")
7 |
--------------------------------------------------------------------------------
/doc/test/gdscript/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [addons]
12 |
13 | imgui/config="res://addons/TestData/config_scale2x.tres"
14 |
15 | [application]
16 |
17 | config/name="test"
18 | run/main_scene="res://main.tscn"
19 | config/features=PackedStringArray("4.3", "Forward Plus")
20 | config/icon="res://icon.svg"
21 |
22 | [autoload]
23 |
24 | ImGuiRoot="*res://addons/imgui-godot/data/ImGuiRoot.tscn"
25 |
26 | [editor_plugins]
27 |
28 | enabled=PackedStringArray("res://addons/imgui-godot/plugin.cfg")
29 |
30 | [rendering]
31 |
32 | textures/vram_compression/import_etc2_astc=true
33 |
--------------------------------------------------------------------------------
/doc/test/gdscript/test_base.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 |
3 | var test_passes := 0
4 | var test_failures := 0
5 |
6 | func __get_stack_frame():
7 | var me = get_script()
8 | for s in get_stack():
9 | if s.source == me.resource_path:
10 | return s
11 | return null
12 |
13 | func __assert_pass():
14 | test_passes += 1
15 |
16 | func __assert_fail():
17 | test_failures += 1
18 | var s = __get_stack_frame()
19 | if s != null:
20 | print_rich ("[color=red] == FAILURE: In function %s() from '%s' on line %s[/color]" % [s.function, s.source, s.line])
21 | else:
22 | print_rich ("[color=red] == FAILURE (run with --debug to get more information!) ==[/color]")
23 |
24 | func assert_equal(actual, expected):
25 | if actual == expected:
26 | __assert_pass()
27 | else:
28 | __assert_fail()
29 | print (" |-> Expected '%s' but got '%s'" % [expected, actual])
30 |
31 | func assert_true(v):
32 | assert_equal(v, true)
33 |
34 | func assert_false(v):
35 | assert_equal(v, false)
36 |
37 | func assert_not_equal(actual, expected):
38 | if actual != expected:
39 | __assert_pass()
40 | else:
41 | __assert_fail()
42 | print (" |-> Expected '%s' NOT to equal '%s'" % [expected, actual])
43 |
44 | func exit_with_status() -> void:
45 | var success: bool = (test_failures == 0)
46 | print ("")
47 | print_rich ("[color=%s] ==== TESTS FINISHED ==== [/color]" % ("green" if success else "red"))
48 | print ("")
49 | print_rich (" PASSES: [color=green]%s[/color]" % test_passes)
50 | print_rich (" FAILURES: [color=red]%s[/color]" % test_failures)
51 | print ("")
52 |
53 | if success:
54 | print_rich("[color=green] ******** PASSED ******** [/color]")
55 | else:
56 | print_rich("[color=red] ******** FAILED ********[/color]")
57 | print("")
58 |
59 | get_tree().quit(0 if success else 1)
60 |
--------------------------------------------------------------------------------
/export_presets.cfg:
--------------------------------------------------------------------------------
1 | [preset.0]
2 |
3 | name="Linux"
4 | platform="Linux/X11"
5 | runnable=true
6 | dedicated_server=false
7 | custom_features=""
8 | export_filter="all_resources"
9 | include_filter=""
10 | exclude_filter=""
11 | export_path="export/demo"
12 | encryption_include_filters=""
13 | encryption_exclude_filters=""
14 | encrypt_pck=false
15 | encrypt_directory=false
16 |
17 | [preset.0.options]
18 |
19 | custom_template/debug=""
20 | custom_template/release=""
21 | debug/export_console_wrapper=1
22 | binary_format/embed_pck=false
23 | texture_format/bptc=false
24 | texture_format/s3tc=true
25 | texture_format/etc=false
26 | texture_format/etc2=false
27 | binary_format/architecture="x86_64"
28 | ssh_remote_deploy/enabled=false
29 | ssh_remote_deploy/host="user@host_ip"
30 | ssh_remote_deploy/port="22"
31 | ssh_remote_deploy/extra_args_ssh=""
32 | ssh_remote_deploy/extra_args_scp=""
33 | ssh_remote_deploy/run_script="#!/usr/bin/env bash
34 | export DISPLAY=:0
35 | unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
36 | \"{temp_dir}/{exe_name}\" {cmd_args}"
37 | ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
38 | kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
39 | rm -rf \"{temp_dir}\""
40 | dotnet/include_scripts_content=false
41 | dotnet/include_debug_symbols=true
42 | dotnet/embed_build_outputs=false
43 | texture_format/s3tc_bptc=true
44 | texture_format/etc2_astc=false
45 | debug/export_console_script=1
46 | texture_format/no_bptc_fallbacks=true
47 | imgui/debug=true
48 | imgui/release=true
49 |
--------------------------------------------------------------------------------
/gdext/.gdignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/gdext/.gdignore
--------------------------------------------------------------------------------
/gdext/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.26)
2 |
3 | # using cmake for dev on Windows, scons for production builds
4 |
5 | # set up vcpkg
6 | if (WIN32)
7 | set(VCPKG_TARGET_TRIPLET x64-windows-static-md)
8 | endif()
9 | file(TO_CMAKE_PATH "$ENV{VCPKG_ROOT}" VCPKG_ROOT)
10 | set(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
11 |
12 | project(imgui-godot-native CXX)
13 |
14 | if (NOT TARGET godot-cpp)
15 | include(FetchContent)
16 | FetchContent_Declare(
17 | godot-cpp
18 | GIT_REPOSITORY https://github.com/godotengine/godot-cpp
19 | GIT_TAG 4.2
20 | )
21 | FetchContent_MakeAvailable(godot-cpp)
22 | endif()
23 |
24 | find_package(freetype CONFIG REQUIRED)
25 | #find_package(unofficial-lunasvg CONFIG REQUIRED)
26 |
27 | add_library(imgui-godot-native SHARED)
28 | target_compile_features(imgui-godot-native PRIVATE cxx_std_20)
29 | target_compile_definitions(imgui-godot-native PUBLIC
30 | IMGUI_USER_CONFIG="imconfig-godot.h"
31 | IMGUI_ENABLE_FREETYPE
32 | # IMGUI_ENABLE_FREETYPE_LUNASVG
33 | IGN_EXPORT
34 | # REAL_T_IS_DOUBLE
35 | )
36 |
37 | # target_compile_definitions(godot-cpp PUBLIC
38 | # REAL_T_IS_DOUBLE
39 | # )
40 |
41 | if (MSVC)
42 | target_compile_options(godot-cpp PRIVATE "/MP")
43 | target_compile_options(imgui-godot-native PRIVATE "/MP")
44 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD ON)
45 | endif()
46 |
47 | add_subdirectory(src)
48 |
49 | target_sources(imgui-godot-native PRIVATE
50 | imgui/imgui.cpp
51 | imgui/imgui_demo.cpp
52 | imgui/imgui_draw.cpp
53 | imgui/imgui_tables.cpp
54 | imgui/imgui_widgets.cpp
55 | imgui/imgui.h
56 | imgui/misc/freetype/imgui_freetype.cpp
57 | imgui/misc/freetype/imgui_freetype.h
58 | include/imconfig-godot.h
59 | include/imgui-godot.h
60 | gen/imgui_bindings.gen.h
61 | gen/cimgui.cpp
62 | gen/cimgui.h
63 | )
64 |
65 | target_link_libraries(imgui-godot-native PUBLIC
66 | godot-cpp
67 | freetype
68 | # unofficial::lunasvg::lunasvg
69 | )
70 |
71 | target_include_directories(imgui-godot-native PRIVATE src imgui gen PUBLIC include)
72 | set_target_properties(imgui-godot-native PROPERTIES PUBLIC_HEADER "include/imconfig-godot.h;include/imgui-godot.h")
73 |
74 | if(WIN32)
75 | set_property(TARGET imgui-godot-native
76 | PROPERTY OUTPUT_NAME "libimgui-godot-native.windows.$,debug,release>.x86_64")
77 | elseif(APPLE)
78 | set_property(TARGET imgui-godot-native
79 | PROPERTY OUTPUT_NAME "imgui-godot-native.macos.$,debug,release>")
80 | set_target_properties(imgui-godot-native PROPERTIES SUFFIX "")
81 | endif()
82 |
83 | set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/../addons/imgui-godot")
84 |
85 | if(WIN32)
86 | install(TARGETS imgui-godot-native
87 | RUNTIME DESTINATION bin
88 | PUBLIC_HEADER DESTINATION include
89 | )
90 | elseif(APPLE)
91 | install(TARGETS imgui-godot-native
92 | DESTINATION bin/libimgui-godot-native.macos.$,debug,release>.framework
93 | PUBLIC_HEADER DESTINATION include
94 | )
95 | endif()
96 | install(FILES "${CMAKE_SOURCE_DIR}/imgui-godot-native.gdextension"
97 | DESTINATION .
98 | )
99 |
--------------------------------------------------------------------------------
/gdext/SConstruct:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from glob import glob
3 | from pathlib import Path
4 | import os
5 | import shutil
6 | import subprocess
7 | import SCons
8 | import sys
9 |
10 |
11 | class CustomCacheDir(SCons.CacheDir.CacheDir):
12 | @classmethod
13 | def copy_to_cache(cls, env, src, dst) -> str:
14 | fn = str(src)
15 | if fn.startswith("godot-cpp"):
16 | if os.path.splitext(fn)[1] not in [".lib", ".dll", ".exp", ".a", ".so"]:
17 | return super().copy_to_cache(env, src, dst)
18 | return None
19 |
20 |
21 | env = SConscript("godot-cpp/SConstruct")
22 | env.CacheDir("scons_cache", CustomCacheDir)
23 | env.Append(CPPDEFINES=['IMGUI_USER_CONFIG="\\"imconfig-godot.h\\""', "IGN_EXPORT"])
24 | env.Append(CPPPATH=["src/", "imgui/", "include/", "gen/"])
25 | env.Replace(CXXFLAGS=str(env["CXXFLAGS"]).replace("c++17", "c++20"))
26 |
27 | windows = env["platform"] == "windows"
28 | linux = env["platform"] == "linux"
29 | config = "release" if env["target"] == "template_release" else "debug"
30 |
31 | if config == "release":
32 | if windows:
33 | env.Append(CPPDEFINES=["NDEBUG"])
34 |
35 | if windows:
36 | if env["arch"] == "arm64":
37 | triplet = "arm64-windows-static"
38 | else:
39 | triplet = "x64-windows-static"
40 | if not os.path.exists(f"vcpkg_installed/{triplet}"):
41 | subprocess.call(f'"%VCPKG_ROOT%/vcpkg" install --triplet {triplet}', shell=True)
42 | elif linux:
43 | triplet = "x64-linux"
44 | if not os.path.exists("vcpkg_installed"):
45 | subprocess.call("$VCPKG_ROOT/vcpkg install", shell=True)
46 | else:
47 | triplet = "arm64-osx"
48 | if not os.path.exists("vcpkg_installed"):
49 | if subprocess.call("zsh scripts/vcpkg-macos.sh", shell=True) != 0:
50 | sys.exit(1)
51 |
52 | if not os.path.exists("gen/imgui_bindings.gen.h"):
53 | subprocess.call("python scripts/gds_bindings.py", shell=True)
54 |
55 | shutil.copy("imgui-godot-native.gdextension", "../addons/imgui-godot/")
56 | shutil.copytree("include", "../addons/imgui-godot/include", dirs_exist_ok=True)
57 |
58 | sources = Glob("src/*.cpp") + Glob("imgui/*.cpp") + Glob("gen/*.cpp")
59 |
60 | (extension_path,) = glob("../addons/imgui-godot/*.gdextension")
61 | addon_path = Path(extension_path).parent
62 | project_name = Path(extension_path).stem
63 |
64 | libpath = env.get("LIBPATH", [])
65 | libs = [env["LIBS"]]
66 |
67 | env.Append(CPPPATH=["imgui/misc/freetype/"])
68 | env.Append(CPPPATH=[f"vcpkg_installed/{triplet}/include"])
69 | env.Append(CPPDEFINES=["IMGUI_ENABLE_FREETYPE"])
70 | # env.Append(CPPDEFINES=["IMGUI_ENABLE_FREETYPE_LUNASVG"])
71 | sources += Glob("imgui/misc/freetype/*.cpp")
72 | libpath += [f"vcpkg_installed/{triplet}/lib"]
73 | libs += [
74 | "freetype",
75 | # "lunasvg",
76 | "bz2",
77 | "libpng16" if windows else "png16",
78 | "zlib" if windows else "z",
79 | "brotlidec",
80 | "brotlicommon",
81 | ]
82 |
83 | if env["platform"] == "macos":
84 | library = env.SharedLibrary(
85 | "{0}/bin/lib{1}.{2}.{3}.framework/{1}.{2}.{3}".format(
86 | addon_path,
87 | project_name,
88 | env["platform"],
89 | config,
90 | ),
91 | source=sources,
92 | LIBPATH=libpath,
93 | LIBS=libs,
94 | )
95 | else:
96 | library = env.SharedLibrary(
97 | "{}/bin/lib{}.{}.{}.{}{}".format(
98 | addon_path,
99 | project_name,
100 | env["platform"],
101 | config,
102 | env["arch"],
103 | env["SHLIBSUFFIX"],
104 | ),
105 | source=sources,
106 | LIBPATH=libpath,
107 | LIBS=libs,
108 | )
109 |
110 | Default(library)
111 |
--------------------------------------------------------------------------------
/gdext/imgui-godot-native.gdextension:
--------------------------------------------------------------------------------
1 | [configuration]
2 |
3 | entry_symbol = "ign_init"
4 | compatibility_minimum = 4.2
5 |
6 | [libraries]
7 |
8 | macos.debug = "bin/libimgui-godot-native.macos.debug.framework"
9 | macos.release = "bin/libimgui-godot-native.macos.release.framework"
10 | windows.debug.x86_64 = "bin/libimgui-godot-native.windows.debug.x86_64.dll"
11 | windows.release.x86_64 = "bin/libimgui-godot-native.windows.release.x86_64.dll"
12 | linux.debug.x86_64 = "bin/libimgui-godot-native.linux.debug.x86_64.so"
13 | linux.release.x86_64 = "bin/libimgui-godot-native.linux.release.x86_64.so"
14 |
--------------------------------------------------------------------------------
/gdext/include/.gdignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pkdawson/imgui-godot/8a9f0c423533e22a8fa156c5f7c79877c01f437d/gdext/include/.gdignore
--------------------------------------------------------------------------------
/gdext/include/imconfig-godot.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS // match ImGui.NET
4 |
5 | #if __has_include("godot_cpp/godot.hpp") // GDExtension
6 | #include
7 | #include
8 | #include
9 | #include
10 | using godot::Color;
11 | using godot::Vector2;
12 | using godot::Vector2i;
13 | using godot::Vector4;
14 |
15 | #if defined(DEBUG_ENABLED) && defined(IGN_EXPORT)
16 | #ifndef IM_ASSERT
17 | #include
18 | #define IM_ASSERT(_EXPR) \
19 | do \
20 | { \
21 | if (!(_EXPR)) \
22 | godot::UtilityFunctions::push_error(godot::vformat("IM_ASSERT %s (%s:%d)", #_EXPR, __FILE__, __LINE__)); \
23 | } while (0)
24 | #endif
25 | #endif
26 | #else // module
27 | #include "core/math/color.h"
28 | #include "core/math/vector2.h"
29 | #include "core/math/vector2i.h"
30 | #include "core/math/vector4.h"
31 | #endif
32 |
33 | #define IM_VEC2_CLASS_EXTRA \
34 | constexpr ImVec2(const Vector2& f) : x(f.x), y(f.y) \
35 | { \
36 | } \
37 | operator Vector2() const \
38 | { \
39 | return Vector2(x, y); \
40 | } \
41 | constexpr ImVec2(const Vector2i& f) : x(static_cast(f.x)), y(static_cast(f.y)) \
42 | { \
43 | } \
44 | operator Vector2i() const \
45 | { \
46 | return Vector2i(static_cast(x), static_cast(y)); \
47 | }
48 |
49 | #define IM_VEC4_CLASS_EXTRA \
50 | constexpr ImVec4(const Vector4& f) : x(f.x), y(f.y), z(f.z), w(f.w) \
51 | { \
52 | } \
53 | operator Vector4() const \
54 | { \
55 | return Vector4(x, y, z, w); \
56 | } \
57 | constexpr ImVec4(const Color& c) : x(c.r), y(c.g), z(c.b), w(c.a) \
58 | { \
59 | } \
60 | operator Color() const \
61 | { \
62 | return Color(x, y, z, w); \
63 | }
64 |
--------------------------------------------------------------------------------
/gdext/scripts/vcpkg-macos.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 |
3 | vcpkg_x64=$(pwd)/vcpkg_installed.x64
4 |
5 | $VCPKG_ROOT/vcpkg install --triplet x64-osx
6 | mv vcpkg_installed $vcpkg_x64
7 | $VCPKG_ROOT/vcpkg install --triplet arm64-osx
8 |
9 | for libpath in "lib" "debug/lib"
10 | do
11 | pushd vcpkg_installed/arm64-osx/$libpath
12 | for x in *.a
13 | do
14 | echo "$libpath/$x"
15 | lipo -create -output $x $x $vcpkg_x64/x64-osx/$libpath/$x
16 | done
17 | popd
18 | done
19 |
20 | rm -r $vcpkg_x64
21 |
--------------------------------------------------------------------------------
/gdext/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | target_sources(imgui-godot-native PRIVATE
2 | CanvasRenderer.cpp
3 | CanvasRenderer.h
4 | common.h
5 | Context.cpp
6 | Context.h
7 | DummyRenderer.h
8 | Fonts.cpp
9 | Fonts.h
10 | GdsCache.cpp
11 | GdsCache.h
12 | ImGuiAPI.cpp
13 | ImGuiAPI.h
14 | ImGuiController.cpp
15 | ImGuiController.h
16 | ImGuiControllerHelper.cpp
17 | ImGuiControllerHelper.h
18 | ImGuiGD.cpp
19 | ImGuiGD.h
20 | ImGuiLayer.cpp
21 | ImGuiLayer.h
22 | ImGuiSync.cpp
23 | ImGuiSync.h
24 | Input.cpp
25 | Input.h
26 | InputLocal.cpp
27 | InputLocal.h
28 | main.cpp
29 | RdRenderer.cpp
30 | RdRenderer.h
31 | RdRendererThreadSafe.cpp
32 | RdRendererThreadSafe.h
33 | Renderer.h
34 | Viewports.cpp
35 | Viewports.h
36 | )
37 |
--------------------------------------------------------------------------------
/gdext/src/CanvasRenderer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Renderer.h"
3 | #include
4 | #include
5 | #include
6 |
7 | using godot::RID;
8 |
9 | namespace ImGui::Godot {
10 |
11 | class CanvasRenderer : public Renderer
12 | {
13 | public:
14 | CanvasRenderer();
15 | virtual ~CanvasRenderer();
16 |
17 | virtual const char* Name() override { return "godot4_canvas"; }
18 |
19 | bool Init() override;
20 | void InitViewport(RID vprid) override;
21 | void CloseViewport(RID vprid) override;
22 | void Render() override;
23 | void OnHide() override;
24 |
25 | private:
26 | struct Impl;
27 | std::unique_ptr impl;
28 | };
29 |
30 | } // namespace ImGui::Godot
31 |
--------------------------------------------------------------------------------
/gdext/src/Context.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "DummyRenderer.h"
22 | #include "Fonts.h"
23 | #include "GdsCache.h"
24 | #include "ImGuiGD.h"
25 | #include "ImGuiLayer.h"
26 | #include "Input.h"
27 | #include "RdRenderer.h"
28 | #include "RdRendererThreadSafe.h"
29 | #include "Renderer.h"
30 | #include "Viewports.h"
31 |
32 | using namespace godot;
33 |
34 | namespace ImGui::Godot {
35 |
36 | enum class RendererType
37 | {
38 | Dummy,
39 | Canvas,
40 | RenderingDevice,
41 | };
42 |
43 | struct Context
44 | {
45 | std::unique_ptr viewports;
46 | std::unique_ptr fonts;
47 | std::unique_ptr input;
48 | std::unique_ptr renderer;
49 |
50 | float scale = 1.0f;
51 | float joyAxisDeadZone = 0.15f;
52 | int layerNum = 128;
53 | ImGuiLayer* layer = nullptr;
54 | bool inProcessFrame = false;
55 | std::vector iniFilename;
56 |
57 | Context(std::unique_ptr r);
58 | ~Context();
59 |
60 | void Render();
61 | void Update(double delta, Vector2 displaySize);
62 | };
63 |
64 | Context* GetContext();
65 |
66 | void Init(const Ref& config);
67 | void Shutdown();
68 | void Connect(const Callable& callable);
69 | void ResetFonts();
70 | void AddFont(const Ref& fontFile, int fontSize, bool merge = false,
71 | const ImVector& glyphRanges = {});
72 | void AddFontDefault();
73 | void RebuildFontAtlas();
74 | void SetIniFilename(const String& fn);
75 | void SetVisible(bool visible);
76 |
77 | bool SubViewportWidget(SubViewport* svp);
78 | } // namespace ImGui::Godot
79 |
--------------------------------------------------------------------------------
/gdext/src/DummyRenderer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Renderer.h"
3 |
4 | namespace ImGui::Godot {
5 |
6 | class DummyRenderer : public Renderer
7 | {
8 | public:
9 | DummyRenderer() {}
10 | ~DummyRenderer() {}
11 |
12 | const char* Name() override { return "godot4_dummy"; }
13 |
14 | bool Init() override { return true; }
15 | void InitViewport(RID vprid) override {}
16 | void CloseViewport(RID vprid) override {}
17 | void Render() override {}
18 | void OnHide() override {}
19 | };
20 |
21 | } // namespace ImGui::Godot
22 |
--------------------------------------------------------------------------------
/gdext/src/Fonts.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | using namespace godot;
6 |
7 | namespace ImGui::Godot {
8 |
9 | class Fonts
10 | {
11 | public:
12 | Fonts();
13 | ~Fonts();
14 |
15 | void Reset();
16 | void Add(Ref fontData, int fontSize, bool merge = false, const ImVector& glyphRanges = {});
17 | void RebuildFontAtlas(float scale);
18 |
19 | private:
20 | struct Impl;
21 | std::unique_ptr impl;
22 | };
23 |
24 | } // namespace ImGui::Godot
25 |
--------------------------------------------------------------------------------
/gdext/src/GdsCache.cpp:
--------------------------------------------------------------------------------
1 | #include "GdsCache.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | using namespace godot;
9 |
10 | namespace ImGui::Godot {
11 |
12 | std::unique_ptr gdscache = std::make_unique();
13 |
14 | struct GdsCache::Impl
15 | {
16 | std::unordered_map> bufs;
17 | std::unordered_map used;
18 |
19 | static void CopyInput(std::vector& buf, const Array& a)
20 | {
21 | CharString cs = String(a[0]).utf8();
22 | const std::string_view sv = cs.get_data();
23 | if (sv.size() >= buf.size())
24 | return;
25 | std::copy(sv.begin(), sv.end(), buf.begin());
26 | buf[sv.size()] = '\0';
27 | }
28 | };
29 |
30 | GdsCache::GdsCache() : impl(std::make_unique())
31 | {
32 | }
33 |
34 | GdsCache::~GdsCache()
35 | {
36 | }
37 |
38 | void GdsCache::OnNewFrame()
39 | {
40 | for (auto it = impl->used.begin(); it != impl->used.end();)
41 | {
42 | if (!it->second)
43 | {
44 | impl->bufs.erase(it->first);
45 | it = impl->used.erase(it);
46 | }
47 | else
48 | {
49 | it->second = false;
50 | ++it;
51 | }
52 | }
53 | }
54 |
55 | std::vector& GdsCache::GetTextBuf(const StringName& label, size_t size, const Array& a)
56 | {
57 | const int64_t hash = ImGui::GetID((void*)label.hash());
58 | impl->used[hash] = true;
59 | auto it = impl->bufs.find(hash);
60 | if (it == impl->bufs.end())
61 | {
62 | impl->bufs[hash] = std::vector(size);
63 | std::vector& buf = impl->bufs[hash];
64 | Impl::CopyInput(buf, a);
65 | return buf;
66 | }
67 | else
68 | {
69 | std::vector& buf = it->second;
70 | buf.resize(size);
71 | Impl::CopyInput(buf, a);
72 | return buf;
73 | }
74 | }
75 |
76 | const std::vector& GdsCache::GetZeroArray(const Array& a)
77 | {
78 | const int64_t hash = a.hash();
79 | impl->used[hash] = true;
80 | if (auto it = impl->bufs.find(hash); it != impl->bufs.end())
81 | {
82 | return it->second;
83 | }
84 |
85 | impl->bufs[hash] = {};
86 | std::vector& buf = impl->bufs[hash];
87 | for (int i = 0; i < a.size(); ++i)
88 | {
89 | CharString cs = String(a[i]).utf8();
90 | const std::string_view sv = cs.get_data();
91 | std::copy(sv.begin(), sv.end(), std::back_inserter(buf));
92 | buf.push_back('\0');
93 | }
94 | buf.push_back('\0');
95 | return buf;
96 | }
97 |
98 | } // namespace ImGui::Godot
99 |
--------------------------------------------------------------------------------
/gdext/src/GdsCache.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace godot;
7 |
8 | namespace ImGui::Godot {
9 |
10 | class GdsCache
11 | {
12 | public:
13 | GdsCache();
14 | ~GdsCache();
15 |
16 | void OnNewFrame();
17 | std::vector& GetTextBuf(const StringName& label, size_t size, const Array& a);
18 | const std::vector& GetZeroArray(const Array& a);
19 |
20 | private:
21 | struct Impl;
22 | std::unique_ptr impl;
23 | };
24 |
25 | extern std::unique_ptr gdscache;
26 |
27 | } // namespace ImGui::Godot
28 |
--------------------------------------------------------------------------------
/gdext/src/ImGuiAPI.cpp:
--------------------------------------------------------------------------------
1 | #include "ImGuiAPI.h"
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace godot;
7 |
8 | namespace {
9 | inline Vector2 ToVector2(ImVec2 v)
10 | {
11 | return Vector2(v.x, v.y);
12 | }
13 |
14 | inline Color ToColor(const ImVec4& v)
15 | {
16 | return Color(v.x, v.y, v.z, v.w);
17 | }
18 |
19 | inline ImVec4 FromColor(const Color& c)
20 | {
21 | return {c.r, c.g, c.b, c.a};
22 | }
23 |
24 | inline PackedColorArray ToPackedColorArray(ImVec4* colors, int size)
25 | {
26 | PackedColorArray rv;
27 | rv.resize(size);
28 | for (int i = 0; i < size; ++i)
29 | rv[i] = ToColor(colors[i]);
30 | return rv;
31 | }
32 |
33 | inline void FromPackedColorArray(const PackedColorArray& in, ImVec4* out)
34 | {
35 | for (int i = 0; i < in.size(); ++i)
36 | out[i] = FromColor(in[i]);
37 | }
38 |
39 | inline Array FromImVector(const ImVector_ImGuiSelectionRequest& in)
40 | {
41 | Array rv;
42 | for (int i = 0; i < in.Size; ++i)
43 | {
44 | Ref req;
45 | req.instantiate();
46 | req->_SetPtr(&in.Data[i]);
47 | rv.append(req);
48 | }
49 | return rv;
50 | }
51 |
52 | inline ImVector_ImGuiSelectionRequest ToImVector(const Array& in)
53 | {
54 | ERR_FAIL_V_MSG({}, "ToImVector not implemented");
55 | return {};
56 | }
57 |
58 | inline Array SpecsToArray(const ImGuiTableSortSpecs* p)
59 | {
60 | ERR_FAIL_COND_V(!p, {});
61 |
62 | Array rv;
63 | for (int i = 0; i < p->SpecsCount; ++i)
64 | {
65 | Ref col;
66 | col.instantiate();
67 | col->_SetPtr(const_cast(&p->Specs[i]));
68 | rv.append(col);
69 | }
70 | return rv;
71 | }
72 |
73 | const char* sn_to_cstr(const StringName& sn)
74 | {
75 | static std::unordered_map stringname_cache;
76 | const int64_t hash = sn.hash();
77 | if (!stringname_cache.contains(hash))
78 | {
79 | stringname_cache[hash] = std::string(String(sn).utf8().get_data());
80 | }
81 | return stringname_cache[hash].c_str();
82 | }
83 | } // namespace
84 |
85 | namespace ImGui::Godot {
86 |
87 | void register_imgui_api()
88 | {
89 | ClassDB::register_class<::ImGui::Godot::ImGui>();
90 |
91 | Engine::get_singleton()->register_singleton("ImGuiAPI", memnew(::ImGui::Godot::ImGui));
92 | }
93 |
94 | void unregister_imgui_api()
95 | {
96 | ::ImGui::Godot::ImGui* api = (::ImGui::Godot::ImGui*)Engine::get_singleton()->get_singleton("ImGuiAPI");
97 | Engine::get_singleton()->unregister_singleton("ImGuiAPI");
98 | memdelete(api);
99 | }
100 |
101 | #include "imgui_bindings_impl.gen.h"
102 |
103 | } // namespace ImGui::Godot
104 |
--------------------------------------------------------------------------------
/gdext/src/ImGuiAPI.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "GdsCache.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include
12 |
13 | using namespace godot;
14 |
15 | namespace ImGui::Godot {
16 |
17 | template
18 | struct GdsPtr
19 | {
20 | // TypedArray& arr;
21 | Array& arr;
22 | T val;
23 |
24 | GdsPtr(Array& x) : arr(x)
25 | {
26 | // safety for tool script reload, and programming errors
27 | if (arr.size() == 0) [[unlikely]]
28 | arr.append(T());
29 | val = arr[0];
30 | }
31 |
32 | ~GdsPtr() { arr[0] = val; }
33 |
34 | operator T*() { return &val; }
35 | };
36 |
37 | template <>
38 | struct GdsPtr
39 | {
40 | Array& arr;
41 | std::vector& buf;
42 | int64_t bufhash;
43 |
44 | GdsPtr(Array& x, size_t s, const StringName& label) : arr(x), buf(gdscache->GetTextBuf(label, s, x))
45 | {
46 | bufhash = std::hash{}({buf.begin(), buf.end()});
47 | }
48 |
49 | ~GdsPtr()
50 | {
51 | if (bufhash != std::hash{}({buf.begin(), buf.end()}))
52 | {
53 | arr[0] = String::utf8(buf.data());
54 | }
55 | }
56 |
57 | operator char*() { return buf.data(); }
58 | };
59 |
60 | template
61 | struct GdsArray
62 | {
63 | Array& arr;
64 | std::vector buf;
65 |
66 | GdsArray(Array& a) : arr(a), buf(a.size())
67 | {
68 | for (int i = 0; i < arr.size(); ++i)
69 | {
70 | buf[i] = arr[i];
71 | }
72 | }
73 |
74 | ~GdsArray()
75 | {
76 | for (int i = 0; i < arr.size(); ++i)
77 | {
78 | arr[i] = buf[i];
79 | }
80 | }
81 |
82 | operator T*() { return buf.data(); }
83 | };
84 |
85 | // TODO: take PackedFloat32Array parameters instead
86 | template <>
87 | struct GdsArray
88 | {
89 | std::vector buf;
90 |
91 | GdsArray(Array& arr) : buf(arr.size())
92 | {
93 | for (int i = 0; i < arr.size(); ++i)
94 | {
95 | buf[i] = arr[i];
96 | }
97 | }
98 |
99 | operator const float*() { return buf.data(); }
100 | };
101 |
102 | template <>
103 | struct GdsArray
104 | {
105 | std::vector buf;
106 | std::vector ptrs;
107 |
108 | GdsArray(Array& arr) : buf(arr.size()), ptrs(arr.size())
109 | {
110 | for (int i = 0; i < arr.size(); ++i)
111 | {
112 | buf[i] = String(arr[i]).utf8();
113 | ptrs[i] = buf[i].get_data();
114 | }
115 | }
116 |
117 | operator const char* const*() { return ptrs.data(); }
118 | };
119 |
120 | struct GdsZeroArray
121 | {
122 | const std::vector& buf;
123 |
124 | GdsZeroArray(const Array& a) : buf(gdscache->GetZeroArray(a)) {}
125 |
126 | operator const char*() { return buf.data(); }
127 | };
128 |
129 | #define VARIANT_CSTR(v) v.get_type() == Variant::STRING ? static_cast(v).utf8().get_data() : nullptr
130 |
131 | #define GDS_PTR(T, a) a.size() == 0 ? nullptr : (T*)GdsPtr(a)
132 | // #define GDS_PTR_STR(a, len, label) a.size() == 0 ? nullptr : (char*)GdsPtr(a, len, label)
133 |
134 | } // namespace ImGui::Godot
135 |
136 | #include "imgui_bindings.gen.h"
137 |
--------------------------------------------------------------------------------
/gdext/src/ImGuiController.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | using namespace godot;
6 |
7 | namespace ImGui::Godot {
8 |
9 | class ImGuiController : public Node
10 | {
11 | GDCLASS(ImGuiController, Node);
12 |
13 | protected:
14 | static void _bind_methods();
15 |
16 | public:
17 | static ImGuiController* Instance();
18 |
19 | ImGuiController();
20 | ~ImGuiController();
21 |
22 | void _ready() override;
23 | void _enter_tree() override;
24 | void _exit_tree() override;
25 | void _process(double delta) override;
26 | void _notification(int p_what);
27 | void SetMainViewport(Viewport* vp);
28 |
29 | void OnLayerExiting();
30 | void on_frame_pre_draw();
31 | void window_input_callback(Ref evt);
32 |
33 | private:
34 | struct Impl;
35 | std::unique_ptr impl;
36 | };
37 |
38 | } // namespace ImGui::Godot
39 |
--------------------------------------------------------------------------------
/gdext/src/ImGuiControllerHelper.cpp:
--------------------------------------------------------------------------------
1 | #include "ImGuiControllerHelper.h"
2 | #include "Context.h"
3 | using namespace godot;
4 |
5 | namespace ImGui::Godot {
6 |
7 | ImGuiControllerHelper::ImGuiControllerHelper()
8 | {
9 | }
10 |
11 | ImGuiControllerHelper::~ImGuiControllerHelper()
12 | {
13 | }
14 |
15 | void ImGuiControllerHelper::_bind_methods()
16 | {
17 | }
18 |
19 | void ImGuiControllerHelper::_enter_tree()
20 | {
21 | }
22 |
23 | void ImGuiControllerHelper::_ready()
24 | {
25 | set_name("ImGuiControllerHelper");
26 | set_process_priority(std::numeric_limits::min());
27 | set_process_mode(Node::PROCESS_MODE_ALWAYS);
28 | }
29 |
30 | void ImGuiControllerHelper::_exit_tree()
31 | {
32 | }
33 |
34 | void ImGuiControllerHelper::_process(double delta)
35 | {
36 | Context* ctx = GetContext();
37 | ctx->inProcessFrame = true;
38 | ctx->Update(delta, ctx->layer->UpdateViewport());
39 | }
40 |
41 | } // namespace ImGui::Godot
42 |
--------------------------------------------------------------------------------
/gdext/src/ImGuiControllerHelper.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | using godot::Node;
5 |
6 | namespace ImGui::Godot {
7 |
8 | class ImGuiControllerHelper : public Node
9 | {
10 | GDCLASS(ImGuiControllerHelper, Node);
11 |
12 | protected:
13 | static void _bind_methods();
14 |
15 | public:
16 | void _ready() override;
17 | void _enter_tree() override;
18 | void _exit_tree() override;
19 | void _process(double delta) override;
20 |
21 | ImGuiControllerHelper();
22 | ~ImGuiControllerHelper();
23 | };
24 |
25 | } // namespace ImGui::Godot
26 |
--------------------------------------------------------------------------------
/gdext/src/ImGuiGD.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | using namespace godot;
10 |
11 | namespace ImGui::Godot {
12 |
13 | class ImGuiGD : public Object
14 | {
15 | GDCLASS(ImGuiGD, Object);
16 |
17 | protected:
18 | static void _bind_methods();
19 |
20 | public:
21 | bool ToolInit();
22 |
23 | void Connect(const Callable& cb);
24 |
25 | void ResetFonts();
26 | void AddFont(const Ref& fontFile, int fontSize, bool merge = false,
27 | const PackedInt32Array& glyphRanges = {});
28 | void AddFontDefault();
29 | void RebuildFontAtlas();
30 |
31 | void _SetJoyAxisDeadZone(real_t zone);
32 | real_t _GetJoyAxisDeadZone();
33 |
34 | void _SetVisible(bool visible);
35 | bool _GetVisible();
36 |
37 | void _SetScale(real_t scale);
38 | real_t _GetScale();
39 |
40 | void SetMainViewport(Viewport* vp);
41 | void SetIniFilename(String fn);
42 |
43 | PackedInt64Array GetFontPtrs();
44 | PackedInt64Array GetImGuiPtrs(String version, int ioSize, int vertSize, int idxSize, int charSize);
45 |
46 | bool SubViewport(godot::SubViewport* svp);
47 | };
48 |
49 | } // namespace ImGui::Godot
50 |
--------------------------------------------------------------------------------
/gdext/src/ImGuiLayer.cpp:
--------------------------------------------------------------------------------
1 | #include "ImGuiLayer.h"
2 | #include "Context.h"
3 | #include "ImGuiControllerHelper.h"
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | using namespace godot;
17 |
18 | namespace ImGui::Godot {
19 |
20 | struct ImGuiLayer::Impl
21 | {
22 | RID subViewportRid;
23 | Vector2i subViewportSize{0, 0};
24 | RID canvasItem;
25 | Transform2D finalTransform{1.f, 0.f, 0.f, 1.f, 0.f, 0.f}; // identity
26 | bool visible = true;
27 | Viewport* parentViewport = nullptr;
28 |
29 | static RID AddLayerSubViewport(Node* parent);
30 | };
31 |
32 | RID ImGuiLayer::Impl::AddLayerSubViewport(Node* parent)
33 | {
34 | RenderingServer* RS = RenderingServer::get_singleton();
35 | RID svp = RS->viewport_create();
36 | RS->viewport_set_transparent_background(svp, true);
37 | RS->viewport_set_update_mode(svp, RenderingServer::VIEWPORT_UPDATE_ALWAYS);
38 | RS->viewport_set_clear_mode(svp, RenderingServer::VIEWPORT_CLEAR_ALWAYS);
39 | RS->viewport_set_active(svp, true);
40 | RS->viewport_set_parent_viewport(svp, parent->get_window()->get_viewport_rid());
41 | return svp;
42 | }
43 |
44 | ImGuiLayer::ImGuiLayer() : impl(std::make_unique())
45 | {
46 | }
47 |
48 | ImGuiLayer::~ImGuiLayer()
49 | {
50 | }
51 |
52 | void ImGuiLayer::_bind_methods()
53 | {
54 | ClassDB::bind_method(D_METHOD("on_visibility_changed"), &ImGuiLayer::on_visibility_changed);
55 | }
56 |
57 | void ImGuiLayer::_enter_tree()
58 | {
59 | Context* ctx = GetContext();
60 | set_name("ImGuiLayer");
61 | set_layer(ctx->layerNum);
62 |
63 | impl->parentViewport = get_viewport();
64 | impl->subViewportRid = Impl::AddLayerSubViewport(this);
65 |
66 | RenderingServer* RS = RenderingServer::get_singleton();
67 | impl->canvasItem = RS->canvas_item_create();
68 | RS->canvas_item_set_parent(impl->canvasItem, get_canvas());
69 |
70 | ctx->renderer->InitViewport(impl->subViewportRid);
71 | ctx->viewports->SetMainWindow(get_window(), impl->subViewportRid);
72 | }
73 |
74 | void ImGuiLayer::_ready()
75 | {
76 | connect("visibility_changed", Callable(this, "on_visibility_changed"));
77 | }
78 |
79 | void ImGuiLayer::_exit_tree()
80 | {
81 | RenderingServer::get_singleton()->free_rid(impl->canvasItem);
82 | RenderingServer::get_singleton()->free_rid(impl->subViewportRid);
83 | }
84 |
85 | void ImGuiLayer::on_visibility_changed()
86 | {
87 | impl->visible = is_visible();
88 | if (impl->visible)
89 | {
90 | set_process_input(true);
91 | }
92 | else
93 | {
94 | set_process_input(false);
95 | ImGui::Godot::GetContext()->renderer->OnHide();
96 | impl->subViewportSize = {0, 0};
97 | RenderingServer::get_singleton()->canvas_item_clear(impl->canvasItem);
98 | }
99 | }
100 |
101 | void ImGuiLayer::_input(const Ref& event)
102 | {
103 | if (GetContext()->input->ProcessInput(event))
104 | {
105 | impl->parentViewport->set_input_as_handled();
106 | }
107 | }
108 |
109 | Vector2i ImGuiLayer::UpdateViewport()
110 | {
111 | Vector2i vpSize;
112 | if (Window* w = Object::cast_to(impl->parentViewport))
113 | vpSize = w->get_size();
114 | else
115 | vpSize = Object::cast_to(impl->parentViewport)->get_size();
116 |
117 | if (impl->visible)
118 | {
119 | const Transform2D ft = impl->parentViewport->get_final_transform();
120 |
121 | if (impl->subViewportSize != vpSize ||
122 | impl->finalTransform != ft
123 | #ifdef DEBUG_ENABLED
124 | // force redraw on every frame in editor
125 | || Engine::get_singleton()->is_editor_hint()
126 | #endif
127 | )
128 | {
129 | // this is more or less how SubViewportContainer works
130 | impl->subViewportSize = vpSize;
131 | impl->finalTransform = ft;
132 |
133 | RenderingServer* RS = RenderingServer::get_singleton();
134 | RS->viewport_set_size(impl->subViewportRid, impl->subViewportSize.x, impl->subViewportSize.y);
135 | const RID vptex = RS->viewport_get_texture(impl->subViewportRid);
136 | RS->canvas_item_clear(impl->canvasItem);
137 | RS->canvas_item_set_transform(impl->canvasItem, ft.affine_inverse());
138 | RS->canvas_item_add_texture_rect(impl->canvasItem,
139 | Rect2(0, 0, impl->subViewportSize.x, impl->subViewportSize.y),
140 | vptex);
141 | }
142 | }
143 |
144 | return vpSize;
145 | }
146 |
147 | } // namespace ImGui::Godot
148 |
--------------------------------------------------------------------------------
/gdext/src/ImGuiLayer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace godot;
7 |
8 | namespace ImGui::Godot {
9 |
10 | class ImGuiLayer : public CanvasLayer
11 | {
12 | GDCLASS(ImGuiLayer, CanvasLayer);
13 |
14 | protected:
15 | static void _bind_methods();
16 |
17 | public:
18 | ImGuiLayer();
19 | ~ImGuiLayer();
20 |
21 | void _ready() override;
22 | void _enter_tree() override;
23 | void _exit_tree() override;
24 | void _input(const Ref& event) override;
25 |
26 | void on_visibility_changed();
27 |
28 | Vector2i UpdateViewport();
29 |
30 | private:
31 | struct Impl;
32 | std::unique_ptr impl;
33 | };
34 |
35 | } // namespace ImGui::Godot
36 |
--------------------------------------------------------------------------------
/gdext/src/ImGuiSync.cpp:
--------------------------------------------------------------------------------
1 | #include "ImGuiSync.h"
2 | #include
3 | #include
4 | #include
5 |
6 | namespace ImGui::Godot {
7 |
8 | void ImGuiSync::_bind_methods()
9 | {
10 | ClassDB::bind_static_method("ImGuiSync", D_METHOD("GetImGuiPtrs"), &ImGuiSync::GetImGuiPtrs);
11 | }
12 |
13 | PackedInt64Array ImGuiSync::GetImGuiPtrs(String version, int ioSize, int vertSize, int idxSize, int charSize)
14 | {
15 | if (version != String(ImGui::GetVersion()) || ioSize != sizeof(ImGuiIO) || vertSize != sizeof(ImDrawVert) ||
16 | idxSize != sizeof(ImDrawIdx) || charSize != sizeof(ImWchar))
17 | {
18 | UtilityFunctions::push_error("ImGui version mismatch, use v", ImGui::GetVersion(), "-docking");
19 | return {};
20 | }
21 |
22 | ImGuiMemAllocFunc alloc_func = nullptr;
23 | ImGuiMemFreeFunc free_func = nullptr;
24 | void* user_data = nullptr;
25 |
26 | ImGui::GetAllocatorFunctions(&alloc_func, &free_func, &user_data);
27 |
28 | PackedInt64Array rv;
29 | rv.resize(3);
30 | rv[0] = reinterpret_cast(ImGui::GetCurrentContext());
31 | rv[1] = reinterpret_cast(alloc_func);
32 | rv[2] = reinterpret_cast(free_func);
33 | return rv;
34 | }
35 |
36 | } // namespace ImGui::Godot
37 |
--------------------------------------------------------------------------------
/gdext/src/ImGuiSync.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | using namespace godot;
5 |
6 | namespace ImGui::Godot {
7 |
8 | class ImGuiSync : public Object
9 | {
10 | GDCLASS(ImGuiSync, Object);
11 |
12 | protected:
13 | static void _bind_methods();
14 |
15 | public:
16 | static PackedInt64Array GetImGuiPtrs(String version, int ioSize, int vertSize, int idxSize, int charSize);
17 | };
18 |
19 | } // namespace ImGui::Godot
20 |
--------------------------------------------------------------------------------
/gdext/src/Input.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | using namespace godot;
10 |
11 | namespace ImGui::Godot {
12 | class Input
13 | {
14 | public:
15 | Input();
16 | virtual ~Input();
17 |
18 | void Update();
19 | virtual bool ProcessInput(const Ref& evt);
20 | void ProcessNotification(int what);
21 | void SetActiveSubViewport(godot::SubViewport* svp, Vector2 pos);
22 |
23 | protected:
24 | virtual void UpdateMousePos();
25 | void ProcessSubViewportWidget(const Ref& evt);
26 | bool HandleEvent(const Ref& evt);
27 |
28 | private:
29 | void UpdateMouse();
30 |
31 | struct Impl;
32 | std::unique_ptr impl;
33 | };
34 | } // namespace ImGui::Godot
35 |
--------------------------------------------------------------------------------
/gdext/src/InputLocal.cpp:
--------------------------------------------------------------------------------
1 | #include "InputLocal.h"
2 | #include
3 | #include
4 |
5 | namespace ImGui::Godot {
6 |
7 | void InputLocal::UpdateMousePos()
8 | {
9 | // do not use global mouse position
10 | }
11 |
12 | bool InputLocal::ProcessInput(const Ref& evt)
13 | {
14 | // no support for SubViewport widgets
15 |
16 | if (Ref mm = evt; mm.is_valid())
17 | {
18 | ImGuiIO& io = ImGui::GetIO();
19 | Vector2 mousePos = mm->get_position();
20 | io.AddMousePosEvent(mousePos.x, mousePos.y);
21 | return io.WantCaptureMouse;
22 | }
23 | return HandleEvent(evt);
24 | }
25 |
26 | } // namespace ImGui::Godot
27 |
--------------------------------------------------------------------------------
/gdext/src/InputLocal.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Input.h"
3 |
4 | using namespace godot;
5 |
6 | namespace ImGui::Godot {
7 |
8 | class InputLocal : public Input
9 | {
10 | protected:
11 | void UpdateMousePos() override;
12 | bool ProcessInput(const Ref& evt) override;
13 | };
14 |
15 | } // namespace ImGui::Godot
16 |
--------------------------------------------------------------------------------
/gdext/src/RdRenderer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Renderer.h"
3 | #include
4 | #include
5 | #include
6 |
7 | using godot::RID;
8 |
9 | namespace ImGui::Godot {
10 |
11 | class RdRenderer : public Renderer
12 | {
13 | public:
14 | RdRenderer();
15 | virtual ~RdRenderer();
16 |
17 | virtual const char* Name() override { return "godot4_rd"; }
18 |
19 | bool Init() override;
20 | void InitViewport(RID vprid) override;
21 | void CloseViewport(RID vprid) override {}
22 | virtual void Render() override;
23 | void OnHide() override {}
24 |
25 | protected:
26 | void Render(RID fb, ImDrawData* drawData);
27 | static void ReplaceTextureRIDs(ImDrawData* drawData);
28 | RID GetFramebuffer(RID vprid);
29 | void FreeUnusedTextures();
30 |
31 | private:
32 | struct Impl;
33 | std::unique_ptr impl;
34 | };
35 |
36 | } // namespace ImGui::Godot
37 |
--------------------------------------------------------------------------------
/gdext/src/RdRendererThreadSafe.cpp:
--------------------------------------------------------------------------------
1 | #include "RdRendererThreadSafe.h"
2 | #include "common.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | using namespace godot;
10 |
11 | namespace ImGui::Godot {
12 |
13 | struct RdRendererThreadSafe::Impl
14 | {
15 | struct ClonedDrawData
16 | {
17 | ClonedDrawData(ImDrawData* drawData)
18 | {
19 | static_assert(sizeof(ImDrawData) == 64);
20 | data = IM_NEW(ImDrawData);
21 | data->Valid = drawData->Valid;
22 | data->CmdListsCount = drawData->CmdListsCount;
23 | data->TotalIdxCount = drawData->TotalIdxCount;
24 | data->TotalVtxCount = drawData->TotalVtxCount;
25 | data->CmdLists = {};
26 | data->DisplayPos = drawData->DisplayPos;
27 | data->DisplaySize = drawData->DisplaySize;
28 | data->FramebufferScale = drawData->FramebufferScale;
29 | data->OwnerViewport = drawData->OwnerViewport;
30 |
31 | for (int i = 0; i < drawData->CmdLists.Size; ++i)
32 | {
33 | data->CmdLists.push_back(drawData->CmdLists[i]->CloneOutput());
34 | }
35 | }
36 |
37 | ~ClonedDrawData()
38 | {
39 | for (int i = 0; i < data->CmdLists.Size; ++i)
40 | {
41 | IM_DELETE(data->CmdLists[i]);
42 | }
43 | IM_DELETE(data);
44 | }
45 |
46 | ImDrawData* data;
47 | };
48 |
49 | bool isGodot42 = false;
50 |
51 | using SharedData = std::pair>;
52 |
53 | // mutex overhead should be minimal (near-zero contention), and refactoring to atomic is ugly
54 | std::mutex sharedDataMutex;
55 | std::vector dataToDraw;
56 | };
57 |
58 | RdRendererThreadSafe::RdRendererThreadSafe() : impl(std::make_unique())
59 | {
60 | // TODO: remove 4.2 compatibility when 4.4 is released
61 | Dictionary vinfo = Engine::get_singleton()->get_version_info();
62 | impl->isGodot42 = (int)vinfo["hex"] < 0x040300;
63 |
64 | if (impl->isGodot42)
65 | {
66 | RenderingServer* RS = RenderingServer::get_singleton();
67 | RS->connect("frame_pre_draw",
68 | Callable(Engine::get_singleton()->get_singleton("ImGuiController"), "on_frame_pre_draw"));
69 | }
70 |
71 | if (DisplayServer::get_singleton()->window_get_vsync_mode() == DisplayServer::VSYNC_DISABLED)
72 | {
73 | UtilityFunctions::push_warning("[imgui-godot] Multi-threaded renderer with vsync disabled will probably crash");
74 | }
75 | }
76 |
77 | RdRendererThreadSafe::~RdRendererThreadSafe()
78 | {
79 | }
80 |
81 | void RdRendererThreadSafe::Render()
82 | {
83 | auto& pio = ImGui::GetPlatformIO();
84 | std::vector newData(pio.Viewports.size());
85 |
86 | for (int i = 0; i < pio.Viewports.size(); ++i)
87 | {
88 | ImGuiViewport* vp = pio.Viewports[i];
89 | if (vp->Flags & ImGuiViewportFlags_IsMinimized)
90 | continue;
91 |
92 | RID vprid = make_rid(vp->RendererUserData);
93 | if (impl->isGodot42)
94 | {
95 | ReplaceTextureRIDs(vp->DrawData);
96 | newData[i].first = GetFramebuffer(vprid);
97 | }
98 | else
99 | {
100 | newData[i].first = vprid;
101 | }
102 | newData[i].second = std::make_unique(vp->DrawData);
103 | }
104 |
105 | {
106 | std::unique_lock lock(impl->sharedDataMutex);
107 | impl->dataToDraw = std::move(newData);
108 | }
109 |
110 | if (!impl->isGodot42)
111 | {
112 | RenderingServer::get_singleton()->call_on_render_thread(
113 | Callable(Engine::get_singleton()->get_singleton("ImGuiController"), "on_frame_pre_draw"));
114 | }
115 | }
116 |
117 | void RdRendererThreadSafe::OnFramePreDraw()
118 | {
119 | std::vector dataArray;
120 |
121 | {
122 | std::unique_lock lock(impl->sharedDataMutex);
123 | // take ownership of shared data
124 | dataArray = std::move(impl->dataToDraw);
125 | }
126 |
127 | RenderingDevice* RD = RenderingServer::get_singleton()->get_rendering_device();
128 | for (const auto& kv : dataArray)
129 | {
130 | RID fb = kv.first;
131 | ImDrawData* drawData = kv.second->data;
132 |
133 | if (!impl->isGodot42)
134 | {
135 | fb = GetFramebuffer(fb);
136 | ReplaceTextureRIDs(drawData);
137 | }
138 |
139 | if (RD->framebuffer_is_valid(fb))
140 | {
141 | RdRenderer::Render(fb, drawData);
142 | }
143 | }
144 |
145 | FreeUnusedTextures();
146 | }
147 |
148 | } // namespace ImGui::Godot
149 |
--------------------------------------------------------------------------------
/gdext/src/RdRendererThreadSafe.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "RdRenderer.h"
3 | #include
4 | #include
5 | #include
6 |
7 | using godot::RID;
8 |
9 | namespace ImGui::Godot {
10 |
11 | class RdRendererThreadSafe : public RdRenderer
12 | {
13 | public:
14 | RdRendererThreadSafe();
15 | virtual ~RdRendererThreadSafe();
16 |
17 | const char* Name() override { return "godot4_rd_mt"; }
18 |
19 | void Render() override;
20 | void OnFramePreDraw() override;
21 |
22 | private:
23 | struct Impl;
24 | std::unique_ptr impl;
25 | };
26 |
27 | } // namespace ImGui::Godot
28 |
--------------------------------------------------------------------------------
/gdext/src/Renderer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 |
6 | using godot::RID;
7 |
8 | namespace ImGui::Godot {
9 |
10 | class Renderer
11 | {
12 | public:
13 | Renderer() {}
14 | virtual ~Renderer() {}
15 |
16 | virtual const char* Name() = 0;
17 |
18 | virtual bool Init() = 0;
19 | virtual void InitViewport(RID vprid) = 0;
20 | virtual void CloseViewport(RID vprid) = 0;
21 | virtual void Render() = 0;
22 | virtual void OnHide() = 0;
23 | virtual void OnFramePreDraw() {}
24 | };
25 |
26 | } // namespace ImGui::Godot
27 |
--------------------------------------------------------------------------------
/gdext/src/Viewports.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | using namespace godot;
8 |
9 | namespace ImGui::Godot {
10 |
11 | class ImGuiWindow : public Window
12 | {
13 | GDCLASS(ImGuiWindow, Window);
14 |
15 | protected:
16 | static void _bind_methods()
17 | {
18 | ClassDB::bind_method(D_METHOD("_close_requested"), &ImGuiWindow::_close_requested);
19 | ClassDB::bind_method(D_METHOD("_size_changed"), &ImGuiWindow::_size_changed);
20 | }
21 |
22 | public:
23 | void init(ImGuiViewport* vp)
24 | {
25 | _vp = vp;
26 | connect("close_requested", Callable(this, "_close_requested"));
27 | connect("size_changed", Callable(this, "_size_changed"));
28 | }
29 |
30 | void _close_requested() { _vp->PlatformRequestClose = true; }
31 |
32 | void _size_changed() { _vp->PlatformRequestResize = true; }
33 |
34 | private:
35 | ImGuiViewport* _vp = nullptr;
36 | };
37 |
38 | class Viewports
39 | {
40 | public:
41 | Viewports();
42 | ~Viewports();
43 |
44 | void SetMainWindow(Window* mainWindow, RID mainSubViewport);
45 |
46 | private:
47 | struct Impl;
48 | std::unique_ptr impl;
49 | };
50 |
51 | } // namespace ImGui::Godot
52 |
--------------------------------------------------------------------------------
/gdext/src/common.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | using godot::RID;
6 |
7 | namespace ImGui::Godot {
8 |
9 | inline RID make_rid(int64_t id)
10 | {
11 | // HACK: only way to set a RID value
12 | RID rv;
13 | memcpy(rv._native_ptr(), &id, sizeof(int64_t));
14 | return rv;
15 | }
16 |
17 | inline RID make_rid(void* p)
18 | {
19 | return make_rid(reinterpret_cast(p));
20 | }
21 |
22 | } // namespace ImGui::Godot
23 |
24 | template <>
25 | struct std::hash
26 | {
27 | std::size_t operator()(const RID& rid) const noexcept { return rid.get_id(); }
28 | };
29 |
--------------------------------------------------------------------------------
/gdext/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | static_assert(GODOT_VERSION_MAJOR == 4 && GODOT_VERSION_MINOR >= 2);
13 |
14 | #include
15 |
16 | #include "ImGuiController.h"
17 | #include "ImGuiControllerHelper.h"
18 | #include "ImGuiGD.h"
19 | #include "ImGuiLayer.h"
20 | #include "ImGuiSync.h"
21 | #include "Viewports.h"
22 |
23 | // avoid including cimgui.h elsewhere
24 |
25 | namespace ImGui::Godot {
26 | void register_imgui_api();
27 | void unregister_imgui_api();
28 | } // namespace ImGui::Godot
29 |
30 | using namespace godot;
31 | using namespace ImGui::Godot;
32 |
33 | ImGuiGD* gd = nullptr;
34 |
35 | #ifdef _WIN32
36 | #define WIN32_LEAN_AND_MEAN
37 | #include
38 | #else
39 | #include
40 | #endif
41 |
42 | void sync_modules()
43 | {
44 | typedef void (*pmodinit)(uint32_t, ImGuiContext*, ImGuiMemAllocFunc, ImGuiMemFreeFunc);
45 | #ifdef _WIN32
46 | pmodinit mod_init = (pmodinit)GetProcAddress(GetModuleHandle(nullptr), "imgui_godot_module_init");
47 | #else
48 | pmodinit mod_init = (pmodinit)dlsym(dlopen(nullptr, RTLD_LAZY), "imgui_godot_module_init");
49 | #endif
50 | if (mod_init)
51 | {
52 | ImGuiMemAllocFunc afunc;
53 | ImGuiMemFreeFunc ffunc;
54 | void* ud;
55 | ImGui::GetAllocatorFunctions(&afunc, &ffunc, &ud);
56 | mod_init(IMGUI_VERSION_NUM, ImGui::GetCurrentContext(), afunc, ffunc);
57 | }
58 | }
59 |
60 | void initialize_ign_module(ModuleInitializationLevel p_level)
61 | {
62 | if (p_level == MODULE_INITIALIZATION_LEVEL_SERVERS)
63 | {
64 | ImGui::CreateContext();
65 | ClassDB::register_internal_class();
66 | }
67 |
68 | if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE)
69 | return;
70 |
71 | ClassDB::register_internal_class();
72 | ClassDB::register_internal_class();
73 | ClassDB::register_class();
74 | ClassDB::register_class();
75 | ClassDB::register_internal_class();
76 | register_imgui_api();
77 |
78 | gd = memnew(ImGuiGD);
79 | Engine::get_singleton()->register_singleton("ImGuiGD", gd);
80 | sync_modules();
81 |
82 | if (!ProjectSettings::get_singleton()->has_setting("autoload/ImGuiRoot"))
83 | {
84 | UtilityFunctions::push_warning(
85 | "[imgui-godot] Plugin is not enabled. If you call ImGui methods, your project will crash!");
86 | }
87 | }
88 |
89 | void uninitialize_ign_module(ModuleInitializationLevel p_level)
90 | {
91 | if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE)
92 | return;
93 |
94 | Engine::get_singleton()->unregister_singleton("ImGuiGD");
95 | memdelete(gd);
96 | unregister_imgui_api();
97 | }
98 |
99 | extern "C" {
100 | GDExtensionBool GDE_EXPORT ign_init(GDExtensionInterfaceGetProcAddress p_get_proc_address,
101 | GDExtensionClassLibraryPtr p_library, GDExtensionInitialization* r_initialization)
102 | {
103 | GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
104 |
105 | init_obj.register_initializer(initialize_ign_module);
106 | init_obj.register_terminator(uninitialize_ign_module);
107 | init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SERVERS);
108 |
109 | return init_obj.init();
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/gdext/vcpkg.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | "freetype"
4 | ],
5 | "builtin-baseline": "6f29f12e82a8293156836ad81cc9bf5af41fe836"
6 | }
--------------------------------------------------------------------------------
/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="Dear ImGui for Godot Demo"
14 | run/main_scene="res://data/demo.tscn"
15 | config/features=PackedStringArray("4.3", "C#")
16 | run/max_fps=60
17 | config/icon="res://data/icon.svg"
18 |
19 | [autoload]
20 |
21 | ImGuiRoot="*res://addons/imgui-godot/data/ImGuiRoot.tscn"
22 |
23 | [display]
24 |
25 | window/size/viewport_width=1280
26 | window/size/viewport_height=720
27 | window/subwindows/embed_subwindows=false
28 | window/stretch/mode="canvas_items"
29 | window/stretch/aspect="expand"
30 | window/vsync/vsync_mode=0
31 |
32 | [dotnet]
33 |
34 | project/assembly_name="Dear ImGui for Godot Demo"
35 |
36 | [editor_plugins]
37 |
38 | enabled=PackedStringArray("res://addons/imgui-godot/plugin.cfg")
39 |
--------------------------------------------------------------------------------
/src/MyNode.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using ImGuiGodot;
3 | using ImGuiNET;
4 |
5 | namespace DemoProject;
6 |
7 | public partial class MyNode : Node
8 | {
9 | private Window _window = null!;
10 | private CheckBox _checkBox = null!;
11 |
12 | public override void _Ready()
13 | {
14 | _window = GetWindow();
15 | GetNode