Skip to content

Commit

Permalink
Dynamic font reloading and fix imgui renderer (#262)
Browse files Browse the repository at this point in the history
  • Loading branch information
katalash authored Nov 27, 2022
1 parent 86be484 commit d41b8c8
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 39 deletions.
11 changes: 7 additions & 4 deletions StudioCore/ImGuiRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,11 @@ public unsafe void Render(GraphicsDevice gd, CommandList cl)
/// <summary>
/// Updates ImGui input and IO configuration state.
/// </summary>
public void Update(float deltaSeconds, InputSnapshot snapshot)
public void Update(float deltaSeconds, InputSnapshot snapshot, Action updateFontAction)
{
BeginUpdate(deltaSeconds);
if (updateFontAction != null)
updateFontAction.Invoke();
UpdateImGuiInput(snapshot);
EndUpdate();
}
Expand Down Expand Up @@ -628,11 +630,12 @@ private unsafe void RenderImDrawData(ImDrawDataPtr draw_data, GraphicsDevice gd,
(uint)(pcmd.ClipRect.Z - pcmd.ClipRect.X),
(uint)(pcmd.ClipRect.W - pcmd.ClipRect.Y));

cl.DrawIndexed(pcmd.ElemCount, 1, (uint)idx_offset, vtx_offset, (uint)pcmd.TextureId);
cl.DrawIndexed(pcmd.ElemCount, 1, (uint)idx_offset + pcmd.IdxOffset, vtx_offset, (uint)pcmd.TextureId);
}

idx_offset += (int)pcmd.ElemCount;

}

idx_offset += cmd_list.IdxBuffer.Size;
vtx_offset += cmd_list.VtxBuffer.Size;
}
}
Expand Down
84 changes: 50 additions & 34 deletions StudioCore/MapStudioNew.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace StudioCore
{
public class MapStudioNew
{
private static string _version = "1.04.1";
private static string _version = "1.05";
private static string _programTitle = $"Dark Souls Map Studio version {_version}";

private Sdl2Window _window;
Expand Down Expand Up @@ -78,6 +78,8 @@ public class MapStudioNew
private static bool _firstframe = true;
public static bool FirstFrame = true;

private bool _needsRebuildFont = false;

public MapStudioNew()
{
CFG.AttemptLoadOrDefault();
Expand Down Expand Up @@ -174,25 +176,32 @@ private unsafe void SetupFonts()
var fonts = ImGui.GetIO().Fonts;
var fileEn = Path.Combine(AppContext.BaseDirectory, $@"Assets\Fonts\RobotoMono-Light.ttf");
var fontEn = File.ReadAllBytes(fileEn);
var fontEnNative = ImGui.MemAlloc((uint)fontEn.Length);
Marshal.Copy(fontEn, 0, fontEnNative, fontEn.Length);
var fileOther = Path.Combine(AppContext.BaseDirectory, $@"Assets\Fonts\NotoSansCJKtc-Light.otf");
var fontOther = File.ReadAllBytes(fileOther);
var fontOtherNative = ImGui.MemAlloc((uint)fontOther.Length);
Marshal.Copy(fontOther, 0, fontOtherNative, fontOther.Length);
var fileIcon = Path.Combine(AppContext.BaseDirectory, $@"Assets\Fonts\forkawesome-webfont.ttf");
var fontIcon = File.ReadAllBytes(fileIcon);
var fontIconNative = ImGui.MemAlloc((uint)fontIcon.Length);
Marshal.Copy(fontIcon, 0, fontIconNative, fontIcon.Length);
//fonts.AddFontFromFileTTF($@"Assets\Fonts\NotoSansCJKtc-Medium.otf", 20.0f, null, fonts.GetGlyphRangesJapanese());
fonts.Clear();

float scale = ImGuiRenderer.GetUIScale();

fixed (byte* p = fontEn)
// English fonts
{
var ptr = ImGuiNative.ImFontConfig_ImFontConfig();
var cfg = new ImFontConfigPtr(ptr);
cfg.GlyphMinAdvanceX = 5.0f;
cfg.OversampleH = 5;
cfg.OversampleV = 5;
fonts.AddFontFromMemoryTTF((IntPtr)p, fontEn.Length, 14.0f * scale, cfg, fonts.GetGlyphRangesDefault());
fonts.AddFontFromMemoryTTF(fontEnNative, fontIcon.Length, 14.0f * scale, cfg, fonts.GetGlyphRangesDefault());
}
fixed (byte* p = fontOther)

// Other language fonts
{
var ptr = ImGuiNative.ImFontConfig_ImFontConfig();
var cfg = new ImFontConfigPtr(ptr);
Expand All @@ -201,26 +210,27 @@ private unsafe void SetupFonts()
cfg.OversampleH = 5;
cfg.OversampleV = 5;

var glyphJP = new ImFontGlyphRangesBuilderPtr(ImGuiNative.ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder());
glyphJP.AddRanges(fonts.GetGlyphRangesJapanese());
Array.ForEach(SpecialCharsJP, c => glyphJP.AddChar(c));
glyphJP.BuildRanges(out ImVector glyphRangeJP);
fonts.AddFontFromMemoryTTF((IntPtr)p, fontOther.Length, 16.0f * scale, cfg, glyphRangeJP.Data);
glyphJP.Destroy();

var glyphRanges = new ImFontGlyphRangesBuilderPtr(ImGuiNative.ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder());
glyphRanges.AddRanges(fonts.GetGlyphRangesJapanese());
Array.ForEach(SpecialCharsJP, c => glyphRanges.AddChar(c));

if (CFG.Current.FontChinese)
fonts.AddFontFromMemoryTTF((IntPtr)p, fontOther.Length, 16.0f * scale, cfg, fonts.GetGlyphRangesChineseFull());
glyphRanges.AddRanges(fonts.GetGlyphRangesChineseFull());
if (CFG.Current.FontKorean)
fonts.AddFontFromMemoryTTF((IntPtr)p, fontOther.Length, 16.0f * scale, cfg, fonts.GetGlyphRangesKorean());
glyphRanges.AddRanges(fonts.GetGlyphRangesKorean());
if (CFG.Current.FontThai)
fonts.AddFontFromMemoryTTF((IntPtr)p, fontOther.Length, 16.0f * scale, cfg, fonts.GetGlyphRangesThai());
glyphRanges.AddRanges(fonts.GetGlyphRangesThai());
if (CFG.Current.FontVietnamese)
fonts.AddFontFromMemoryTTF((IntPtr)p, fontOther.Length, 16.0f * scale, cfg, fonts.GetGlyphRangesVietnamese());
cfg.GlyphMinAdvanceX = 5.0f;
glyphRanges.AddRanges(fonts.GetGlyphRangesVietnamese());
if (CFG.Current.FontCyrillic)
fonts.AddFontFromMemoryTTF((IntPtr)p, fontOther.Length, 18.0f * scale, cfg, fonts.GetGlyphRangesCyrillic());
glyphRanges.AddRanges(fonts.GetGlyphRangesCyrillic());

glyphRanges.BuildRanges(out ImVector glyphRange);
fonts.AddFontFromMemoryTTF(fontOtherNative, fontOther.Length, 16.0f * scale, cfg, glyphRange.Data);
glyphRanges.Destroy();
}
fixed (byte* p = fontIcon)

// Icon fonts
{
ushort[] ranges = { ForkAwesome.IconMin, ForkAwesome.IconMax, 0 };
var ptr = ImGuiNative.ImFontConfig_ImFontConfig();
Expand All @@ -233,10 +243,10 @@ private unsafe void SetupFonts()

fixed (ushort* r = ranges)
{
var f = fonts.AddFontFromMemoryTTF((IntPtr)p, fontIcon.Length, 16.0f * scale, cfg, (IntPtr)r);
var f = fonts.AddFontFromMemoryTTF(fontIconNative, fontIcon.Length, 16.0f * scale, cfg, (IntPtr)r);
}
}
fonts.Build();

ImguiRenderer.RecreateFontDeviceTexture();
}

Expand Down Expand Up @@ -329,7 +339,7 @@ public void Run()
{
break;
}

if (true)//_window.Focused)
{
ctx = Tracy.TracyCZoneNC(1, "Draw", 0xFFFF0000);
Expand Down Expand Up @@ -619,7 +629,16 @@ private void Update(float deltaseconds)

float scale = ImGuiRenderer.GetUIScale();

ImguiRenderer.Update(deltaseconds, InputTracker.FrameSnapshot);
if (_needsRebuildFont)
{
ImguiRenderer.Update(deltaseconds, InputTracker.FrameSnapshot, SetupFonts);
_needsRebuildFont = false;
}
else
{
ImguiRenderer.Update(deltaseconds, InputTracker.FrameSnapshot, null);
}

Tracy.TracyCZoneEnd(ctx);
List<string> tasks = Editor.TaskManager.GetLiveThreads();
Editor.TaskManager.ThrowTaskExceptions();
Expand Down Expand Up @@ -819,16 +838,14 @@ private void Update(float deltaseconds)

if (ImGui.BeginMenu("UI"))
{
ImGui.Text("Please restart program for UI changes to take effect.");
ImGui.Separator();

ImGui.SliderFloat("UI Scale", ref _uiScale, 0.5f, 4.0f);
if (ImGui.IsItemDeactivatedAfterEdit())
{
// Round to 0.05
float newScale = (float)Math.Round(_uiScale * 20) / 20;
_uiScale = newScale;
CFG.Current.UIScale = newScale;
_needsRebuildFont = true;
}
if (ImGui.BeginMenu("Additional Language Fonts"))
{
Expand All @@ -837,22 +854,27 @@ private void Update(float deltaseconds)
if (ImGui.MenuItem("Chinese", "", CFG.Current.FontChinese))
{
CFG.Current.FontChinese = !CFG.Current.FontChinese;
_needsRebuildFont = true;
}
if (ImGui.MenuItem("Korean", "", CFG.Current.FontKorean))
{
CFG.Current.FontKorean = !CFG.Current.FontKorean;
_needsRebuildFont = true;
}
if (ImGui.MenuItem("Thai", "", CFG.Current.FontThai))
{
CFG.Current.FontThai = !CFG.Current.FontThai;
_needsRebuildFont = true;
}
if (ImGui.MenuItem("Vietnamese", "", CFG.Current.FontVietnamese))
{
CFG.Current.FontVietnamese = !CFG.Current.FontVietnamese;
_needsRebuildFont = true;
}
if (ImGui.MenuItem("Cyrillic", "", CFG.Current.FontCyrillic))
{
CFG.Current.FontCyrillic = !CFG.Current.FontCyrillic;
_needsRebuildFont = true;
}
ImGui.EndMenu();
}
Expand Down Expand Up @@ -938,7 +960,8 @@ private void Update(float deltaseconds)
"Additional Contributors:\n" +
"Thefifthmatt\n" +
"Shadowth117\n" +
"Nordgaren\n\n" +
"Nordgaren\n" +
"ivi\n\n" +
"Special Thanks:\n" +
"TKGP\n" +
"Meowmaritus\n" +
Expand Down Expand Up @@ -995,13 +1018,6 @@ private void Update(float deltaseconds)
UseShellExecute = true
});
}
/*
if (ImGui.BeginMenu("Edits aren't sticking!"))
{
ImGui.Text("The mechanism that is used to detect if a field has been changed can stop existing before registering a change.\nThis occurs when switching param, row or using tab between fields.\nI hope to have this fixed soon, however it is a complicated issue.\nTo ensure a change sticks, simply click off the field you are editing.");
ImGui.EndMenu();
}
*/
ImGui.EndMenu();
}
if (FeatureFlags.TestMenu)
Expand Down Expand Up @@ -1130,7 +1146,7 @@ private void Update(float deltaseconds)
_newProjectOptions.directory = "";
ImGui.OpenPopup("New Project");
}
if (ImGui.BeginPopupModal("New Project", ref open, ImGuiWindowFlags.AlwaysAutoResize)) // The Grey overlay is apparently an imgui bug (that has been fixed in updated builds; in some forks at least).
if (ImGui.BeginPopupModal("New Project", ref open, ImGuiWindowFlags.AlwaysAutoResize))
{
ImGui.AlignTextToFramePadding();
ImGui.Text("Project Name: ");
Expand Down
2 changes: 1 addition & 1 deletion StudioCore/MsbEditor/AssetBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public void OnGui()
if (InputTracker.GetKeyDown(KeyBindings.Current.Map_PropSearch))
ImGui.SetKeyboardFocusHere();
ImGui.InputText($"Search <{KeyBindings.Current.Map_PropSearch.HintText}>", ref _searchStr, 255);

ImGui.Spacing();
ImGui.Separator();
ImGui.Spacing();
Expand Down

0 comments on commit d41b8c8

Please sign in to comment.