#include "UI.hpp" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" #include "pass/Program.hpp" void UI::setup(GLFWwindow* window) { // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGui::StyleColorsDark(); // Setup Platform/Renderer bindings ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init("#version 130"); } void UI::unload() { ImGui_ImplGlfw_Shutdown(); ImGui_ImplOpenGL3_Shutdown(); ImGui::DestroyContext(); } UI::Actions UI::draw(options &options, state &state, const reports &reports, GLuint aim) { auto actions = Actions::None; ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); const ImGuiIO &io = ImGui::GetIO(); if (options.show_debug_menu) { ImGui::BeginMainMenuBar(); ImGui::Checkbox("Render", &options.show_debug_render); ImGui::Checkbox("World", &options.show_debug_world); ImGui::Checkbox("Contouring", &options.show_debug_contouring); ImGui::Checkbox("Controls", &options.show_debug_controls); if(ImGui::MenuItem("Close")) options.show_debug_menu = false; ImGui::EndMainMenuBar(); } if (options.show_debug_render) { ImGui::Begin("Debug: Render", &options.show_debug_render, ImGuiWindowFlags_AlwaysAutoResize); ImGui::PlotHistogram("FPS", reports.main.fps.buffer.get(), reports.main.fps.size, 0, std::to_string(reports.main.fps.current()).c_str(), 0, options.target_fps >= MIN_FPS && options.target_fps <= MAX_FPS ? options.target_fps * 1.2 : FLT_MAX, ImVec2(0, 30)); ImGui::PlotHistogram("Update", reports.main.update.buffer.get(), reports.main.update.size, 0, std::to_string(reports.main.update.current()).c_str(), 0); ImGui::PlotHistogram("Render", reports.main.render.buffer.get(), reports.main.render.size, 0, std::to_string(reports.main.render.current()).c_str(), 0); ImGui::PlotHistogram("Swap", reports.main.swap.buffer.get(), reports.main.swap.size, 0, std::to_string(reports.main.swap.current()).c_str(), 0); ImGui::PlotHistogram("Wait", reports.main.wait.buffer.get(), reports.main.wait.size, 0, std::to_string(reports.main.wait.current()).c_str(), 0); ImGui::Text("Tris: %ld (%ld models)", reports.main.tris_count, reports.main.models_count); ImGui::Separator(); ImGui::Checkbox("Overlay", &options.show_overlay); if (ImGui::SliderInt("FPS", &options.target_fps, MIN_FPS-1, MAX_FPS+1, options.target_fps > MIN_FPS ? (options.target_fps < MAX_FPS ? "%d" : "UNLIMITED") : "VSYNC")){ actions = actions | Actions::FPS; } ImGui::Text("Sampling %d (requires restart)", options.samples); if (ImGui::Checkbox("Fullscreen", &options.fullscreen)){ actions = actions | Actions::FullScreen; } if (ImGui::ColorEdit3("Fog color", (float *)&options.clear_color)) { actions = actions | Actions::ClearColor; } { bool changeRenderer = false; changeRenderer |= ImGui::Checkbox("Triplanar", &options.renderer_triplanar); ImGui::SameLine(); changeRenderer |= ImGui::Checkbox("Blend", &options.renderer_blend); ImGui::SameLine(); changeRenderer |= ImGui::Checkbox("Fog", &options.renderer_fog); if (changeRenderer) { //TODO: } if (ImGui::Checkbox("Wireframe", &options.renderer_wireframe)) glPolygonMode(GL_FRONT_AND_BACK, options.renderer_wireframe ? GL_LINE : GL_FILL); } ImGui::Checkbox("Culling", &options.culling); ImGui::End(); } /*if (show_debug_world) { ImGui::Begin("Debug: World", &show_debug_world, ImGuiWindowFlags_AlwaysAutoResize); ImGui::PlotHistogram("Count", chunk_count_tracker.buffer.get(), chunk_count_tracker.size, 0, std::to_string(chunk_count_tracker.current()).c_str(), 0); ImGui::PlotHistogram("Loading", chunk_load_tracker.buffer.get(), chunk_load_tracker.size, 0, std::to_string(chunk_load_tracker.current()).c_str(), 0); ImGui::PlotHistogram("Saving", chunk_unload_tracker.buffer.get(), chunk_unload_tracker.size, 0, std::to_string(chunk_unload_tracker.current()).c_str(), 0); ImGui::Separator(); if (ImGui::SliderInt("Load distance", &world.loadDistance, 1, world.keepDistance) | ImGui::SliderInt("Keep distance", &world.keepDistance, world.loadDistance + 1, 21)) { world.triggerChunkChange(); } ImGui::End(); }*/ /*if (show_debug_contouring) { ImGui::Begin("Debug: Contouring", &show_debug_contouring, ImGuiWindowFlags_AlwaysAutoResize); if(ImGui::Combo("Contouring", &contouring_idx, contouring::names)) { world.setContouring(contouring::getContouring(contouring_idx, &world)); } if (ImGui::Button("Render all")) world.renderAll(); world.getContouring()->onGui(); ImGui::End(); }*/ /*if (options.show_debug_controls) { ImGui::Begin("Debug: Controls", &options.show_debug_controls, ImGuiWindowFlags_AlwaysAutoResize); ImGui::Text("Position: (%.3f, %.3f, %.3f)", camera.getPosition().x, camera.getPosition().y, camera.getPosition().z); if (look_at.has_value()) { ImGui::Text("Look at: (%d, %d, %d) (%d, %.1f)", look_at.value().first.x, look_at.value().first.y, look_at.value().first.z, look_at.value().second.Material, look_at.value().second.Density); // TODO: printf array ImGui::Text("(%.3f, %.3f, %.3f)", look_at.value().first.x * scale, look_at.value().first.y * scale, look_at.value().first.z * scale); // TODO: printf array } else { ImGui::Text("Look at: none"); } ImGui::Separator(); { bool changePerspective = false; changePerspective |= ImGui::SliderAngle("FoV", &camera.FoV, 30, 110); changePerspective |= ImGui::SliderFloat("Near", &camera.Near, 0.01, 10); changePerspective |= ImGui::SliderFloat("Far", &camera.Far, (world.getContouring()->getViewDistance() - 1.5) * CHUNK_LENGTH * scale, (world.getContouring()->getViewDistance() + .5) * CHUNK_LENGTH * scale); if(changePerspective) { camera.updateProjection(); } } ImGui::SliderFloat("Move speed", &camera.Speed, 0.1, 50); ImGui::SliderInt("Sensibility", &camera.Sensibility, 1, 100, "%d%%"); ImGui::End(); }*/ /*if (show_console) { ImGui::SetNextWindowPos(ImVec2(UI_MARGIN, 500), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiCond_FirstUseEver); ImGui::Begin("Console", &show_console, ImGuiWindowFlags_MenuBar); ImGui::BeginMenuBar(); ImGui::MenuItem("Auto-scrool", NULL, &console_scrool); ImGui::EndMenuBar(); // TODO: text ImGui::Separator(); // Command-line bool reclaim_focus = false; // TODO: completion callback if (ImGui::InputText("Input", console_buffer, IM_ARRAYSIZE(console_buffer), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory)) { char *s = console_buffer; //Strtrim(s); //if (s[0]) // ExecCommand(s); strcpy(s, ""); reclaim_focus = true; } // Auto-focus on window apparition ImGui::SetItemDefaultFocus(); if (reclaim_focus) ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget ImGui::End(); }*/ if (options.show_overlay) { if (options.overlay_corner != -1) { ImVec2 window_pos = ImVec2((options.overlay_corner & 1) ? io.DisplaySize.x - UI_MARGIN : UI_MARGIN, (options.overlay_corner & 2) ? io.DisplaySize.y - UI_MARGIN : UI_MARGIN); ImVec2 window_pos_pivot = ImVec2((options.overlay_corner & 1) ? 1.0f : 0.0f, (options.overlay_corner & 2) ? 1.0f : 0.0f); ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); } ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background ImGui::Begin("Overlay", &options.show_overlay, (options.overlay_corner != -1 ? ImGuiWindowFlags_NoMove : 0) | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav); ImGui::Text("%.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); ImGui::Text("%ld tris(%ld models)", reports.main.tris_count, reports.main.models_count); if (ImGui::BeginPopupContextWindow()) { if (ImGui::MenuItem("Custom", NULL, options.overlay_corner == -1)) options.overlay_corner = -1; if (ImGui::MenuItem("Top-left", NULL, options.overlay_corner == 0)) options.overlay_corner = 0; if (ImGui::MenuItem("Top-right", NULL, options.overlay_corner == 1)) options.overlay_corner = 1; if (ImGui::MenuItem("Bottom-left", NULL, options.overlay_corner == 2)) options.overlay_corner = 2; if (ImGui::MenuItem("Bottom-right", NULL, options.overlay_corner == 3)) options.overlay_corner = 3; if (options.show_overlay && ImGui::MenuItem("Close")) options.show_overlay = false; ImGui::EndPopup(); } ImGui::End(); } ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x / 2, io.DisplaySize.y / 2), ImGuiCond_Always, ImVec2(.5f, .5f)); ImGui::Begin("Aim", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoBackground); ImGui::Image((void *)(intptr_t)aim, ImVec2(32, 32)); ImGui::Render(); return actions; } void UI::render() { ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); } bool UI::isFocus() { return ImGui::IsAnyItemActive(); }