From 669ed5e098496d6cc44ced650810d087a09e9f77 Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Wed, 25 Oct 2023 19:33:48 +0200 Subject: [PATCH] Update for ImguiBackend - Use RobotoMono-Regular.ttf instead of the default font - Use delta-time instead of elapsed-time - Fix for scissor/clipping rectangle --- src/engine/engine.cc | 5 +-- src/engine/imgui_backend.cc | 35 ++++++++++++++----- src/engine/imgui_backend.h | 2 +- src/engine/renderer/opengl/renderer_opengl.cc | 2 -- src/engine/renderer/vulkan/renderer_vulkan.cc | 10 ++++-- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/engine/engine.cc b/src/engine/engine.cc index f3e3664..978a6a7 100644 --- a/src/engine/engine.cc +++ b/src/engine/engine.cc @@ -45,7 +45,7 @@ Engine::Engine(Platform* platform) platform_->SetObserver(this); } -Engine::~Engine() { +Engine::~Engine() noexcept { LOG(0) << "Shutting down engine."; thread_pool_.CancelTasks(); @@ -157,12 +157,13 @@ void Engine::Draw(float 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::PushItemWidth(ImGui::GetFontSize() * -12); ImGui::Text("%s", renderer_->GetDebugName()); ImGui::Text("%d fps", fps_); ImGui::End(); diff --git a/src/engine/imgui_backend.cc b/src/engine/imgui_backend.cc index b11505c..666cd2b 100644 --- a/src/engine/imgui_backend.cc +++ b/src/engine/imgui_backend.cc @@ -6,6 +6,7 @@ #include "engine/asset/shader_source.h" #include "engine/engine.h" #include "engine/input_event.h" +#include "engine/platform/asset_file.h" #include "engine/renderer/renderer.h" #include "engine/renderer/shader.h" #include "engine/renderer/texture.h" @@ -26,6 +27,22 @@ ImguiBackend::~ImguiBackend() = default; void ImguiBackend::Initialize() { IMGUI_CHECKVERSION(); ImGui::CreateContext(); + + size_t buffer_size = 0; + auto buffer = AssetFile::ReadWholeFile("engine/RobotoMono-Regular.ttf", + Engine::Get().GetRootPath().c_str(), + &buffer_size); + if (buffer) { + ImFontConfig font_cfg = ImFontConfig(); + font_cfg.FontDataOwnedByAtlas = false; + float size_pixels = Engine::Get().IsMobile() ? 64 : 32; + ImGui::GetIO().Fonts->AddFontFromMemoryTTF(buffer.get(), (int)buffer_size, + size_pixels, &font_cfg); + ImGui::GetIO().Fonts->Build(); + } else { + LOG(0) << "Failed to read font file."; + } + Engine::Get().SetImageSource( "imgui_atlas", []() -> std::unique_ptr { @@ -33,7 +50,7 @@ void ImguiBackend::Initialize() { unsigned char* pixels; int width, height; ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); - LOG(0) << "imgui font width: " << width << " height: " << height; + LOG(0) << "Font atlas size: " << width << ", " << height; auto image = std::make_unique(); image->Create(width, height); memcpy(image->GetBuffer(), pixels, width * height * 4); @@ -98,7 +115,7 @@ void ImguiBackend::NewFrame() { ImGuiIO& io = ImGui::GetIO(); io.DisplaySize = ImVec2((float)renderer_->GetScreenWidth(), (float)renderer_->GetScreenHeight()); - io.DeltaTime = timer_.Elapsed(); + io.DeltaTime = timer_.Delta(); ImGui::NewFrame(); } @@ -131,14 +148,14 @@ void ImguiBackend::Render() { for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - reinterpret_cast(pcmd->GetTexID())->Activate(0); + if (pcmd->ClipRect.z <= pcmd->ClipRect.x || + pcmd->ClipRect.w <= pcmd->ClipRect.y) + continue; - if (pcmd->ClipRect.z > pcmd->ClipRect.x && - pcmd->ClipRect.w > pcmd->ClipRect.y) { - renderer_->SetScissor(int(pcmd->ClipRect.x), int(pcmd->ClipRect.y), - int(pcmd->ClipRect.z - pcmd->ClipRect.x), - int(pcmd->ClipRect.w - pcmd->ClipRect.y)); - } + reinterpret_cast(pcmd->GetTexID())->Activate(0); + renderer_->SetScissor(int(pcmd->ClipRect.x), int(pcmd->ClipRect.y), + int(pcmd->ClipRect.z - pcmd->ClipRect.x), + int(pcmd->ClipRect.w - pcmd->ClipRect.y)); renderer_->Draw(geometry_id, pcmd->ElemCount, pcmd->IdxOffset); } renderer_->DestroyGeometry(geometry_id); diff --git a/src/engine/imgui_backend.h b/src/engine/imgui_backend.h index 109a179..73ea57d 100644 --- a/src/engine/imgui_backend.h +++ b/src/engine/imgui_backend.h @@ -29,7 +29,7 @@ class ImguiBackend { private: std::unique_ptr shader_; Renderer* renderer_ = nullptr; - base::ElapsedTimer timer_; + base::DeltaTimer timer_; }; } // namespace eng diff --git a/src/engine/renderer/opengl/renderer_opengl.cc b/src/engine/renderer/opengl/renderer_opengl.cc index 010e1ef..f7c6ca4 100644 --- a/src/engine/renderer/opengl/renderer_opengl.cc +++ b/src/engine/renderer/opengl/renderer_opengl.cc @@ -59,8 +59,6 @@ int RendererOpenGL::GetScreenHeight() const { } void RendererOpenGL::SetScissor(int x, int y, int width, int height) { - DCHECK(x >= 0 && y >= 0 && width >= 0 && height >= 0); - DCHECK(x + width <= GetScreenWidth() && y + height <= GetScreenHeight()); glScissor(x, screen_height_ - y - height, width, height); glEnable(GL_SCISSOR_TEST); } diff --git a/src/engine/renderer/vulkan/renderer_vulkan.cc b/src/engine/renderer/vulkan/renderer_vulkan.cc index f487e50..b5e2806 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.cc +++ b/src/engine/renderer/vulkan/renderer_vulkan.cc @@ -391,8 +391,14 @@ int RendererVulkan::GetScreenHeight() const { } void RendererVulkan::SetScissor(int x, int y, int width, int height) { - DCHECK(x >= 0 && y >= 0 && width >= 0 && height >= 0); - DCHECK(x + width <= GetScreenWidth() && y + height <= GetScreenHeight()); + if (x < 0) + x = 0; + if (y < 0) + y = 0; + if (x + width > GetScreenWidth()) + width = GetScreenWidth() - x; + if (y + height > GetScreenHeight()) + height = GetScreenHeight() - y; VkRect2D scissor; scissor.offset.x = x;