diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index 48380a641..91d82c6f5 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -328,6 +328,8 @@ bool GPU_HW_D3D11::CompileShaders() GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_texture_filtering, m_supports_dual_source_blend); + m_system->GetHostInterface()->DisplayLoadingScreen("Compiling shaders..."); + m_screen_quad_vertex_shader = m_shader_cache.GetVertexShader(m_device.Get(), shadergen.GenerateScreenQuadVertexShader()); if (!m_screen_quad_vertex_shader) diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index fbc869abe..2728cd969 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -296,6 +296,8 @@ bool GPU_HW_OpenGL::CompilePrograms() GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_texture_filtering, m_supports_dual_source_blend); + m_system->GetHostInterface()->DisplayLoadingScreen("Compiling Shaders..."); + for (u32 render_mode = 0; render_mode < 4; render_mode++) { for (u32 texture_mode = 0; texture_mode < 9; texture_mode++) diff --git a/src/core/host_interface.cpp b/src/core/host_interface.cpp index 8cacd8c08..3a4c70003 100644 --- a/src/core/host_interface.cpp +++ b/src/core/host_interface.cpp @@ -931,6 +931,46 @@ void HostInterface::SetTimerResolutionIncreased(bool enabled) #endif } +void HostInterface::DisplayLoadingScreen(const char* message, int progress_min /*= -1*/, int progress_max /*= -1*/, + int progress_value /*= -1*/) +{ + const auto& io = ImGui::GetIO(); + const float scale = io.DisplayFramebufferScale.x; + const float width = (400.0f * scale); + const bool has_progress = (progress_min < progress_max); + + // eat the last imgui frame, it might've been partially rendered by the caller. + ImGui::EndFrame(); + ImGui::NewFrame(); + + ImGui::SetNextWindowSize(ImVec2(width, (has_progress ? 50.0f : 30.0f) * scale), ImGuiCond_Always); + ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), ImGuiCond_Always, + ImVec2(0.5f, 0.5f)); + if (ImGui::Begin("LoadingScreen", nullptr, + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav | + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing)) + { + if (has_progress) + { + ImGui::Text("%s: %d/%d", message, progress_value, progress_max); + ImGui::ProgressBar(static_cast(progress_value) / static_cast(progress_max - progress_min), + ImVec2(-1.0f, 0.0f), ""); + Log_InfoPrintf("%s: %d/%d", message, progress_value, progress_max); + } + else + { + const ImVec2 text_size(ImGui::CalcTextSize(message)); + ImGui::SetCursorPosX((width - text_size.x) / 2.0f); + ImGui::TextUnformatted(message); + Log_InfoPrintf("%s", message); + } + } + ImGui::End(); + + m_display->Render(); +} + bool HostInterface::SaveResumeSaveState() { if (!m_system) diff --git a/src/core/host_interface.h b/src/core/host_interface.h index ebd8f0f35..1f93aa046 100644 --- a/src/core/host_interface.h +++ b/src/core/host_interface.h @@ -82,6 +82,10 @@ public: /// Returns a path relative to the user directory. std::string GetUserDirectoryRelativePath(const char* format, ...) const; + /// Displays a loading screen with the logo, rendered with ImGui. Use when executing possibly-time-consuming tasks + /// such as compiling shaders when starting up. + void DisplayLoadingScreen(const char* message, int progress_min = -1, int progress_max = -1, int progress_value = -1); + protected: enum : u32 {