|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using ImGuiNET;
|
|
|
using ImGuiNET.SampleProgram.XNA;
|
|
|
|
|
|
using Num = System.Numerics;
|
|
|
using Microsoft.Xna.Framework;
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
using isometricparkfna.Engines;
|
|
|
using isometricparkfna.Messages;
|
|
|
|
|
|
namespace isometricparkfna.UI
|
|
|
{
|
|
|
|
|
|
public struct DebugInfo
|
|
|
{
|
|
|
public float fps;
|
|
|
public float[] pastFps;
|
|
|
public TimeSpan drawTime;
|
|
|
public TimeSpan treeDrawTime;
|
|
|
public TimeSpan gridDrawTime;
|
|
|
public TimeSpan tileDrawTime;
|
|
|
public TimeSpan rendererDrawTime;
|
|
|
public TimeSpan miscUIDrawTime;
|
|
|
public TimeSpan debugDrawTime;
|
|
|
public Vector2 cameraPosition;
|
|
|
public int treeCount;
|
|
|
public Vector2 mouseGrid;
|
|
|
public Boolean hasTree;
|
|
|
public int tilesDrawn;
|
|
|
public TimeSpan updateTime;
|
|
|
public TimeSpan worldUpdateTime;
|
|
|
public TimeSpan simulationUpdateTime;
|
|
|
|
|
|
}
|
|
|
|
|
|
public class DebugWindow
|
|
|
{
|
|
|
|
|
|
private Texture2D _xnaTexture;
|
|
|
private IntPtr _imGuiTexture;
|
|
|
private bool show_test_window;
|
|
|
|
|
|
public ImFontPtr monoFont;
|
|
|
public ImFontPtr italicFont;
|
|
|
|
|
|
public ImageMap map;
|
|
|
|
|
|
private ImGuiWindowBridgeEngine _engine;
|
|
|
public ImGuiWindowBridgeEngine engine {
|
|
|
get {
|
|
|
return this._engine;
|
|
|
}
|
|
|
set {
|
|
|
this._engine = value;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private ImGuiRenderer renderer;
|
|
|
|
|
|
public static Dictionary<string, string> fonts = new Dictionary<String, string> {{"Roboto", @"Content/Roboto-Regular.ttf"},
|
|
|
{"RobotoMedium", @"Content/Roboto-Medium.ttf"},
|
|
|
{"Iosevka", @"Content/iosevka-term-extendedmedium.ttf"}
|
|
|
};
|
|
|
public static Dictionary<string, string> italicFonts = new Dictionary<String, string> {{"Roboto", @"Content/Roboto-Italic.ttf"},
|
|
|
{"RobotoMedium", @"Content/Roboto-Medium.ttf"},
|
|
|
{"Iosevka", @"Content/iosevka-term-extendedmediumitalic.ttf"}
|
|
|
};
|
|
|
|
|
|
|
|
|
public DebugWindow(ImGuiRenderer _imGuiRenderer, GraphicsDevice graphicsDevice, ImageMap map)
|
|
|
{
|
|
|
|
|
|
this.renderer = _imGuiRenderer;
|
|
|
ImGuiIOPtr io = ImGui.GetIO();
|
|
|
//io.Fonts.AddFontFromFileTTF(@"Content/iosevka-term-medium.ttf", 15);
|
|
|
|
|
|
#if DEBUG
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/iosevka-medium.ttf", 15);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/iosevka-term-medium.ttf", 15);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/iosevka-term-medium.ttf", 17);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/iosevka-term-extendedmedium.ttf", 20);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/iosevka-term-extendedmedium.ttf", 25);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/iosevka-term-extendedmedium.ttf", 30);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/Roboto-Regular.ttf", 15);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/Roboto-Regular.ttf", 30);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/Roboto-Medium.ttf", 15);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/Roboto-Medium.ttf", 30);
|
|
|
#endif
|
|
|
|
|
|
this.monoFont = io.Fonts.AddFontFromFileTTF(@"Content/iosevka-term-extendedmedium.ttf", 15);
|
|
|
unsafe //god this sucks
|
|
|
{
|
|
|
ImFontConfigPtr config = ImGuiNative.ImFontConfig_ImFontConfig();
|
|
|
config.MergeMode = true;
|
|
|
var builder = new ImFontGlyphRangesBuilderPtr(ImGuiNative.ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder());
|
|
|
// builder.AddText("\ue125\ue126");
|
|
|
var icon_ranges = new ushort[] { 0xe000, 0xe1f4, 0 };
|
|
|
GCHandle rangeHandle = GCHandle.Alloc(icon_ranges, GCHandleType.Pinned);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/typicons.ttf", 15, config, rangeHandle.AddrOfPinnedObject());
|
|
|
|
|
|
|
|
|
}
|
|
|
this.italicFont = io.Fonts.AddFontFromFileTTF(@"Content/iosevka-term-extendedmediumitalic.ttf", 15);
|
|
|
|
|
|
_imGuiRenderer.RebuildFontAtlas(); // Required so fonts are available for rendering
|
|
|
|
|
|
|
|
|
this.map = map;
|
|
|
this.engine = engine;
|
|
|
_xnaTexture = map.ImageMapTexture;
|
|
|
// _xnaTexture = CreateTexture(graphicsDevice, 300, 150, pixel =>
|
|
|
// {
|
|
|
// var red = (pixel % 300) / 2;
|
|
|
// return new Color(red, 1, 1);
|
|
|
// });
|
|
|
//
|
|
|
// Then, bind it to an ImGui-friendly pointer, that we can use during regular ImGui.** calls (see below)
|
|
|
_imGuiTexture = _imGuiRenderer.BindTexture(_xnaTexture);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void swap()
|
|
|
{
|
|
|
ImGuiIOPtr io = ImGui.GetIO();
|
|
|
|
|
|
this.monoFont = io.Fonts.AddFontFromFileTTF(@"Content/Roboto-Regular.ttf", 15);
|
|
|
unsafe //god this sucks
|
|
|
{
|
|
|
ImFontConfigPtr config = ImGuiNative.ImFontConfig_ImFontConfig();
|
|
|
config.MergeMode = true;
|
|
|
var builder = new ImFontGlyphRangesBuilderPtr(ImGuiNative.ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder());
|
|
|
// builder.AddText("\ue125\ue126");
|
|
|
var icon_ranges = new ushort[] { 0xe000, 0xe1f4, 0 };
|
|
|
GCHandle rangeHandle = GCHandle.Alloc(icon_ranges, GCHandleType.Pinned);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/typicons.ttf", 15, config, rangeHandle.AddrOfPinnedObject());
|
|
|
|
|
|
|
|
|
}
|
|
|
this.renderer.RebuildFontAtlas(); // Required so fonts are available for rendering
|
|
|
}
|
|
|
|
|
|
public ImFontPtr addFont(String name, int size, bool italic)
|
|
|
{
|
|
|
ImGuiIOPtr io = ImGui.GetIO();
|
|
|
ImFontPtr font;
|
|
|
|
|
|
if (italic)
|
|
|
{
|
|
|
font = io.Fonts.AddFontFromFileTTF(italicFonts[name], size);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
font = io.Fonts.AddFontFromFileTTF(fonts[name], size);
|
|
|
}
|
|
|
unsafe //god this sucks
|
|
|
{
|
|
|
ImFontConfigPtr config = ImGuiNative.ImFontConfig_ImFontConfig();
|
|
|
config.MergeMode = true;
|
|
|
var builder = new ImFontGlyphRangesBuilderPtr(ImGuiNative.ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder());
|
|
|
// builder.AddText("\ue125\ue126");
|
|
|
var icon_ranges = new ushort[] { 0xe000, 0xe1f4, 0 };
|
|
|
GCHandle rangeHandle = GCHandle.Alloc(icon_ranges, GCHandleType.Pinned);
|
|
|
io.Fonts.AddFontFromFileTTF(@"Content/typicons.ttf", size, config, rangeHandle.AddrOfPinnedObject());
|
|
|
|
|
|
|
|
|
}
|
|
|
this.renderer.RebuildFontAtlas(); // Required so fonts are available for rendering
|
|
|
return font;
|
|
|
}
|
|
|
|
|
|
public void setMonoFont(ImFontPtr font)
|
|
|
{
|
|
|
this.monoFont = font;
|
|
|
}
|
|
|
|
|
|
public void setItalicFont(ImFontPtr font)
|
|
|
{
|
|
|
this.italicFont = font;
|
|
|
}
|
|
|
|
|
|
public static Texture2D CreateTexture(GraphicsDevice device, int width, int height, Func<int, Color> paint)
|
|
|
{
|
|
|
//initialize a texture
|
|
|
var texture = new Texture2D(device, width, height);
|
|
|
|
|
|
//the array holds the color for each pixel in the texture
|
|
|
Color[] data = new Color[width * height];
|
|
|
for (var pixel = 0; pixel < data.Length; pixel++)
|
|
|
{
|
|
|
//the function applies the color according to the specified pixel
|
|
|
data[pixel] = paint(pixel);
|
|
|
}
|
|
|
|
|
|
//set the color
|
|
|
texture.SetData(data);
|
|
|
|
|
|
return texture;
|
|
|
}
|
|
|
|
|
|
public virtual void ImGuiLayout()
|
|
|
{
|
|
|
|
|
|
float f = 0.0f;
|
|
|
|
|
|
bool show_test_window = false;
|
|
|
bool show_another_window = false;
|
|
|
Num.Vector3 clear_color = new Num.Vector3(114f / 255f, 144f / 255f, 154f / 255f);
|
|
|
byte[] _textBuffer = new byte[100];
|
|
|
|
|
|
// 1. Show a simple window
|
|
|
// Tip: if we don't call ImGui.Begin()/ImGui.End() the widgets appears in a window automatically called "Debug"
|
|
|
{
|
|
|
|
|
|
|
|
|
ImGui.Text("Hello, world!");
|
|
|
ImGui.SliderFloat("float", ref f, 0.0f, 1.0f, string.Empty);
|
|
|
ImGui.ColorEdit3("clear color", ref clear_color);
|
|
|
if (ImGui.Button("Test Window")) show_test_window = !show_test_window;
|
|
|
if (ImGui.Button("Another Window")) show_another_window = !show_another_window;
|
|
|
ImGui.Text(string.Format("Application average {0:F3} ms/frame ({1:F1} FPS)", 1000f / ImGui.GetIO().Framerate, ImGui.GetIO().Framerate));
|
|
|
|
|
|
ImGui.InputText("Text input", _textBuffer, 100);
|
|
|
|
|
|
ImGui.Text("Texture sample");
|
|
|
// ImGui.Image(_imGuiTexture, new Num.Vector2(300, 150), Num.Vector2.Zero, map.GetSourceUV(1), Num.Vector4.One, Num.Vector4.One); // Here, the previously loaded texture is used
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
public virtual void Layout(DebugInfo debugInfo, Dictionary<String, String> additionalInfo, ref bool show)
|
|
|
{
|
|
|
|
|
|
if (show)
|
|
|
{
|
|
|
ImGui.Begin("Debug", ref show);
|
|
|
|
|
|
if (ImGui.BeginTabBar("DebugTabs"))
|
|
|
{
|
|
|
if(ImGui.BeginTabItem("Debug"))
|
|
|
{
|
|
|
|
|
|
ImGui.Text(string.Format("fps: {0:F3}", debugInfo.fps));
|
|
|
ImGui.Text(string.Format("Draw Time: {0:F3}", debugInfo.drawTime.TotalMilliseconds.ToString()));
|
|
|
ImGui.Text(string.Format("\tTree: {0,7:F3}; Grid: {1,7:F3}; Tile: {2,7:F3}\n\tRenderer: {3,7:F3}; Misc UI: {4,7:F3}; Debug: {5,7:F3}",
|
|
|
debugInfo.treeDrawTime.TotalMilliseconds.ToString(),
|
|
|
debugInfo.gridDrawTime.TotalMilliseconds.ToString(),
|
|
|
debugInfo.tileDrawTime.TotalMilliseconds.ToString(),
|
|
|
debugInfo.rendererDrawTime.TotalMilliseconds.ToString(),
|
|
|
debugInfo.miscUIDrawTime.TotalMilliseconds.ToString(),
|
|
|
debugInfo.debugDrawTime.TotalMilliseconds.ToString()));
|
|
|
ImGui.Text(string.Format("Update Time: {0:F3}", debugInfo.updateTime.TotalMilliseconds.ToString()));
|
|
|
ImGui.Text(string.Format("\tWorld: {0:F3}; Simulation: {1:F3}",
|
|
|
debugInfo.worldUpdateTime.TotalMilliseconds.ToString(),
|
|
|
debugInfo.simulationUpdateTime.TotalMilliseconds.ToString()));
|
|
|
ImGui.Text(string.Format("Tiles Drawn: {0:F}", debugInfo.tilesDrawn));
|
|
|
|
|
|
|
|
|
ImGui.Text(string.Format("\nCamera Position: {0}", debugInfo.cameraPosition.ToString()));
|
|
|
ImGui.Text(string.Format("\nGrid Position: {0} (has tree: {1})", debugInfo.mouseGrid.ToString(), debugInfo.hasTree));
|
|
|
|
|
|
ImGui.Text(string.Format("Application average {0:F3} ms/frame ({1:F1} FPS", 1000f / ImGui.GetIO().Framerate, ImGui.GetIO().Framerate));
|
|
|
|
|
|
if (ImGui.Button("Test Window"))
|
|
|
{
|
|
|
this.show_test_window = !this.show_test_window;
|
|
|
}
|
|
|
|
|
|
if (ImGui.Button("Test Logging"))
|
|
|
{
|
|
|
Logging.Log(LogLevel.Critical, "Test");
|
|
|
Logging.Log(LogLevel.Error, "Test");
|
|
|
Logging.Log(LogLevel.Warning, "Test");
|
|
|
Logging.Log(LogLevel.Info, "Test");
|
|
|
Logging.Log(LogLevel.Debug, "Test");
|
|
|
Logging.Log(LogLevel.Trace, "Test");
|
|
|
|
|
|
Logging.Critical("Test");
|
|
|
Logging.Error("Test");
|
|
|
Logging.Warning("Test");
|
|
|
Logging.Success("Test");
|
|
|
Logging.Info("Test");
|
|
|
Logging.Debug("Test");
|
|
|
Logging.Trace("Test");
|
|
|
|
|
|
// var t = (testa: 1, testb: 2);
|
|
|
//Logging.Log(LogLevel.Critical, "Test", t);
|
|
|
Logging.Log(LogLevel.Critical, "test", new {test=9.0f});
|
|
|
//Logging.Log(LogLevel.Critical, "{0}", 0, null, "", 9.0f);
|
|
|
|
|
|
Logging.Spy(new {debugInfo.cameraPosition, debugInfo.updateTime, test = 9.0f /2});
|
|
|
|
|
|
}
|
|
|
|
|
|
if (ImGui.BeginCombo("Log Level", Logging.minimumConsoleLevel.ToString()))
|
|
|
{
|
|
|
foreach(LogLevel level in LogLevel.GetValues(typeof(LogLevel)))
|
|
|
{
|
|
|
if(ImGui.Selectable(level.ToString()))
|
|
|
{
|
|
|
Logging.minimumConsoleLevel = level;
|
|
|
}
|
|
|
}
|
|
|
ImGui.EndCombo();
|
|
|
}
|
|
|
|
|
|
if (debugInfo.pastFps.Length >= 1)
|
|
|
{
|
|
|
ImGui.PlotLines("Frame Rate", ref debugInfo.pastFps[0], debugInfo.pastFps.Length);
|
|
|
}
|
|
|
ImGui.EndTabItem();
|
|
|
}
|
|
|
if(ImGui.BeginTabItem("Additional Info"))
|
|
|
{
|
|
|
foreach (string k in additionalInfo.Keys)
|
|
|
{
|
|
|
ImGui.Text(string.Format("{0}: {1}", k, additionalInfo[k]));
|
|
|
}
|
|
|
|
|
|
ImGui.EndTabItem();
|
|
|
}
|
|
|
|
|
|
if(ImGui.BeginTabItem("Texture Samples"))
|
|
|
{
|
|
|
ImGui.Text("Texture sample");
|
|
|
ImGui.Image(_imGuiTexture, new Num.Vector2(250, 200), map.GetSourceUVStart(1), map.GetSourceUVEnd(1), Num.Vector4.One, Num.Vector4.One); // Here, the previously loaded texture is used
|
|
|
ImGui.Image(_imGuiTexture, new Num.Vector2(250, 200), map.GetSourceUVStart(4), map.GetSourceUVEnd(4), Num.Vector4.One, Num.Vector4.One); // Here, the previously loaded texture is used
|
|
|
|
|
|
ImGui.EndTabItem();
|
|
|
}
|
|
|
|
|
|
if(ImGui.BeginTabItem("Debug Controls"))
|
|
|
{
|
|
|
if (ImGui.Button("Cull 100 Trees"))
|
|
|
{
|
|
|
this.engine.debugAlterTreesMessages.Add(new DebugAlterTreesMessage {
|
|
|
DeltaTrees = 100});
|
|
|
}
|
|
|
if (ImGui.Button("Cull 1000 Trees"))
|
|
|
{
|
|
|
this.engine.debugAlterTreesMessages.Add(new DebugAlterTreesMessage {
|
|
|
DeltaTrees = 1000});
|
|
|
}
|
|
|
ImGui.EndTabItem();
|
|
|
}
|
|
|
ImGui.EndTabBar();
|
|
|
ImGui.End();
|
|
|
}
|
|
|
|
|
|
if (this.show_test_window)
|
|
|
{
|
|
|
ImGui.SetNextWindowPos(new Num.Vector2(650, 20), ImGuiCond.FirstUseEver);
|
|
|
ImGui.ShowDemoWindow(ref show_test_window);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|