Implement viewChanged() in multiple examples for proper window resize handling, fix triangle example resizing on macOS

This commit is contained in:
Stephen Saunders 2022-06-13 23:04:53 -04:00
parent b2f501dc98
commit 279c95422d
42 changed files with 240 additions and 37 deletions

View file

@ -654,6 +654,12 @@ public:
}
}
virtual void viewChanged()
{
camera.setPerspective(60.0f, (float)width * 0.5f / (float)height, 1.0f, 256.0f);
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -330,6 +330,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Visibility")) {

View file

@ -777,6 +777,10 @@ public:
updateUniformBuffers();
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
@ -796,4 +800,4 @@ public:
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -809,6 +809,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBufferOffscreen();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -647,6 +647,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBufferOffscreen();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -808,6 +808,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBufferOffscreen();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -409,6 +409,11 @@ public:
updateUniformBuffersCamera();
}
virtual void viewChanged()
{
updateUniformBuffersCamera();
}
};
VULKAN_EXAMPLE_MAIN()

View file

@ -385,6 +385,12 @@ public:
updateUniformBuffers();
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {
@ -408,4 +414,4 @@ public:
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -643,6 +643,7 @@ public:
virtual void viewChanged()
{
camera.setPerspective(splitScreen ? 30.0f : 45.0f, (float)width / (float)(height * ((splitScreen) ? 0.5f : 1.0f)), 1.0f, 256.0f);
updateUniformBuffers();
}
@ -663,4 +664,4 @@ public:
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -729,6 +729,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -631,6 +631,11 @@ void VulkanExample::render()
}
}
void VulkanExample::viewChanged()
{
updateUniformBuffers();
}
void VulkanExample::OnUpdateUIOverlay(vks::UIOverlay* overlay)
{
if (overlay->header("Visibility")) {
@ -659,4 +664,4 @@ void VulkanExample::OnUpdateUIOverlay(vks::UIOverlay* overlay)
}
}
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -162,5 +162,6 @@ public:
void updateUniformBuffers();
void prepare();
virtual void render();
virtual void viewChanged();
virtual void OnUpdateUIOverlay(vks::UIOverlay* overlay);
};

View file

@ -995,6 +995,11 @@ void VulkanExample::render()
}
}
void VulkanExample::viewChanged()
{
updateUniformBuffers();
}
void VulkanExample::OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings"))
@ -1006,4 +1011,4 @@ void VulkanExample::OnUpdateUIOverlay(vks::UIOverlay *overlay)
}
}
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -232,5 +232,6 @@ class VulkanExample : public VulkanExampleBase
void updateUniformBuffers();
void prepare();
virtual void render();
virtual void viewChanged();
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay);
};

View file

@ -870,6 +870,11 @@ public:
updateUniformBuffers();
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -499,6 +499,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffer(true);
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (!vulkanDevice->features.multiDrawIndirect) {
@ -512,4 +517,4 @@ public:
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -357,6 +357,11 @@ public:
updateUniformBuffers();
}
virtual void viewChanged()
{
updateUniformBuffers();
}
/*
[POI] Update descriptor sets at runtime
*/
@ -401,4 +406,4 @@ public:
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -606,6 +606,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -482,6 +482,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffer(true);
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Statistics")) {
@ -490,4 +495,4 @@ public:
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -541,6 +541,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
// Returns the maximum sample count usable by the platform
VkSampleCountFlagBits getMaxUsableSampleCount()
{

View file

@ -527,6 +527,11 @@ public:
}
}
virtual void viewChanged()
{
updateMatrices();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Statistics")) {
@ -539,4 +544,4 @@ public:
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -738,6 +738,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -507,7 +507,7 @@ private:
vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL);
}
void buildCommandBuffers()
void buildCommandBuffers() override
{
if (resized)
return;
@ -656,4 +656,4 @@ private:
VkDeviceSize objectUniformBufferSize;
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -589,6 +589,11 @@ public:
updateUniformBuffers();
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -1340,6 +1340,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -334,6 +334,12 @@ public:
}
}
virtual void viewChanged()
{
camera.setPerspective(60.0f, (float)(width / 3.0f) / (float)height, 0.1f, 256.0f);
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (!deviceFeatures.fillModeNonSolid) {
@ -344,4 +350,4 @@ public:
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -337,6 +337,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -320,10 +320,10 @@ public:
}
}
virtual void windowResized()
virtual void viewChanged()
{
updateUniformBuffers();
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -277,6 +277,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {
@ -288,4 +293,4 @@ public:
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -944,6 +944,12 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBufferMatrices();
updateUniformBufferSSAOParams();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -903,6 +903,12 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBufferDeferredMatrices();
updateUniformBufferDeferredLights();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Subpasses")) {

View file

@ -828,6 +828,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {
@ -853,4 +858,4 @@ public:
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -326,6 +326,12 @@ public:
}
}
virtual void viewChanged()
{
camera.setPerspective(45.0f, (float)(width * ((splitScreen) ? 0.5f : 1.0f)) / (float)height, 0.1f, 256.0f);
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -514,6 +514,8 @@ public:
case alignCenter:
x -= textWidth / 2.0f;
break;
case alignLeft:
break;
}
// Generate a uv mapped quad per char in the new text
@ -885,6 +887,10 @@ public:
if (!prepared)
return;
draw();
if (camera.updated)
{
updateUniformBuffers();
}
if (frameCounter == 0)
{
vkDeviceWaitIdle(device);
@ -892,13 +898,6 @@ public:
}
}
virtual void viewChanged()
{
vkDeviceWaitIdle(device);
updateUniformBuffers();
updateTextOverlay();
}
virtual void windowResized()
{
// SRS - Recreate text overlay resources in case number of swapchain images has changed on resize
@ -906,6 +905,12 @@ public:
prepareTextOverlay();
}
virtual void viewChanged()
{
updateUniformBuffers();
updateTextOverlay();
}
#if !defined(__ANDROID__)
virtual void keyPressed(uint32_t keyCode)
{

View file

@ -773,6 +773,11 @@ public:
updateUniformBuffers(camera.updated);
}
virtual void viewChanged()
{
updateUniformBuffers(true);
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {

View file

@ -550,6 +550,10 @@ public:
updateUniformBuffersCamera();
}
virtual void viewChanged()
{
updateUniformBuffersCamera();
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -529,6 +529,11 @@ public:
}
}
virtual void viewChanged()
{
updateUniformBuffers();
}
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
{
if (overlay->header("Settings")) {
@ -548,4 +553,4 @@ public:
}
};
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -708,6 +708,11 @@ void VulkanExample::render()
}
}
void VulkanExample::viewChanged()
{
updateUniformBuffers();
}
// Fills a buffer with random colors
void VulkanExample::randomPattern(uint8_t* buffer, uint32_t width, uint32_t height)
{

View file

@ -116,6 +116,7 @@ public:
void updateUniformBuffers();
void prepare();
virtual void render();
virtual void viewChanged();
void uploadContent(VirtualTexturePage page, VkImage image);
void fillRandomPages();
void fillMipTail();

View file

@ -109,7 +109,7 @@ public:
// Fences
// Used to check the completion of queue operations (e.g. command buffer execution)
std::vector<VkFence> waitFences;
std::vector<VkFence> queueCompleteFences;
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION)
{
@ -148,7 +148,7 @@ public:
vkDestroySemaphore(device, presentCompleteSemaphore, nullptr);
vkDestroySemaphore(device, renderCompleteSemaphore, nullptr);
for (auto& fence : waitFences)
for (auto& fence : queueCompleteFences)
{
vkDestroyFence(device, fence, nullptr);
}
@ -196,8 +196,8 @@ public:
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
// Create in signaled state so we don't wait on first render of each command buffer
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
waitFences.resize(drawCmdBuffers.size());
for (auto& fence : waitFences)
queueCompleteFences.resize(drawCmdBuffers.size());
for (auto& fence : queueCompleteFences)
{
VK_CHECK_RESULT(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
}
@ -337,6 +337,16 @@ public:
void draw()
{
#if defined(VK_USE_PLATFORM_MACOS_MVK)
// SRS - on macOS use swapchain helper function with common semaphores/fences for proper resize handling
// Get next image in the swap chain (back/front buffer)
prepareFrame();
// Use a fence to wait until the command buffer has finished execution before using it again
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[currentBuffer], VK_TRUE, UINT64_MAX));
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[currentBuffer]));
#else
// SRS - on other platforms use original bare code with local semaphores/fences for illustrative purposes
// Get next image in the swap chain (back/front buffer)
VkResult acquire = swapChain.acquireNextImage(presentCompleteSemaphore, &currentBuffer);
if (!((acquire == VK_SUCCESS) || (acquire == VK_SUBOPTIMAL_KHR))) {
@ -344,8 +354,9 @@ public:
}
// Use a fence to wait until the command buffer has finished execution before using it again
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[currentBuffer], VK_TRUE, UINT64_MAX));
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[currentBuffer]));
VK_CHECK_RESULT(vkWaitForFences(device, 1, &queueCompleteFences[currentBuffer], VK_TRUE, UINT64_MAX));
VK_CHECK_RESULT(vkResetFences(device, 1, &queueCompleteFences[currentBuffer]));
#endif
// Pipeline stage at which the queue submission will wait (via pWaitSemaphores)
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
@ -353,16 +364,29 @@ public:
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.pWaitDstStageMask = &waitStageMask; // Pointer to the list of pipeline stages that the semaphore waits will occur at
submitInfo.pWaitSemaphores = &presentCompleteSemaphore; // Semaphore(s) to wait upon before the submitted command buffer starts executing
submitInfo.waitSemaphoreCount = 1; // One wait semaphore
submitInfo.pSignalSemaphores = &renderCompleteSemaphore; // Semaphore(s) to be signaled when command buffers have completed
submitInfo.signalSemaphoreCount = 1; // One signal semaphore
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; // Command buffers(s) to execute in this batch (submission)
submitInfo.commandBufferCount = 1; // One command buffer
#if defined(VK_USE_PLATFORM_MACOS_MVK)
// SRS - on macOS use swapchain helper function with common semaphores/fences for proper resize handling
submitInfo.pWaitSemaphores = &semaphores.presentComplete; // Semaphore(s) to wait upon before the submitted command buffer starts executing
submitInfo.pSignalSemaphores = &semaphores.renderComplete; // Semaphore(s) to be signaled when command buffers have completed
// Submit to the graphics queue passing a wait fence
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, waitFences[currentBuffer]));
// Present the current buffer to the swap chain
submitFrame();
#else
// SRS - on other platforms use original bare code with local semaphores/fences for illustrative purposes
submitInfo.pWaitSemaphores = &presentCompleteSemaphore; // Semaphore(s) to wait upon before the submitted command buffer starts executing
submitInfo.pSignalSemaphores = &renderCompleteSemaphore; // Semaphore(s) to be signaled when command buffers have completed
// Submit to the graphics queue passing a wait fence
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, queueCompleteFences[currentBuffer]));
// Present the current buffer to the swap chain
// Pass the semaphore signaled by the command buffer submission from the submit info as the wait semaphore for swap chain presentation
// This ensures that the image is not presented to the windowing system until all commands have been submitted
@ -370,7 +394,7 @@ public:
if (!((present == VK_SUCCESS) || (present == VK_SUBOPTIMAL_KHR))) {
VK_CHECK_RESULT(present);
}
#endif
}
// Prepare vertex and index buffers for an indexed triangle
@ -1235,7 +1259,7 @@ int main(const int argc, const char *argv[])
vulkanExample->setupWindow(nullptr);
vulkanExample->prepare();
vulkanExample->renderLoop();
delete(vulkanExample);
//delete(vulkanExample); // SRS - vulkanExample deleted by AppDelegate termination event handler
}
return 0;
}

View file

@ -580,6 +580,11 @@ void VulkanExample::render()
}
}
void VulkanExample::viewChanged()
{
updateUniformBuffers();
}
void VulkanExample::OnUpdateUIOverlay(vks::UIOverlay* overlay)
{
if (overlay->header("Vertex buffer attributes")) {
@ -596,4 +601,4 @@ void VulkanExample::OnUpdateUIOverlay(vks::UIOverlay* overlay)
}
}
VULKAN_EXAMPLE_MAIN()
VULKAN_EXAMPLE_MAIN()

View file

@ -139,5 +139,6 @@ public:
void loadSceneNode(const tinygltf::Node& inputNode, const tinygltf::Model& input, Node* parent);
void drawSceneNode(VkCommandBuffer commandBuffer, Node node);
virtual void render();
virtual void viewChanged();
virtual void OnUpdateUIOverlay(vks::UIOverlay* overlay);
};