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,22 +99,24 @@ 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{};
|
VkCommandBufferBeginInfo beginInfo{};
|
||||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
if (vkBeginCommandBuffer(commandBuffers[i], &beginInfo) != VK_SUCCESS)
|
if (vkBeginCommandBuffer(commandBuffers[imageIndex], &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{};
|
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};
|
||||||
|
@ -108,30 +124,44 @@ namespace hk
|
||||||
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