Skip to content

Commit

Permalink
window resizing
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerboa-app committed Sep 7, 2023
1 parent c03f335 commit 128504a
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 36 deletions.
10 changes: 8 additions & 2 deletions include/Renderer/vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ namespace Renderer

void finish(){ vkDeviceWaitIdle(device); }

void setExtent(uint32_t w, uint32_t h) { width = w; height = h; recreateSwapChain(); }

private:

VkInstance instance;
Expand Down Expand Up @@ -100,6 +102,8 @@ namespace Renderer
VkFormat swapChainImageFormat;
VkExtent2D swapChainExtent;

uint32_t width, height;

std::vector<VkImageView> swapChainImageViews;
std::vector<VkFramebuffer> swapChainFramebuffers;

Expand All @@ -122,11 +126,13 @@ namespace Renderer
bool checkDeviceExtensionSupport(VkPhysicalDevice physicalDevice);
void getRequiredExtensions();

void createSwapChain(GLFWwindow * window);
void createSwapChain();
void recreateSwapChain();
void cleanupSwapChain();
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice physicalDevice);
VkSurfaceFormatKHR chooseSwapChainSurfaceFormat(const std::vector<VkSurfaceFormatKHR> & availableFormats);
VkPresentModeKHR chooseSwapChainPresentMode(const std::vector<VkPresentModeKHR> & availablePresentModes);
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR & capabilities, GLFWwindow * window);
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR & capabilities);
void createImageViews();

void createRenderPass();
Expand Down
104 changes: 71 additions & 33 deletions src/Renderer/vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ namespace Renderer

VulkanRenderer::VulkanRenderer(GLFWwindow * window)
{

// must be careful, GLFW uses screen units not pixels, we need pixels
int w, h;
glfwGetFramebufferSize(window, &w, &h);
width = static_cast<uint32_t>(w);
height = static_cast<uint32_t>(h);

viewport = VkViewport{};
scissor = VkRect2D{};
// optional application information
Expand Down Expand Up @@ -60,7 +67,7 @@ namespace Renderer

createLogicalDevice();

createSwapChain(window);
createSwapChain();

createImageViews();

Expand All @@ -79,6 +86,13 @@ namespace Renderer

VulkanRenderer::~VulkanRenderer()
{
cleanupSwapChain();

vkDestroyPipeline(device, pipeline, nullptr);

vkDestroyPipelineLayout(device, pipelineLayout, nullptr);

vkDestroyRenderPass(device, renderPass, nullptr);

for (unsigned i = 0; i < MAX_CONCURRENT_FRAMES; i++)
{
Expand All @@ -90,31 +104,13 @@ namespace Renderer
// command buffers are also freed here
vkDestroyCommandPool(device, commandPool, nullptr);

vkDestroyDevice(device, nullptr);

if (enableValidationLayers)
{
destroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
}

vkDestroyPipeline(device, pipeline, nullptr);

vkDestroyPipelineLayout(device, pipelineLayout, nullptr);

for (auto framebuffer : swapChainFramebuffers)
{
vkDestroyFramebuffer(device, framebuffer, nullptr);
}

vkDestroyRenderPass(device, renderPass, nullptr);

for (auto imageView : swapChainImageViews)
{
vkDestroyImageView(device, imageView, nullptr);
}

vkDestroySwapchainKHR(device, swapChain, nullptr);

vkDestroyDevice(device, nullptr);

vkDestroySurfaceKHR(instance, surface, nullptr);

vkDestroyInstance(instance, nullptr);
Expand Down Expand Up @@ -365,12 +361,12 @@ namespace Renderer
}


void VulkanRenderer::createSwapChain(GLFWwindow * window)
void VulkanRenderer::createSwapChain()
{
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);
VkSurfaceFormatKHR surfaceFormat = chooseSwapChainSurfaceFormat(swapChainSupport.formats);
VkPresentModeKHR presentMode = chooseSwapChainPresentMode(swapChainSupport.presentModes);
VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities, window);
VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities);

uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
if
Expand Down Expand Up @@ -434,6 +430,32 @@ namespace Renderer
swapChainExtent = extent;
}

void VulkanRenderer::recreateSwapChain()
{
vkDeviceWaitIdle(device);

cleanupSwapChain();

createSwapChain();
createImageViews();
createFramebuffers();
}

void VulkanRenderer::cleanupSwapChain()
{
for (auto framebuffer : swapChainFramebuffers)
{
vkDestroyFramebuffer(device, framebuffer, nullptr);
}

for (auto imageView : swapChainImageViews)
{
vkDestroyImageView(device, imageView, nullptr);
}

vkDestroySwapchainKHR(device, swapChain, nullptr);
}

SwapChainSupportDetails VulkanRenderer::querySwapChainSupport(VkPhysicalDevice physicalDevice)
{
SwapChainSupportDetails details;
Expand Down Expand Up @@ -525,7 +547,7 @@ namespace Renderer

}

VkExtent2D VulkanRenderer::chooseSwapExtent(const VkSurfaceCapabilitiesKHR & capabilities, GLFWwindow * window)
VkExtent2D VulkanRenderer::chooseSwapExtent(const VkSurfaceCapabilitiesKHR & capabilities)
{
if (capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max())
{
Expand All @@ -534,14 +556,9 @@ namespace Renderer
}
else
{
// must be careful, GLFW uses screen units not pixels, we need pixels
int width, height;
glfwGetFramebufferSize(window, &width, &height);

VkExtent2D actualExtent =
{
static_cast<uint32_t>(width),
static_cast<uint32_t>(height)
width, height
};

actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
Expand Down Expand Up @@ -941,12 +958,23 @@ namespace Renderer
// VK_TRUE = wait for all fences
// last is a timeout integer
vkWaitForFences(device, 1, &framesFinished[currentFrame], VK_TRUE, UINT64_MAX);
vkResetFences(device, 1, &framesFinished[currentFrame]);

// aquire an image
uint32_t imageIndex;
vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);

if (result == VK_ERROR_OUT_OF_DATE_KHR)
{
recreateSwapChain();
return;
}
else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
{
throw std::runtime_error("Failed to aquire swap chain image");
}

vkResetFences(device, 1, &framesFinished[currentFrame]);

vkResetCommandBuffer(commandBuffers[currentFrame], 0);
recordCommandBuffer(commandBuffers[currentFrame], imageIndex);
// submit the command buffer
Expand Down Expand Up @@ -983,7 +1011,17 @@ namespace Renderer
presentInfo.pImageIndices = &imageIndex;
// can check on success
presentInfo.pResults = nullptr;
vkQueuePresentKHR(presentQueue, &presentInfo);

result = vkQueuePresentKHR(presentQueue, &presentInfo);

if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
{
recreateSwapChain();
}
else if (result != VK_SUCCESS)
{
throw std::runtime_error("Failed to present swap chain image");
}

currentFrame = (currentFrame+1)%MAX_CONCURRENT_FRAMES;
}
Expand Down
18 changes: 17 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
class HelloTriangleApplication
{
public:

void run()
{
initWindow();
Expand All @@ -19,6 +20,8 @@ class HelloTriangleApplication
cleanup();
}

void resize(uint32_t w, uint32_t h) { renderer->setExtent(w, h); }

private:

GLFWwindow * window;
Expand All @@ -32,9 +35,11 @@ class HelloTriangleApplication
glfwInit();
// no opengl
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
glfwSetWindowUserPointer(window, this);
glfwSetFramebufferSizeCallback(window, frameBufferResizedCallback);
}

void initVulkan()
Expand All @@ -59,6 +64,17 @@ class HelloTriangleApplication
glfwTerminate();
}

static void frameBufferResizedCallback(GLFWwindow * window, int width, int height)
{
auto app = reinterpret_cast<HelloTriangleApplication*>(glfwGetWindowUserPointer(window));
int w, h;
glfwGetFramebufferSize(window, &w, &h);
width = static_cast<uint32_t>(w);
height = static_cast<uint32_t>(h);
app->resize(width, height);

}


};

Expand Down

0 comments on commit 128504a

Please sign in to comment.