diff --git a/lib/DaggerImGuiDash/.gitignore b/lib/DaggerImGuiDash/.gitignore new file mode 100644 index 000000000..312b3b30d --- /dev/null +++ b/lib/DaggerImGuiDash/.gitignore @@ -0,0 +1,3 @@ +Manifest.toml +*.swp +imgui.ini diff --git a/lib/DaggerImGuiDash/Project.toml b/lib/DaggerImGuiDash/Project.toml new file mode 100644 index 000000000..2444dbb9a --- /dev/null +++ b/lib/DaggerImGuiDash/Project.toml @@ -0,0 +1,20 @@ +name = "DaggerImGuiDash" +uuid = "d9a9aedf-3684-4bd7-b6b6-001f8c61829c" +authors = ["Julian P Samaroo "] +version = "0.1.0" + +[deps] +CImGui = "5d785b6c-b76f-510e-a07c-3070796c7e87" +CSyntax = "ea656a56-6ca6-5dda-bba5-7b6963a5f74c" +GLFW = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +TimespanLogging = "a526e669-04d3-4846-9525-c66122c55f63" + +[compat] +CImGui = "1.82" +CSyntax = "0.4" +GLFW = "3" +ModernGL = "1" +TimespanLogging = "0.1" +julia = "1" diff --git a/lib/DaggerImGuiDash/src/DaggerImGuiDash.jl b/lib/DaggerImGuiDash/src/DaggerImGuiDash.jl new file mode 100644 index 000000000..3191a7afe --- /dev/null +++ b/lib/DaggerImGuiDash/src/DaggerImGuiDash.jl @@ -0,0 +1,99 @@ +module DaggerImGuiDash + +using Printf + +include("logging.jl") +include("ui.jl") + +using CImGui +import CSyntax: @c +import CSyntax.CStatic: @cstatic +import CImGui: ImGuiGLFWBackend +if CImGui.opengl_major_version == 2 +import CImGui: ImGuiOpenGL2Backend +const OpenGLBackend = ImGuiOpenGL2Backend +elseif CImGui.opengl_major_version >= 3 +import CImGui: ImGuiOpenGLBackend +const OpenGLBackend = ImGuiOpenGLBackend +end +using ModernGL +using GLFW +#using ImPlot + +function run_gui(r::Renderer) + +CLEAR_COLOR = Cfloat[0.45, 0.55, 0.60, 1.00] + +glsl_version = 130 + +# setup GLFW error callback +#? error_callback(err::GLFW.GLFWError) = @error "GLFW ERROR: code $(err.code) msg: $(err.description)" +#? GLFW.SetErrorCallback(error_callback) + +# create window +window = GLFW.Window(;name="DaggerImGuiDash", windowhints=[], contexthints=[ + (GLFW.CONTEXT_VERSION_MAJOR, 2), + (GLFW.CONTEXT_VERSION_MINOR, 0), +]) +GLFW.MakeContextCurrent(window) +GLFW.SwapInterval(1) # enable vsync + +# setup Dear ImGui context +ctx = CImGui.CreateContext() + +# setup Dear ImGui style +CImGui.StyleColorsDark() + +# load Fonts +fonts = unsafe_load(CImGui.GetIO().Fonts) +CImGui.AddFontDefault(fonts) + +# setup Platform/Renderer bindings +glfw_ctx = ImGuiGLFWBackend.create_context(window.handle, install_callbacks = true) +ImGuiGLFWBackend.init(glfw_ctx) +opengl_ctx = OpenGLBackend.create_context(glsl_version) +OpenGLBackend.init(opengl_ctx) + +try + while GLFW.WindowShouldClose(window) == 0 + GLFW.PollEvents() + # start the Dear ImGui frame + OpenGLBackend.new_frame(opengl_ctx) #ImGui_ImplOpenGL3_NewFrame() + ImGuiGLFWBackend.new_frame(glfw_ctx) #ImGui_ImplGlfw_NewFrame() + CImGui.NewFrame() + + if CImGui.Begin("DaggerImGuiDash") + inner_gui(r) + CImGui.End() + end + + # rendering + CImGui.Render() + GLFW.MakeContextCurrent(window) + + display_w, display_h = GLFW.GetFramebufferSize(window) + + glViewport(0, 0, display_w, display_h) + glClearColor(CLEAR_COLOR...) + glClear(GL_COLOR_BUFFER_BIT) + OpenGLBackend.render(opengl_ctx) #ImGui_ImplOpenGL3_RenderDrawData(CImGui.GetDrawData()) + + GLFW.MakeContextCurrent(window) + GLFW.SwapBuffers(window) + + # Let background tasks run + yield() + end +catch e + @error "Error in renderloop!" exception=e + Base.show_backtrace(stderr, catch_backtrace()) +finally + OpenGLBackend.shutdown(opengl_ctx) #ImGui_ImplOpenGL3_Shutdown() + ImGuiGLFWBackend.shutdown(glfw_ctx) #ImGui_ImplGlfw_Shutdown() + CImGui.DestroyContext(ctx) + GLFW.DestroyWindow(window) +end + +end # function run_gui() + +end # module DaggerImGuiDash diff --git a/lib/DaggerImGuiDash/src/logging.jl b/lib/DaggerImGuiDash/src/logging.jl new file mode 100644 index 000000000..73a5deb94 --- /dev/null +++ b/lib/DaggerImGuiDash/src/logging.jl @@ -0,0 +1,23 @@ +using TimespanLogging + +struct Renderer + logs::Dict{Symbol,Vector{Any}} + custom_plots::Vector{Base.Callable} +end +Renderer() = Renderer(Dict{Symbol,Vector{Any}}(), Base.Callable[]) +Base.push!(r::Renderer, f::Base.Callable) = + push!(r.custom_plots, f) + +function TimespanLogging.Events.creation_hook(r::Renderer, log) + for id in keys(log) + log_vec = get!(r.logs, id) do + [] + end + push!(log_vec, log[id]) + end +end +function TimespanLogging.Events.deletion_hook(r::Renderer, idx) + for id in keys(r.logs) + deleteat!(r.logs[id], 1:idx) + end +end diff --git a/lib/DaggerImGuiDash/src/ui.jl b/lib/DaggerImGuiDash/src/ui.jl new file mode 100644 index 000000000..e13ee8fab --- /dev/null +++ b/lib/DaggerImGuiDash/src/ui.jl @@ -0,0 +1,40 @@ +function render_saturation!(logs, key::Symbol) + sat = logs[key] + if length(sat) == 0 + return + end + all_keys = unique(Iterators.flatten(if sat[1] isa NamedTuple + map(ks->keys(ks), sat) + elseif sat[1] isa Vector + map(ks->map(first, ks), sat) + end)) + sort!(all_keys; by=x->repr(x)) + for key in all_keys + vec = if sat[1] isa NamedTuple + map(e->Float32(get(e, key, 0)), sat) + elseif sat[1] isa Vector + map(e->Float32(last(get(e, something(findfirst(x->first(x) == key, e), 0), (key, 0)))), sat) + end + str = @sprintf("%0.2f %s", Float64(sum(vec)/length(vec)), key) + CImGui.PlotLines(str, vec, length(vec)) + end +end +function inner_gui(r::Renderer) + # Render event saturation + render_saturation!(r.logs, :esat) + + CImGui.Separator() + + # Render processor saturation + render_saturation!(r.logs, :psat) + + CImGui.Separator() + + # Custom rendering + for (idx,f) in enumerate(r.custom_plots) + f(r.logs) + if idx < length(r.custom_plots) + CImGui.Separator() + end + end +end