Dear ImGui
The engine runs Dear ImGui through ImGui.NET, with docking enabled and the dark style. It is for debug panels, tools and developer views. Player-facing screens belong in BSGameLib.UI.
The engine starts a frame before your drawing and ends it after. Your code only adds windows and
widgets, so use the ImGuiNET namespace as you would in any ImGui.NET program:
using ImGuiNET;
protected override void EndFrame(IGameTime gameTime)
{
ImGui.Begin("Debug");
ImGui.Text($"Frame: {gameTime.DeltaSeconds * 1000f:F1} ms");
if (ImGui.Button("Pause"))
_paused = true;
ImGui.End();
base.EndFrame(gameTime);
}
Where to call ImGui
Call ImGui while a frame is open. That is from EndFrame, which is the usual place for windows, and
also from Draw and ConfigureRenderGraph. Outside a frame an ImGui call is invalid, so do not make
them from Update or Initialize. Put a window in EndFrame and it is drawn in that same frame, on
top of the game.
The engine finishes the frame and draws it after EndFrame returns. Do not call ImGui.NewFrame,
ImGui.EndFrame or ImGui.Render yourself.
Fonts
ImGui's built-in font has Latin letters only. Text in another script comes out blank unless a font with those glyphs is merged in. IImGuiFonts chooses that font:
using BSGameLib.Game;
using BSGameLib.Game.Localization;
var fonts = GetService<IImGuiFonts>();
fonts.UseFont(
Path.Combine(AppContext.BaseDirectory, "Fonts", "NotoSansJP-Regular.ttf"),
LanguageScripts.Japanese);
UseFont merges the font's glyphs for one script into the built-in font. English draws as before, and
the script draws in the font. Pass null to go back to the built-in font alone.
- The script is one of the constants in LanguageScripts:
Latin(the default),Cyrillic,Greek,Vietnamese,Thai,Japanese,Korean,ChineseSimplifiedandChineseFull. An unknown name is treated asLatin. - A file that does not exist is logged, and the built-in font is kept.
- The change takes effect at the start of the next frame, when the font texture is rebuilt.
ChineseFullcovers every Chinese character, which makes a large texture. PreferChineseSimplifiedunless the game needs more.
FontPath and Script on the same interface report what is in use. A localized game can pass the
font and script a language file names (LanguageInfo.FontFile and Script) when the language
changes. See Localization.
ImGui and the game's own text are separate. This font is used only by ImGui windows.
Input and ImGui
When one of its windows wants the keyboard or the mouse, ImGui has first claim on that input. The game's input follows from that:
- While ImGui wants the keyboard, the game receives no keys. The bindings and
IKeyboardManagersee nothing, and the key events are not raised. Typing into an ImGui text field does not also reach a game action. A key released while ImGui has the keyboard is still released for the game, so no key is left held down. See Input. - While ImGui wants the mouse, the scroll wheel is withheld from the game. Clicks and movement still reach it, so a game that should ignore clicks over an ImGui window must check for itself.
ImGui's text fields receive typed text for as long as the renderer runs. It holds text input through the same count as the game's text handlers, so a game text box losing focus does not switch it off.
To ask ImGui, read ImGui.GetIO().WantCaptureMouse or WantCaptureKeyboard. ImGui sets these during
its own frame, so in Update they describe the frame before.
protected override void Update(IGameTime gameTime)
{
if (!ImGui.GetIO().WantCaptureMouse && _mouse.IsClicked)
SelectTile();
base.Update(gameTime);
}
Clipboard
ImGui's clipboard reads and writes the same system clipboard as SdlClipboard, so text copied in an ImGui field can be pasted into a game control, and the reverse.