diff --git a/src/common/util.cpp b/src/common/util.cpp index f86c4b8..921c539 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -20,6 +20,7 @@ namespace util { fs::path k_spaceCalibratorInstallDirectory{}; fs::path k_spaceCalibratorLangsDirectory{}; + fs::path k_spaceCalibratorImagesDir{}; fs::path k_spaceCalibratorConfigDirectory{}; fs::path k_spaceCalibratorLogsDirectory{}; fs::path k_spaceCalibratorDumpsDirectory{}; @@ -34,6 +35,7 @@ namespace util { k_spaceCalibratorDumpsDirectory = k_spaceCalibratorConfigDirectory / "dumps"; k_spaceCalibratorLangsDirectory = k_spaceCalibratorInstallDirectory / "assets" / "lang"; + k_spaceCalibratorImagesDir = k_spaceCalibratorInstallDirectory / "assets" / "images"; // create dirs if they dont exist if (!std::filesystem::is_directory(k_spaceCalibratorConfigDirectory)) { @@ -60,6 +62,13 @@ namespace util { #endif return k_spaceCalibratorLangsDirectory; } + + const fs::path& getSpaceCalibratorImagesDir() { +#if _DEBUG + assert(!k_spaceCalibratorImagesDir.empty()); +#endif + return k_spaceCalibratorImagesDir; + } const fs::path& getSpaceCalibratorConfigDir() { #if _DEBUG diff --git a/src/common/util.h b/src/common/util.h index 6c8bc78..b489e9d 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -9,6 +9,7 @@ namespace util { void init(); const std::filesystem::path& getSpaceCalibratorInstallDir(); const std::filesystem::path& getSpaceCalibratorLangsDir(); + const std::filesystem::path& getSpaceCalibratorImagesDir(); const std::filesystem::path& getSpaceCalibratorConfigDir(); const std::filesystem::path& getSpaceCalibratorLogsDir(); diff --git a/src/overlay/user_interface.cpp b/src/overlay/user_interface.cpp index db3b72b..5f1eecb 100644 --- a/src/overlay/user_interface.cpp +++ b/src/overlay/user_interface.cpp @@ -1520,6 +1520,17 @@ namespace spacecal { ImGui::Spacing(); \ } while (0) +#define DRAW_IMAGE(label, idx) \ + do { \ + if (ImGui::BeginChild((label), ImVec2(-1.0f, (float)g_state.textures[idx].dwHeight))) { \ + ImVec2 avail = ImGui::GetContentRegionAvail(); \ + ImGui::SetCursorPos(ImVec2((avail.x - (float)g_state.textures[idx].dwWidth) * 0.5f, (avail.y - (float)g_state.textures[idx].dwHeight) * 0.5f)); \ + ImGui::Image(g_state.textures[idx].hTexture, ImVec2((float)g_state.textures[idx].dwWidth, (float)g_state.textures[idx].dwHeight)); \ + } \ + ImGui::EndChild(); \ + ImGui::Spacing(); \ + } while (0) + switch (g_state.dwSelectedLearnPage) { default: case LearnPage_Home: @@ -1585,6 +1596,7 @@ namespace spacecal { // video demonstrating calibration method DRAW_DUMMY_IMAGE("TODO: Image here##0", 140.0f); + DRAW_IMAGE("calibrate_diagram", EImageId_LearnStandard_CalibrateDiagram); ImGui::TextHeading(LOCALE_GET("learn_page_standard_speeds_title").c_str()); ImGui::TextWrapped(LOCALE_GET("learn_page_standard_speeds_desc").c_str()); @@ -1622,6 +1634,7 @@ namespace spacecal { // pic of tracker on virtual VR headset to illustrate mounting DRAW_DUMMY_IMAGE("TODO: Image here##0", 140.0f); + DRAW_IMAGE("continuous_mount", EImageId_LearnContinuous_Mounting); ImGui::TextHeading(LOCALE_GET("learn_page_continuous_should_use_title").c_str()); ImGui::Bullet(); @@ -1657,6 +1670,7 @@ namespace spacecal { ImGui::TextWrapped(LOCALE_GET("learn_page_basestation_auto_power_desc").c_str()); DRAW_DUMMY_IMAGE("TODO: Image here##0", 140.0f); + DRAW_IMAGE("basestation_image", EImageId_LearnBaseStation_Unk); break; } case LearnPage_UITour: @@ -1673,12 +1687,14 @@ namespace spacecal { ImGui::TextWrapped(LOCALE_GET("learn_page_ui_tour_cal_desc5").c_str()); DRAW_DUMMY_IMAGE("TODO: Image here##0", 140.0f); + DRAW_IMAGE("ui_tour_0", EImageId_LearnUI_Unk0); ImGui::TextHeading(LOCALE_GET("learn_page_ui_tour_base_stations_heading").c_str()); ImGui::TextWrapped(LOCALE_GET("learn_page_ui_tour_bs_desc").c_str()); ImGui::Spacing(); DRAW_DUMMY_IMAGE("TODO: Image here##2", 140.0f); + DRAW_IMAGE("ui_tour_1", EImageId_LearnUI_Unk1); ImGui::TextHeading(LOCALE_GET("learn_page_ui_tour_settings_heading").c_str()); ImGui::TextWrapped(LOCALE_GET("learn_page_ui_tour_settings_desc1").c_str()); @@ -1855,6 +1871,12 @@ namespace spacecal { // load base station nicknames from config if (!g_state.bNicknamesLoaded) { + g_state.textures[EImageId_LearnStandard_CalibrateDiagram] = renderer::getRenderContext(renderer::GraphicsBackend::OpenGL)->loadTexture(util::getSpaceCalibratorImagesDir() / "img_learn_calibrate_diagram.png"); + g_state.textures[EImageId_LearnContinuous_Mounting] = renderer::getRenderContext(renderer::GraphicsBackend::OpenGL)->loadTexture(util::getSpaceCalibratorImagesDir() / "img_learn_continuous_mount.png"); + g_state.textures[EImageId_LearnBaseStation_Unk] = renderer::getRenderContext(renderer::GraphicsBackend::OpenGL)->loadTexture(util::getSpaceCalibratorImagesDir() / "img_learn_basestations.png"); + g_state.textures[EImageId_LearnUI_Unk0] = renderer::getRenderContext(renderer::GraphicsBackend::OpenGL)->loadTexture(util::getSpaceCalibratorImagesDir() / "img_learn_ui_0.png"); + g_state.textures[EImageId_LearnUI_Unk1] = renderer::getRenderContext(renderer::GraphicsBackend::OpenGL)->loadTexture(util::getSpaceCalibratorImagesDir() / "img_learn_ui_1.png"); + if (g_state.aBaseStations.capacity() == 0) { g_state.aBaseStations.reserve(64); } @@ -1934,4 +1956,10 @@ namespace spacecal { ImGui::ShowDemoWindow(); #endif // IMGUI_USE_DEBUG_WINDOW } + + void cleanupInterface() { + for (size_t i = 0; i < EImageId_Count; i++) { + renderer::getRenderContext(renderer::GraphicsBackend::OpenGL)->destroyTexture(g_state.textures[i]); + } + } } \ No newline at end of file diff --git a/src/overlay/user_interface.h b/src/overlay/user_interface.h index c2bc99f..57cd484 100644 --- a/src/overlay/user_interface.h +++ b/src/overlay/user_interface.h @@ -7,6 +7,7 @@ #include #include #include +#include "renderer/renderer.h" namespace spacecal { @@ -33,6 +34,15 @@ namespace spacecal { LearnPage_Unknown, }; + enum EImageId_t { + EImageId_LearnStandard_CalibrateDiagram, + EImageId_LearnContinuous_Mounting, + EImageId_LearnBaseStation_Unk, + EImageId_LearnUI_Unk0, + EImageId_LearnUI_Unk1, + EImageId_Count, + }; + // state for the UI struct UserInterfaceState_t { bool bIsRunningInOverlay = false; @@ -50,6 +60,8 @@ namespace spacecal { // flat list cuz realistically we won't have enough elements to warrant the overhead of a hashmap bool bNicknamesLoaded = false; std::vector aBaseStations; + + renderer::TextureData_t textures[EImageId_Count] = {}; }; struct SpaceCalibratorVerticalTab_t { @@ -61,4 +73,5 @@ namespace spacecal { // Draws the user interface with ImGUI void drawInterface(bool isOverlay, double currentTime); + void cleanupInterface(); } \ No newline at end of file diff --git a/src/overlay/window.cpp b/src/overlay/window.cpp index 2dc63ea..ef97914 100644 --- a/src/overlay/window.cpp +++ b/src/overlay/window.cpp @@ -530,6 +530,7 @@ namespace spacecal { } } + spacecal::cleanupInterface(); CalibrationManager::getInstance()->shutdown(); } } \ No newline at end of file