From f144bfdb2dfbde409b50f5b204e07d7800754a6a Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Fri, 27 Oct 2023 23:23:28 +0200 Subject: [PATCH] Call ImGui::NewFrame() early in the main loop --- src/engine/engine.cc | 37 ++++++++++++++++--------------- src/engine/engine.h | 2 ++ src/engine/imgui_backend.cc | 26 ++++++++++++---------- src/engine/imgui_backend.h | 8 +++---- src/third_party/imgui/LICENSE.txt | 21 ++++++++++++++++++ 5 files changed, 59 insertions(+), 35 deletions(-) create mode 100644 src/third_party/imgui/LICENSE.txt diff --git a/src/engine/engine.cc b/src/engine/engine.cc index 978a6a7..4646fdf 100644 --- a/src/engine/engine.cc +++ b/src/engine/engine.cc @@ -130,6 +130,8 @@ void Engine::Update(float delta_time) { seconds_accumulated_ += delta_time; ++tick_; + imgui_backend_.NewFrame(delta_time); + for (auto d : animators_) d->Update(delta_time); @@ -140,6 +142,9 @@ void Engine::Update(float delta_time) { fps_ = renderer_->GetAndResetFPS(); fps_seconds_ = 0; } + + if (stats_visible_) + ShowStats(); } void Engine::Draw(float frame_frac) { @@ -150,29 +155,12 @@ void Engine::Draw(float frame_frac) { [](auto& a, auto& b) { return a->GetZOrder() < b->GetZOrder(); }); renderer_->PrepareForDrawing(); - for (auto d : drawables_) { if (d->IsVisible()) d->Draw(frame_frac); } - - if (stats_visible_) { - ImVec2 center = ImGui::GetMainViewport()->GetCenter(); - ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); - ImGuiWindowFlags window_flags = - ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | - ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse | - ImGuiWindowFlags_NoNav | ImGuiWindowFlags_AlwaysAutoResize; - ImGui::Begin("Stats", nullptr, window_flags); - ImGui::Text("%s", renderer_->GetDebugName()); - ImGui::Text("%d fps", fps_); - ImGui::End(); - } - - imgui_backend_.Render(); - + imgui_backend_.Draw(); renderer_->Present(); - imgui_backend_.NewFrame(); } void Engine::AddDrawable(Drawable* drawable) { @@ -696,4 +684,17 @@ void Engine::WaitForAsyncWork() { } } +void Engine::ShowStats() { + ImVec2 center = ImGui::GetMainViewport()->GetCenter(); + ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); + ImGuiWindowFlags window_flags = + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_NoNav | ImGuiWindowFlags_AlwaysAutoResize; + ImGui::Begin("Stats", nullptr, window_flags); + ImGui::Text("%s", renderer_->GetDebugName()); + ImGui::Text("%d fps", fps_); + ImGui::End(); +} + } // namespace eng diff --git a/src/engine/engine.h b/src/engine/engine.h index edf2751..6892660 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -242,6 +242,8 @@ class Engine : public PlatformObserver { void WaitForAsyncWork(); + void ShowStats(); + Engine(const Engine&) = delete; Engine& operator=(const Engine&) = delete; }; diff --git a/src/engine/imgui_backend.cc b/src/engine/imgui_backend.cc index e26b230..61260dd 100644 --- a/src/engine/imgui_backend.cc +++ b/src/engine/imgui_backend.cc @@ -52,7 +52,6 @@ void ImguiBackend::Initialize() { Engine::Get().SetImageSource( "imgui_atlas", []() -> std::unique_ptr { - // Build texture atlas unsigned char* pixels; int width, height; ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); @@ -67,7 +66,7 @@ void ImguiBackend::Initialize() { ImGui::GetIO().Fonts->SetTexID( (ImTextureID)(intptr_t)Engine::Get().AcquireTexture("imgui_atlas")); - NewFrame(); + NewFrame(0); } void ImguiBackend::Shutdown() { @@ -117,28 +116,31 @@ std::unique_ptr ImguiBackend::OnInputEvent( return event; } -void ImguiBackend::NewFrame() { +void ImguiBackend::NewFrame(float delta_time) { + if (is_new_frame_) + ImGui::EndFrame(); + is_new_frame_ = true; + ImGuiIO& io = ImGui::GetIO(); io.DisplaySize = ImVec2((float)renderer_->GetScreenWidth(), (float)renderer_->GetScreenHeight()); - io.DeltaTime = timer_.Delta(); + io.DeltaTime = delta_time; ImGui::NewFrame(); } -void ImguiBackend::Render() { +void ImguiBackend::Draw() { + is_new_frame_ = false; ImGui::Render(); - ImDrawData* draw_data = ImGui::GetDrawData(); if (draw_data->CmdListsCount <= 0) return; - float L = draw_data->DisplayPos.x; - float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; - float T = draw_data->DisplayPos.y; - float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; base::Matrix4f ortho_projection; - ortho_projection.CreateOrthoProjection(L, R, B, T); - + ortho_projection.CreateOrthoProjection( + draw_data->DisplayPos.x, + draw_data->DisplayPos.x + draw_data->DisplaySize.x, + draw_data->DisplayPos.y + draw_data->DisplaySize.y, + draw_data->DisplayPos.y); shader_->Activate(); shader_->SetUniform("projection", ortho_projection); shader_->UploadUniforms(); diff --git a/src/engine/imgui_backend.h b/src/engine/imgui_backend.h index 73ea57d..1a21f94 100644 --- a/src/engine/imgui_backend.h +++ b/src/engine/imgui_backend.h @@ -3,8 +3,6 @@ #include -#include "base/timer.h" - namespace eng { class InputEvent; @@ -23,13 +21,13 @@ class ImguiBackend { std::unique_ptr OnInputEvent(std::unique_ptr event); - void NewFrame(); - void Render(); + void NewFrame(float delta_time); + void Draw(); private: std::unique_ptr shader_; Renderer* renderer_ = nullptr; - base::DeltaTimer timer_; + bool is_new_frame_ = false; }; } // namespace eng diff --git a/src/third_party/imgui/LICENSE.txt b/src/third_party/imgui/LICENSE.txt new file mode 100644 index 0000000..fb715bd --- /dev/null +++ b/src/third_party/imgui/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2023 Omar Cornut + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.