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();
 | 
			
		||||
        createPipelineLayout();
 | 
			
		||||
        createPipeline();
 | 
			
		||||
        recreateSwapChain();
 | 
			
		||||
        createCommandBuffers();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -59,9 +59,9 @@ namespace hk
 | 
			
		|||
    void FirstApp::createPipeline()
 | 
			
		||||
    {
 | 
			
		||||
        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;
 | 
			
		||||
        pipeline = std::make_unique<Pipeline>(
 | 
			
		||||
            device,
 | 
			
		||||
| 
						 | 
				
			
			@ -70,9 +70,23 @@ namespace hk
 | 
			
		|||
            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()
 | 
			
		||||
    {
 | 
			
		||||
        commandBuffers.resize(swapChain.imageCount());
 | 
			
		||||
        commandBuffers.resize(swapChain->imageCount());
 | 
			
		||||
 | 
			
		||||
        VkCommandBufferAllocateInfo allocInfo{};
 | 
			
		||||
        allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
 | 
			
		||||
| 
						 | 
				
			
			@ -85,53 +99,69 @@ namespace hk
 | 
			
		|||
        {
 | 
			
		||||
            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{};
 | 
			
		||||
            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!");
 | 
			
		||||
            }
 | 
			
		||||
            throw std::runtime_error("failed to begin recording command buffer!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            VkRenderPassBeginInfo renderPassInfo{};
 | 
			
		||||
            renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
 | 
			
		||||
            renderPassInfo.renderPass = swapChain.getRenderPass();
 | 
			
		||||
            renderPassInfo.framebuffer = swapChain.getFrameBuffer(i);
 | 
			
		||||
        VkRenderPassBeginInfo renderPassInfo{};
 | 
			
		||||
        renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
 | 
			
		||||
        renderPassInfo.renderPass = swapChain->getRenderPass();
 | 
			
		||||
        renderPassInfo.framebuffer = swapChain->getFrameBuffer(imageIndex);
 | 
			
		||||
 | 
			
		||||
            renderPassInfo.renderArea.offset = {0, 0};
 | 
			
		||||
            renderPassInfo.renderArea.extent = swapChain.getSwapChainExtent();
 | 
			
		||||
        renderPassInfo.renderArea.offset = {0, 0};
 | 
			
		||||
        renderPassInfo.renderArea.extent = swapChain->getSwapChainExtent();
 | 
			
		||||
 | 
			
		||||
            std::array<VkClearValue, 2> clearValues{};
 | 
			
		||||
            clearValues[0].color = {0.1f, 0.1f, 0.1f, 1.0f};
 | 
			
		||||
            clearValues[1].depthStencil = {1.0f, 0};
 | 
			
		||||
            renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
 | 
			
		||||
            renderPassInfo.pClearValues = clearValues.data();
 | 
			
		||||
        std::array<VkClearValue, 2> clearValues{};
 | 
			
		||||
        clearValues[0].color = {0.1f, 0.1f, 0.1f, 1.0f};
 | 
			
		||||
        clearValues[1].depthStencil = {1.0f, 0};
 | 
			
		||||
        renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
 | 
			
		||||
        renderPassInfo.pClearValues = clearValues.data();
 | 
			
		||||
 | 
			
		||||
            vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
 | 
			
		||||
        vkCmdBeginRenderPass(commandBuffers[imageIndex], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
 | 
			
		||||
 | 
			
		||||
            pipeline->bind(commandBuffers[i]);
 | 
			
		||||
            model->bind(commandBuffers[i]);
 | 
			
		||||
            model->draw(commandBuffers[i]);
 | 
			
		||||
        pipeline->bind(commandBuffers[imageIndex]);
 | 
			
		||||
        model->bind(commandBuffers[imageIndex]);
 | 
			
		||||
        model->draw(commandBuffers[imageIndex]);
 | 
			
		||||
 | 
			
		||||
            vkCmdEndRenderPass(commandBuffers[i]);
 | 
			
		||||
            if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS)
 | 
			
		||||
            {
 | 
			
		||||
                throw std::runtime_error("failed to record command buffer!");
 | 
			
		||||
            }
 | 
			
		||||
        vkCmdEndRenderPass(commandBuffers[imageIndex]);
 | 
			
		||||
        if (vkEndCommandBuffer(commandBuffers[imageIndex]) != VK_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            throw std::runtime_error("failed to record command buffer!");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void FirstApp::drawFrame()
 | 
			
		||||
    {
 | 
			
		||||
        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)
 | 
			
		||||
        {
 | 
			
		||||
            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)
 | 
			
		||||
        {
 | 
			
		||||
            throw std::runtime_error("failed to present swap chain image!");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,10 +32,12 @@ namespace hk
 | 
			
		|||
        void createPipeline();
 | 
			
		||||
        void createCommandBuffers();
 | 
			
		||||
        void drawFrame();
 | 
			
		||||
        void recreateSwapChain();
 | 
			
		||||
        void recordCommandBuffer(int imageIndex);
 | 
			
		||||
 | 
			
		||||
        Window window{WIDTH, HEIGHT, "Hello Vulkan!"};
 | 
			
		||||
        Device device{window};
 | 
			
		||||
        SwapChain swapChain{device, window.getExtend()};
 | 
			
		||||
        std::unique_ptr<SwapChain> swapChain;
 | 
			
		||||
        std::unique_ptr<Pipeline> pipeline;
 | 
			
		||||
        VkPipelineLayout pipelineLayout;
 | 
			
		||||
        std::vector<VkCommandBuffer> commandBuffers;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,16 @@ namespace hk
 | 
			
		|||
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
 | 
			
		||||
 | 
			
		||||
        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); }
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        static void framebufferResizeCallback(GLFWwindow* window, int width, int height);
 | 
			
		||||
        void initWindow();
 | 
			
		||||
 | 
			
		||||
        const int m_width;
 | 
			
		||||
        const int m_height;
 | 
			
		||||
        int m_width;
 | 
			
		||||
        int m_height;
 | 
			
		||||
        bool m_framebufferResized = false;
 | 
			
		||||
 | 
			
		||||
        std::string m_windowName;
 | 
			
		||||
        GLFWwindow *m_window;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue