From b492def96e1466653145ebbd98ceb1d1e8a4fdb6 Mon Sep 17 00:00:00 2001 From: Teo-CD Date: Fri, 26 Jan 2024 23:00:26 +0000 Subject: [PATCH] Debug: Introduce Dear ImGui interfaces Introduce Dear ImGui to the CMakeBuild, allow building without it. Add two debug interfaces : one FPS counter and frame time graph, one map visualizer and editor. --- CMakeLists.txt | 28 +++++++++++++++--- World.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ main.cpp | 63 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 160 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index caf14ed..90b4bb5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,8 +11,28 @@ if(NOT SFML_FOUND) message(FATAL_ERROR "SFML could not be found") endif() -add_executable(raycasting main.cpp Player.cpp Player.h World.cpp World.h) - -target_link_libraries(raycasting +set(LIBS sfml-window - sfml-graphics) \ No newline at end of file + sfml-graphics) + +find_package(ImGui QUIET) +find_package(ImGui-SFML QUIET) + +if(NOT ImGui_FOUND OR NOT ImGui-SFML_FOUND OR NO_IMGUI) + message("*Not* building with ImGui") +else () + message("Building with ImGui") + add_compile_definitions(IMGUI) + set(LIBS ${LIBS} + ImGui-SFML::ImGui-SFML) +endif() + +add_compile_options(-Wall -Wextra) + +add_executable(raycasting + main.cpp + Player.cpp + World.cpp + ) + +target_link_libraries(raycasting ${LIBS}) diff --git a/World.cpp b/World.cpp index dea9d5b..3e7ecc9 100644 --- a/World.cpp +++ b/World.cpp @@ -5,6 +5,10 @@ #include "World.h" #include +#ifdef IMGUI +#include +#include +#endif World::World(int w, int h, sf::Color groundColor, sf::Color ceilingColor, std::vector worldMap) : player(0,0,0), w(w), h(h), map(std::move(worldMap)), @@ -263,4 +267,77 @@ void World::step(const float& stepTime) { -player.currentMoveSpeedY*stepTime); } player.rotate(player.currentRotationSpeed*stepTime); + +#ifdef IMGUI + ImGui::Begin("MapEdit"); + static int blockToPlace = 1; + + /* + * Group all the select boxes together : makes it a big block in the + * Dear ImGui layout an allows adding things on the side. + */ + ImGui::BeginGroup(); + for (int y = 0 ; y < h ; y++) { + for (int x = 0 ; x < w ; x++) { + ImGui::PushID(x + y*w); + if (x > 0) + ImGui::SameLine(); + BlockType currentBlock = map[x + w*y]; + + ImVec4 hoverColor; + switch ((BlockType)blockToPlace) { + case BlockType::WALL: + hoverColor = (ImVec4)ImColor(84, 56, 34); + break; + case BlockType::DOOR: + hoverColor = (ImVec4)ImColor(186, 152, 107); + break; + case BlockType::WINDOW: + hoverColor = (ImVec4)ImColor(104, 123, 165); + break; + default: + /* Default header color, it seems ? */ + hoverColor = (ImVec4)ImColor(188, 120, 32); + break; + } + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, hoverColor); + + ImVec4 blockColor; + switch (currentBlock) { + case BlockType::WALL: + blockColor = (ImVec4)ImColor(84, 56, 34); + break; + case BlockType::DOOR: + blockColor = (ImVec4)ImColor(186, 152, 107); + break; + case BlockType::WINDOW: + blockColor = (ImVec4)ImColor(104, 123, 165); + break; + default: + blockColor = (ImVec4)ImColor(188, 120, 32); + break; + } + ImGui::PushStyleColor(ImGuiCol_Header, blockColor); + + if(ImGui::Selectable("", currentBlock != BlockType::AIR, 0, ImVec2(10, 10))) { + map[x + w*y] = currentBlock == (BlockType)blockToPlace ? BlockType::AIR : (BlockType)blockToPlace; + } + ImGui::PopStyleColor(2); + ImGui::PopID(); + } + } + ImGui::EndGroup(); + + ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::Indent(); + ImGui::Text("Place :"); + ImGui::RadioButton("Wall", &blockToPlace, (int)BlockType::WALL); + ImGui::RadioButton("Door", &blockToPlace, (int)BlockType::DOOR); + ImGui::RadioButton("Window", &blockToPlace, (int)BlockType::WINDOW); + ImGui::Unindent(); + ImGui::EndGroup(); + + ImGui::End(); +#endif } diff --git a/main.cpp b/main.cpp index 5b9c8d3..af75df6 100644 --- a/main.cpp +++ b/main.cpp @@ -1,20 +1,35 @@ #include #include +#ifdef IMGUI +#include +#include +#endif + #include "World.h" // TODO: Find a way to go to edges instead of just equally split (?) int main() { - World world(10,10); - world.setBlock(BlockType::AIR,1,1,8,8); + World world(32,32); + world.setBlock(BlockType::AIR,1,1,30,30); world.setBlock(BlockType::WALL,4,4,2,2); world.player.move(2,2); std::cout << world << std::endl; - sf::RenderWindow window(sf::VideoMode(800,600),"Da raycasting"); sf::RenderWindow window(sf::VideoMode(1000,1000),"Da raycasting"); +#ifdef IMGUI + if (!ImGui::SFML::Init(window)) { + std::cout << "Failed to init Dear ImGui SFML" << std::endl; + return -1; + } + sf::Clock fpsDataClock; + float frameTimings[100]; + unsigned int frameCount = 0; +#endif + +// window.setFramerateLimit(60); sf::Event event{}; sf::Clock frameTime; @@ -34,6 +49,13 @@ int main() window.setView(sf::View(newView)); continue; } +#ifdef IMGUI + ImGui::SFML::ProcessEvent(window, event); + // Check if Dear ImGui should process the key events. + ImGuiIO& io = ImGui::GetIO(); + if (io.WantCaptureMouse || io.WantCaptureKeyboard) + continue; +#endif if (event.type == sf::Event::KeyPressed) { switch (event.key.code) { case sf::Keyboard::Key::Escape: @@ -71,11 +93,44 @@ int main() } } window.clear(); + const sf::Time& deltaT = frameTime.restart(); - world.step(frameTime.restart().asSeconds()); +#ifdef IMGUI + ImGui::SFML::Update(window, deltaT); +#endif + + world.step(deltaT.asSeconds()); world.render(window); + +#ifdef IMGUI +// ImGui::ShowDemoWindow(); + + ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration + | ImGuiWindowFlags_AlwaysAutoResize + | ImGuiWindowFlags_NoSavedSettings + | ImGuiWindowFlags_NoFocusOnAppearing + | ImGuiWindowFlags_NoNav; + ImVec2 window_area = ImGui::GetMainViewport()->WorkSize; + ImGui::SetNextWindowPos({window_area.x - 20, 20}, ImGuiCond_Always, {1,0}); + ImGui::SetNextWindowBgAlpha(0.2f); + ImGui::Begin("FPS", nullptr ,window_flags); + if (fpsDataClock.getElapsedTime().asMilliseconds() > 20) { + frameTimings[frameCount%100] = static_cast(deltaT.asMicroseconds()); + frameCount++; + fpsDataClock.restart(); + } + ImGui::Text("FPS : %d", (int)(1.0/deltaT.asSeconds())); + ImGui::PlotLines("µs", frameTimings, frameCount >= 100 ? 100 : frameCount); + ImGui::End(); + + ImGui::SFML::Render(window); +#endif + window.display(); } +#ifdef IMGUI + ImGui::SFML::Shutdown(); +#endif return 0; }