Fix loading screen graphical artifacts on window resize
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run

Recreate Vulkan swapchain in LoadingScreen::render() when the dirty flag
is set, so resizing the window during world loading no longer renders
into a stale swapchain with mismatched framebuffers.
This commit is contained in:
Kelsi 2026-02-25 03:45:13 -08:00
parent 4c8fa9f1fe
commit 570dec8b88
3 changed files with 15 additions and 0 deletions

View file

@ -4,6 +4,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
struct SDL_Window;
namespace wowee { namespace wowee {
namespace rendering { namespace rendering {
@ -27,11 +29,13 @@ public:
// Must be set before initialize() for Vulkan texture upload // Must be set before initialize() for Vulkan texture upload
void setVkContext(VkContext* ctx) { vkCtx = ctx; } void setVkContext(VkContext* ctx) { vkCtx = ctx; }
void setSDLWindow(SDL_Window* win) { sdlWindow = win; }
private: private:
bool loadImage(const std::string& path); bool loadImage(const std::string& path);
VkContext* vkCtx = nullptr; VkContext* vkCtx = nullptr;
SDL_Window* sdlWindow = nullptr;
// Vulkan texture for background image // Vulkan texture for background image
VkImage bgImage = VK_NULL_HANDLE; VkImage bgImage = VK_NULL_HANDLE;

View file

@ -3065,6 +3065,7 @@ void Application::loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float
// --- Loading screen for online mode --- // --- Loading screen for online mode ---
rendering::LoadingScreen loadingScreen; rendering::LoadingScreen loadingScreen;
loadingScreen.setVkContext(window->getVkContext()); loadingScreen.setVkContext(window->getVkContext());
loadingScreen.setSDLWindow(window->getSDLWindow());
bool loadingScreenOk = loadingScreen.initialize(); bool loadingScreenOk = loadingScreen.initialize();
auto showProgress = [&](const char* msg, float progress) { auto showProgress = [&](const char* msg, float progress) {

View file

@ -5,6 +5,7 @@
#include <imgui_internal.h> #include <imgui_internal.h>
#include <imgui_impl_vulkan.h> #include <imgui_impl_vulkan.h>
#include <imgui_impl_sdl2.h> #include <imgui_impl_sdl2.h>
#include <SDL2/SDL.h>
#include <random> #include <random>
#include <chrono> #include <chrono>
#include <cstdio> #include <cstdio>
@ -327,6 +328,15 @@ void LoadingScreen::render() {
// Submit the frame to Vulkan (loading screen runs outside the main render loop) // Submit the frame to Vulkan (loading screen runs outside the main render loop)
if (vkCtx) { if (vkCtx) {
// Handle window resize: recreate swapchain before acquiring an image
if (vkCtx->isSwapchainDirty() && sdlWindow) {
int w = 0, h = 0;
SDL_GetWindowSize(sdlWindow, &w, &h);
if (w > 0 && h > 0) {
vkCtx->recreateSwapchain(w, h);
}
}
uint32_t imageIndex = 0; uint32_t imageIndex = 0;
VkCommandBuffer cmd = vkCtx->beginFrame(imageIndex); VkCommandBuffer cmd = vkCtx->beginFrame(imageIndex);
if (cmd != VK_NULL_HANDLE) { if (cmd != VK_NULL_HANDLE) {