Skip to content

Commit

Permalink
implement resizing + added delta time
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyle Pelham committed Sep 15, 2024
1 parent 35ba8e9 commit 0f73e8f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 16 deletions.
16 changes: 12 additions & 4 deletions include/prism/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ class PRISM_EXPORT Window

private:
GLFWwindow* windowHandle = nullptr; ///< Handle to the GLFW window. (NOT NATIVE HANDLE)
float lastFrameTime = 0.0f; ///< Time of the last frame.
float deltaTime = 0.0f; ///< Delta between frame end and start.

public:
/// Construct a new Window object.
Expand Down Expand Up @@ -177,6 +175,16 @@ class PRISM_EXPORT Window
*/
void setDefaultTheme();

// rebuildSwapchain
/**
* Rebuilds the swapchain for the window.
*
* This method is called when the swapchain needs to be rebuilt due to a window resize or other event.
* It will recreate the swapchain and associated resources.
* @note This method is called automatically inside the render() method.
*/
void rebuildSwapchain();

/**
* Renders ImGui's content to command buffers.
* @param drawData The ImGui draw data to render.
Expand Down Expand Up @@ -304,14 +312,14 @@ class PRISM_EXPORT Window
* Override this method to implement custom update logic before rendering.
* @note The ImGui context will be CORRECT during this callback.
*/
virtual void onUpdate() {}
virtual void onUpdate(float deltaTime) {}

/**
* Called when the window is rendering.
* Override this method to implement custom rendering logic.
* @note The ImGui context will be CORRECT during this callback.
*/
virtual void onRender() {}
virtual void onRender(float deltaTime) {}
};

} // namespace Prism
9 changes: 5 additions & 4 deletions src/prism.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ Application::Application(std::string name)

Application::~Application()
{
stop(); // Stop the application
appWindows.clear(); // Destroy the windows
renderer.reset(); // Destroy the renderer
stop();
for (auto& window : std::ranges::reverse_view(appWindows))
window.reset();
renderer.reset();
}

void Application::run()
Expand Down Expand Up @@ -62,7 +63,7 @@ void Application::cullClosedWindowsExitOnMainDeath()
}

// Remove the window
appWindows.erase(appWindows.begin() + i);
appWindows.erase(appWindows.begin() + (int64_t)i);
}
}
}
Expand Down
51 changes: 43 additions & 8 deletions src/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ Window::Window(WindowSettings settings) :
ImGui_ImplVulkan_CreateFontsTexture();

// Restore the previous contexts
// TODO: Is this really doing what I'm expecting? I'll have to come back to this.
if (backupImGuiContext) ImGui::SetCurrentContext(backupImGuiContext);
}

Expand Down Expand Up @@ -203,17 +202,22 @@ void Window::render()
// Swap contexts
ImGuiContext* backupContext = ImGui::GetCurrentContext();
ImGui::SetCurrentContext(imguiContext);

// TODO: Resize swap chain

// Update the swapchain if needed
if (swapchainNeedRebuild)
rebuildSwapchain();

// Start ImGui Frame
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();

// Get delta time from imgui
ImGuiIO& io = ImGui::GetIO();

// Run update logic, then render ImGui
onUpdate();
onRender();
onUpdate(io.DeltaTime);
onRender(io.DeltaTime);

// Render
ImGui::Render();
Expand All @@ -232,8 +236,6 @@ void Window::render()
else
std::this_thread::sleep_for(std::chrono::milliseconds(5));

// TODO: Do delta time here

// Restore the previous context
if (backupContext) ImGui::SetCurrentContext(backupContext);
}
Expand Down Expand Up @@ -395,6 +397,39 @@ void Window::installGlfwCallbacks()
glfwSetMonitorCallback(MonitorCallback);
}

void Window::rebuildSwapchain()
{
// Get the new window size
int width, height;
glfwGetFramebufferSize(windowHandle, &width, &height);

// If valid size, rebuild the swapchain
if (width > 0 && height > 0) {
// Wait for the device to be idle
auto renderer = Application::Get().getRenderer();
vkDeviceWaitIdle(renderer->getDevice());

// Rebuild the swapchain
ImGui_ImplVulkan_SetMinImageCount(minImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(
renderer->getInstance(),
renderer->getPhysicalDevice(),
renderer->getDevice(),
imguiWindow,
renderer->getQueueFamilyIndex(),
renderer->getAllocator(),
width, height, minImageCount
);

// Reallocate the command buffers
allocatedCommandBuffers.clear();
allocatedCommandBuffers.resize(imguiWindow->ImageCount);

// Reset the swapchain flag
swapchainNeedRebuild = false;
}
}

void Window::frameRender(ImDrawData* drawData)
{
VkResult err;
Expand Down Expand Up @@ -430,7 +465,7 @@ void Window::frameRender(ImDrawData* drawData)

auto& cmdBuf = allocatedCommandBuffers[imguiWindow->FrameIndex];
if (!cmdBuf.empty()) {
vkFreeCommandBuffers(renderer->getDevice(), fd->CommandPool, static_cast<uint32_t>(cmdBuf.size()), cmdBuf.data());
vkFreeCommandBuffers(renderer->getDevice(), fd->CommandPool, (uint32_t)cmdBuf.size(), cmdBuf.data());
cmdBuf.clear();
}

Expand Down

0 comments on commit 0f73e8f

Please sign in to comment.