The open source OpenXR runtime
1// Copyright 2019, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Main entrypoint for the Monado GUI program.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 * @ingroup gui
8 */
9
10#include "util/u_file.h"
11#include "util/u_var.h"
12#include "util/u_time.h"
13#include "util/u_misc.h"
14#include "util/u_sink.h"
15#include "util/u_format.h"
16
17#include "ogl/ogl_api.h"
18#include "gui/gui_imgui.h"
19#include "xrt/xrt_compiler.h"
20
21#include "gui_sdl2.h"
22
23
24/*
25 *
26 * Structs and defines.
27 *
28 */
29
30/*!
31 * Internal gui state.
32 *
33 * @ingroup gui
34 */
35struct gui_imgui
36{
37 bool show_imgui_demo;
38 bool show_implot_demo;
39 struct xrt_colour_rgb_f32 clear;
40};
41
42
43/*
44 *
45 * 'Exported' functions.
46 *
47 */
48
49void
50gui_sdl2_imgui_loop(struct sdl2_program *p)
51{
52 // Need to call this before any other Imgui call.
53 igCreateContext(NULL);
54
55 // Local state
56 ImGuiIO *io = igGetIO();
57
58 // Make window layout file "imgui.ini" live in config dir
59 XRT_MAYBE_UNUSED int res = u_file_get_path_in_config_dir("imgui.ini", p->layout_file, sizeof(p->layout_file));
60 assert(res > 0);
61 io->IniFilename = p->layout_file;
62
63 // Ensure imgui.ini file exists in config dir
64 FILE *imgui_ini = u_file_open_file_in_config_dir("imgui.ini", "a");
65 if (imgui_ini != NULL) {
66 fclose(imgui_ini);
67 }
68
69 // Setup Platform/Renderer bindings
70 ImGui_ImplSDL2_InitForOpenGL(p->win, p->ctx);
71 ImGui_ImplOpenGL3_Init(NULL);
72
73 // Setup Dear ImGui style
74 igStyleColorsDark(NULL);
75
76 // Setup the plot context.
77 ImPlotContext *plot_ctx = ImPlot_CreateContext();
78 ImPlot_SetCurrentContext(plot_ctx);
79
80 // Main loop
81 struct gui_imgui gui = {0};
82 gui.clear.r = 0.45f;
83 gui.clear.g = 0.55f;
84 gui.clear.b = 0.60f;
85 u_var_add_root(&gui, "GUI Control", false);
86 u_var_add_rgb_f32(&gui, &gui.clear, "Clear Colour");
87 u_var_add_bool(&gui, &gui.show_imgui_demo, "Imgui Demo Window");
88 u_var_add_bool(&gui, &gui.show_implot_demo, "Implot Demo Window");
89 u_var_add_bool(&gui, &p->base.stopped, "Exit");
90
91 while (!p->base.stopped) {
92 SDL_Event event;
93
94 while (SDL_PollEvent(&event)) {
95 ImGui_ImplSDL2_ProcessEvent(&event);
96
97 if (event.type == SDL_QUIT) {
98 p->base.stopped = true;
99 }
100
101 if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE &&
102 event.window.windowID == SDL_GetWindowID(p->win)) {
103 p->base.stopped = true;
104 }
105 }
106
107 // Start the Dear ImGui frame
108 ImGui_ImplOpenGL3_NewFrame();
109 ImGui_ImplSDL2_NewFrame();
110
111 // Start new frame.
112 igNewFrame();
113
114 // Render the scene into it.
115 gui_scene_manager_render(&p->base);
116
117 // Handle this here.
118 if (gui.show_imgui_demo) {
119 igShowDemoWindow(&gui.show_imgui_demo);
120 }
121
122 // Handle this here.
123 if (gui.show_implot_demo) {
124 ImPlot_ShowDemoWindow(&gui.show_implot_demo);
125 }
126
127 // Build the DrawData (EndFrame).
128 igRender();
129
130 // Clear the background.
131 glViewport(0, 0, (int)io->DisplaySize.x, (int)io->DisplaySize.y);
132 glClearColor(gui.clear.r, gui.clear.g, gui.clear.b, 1.0f);
133 glClear(GL_COLOR_BUFFER_BIT);
134
135 ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
136
137 SDL_GL_SwapWindow(p->win);
138
139 gui_prober_update(&p->base);
140 }
141
142 // Cleanup
143 u_var_remove_root(&gui);
144 ImPlot_DestroyContext(plot_ctx);
145 ImGui_ImplOpenGL3_Shutdown();
146 ImGui_ImplSDL2_Shutdown();
147 igDestroyContext(NULL);
148}