support resize window
This commit is contained in:
		
							parent
							
								
									dad6ce7a21
								
							
						
					
					
						commit
						eb484e22f8
					
				
							
								
								
									
										
											BIN
										
									
								
								VulkanTest
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								VulkanTest
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -10,7 +10,7 @@ namespace hk
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        loadModels();
 | 
					        loadModels();
 | 
				
			||||||
        createPipelineLayout();
 | 
					        createPipelineLayout();
 | 
				
			||||||
        createPipeline();
 | 
					        recreateSwapChain();
 | 
				
			||||||
        createCommandBuffers();
 | 
					        createCommandBuffers();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,9 +59,9 @@ namespace hk
 | 
				
			||||||
    void FirstApp::createPipeline()
 | 
					    void FirstApp::createPipeline()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        auto pipelineConfig =
 | 
					        auto pipelineConfig =
 | 
				
			||||||
            Pipeline::defaultPipelineConfigInfo(swapChain.width(), swapChain.height());
 | 
					            Pipeline::defaultPipelineConfigInfo(swapChain->width(), swapChain->height());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        pipelineConfig.renderPass = swapChain.getRenderPass();
 | 
					        pipelineConfig.renderPass = swapChain->getRenderPass();
 | 
				
			||||||
        pipelineConfig.pipelineLayout = pipelineLayout;
 | 
					        pipelineConfig.pipelineLayout = pipelineLayout;
 | 
				
			||||||
        pipeline = std::make_unique<Pipeline>(
 | 
					        pipeline = std::make_unique<Pipeline>(
 | 
				
			||||||
            device,
 | 
					            device,
 | 
				
			||||||
| 
						 | 
					@ -70,9 +70,23 @@ namespace hk
 | 
				
			||||||
            pipelineConfig);
 | 
					            pipelineConfig);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void FirstApp::recreateSwapChain()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        auto extent = window.getExtend();
 | 
				
			||||||
 | 
					        while (extent.width == 0 || extent.height == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            extent = window.getExtend();
 | 
				
			||||||
 | 
					            glfwWaitEvents();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        vkDeviceWaitIdle(device.device());
 | 
				
			||||||
 | 
					        swapChain = std::make_unique<SwapChain>(device, extent);
 | 
				
			||||||
 | 
					        createPipeline();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void FirstApp::createCommandBuffers()
 | 
					    void FirstApp::createCommandBuffers()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        commandBuffers.resize(swapChain.imageCount());
 | 
					        commandBuffers.resize(swapChain->imageCount());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        VkCommandBufferAllocateInfo allocInfo{};
 | 
					        VkCommandBufferAllocateInfo allocInfo{};
 | 
				
			||||||
        allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
 | 
					        allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
 | 
				
			||||||
| 
						 | 
					@ -85,53 +99,69 @@ namespace hk
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            throw std::runtime_error("failed to allocate command buffers!");
 | 
					            throw std::runtime_error("failed to allocate command buffers!");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        for (int i = 0; i < commandBuffers.size(); i++)
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void FirstApp::recordCommandBuffer(int imageIndex)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        VkCommandBufferBeginInfo beginInfo{};
 | 
				
			||||||
 | 
					        beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
 | 
				
			||||||
 | 
					        if (vkBeginCommandBuffer(commandBuffers[imageIndex], &beginInfo) != VK_SUCCESS)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            VkCommandBufferBeginInfo beginInfo{};
 | 
					            throw std::runtime_error("failed to begin recording command buffer!");
 | 
				
			||||||
            beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
 | 
					        }
 | 
				
			||||||
            if (vkBeginCommandBuffer(commandBuffers[i], &beginInfo) != VK_SUCCESS)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                throw std::runtime_error("failed to begin recording command buffer!");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            VkRenderPassBeginInfo renderPassInfo{};
 | 
					        VkRenderPassBeginInfo renderPassInfo{};
 | 
				
			||||||
            renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
 | 
					        renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
 | 
				
			||||||
            renderPassInfo.renderPass = swapChain.getRenderPass();
 | 
					        renderPassInfo.renderPass = swapChain->getRenderPass();
 | 
				
			||||||
            renderPassInfo.framebuffer = swapChain.getFrameBuffer(i);
 | 
					        renderPassInfo.framebuffer = swapChain->getFrameBuffer(imageIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            renderPassInfo.renderArea.offset = {0, 0};
 | 
					        renderPassInfo.renderArea.offset = {0, 0};
 | 
				
			||||||
            renderPassInfo.renderArea.extent = swapChain.getSwapChainExtent();
 | 
					        renderPassInfo.renderArea.extent = swapChain->getSwapChainExtent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::array<VkClearValue, 2> clearValues{};
 | 
					        std::array<VkClearValue, 2> clearValues{};
 | 
				
			||||||
            clearValues[0].color = {0.1f, 0.1f, 0.1f, 1.0f};
 | 
					        clearValues[0].color = {0.1f, 0.1f, 0.1f, 1.0f};
 | 
				
			||||||
            clearValues[1].depthStencil = {1.0f, 0};
 | 
					        clearValues[1].depthStencil = {1.0f, 0};
 | 
				
			||||||
            renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
 | 
					        renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
 | 
				
			||||||
            renderPassInfo.pClearValues = clearValues.data();
 | 
					        renderPassInfo.pClearValues = clearValues.data();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
 | 
					        vkCmdBeginRenderPass(commandBuffers[imageIndex], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            pipeline->bind(commandBuffers[i]);
 | 
					        pipeline->bind(commandBuffers[imageIndex]);
 | 
				
			||||||
            model->bind(commandBuffers[i]);
 | 
					        model->bind(commandBuffers[imageIndex]);
 | 
				
			||||||
            model->draw(commandBuffers[i]);
 | 
					        model->draw(commandBuffers[imageIndex]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            vkCmdEndRenderPass(commandBuffers[i]);
 | 
					        vkCmdEndRenderPass(commandBuffers[imageIndex]);
 | 
				
			||||||
            if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS)
 | 
					        if (vkEndCommandBuffer(commandBuffers[imageIndex]) != VK_SUCCESS)
 | 
				
			||||||
            {
 | 
					        {
 | 
				
			||||||
                throw std::runtime_error("failed to record command buffer!");
 | 
					            throw std::runtime_error("failed to record command buffer!");
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void FirstApp::drawFrame()
 | 
					    void FirstApp::drawFrame()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uint32_t imageIndex;
 | 
					        uint32_t imageIndex;
 | 
				
			||||||
        auto result = swapChain.acquireNextImage(&imageIndex);
 | 
					        auto result = swapChain->acquireNextImage(&imageIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (result == VK_ERROR_OUT_OF_DATE_KHR)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            recreateSwapChain();
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
 | 
					        if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            throw std::runtime_error("failed to acquire swap chain image!");
 | 
					            throw std::runtime_error("failed to acquire swap chain image!");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        result = swapChain.submitCommandBuffers(&commandBuffers[imageIndex], &imageIndex);
 | 
					        recordCommandBuffer(imageIndex);
 | 
				
			||||||
 | 
					        result = swapChain->submitCommandBuffers(&commandBuffers[imageIndex], &imageIndex);
 | 
				
			||||||
 | 
					        if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || window.wasWindowResized())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            window.resetWindowResizedFlag();
 | 
				
			||||||
 | 
					            recreateSwapChain();
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        if (result != VK_SUCCESS)
 | 
					        if (result != VK_SUCCESS)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            throw std::runtime_error("failed to present swap chain image!");
 | 
					            throw std::runtime_error("failed to present swap chain image!");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,10 +32,12 @@ namespace hk
 | 
				
			||||||
        void createPipeline();
 | 
					        void createPipeline();
 | 
				
			||||||
        void createCommandBuffers();
 | 
					        void createCommandBuffers();
 | 
				
			||||||
        void drawFrame();
 | 
					        void drawFrame();
 | 
				
			||||||
 | 
					        void recreateSwapChain();
 | 
				
			||||||
 | 
					        void recordCommandBuffer(int imageIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Window window{WIDTH, HEIGHT, "Hello Vulkan!"};
 | 
					        Window window{WIDTH, HEIGHT, "Hello Vulkan!"};
 | 
				
			||||||
        Device device{window};
 | 
					        Device device{window};
 | 
				
			||||||
        SwapChain swapChain{device, window.getExtend()};
 | 
					        std::unique_ptr<SwapChain> swapChain;
 | 
				
			||||||
        std::unique_ptr<Pipeline> pipeline;
 | 
					        std::unique_ptr<Pipeline> pipeline;
 | 
				
			||||||
        VkPipelineLayout pipelineLayout;
 | 
					        VkPipelineLayout pipelineLayout;
 | 
				
			||||||
        std::vector<VkCommandBuffer> commandBuffers;
 | 
					        std::vector<VkCommandBuffer> commandBuffers;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,16 @@ namespace hk
 | 
				
			||||||
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
 | 
					        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        m_window = glfwCreateWindow(m_width, m_height, m_windowName.c_str(), nullptr, nullptr);
 | 
					        m_window = glfwCreateWindow(m_width, m_height, m_windowName.c_str(), nullptr, nullptr);
 | 
				
			||||||
 | 
					        glfwSetWindowUserPointer(m_window, this);
 | 
				
			||||||
 | 
					        glfwSetFramebufferSizeCallback(m_window, framebufferResizeCallback);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void Window::framebufferResizeCallback(GLFWwindow* window, int width, int height)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        auto hkWindow = reinterpret_cast<Window*>(glfwGetWindowUserPointer(window));
 | 
				
			||||||
 | 
					        hkWindow->m_framebufferResized = true;
 | 
				
			||||||
 | 
					        hkWindow->m_width = width;
 | 
				
			||||||
 | 
					        hkWindow->m_height = height;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -18,14 +18,18 @@ namespace hk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool shouldClose() { return glfwWindowShouldClose(m_window); }
 | 
					        bool shouldClose() { return glfwWindowShouldClose(m_window); }
 | 
				
			||||||
        VkExtent2D getExtend() { return {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}; }
 | 
					        VkExtent2D getExtend() { return {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}; }
 | 
				
			||||||
 | 
					        bool wasWindowResized() { return m_framebufferResized; }
 | 
				
			||||||
 | 
					        void resetWindowResizedFlag() { m_framebufferResized = false; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void createWindowSurface(VkInstance instance, VkSurfaceKHR *surface);
 | 
					        void createWindowSurface(VkInstance instance, VkSurfaceKHR *surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
 | 
					        static void framebufferResizeCallback(GLFWwindow* window, int width, int height);
 | 
				
			||||||
        void initWindow();
 | 
					        void initWindow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const int m_width;
 | 
					        int m_width;
 | 
				
			||||||
        const int m_height;
 | 
					        int m_height;
 | 
				
			||||||
 | 
					        bool m_framebufferResized = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::string m_windowName;
 | 
					        std::string m_windowName;
 | 
				
			||||||
        GLFWwindow *m_window;
 | 
					        GLFWwindow *m_window;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue