Fixes in examples: support swapchain image count change on resize, fix multiple validation layer errors on resize and quit, multiview now supports resize/fullscreen, computecloth deltaT now based on frame time, multisampling recreates attachments on resize, P key now pauses computeparticles, descriptorsets, and pushdescriptors
This commit is contained in:
parent
cb343c329a
commit
121612857c
10 changed files with 148 additions and 65 deletions
|
|
@ -101,6 +101,7 @@ public:
|
|||
~VulkanExample()
|
||||
{
|
||||
// Graphics
|
||||
graphics.indices.destroy();
|
||||
graphics.uniformBuffer.destroy();
|
||||
vkDestroyPipeline(device, graphics.pipelines.cloth, nullptr);
|
||||
vkDestroyPipeline(device, graphics.pipelines.sphere, nullptr);
|
||||
|
|
@ -670,13 +671,13 @@ public:
|
|||
void updateComputeUBO()
|
||||
{
|
||||
if (!paused) {
|
||||
compute.ubo.deltaT = 0.000005f;
|
||||
//compute.ubo.deltaT = 0.000005f;
|
||||
// todo: base on frametime
|
||||
//compute.ubo.deltaT = frameTimer * 0.0075f;
|
||||
compute.ubo.deltaT = frameTimer * 0.0015f;
|
||||
|
||||
if (simulateWind) {
|
||||
std::default_random_engine rndEngine(benchmark.active ? 0 : (unsigned)time(nullptr));
|
||||
std::uniform_real_distribution<float> rd(1.0f, 6.0f);
|
||||
std::uniform_real_distribution<float> rd(1.0f, 30.0f);
|
||||
compute.ubo.gravity.x = cos(glm::radians(-timer * 360.0f)) * (rd(rndEngine) - rd(rndEngine));
|
||||
compute.ubo.gravity.z = sin(glm::radians(timer * 360.0f)) * (rd(rndEngine) - rd(rndEngine));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -620,6 +620,13 @@ public:
|
|||
// Semaphore for compute & graphics sync
|
||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
||||
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &graphics.semaphore));
|
||||
|
||||
// Signal the semaphore
|
||||
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = &graphics.semaphore;
|
||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||
VK_CHECK_RESULT(vkQueueWaitIdle(queue));
|
||||
}
|
||||
|
||||
void prepareCompute()
|
||||
|
|
@ -736,13 +743,6 @@ public:
|
|||
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
||||
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &compute.semaphore));
|
||||
|
||||
// Signal the semaphore
|
||||
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = &compute.semaphore;
|
||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||
VK_CHECK_RESULT(vkQueueWaitIdle(queue));
|
||||
|
||||
// Build a single command buffer containing the compute dispatch commands
|
||||
buildComputeCommandBuffer();
|
||||
|
||||
|
|
@ -841,6 +841,20 @@ public:
|
|||
|
||||
void draw()
|
||||
{
|
||||
// Wait for rendering finished
|
||||
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
|
||||
// Submit compute commands
|
||||
VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo();
|
||||
computeSubmitInfo.commandBufferCount = 1;
|
||||
computeSubmitInfo.pCommandBuffers = &compute.commandBuffer;
|
||||
computeSubmitInfo.waitSemaphoreCount = 1;
|
||||
computeSubmitInfo.pWaitSemaphores = &graphics.semaphore;
|
||||
computeSubmitInfo.pWaitDstStageMask = &waitStageMask;
|
||||
computeSubmitInfo.signalSemaphoreCount = 1;
|
||||
computeSubmitInfo.pSignalSemaphores = &compute.semaphore;
|
||||
VK_CHECK_RESULT(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE));
|
||||
|
||||
VulkanExampleBase::prepareFrame();
|
||||
|
||||
VkPipelineStageFlags graphicsWaitStageMasks[] = { VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||
|
|
@ -858,20 +872,6 @@ public:
|
|||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||
|
||||
VulkanExampleBase::submitFrame();
|
||||
|
||||
// Wait for rendering finished
|
||||
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
|
||||
// Submit compute commands
|
||||
VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo();
|
||||
computeSubmitInfo.commandBufferCount = 1;
|
||||
computeSubmitInfo.pCommandBuffers = &compute.commandBuffer;
|
||||
computeSubmitInfo.waitSemaphoreCount = 1;
|
||||
computeSubmitInfo.pWaitSemaphores = &graphics.semaphore;
|
||||
computeSubmitInfo.pWaitDstStageMask = &waitStageMask;
|
||||
computeSubmitInfo.signalSemaphoreCount = 1;
|
||||
computeSubmitInfo.pSignalSemaphores = &compute.semaphore;
|
||||
VK_CHECK_RESULT(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE));
|
||||
}
|
||||
|
||||
void prepare()
|
||||
|
|
@ -901,4 +901,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ public:
|
|||
vkDestroyPipeline(device, graphics.pipeline, nullptr);
|
||||
vkDestroyPipelineLayout(device, graphics.pipelineLayout, nullptr);
|
||||
vkDestroyDescriptorSetLayout(device, graphics.descriptorSetLayout, nullptr);
|
||||
vkDestroySemaphore(device, graphics.semaphore, nullptr);
|
||||
|
||||
// Compute
|
||||
compute.storageBuffer.destroy();
|
||||
|
|
@ -551,6 +552,13 @@ public:
|
|||
// Semaphore for compute & graphics sync
|
||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
||||
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &graphics.semaphore));
|
||||
|
||||
// Signal the semaphore
|
||||
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = &graphics.semaphore;
|
||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||
VK_CHECK_RESULT(vkQueueWaitIdle(queue));
|
||||
}
|
||||
|
||||
void prepareCompute()
|
||||
|
|
@ -636,13 +644,6 @@ public:
|
|||
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
||||
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &compute.semaphore));
|
||||
|
||||
// Signal the semaphore
|
||||
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = &compute.semaphore;
|
||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||
VK_CHECK_RESULT(vkQueueWaitIdle(queue));
|
||||
|
||||
// Build a single command buffer containing the compute dispatch commands
|
||||
buildComputeCommandBuffer();
|
||||
|
||||
|
|
@ -716,7 +717,7 @@ public:
|
|||
|
||||
void updateUniformBuffers()
|
||||
{
|
||||
compute.ubo.deltaT = frameTimer * 2.5f;
|
||||
compute.ubo.deltaT = paused ? 0.0f : frameTimer * 2.5f;
|
||||
if (!attachToCursor)
|
||||
{
|
||||
compute.ubo.destX = sin(glm::radians(timer * 360.0f)) * 0.75f;
|
||||
|
|
@ -735,6 +736,20 @@ public:
|
|||
|
||||
void draw()
|
||||
{
|
||||
// Wait for rendering finished
|
||||
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
|
||||
// Submit compute commands
|
||||
VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo();
|
||||
computeSubmitInfo.commandBufferCount = 1;
|
||||
computeSubmitInfo.pCommandBuffers = &compute.commandBuffer;
|
||||
computeSubmitInfo.waitSemaphoreCount = 1;
|
||||
computeSubmitInfo.pWaitSemaphores = &graphics.semaphore;
|
||||
computeSubmitInfo.pWaitDstStageMask = &waitStageMask;
|
||||
computeSubmitInfo.signalSemaphoreCount = 1;
|
||||
computeSubmitInfo.pSignalSemaphores = &compute.semaphore;
|
||||
VK_CHECK_RESULT(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE));
|
||||
|
||||
VulkanExampleBase::prepareFrame();
|
||||
|
||||
VkPipelineStageFlags graphicsWaitStageMasks[] = { VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||
|
|
@ -752,21 +767,6 @@ public:
|
|||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||
|
||||
VulkanExampleBase::submitFrame();
|
||||
|
||||
// Wait for rendering finished
|
||||
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
|
||||
// Submit compute commands
|
||||
VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo();
|
||||
computeSubmitInfo.commandBufferCount = 1;
|
||||
computeSubmitInfo.pCommandBuffers = &compute.commandBuffer;
|
||||
computeSubmitInfo.waitSemaphoreCount = 1;
|
||||
computeSubmitInfo.pWaitSemaphores = &graphics.semaphore;
|
||||
computeSubmitInfo.pWaitDstStageMask = &waitStageMask;
|
||||
computeSubmitInfo.signalSemaphoreCount = 1;
|
||||
computeSubmitInfo.pSignalSemaphores = &compute.semaphore;
|
||||
VK_CHECK_RESULT(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE));
|
||||
|
||||
}
|
||||
|
||||
void prepare()
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ public:
|
|||
if (!prepared)
|
||||
return;
|
||||
draw();
|
||||
if (animate) {
|
||||
if (animate && !paused) {
|
||||
cubes[0].rotation.x += 2.5f * frameTimer;
|
||||
if (cubes[0].rotation.x > 360.0f)
|
||||
cubes[0].rotation.x -= 360.0f;
|
||||
|
|
@ -370,7 +370,7 @@ public:
|
|||
if (cubes[1].rotation.x > 360.0f)
|
||||
cubes[1].rotation.x -= 360.0f;
|
||||
}
|
||||
if ((camera.updated) || (animate)) {
|
||||
if ((camera.updated) || (animate && !paused)) {
|
||||
updateUniformBuffers();
|
||||
}
|
||||
}
|
||||
|
|
@ -383,4 +383,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
|
|
|
|||
|
|
@ -180,11 +180,23 @@ public:
|
|||
for (auto i = 0; i < attachments.size(); i++) {
|
||||
clearAttachment(&attachments[i].color);
|
||||
clearAttachment(&attachments[i].depth);
|
||||
}
|
||||
|
||||
// SRS - Recreate attachments and descriptors in case number of swapchain images has changed on resize
|
||||
attachments.resize(swapChain.imageCount);
|
||||
for (auto i = 0; i < attachments.size(); i++) {
|
||||
createAttachment(colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &attachments[i].color);
|
||||
createAttachment(depthFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, &attachments[i].depth);
|
||||
// Since the framebuffers/attachments are referred in the descriptor sets, these need to be updated too
|
||||
updateAttachmentReadDescriptors(i);
|
||||
}
|
||||
|
||||
vkDestroyPipelineLayout(device, pipelineLayouts.attachmentWrite, nullptr);
|
||||
vkDestroyPipelineLayout(device, pipelineLayouts.attachmentRead, nullptr);
|
||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.attachmentWrite, nullptr);
|
||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.attachmentRead, nullptr);
|
||||
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
|
||||
|
||||
// Since the framebuffers/attachments are referred in the descriptor sets, these need to be updated on resize
|
||||
setupDescriptors();
|
||||
}
|
||||
|
||||
VkImageView views[3];
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ public:
|
|||
VkPipelineLayout pipelineLayout;
|
||||
VkDescriptorSet descriptorSet;
|
||||
VkDescriptorSetLayout descriptorSetLayout;
|
||||
VkExtent2D attachmentSize;
|
||||
|
||||
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION)
|
||||
{
|
||||
|
|
@ -199,6 +200,8 @@ public:
|
|||
void setupRenderPass()
|
||||
{
|
||||
// Overrides the virtual function of the base class
|
||||
|
||||
attachmentSize = { width, height };
|
||||
|
||||
std::array<VkAttachmentDescription, 3> attachments = {};
|
||||
|
||||
|
|
@ -290,6 +293,20 @@ public:
|
|||
{
|
||||
// Overrides the virtual function of the base class
|
||||
|
||||
// SRS - If the window is resized, the MSAA attachments need to be released and recreated
|
||||
if (attachmentSize.width != width || attachmentSize.height != height)
|
||||
{
|
||||
attachmentSize = { width, height };
|
||||
|
||||
// Destroy MSAA target
|
||||
vkDestroyImage(device, multisampleTarget.color.image, nullptr);
|
||||
vkDestroyImageView(device, multisampleTarget.color.view, nullptr);
|
||||
vkFreeMemory(device, multisampleTarget.color.memory, nullptr);
|
||||
vkDestroyImage(device, multisampleTarget.depth.image, nullptr);
|
||||
vkDestroyImageView(device, multisampleTarget.depth.view, nullptr);
|
||||
vkFreeMemory(device, multisampleTarget.depth.memory, nullptr);
|
||||
}
|
||||
|
||||
std::array<VkImageView, 3> attachments;
|
||||
|
||||
setupMultisampleTarget();
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ public:
|
|||
vkDestroySampler(device, multiviewPass.sampler, nullptr);
|
||||
vkDestroyFramebuffer(device, multiviewPass.frameBuffer, nullptr);
|
||||
|
||||
vkFreeCommandBuffers(device, cmdPool, static_cast<uint32_t>(multiviewPass.commandBuffers.size()), multiviewPass.commandBuffers.data());
|
||||
vkDestroySemaphore(device, multiviewPass.semaphore, nullptr);
|
||||
for (auto& fence : multiviewPass.waitFences) {
|
||||
vkDestroyFence(device, fence, nullptr);
|
||||
|
|
@ -337,6 +338,9 @@ public:
|
|||
|
||||
void buildCommandBuffers()
|
||||
{
|
||||
if (resized)
|
||||
return;
|
||||
|
||||
/*
|
||||
View display
|
||||
*/
|
||||
|
|
@ -392,11 +396,6 @@ public:
|
|||
Multiview layered attachment scene rendering
|
||||
*/
|
||||
|
||||
multiviewPass.commandBuffers.resize(drawCmdBuffers.size());
|
||||
|
||||
VkCommandBufferAllocateInfo cmdBufAllocateInfo = vks::initializers::commandBufferAllocateInfo(cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, static_cast<uint32_t>(drawCmdBuffers.size()));
|
||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, multiviewPass.commandBuffers.data()));
|
||||
|
||||
{
|
||||
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
|
||||
|
||||
|
|
@ -467,13 +466,18 @@ public:
|
|||
*/
|
||||
VkDescriptorSetAllocateInfo allocateInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
|
||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocateInfo, &descriptorSet));
|
||||
updateDescriptors();
|
||||
}
|
||||
|
||||
void updateDescriptors()
|
||||
{
|
||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
|
||||
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor),
|
||||
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &multiviewPass.descriptor),
|
||||
};
|
||||
vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr);
|
||||
}
|
||||
|
||||
|
||||
void preparePipelines()
|
||||
{
|
||||
|
||||
|
|
@ -669,6 +673,11 @@ public:
|
|||
prepareUniformBuffers();
|
||||
prepareDescriptors();
|
||||
preparePipelines();
|
||||
|
||||
VkCommandBufferAllocateInfo cmdBufAllocateInfo = vks::initializers::commandBufferAllocateInfo(cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, static_cast<uint32_t>(drawCmdBuffers.size()));
|
||||
multiviewPass.commandBuffers.resize(drawCmdBuffers.size());
|
||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, multiviewPass.commandBuffers.data()));
|
||||
|
||||
buildCommandBuffers();
|
||||
|
||||
VkFenceCreateInfo fenceCreateInfo = vks::initializers::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
||||
|
|
@ -680,6 +689,45 @@ public:
|
|||
prepared = true;
|
||||
}
|
||||
|
||||
// SRS - Recreate and update Multiview resources when window size has changed
|
||||
virtual void windowResized()
|
||||
{
|
||||
vkDestroyImageView(device, multiviewPass.color.view, nullptr);
|
||||
vkDestroyImage(device, multiviewPass.color.image, nullptr);
|
||||
vkFreeMemory(device, multiviewPass.color.memory, nullptr);
|
||||
vkDestroyImageView(device, multiviewPass.depth.view, nullptr);
|
||||
vkDestroyImage(device, multiviewPass.depth.image, nullptr);
|
||||
vkFreeMemory(device, multiviewPass.depth.memory, nullptr);
|
||||
|
||||
vkDestroyRenderPass(device, multiviewPass.renderPass, nullptr);
|
||||
vkDestroySampler(device, multiviewPass.sampler, nullptr);
|
||||
vkDestroyFramebuffer(device, multiviewPass.frameBuffer, nullptr);
|
||||
|
||||
prepareMultiview();
|
||||
updateDescriptors();
|
||||
|
||||
// SRS - Recreate Multiview command buffers in case number of swapchain images has changed on resize
|
||||
vkFreeCommandBuffers(device, cmdPool, static_cast<uint32_t>(multiviewPass.commandBuffers.size()), multiviewPass.commandBuffers.data());
|
||||
|
||||
VkCommandBufferAllocateInfo cmdBufAllocateInfo = vks::initializers::commandBufferAllocateInfo(cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, static_cast<uint32_t>(drawCmdBuffers.size()));
|
||||
multiviewPass.commandBuffers.resize(drawCmdBuffers.size());
|
||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, multiviewPass.commandBuffers.data()));
|
||||
|
||||
resized = false;
|
||||
buildCommandBuffers();
|
||||
|
||||
// SRS - Recreate Multiview fences in case number of swapchain images has changed on resize
|
||||
for (auto& fence : multiviewPass.waitFences) {
|
||||
vkDestroyFence(device, fence, nullptr);
|
||||
}
|
||||
|
||||
VkFenceCreateInfo fenceCreateInfo = vks::initializers::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
||||
multiviewPass.waitFences.resize(multiviewPass.commandBuffers.size());
|
||||
for (auto& fence : multiviewPass.waitFences) {
|
||||
VK_CHECK_RESULT(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void render()
|
||||
{
|
||||
if (!prepared)
|
||||
|
|
@ -704,4 +752,4 @@ public:
|
|||
|
||||
};
|
||||
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ public:
|
|||
memcpy(cube.uniformBuffer.mapped, &cube.modelMat, sizeof(glm::mat4));
|
||||
}
|
||||
|
||||
if (animate) {
|
||||
if (animate && !paused) {
|
||||
cubes[0].rotation.x += 2.5f * frameTimer;
|
||||
if (cubes[0].rotation.x > 360.0f)
|
||||
cubes[0].rotation.x -= 360.0f;
|
||||
|
|
@ -323,7 +323,7 @@ public:
|
|||
if (!prepared)
|
||||
return;
|
||||
draw();
|
||||
if (animate) {
|
||||
if (animate && !paused) {
|
||||
cubes[0].rotation.x += 2.5f * frameTimer;
|
||||
if (cubes[0].rotation.x > 360.0f)
|
||||
cubes[0].rotation.x -= 360.0f;
|
||||
|
|
@ -348,4 +348,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
|
|
|
|||
|
|
@ -901,7 +901,9 @@ public:
|
|||
|
||||
virtual void windowResized()
|
||||
{
|
||||
updateTextOverlay();
|
||||
// SRS - Recreate text overlay resources in case number of swapchain images has changed on resize
|
||||
delete textOverlay;
|
||||
prepareTextOverlay();
|
||||
}
|
||||
|
||||
#if !defined(__ANDROID__)
|
||||
|
|
@ -917,4 +919,4 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
|
|
|
|||
|
|
@ -126,6 +126,9 @@ public:
|
|||
|
||||
~VulkanExample()
|
||||
{
|
||||
// SRS - Ensure all operations on the device have finished before destroying resources
|
||||
vkDeviceWaitIdle(device);
|
||||
|
||||
// Clean up used Vulkan resources
|
||||
// Note: Inherited destructor cleans up resources stored in base class
|
||||
vkDestroyPipeline(device, pipeline, nullptr);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue