Complete "Hello Triangle" program with resizing and minimization handled
This commit is contained in:
parent
54e69982eb
commit
75e9921d45
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,3 @@
|
||||
.cache/
|
||||
.vscode/
|
||||
build/
|
||||
|
||||
|
||||
@ -42,6 +42,13 @@ add_executable(${EXE_NAME} ${CMAKE_SOURCE_DIR}/src/main.cc ${PROGRAM_SOURCES} ${
|
||||
target_include_directories(${EXE_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
||||
add_dependencies(${EXE_NAME} shaders)
|
||||
|
||||
if ( CMAKE_COMPILER_IS_GNUCC )
|
||||
target_compile_options(${EXE_NAME} PRIVATE -Wall -Wextra)
|
||||
endif()
|
||||
if ( MSVC )
|
||||
target_compile_options(${EXE_NAME} PRIVATE /W4)
|
||||
endif()
|
||||
|
||||
# Linking
|
||||
target_link_libraries(${EXE_NAME} PRIVATE SDL2::SDL2)
|
||||
target_link_libraries(${EXE_NAME} PRIVATE Vulkan::Vulkan)
|
||||
@ -17,6 +17,8 @@ const std::vector<const char*> deviceExtensions = {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||
};
|
||||
|
||||
const int MAX_FRAMES_IN_FLIGHT = 2;
|
||||
|
||||
#ifdef NDEBUG
|
||||
const bool enableValidationLayers = false;
|
||||
#else
|
||||
@ -44,7 +46,7 @@ struct SwapChainSupportDetails {
|
||||
class VulkanApp {
|
||||
public:
|
||||
VulkanApp(const uint32_t& _w, const uint32_t& _h) :
|
||||
mWidth(_w), mHeight(_h), mWin(nullptr), mActive(false) {}
|
||||
mWin(nullptr), mWidth(_w), mHeight(_h) {}
|
||||
|
||||
void init();
|
||||
void loop();
|
||||
@ -55,9 +57,11 @@ private:
|
||||
SDL_Event mEvent;
|
||||
|
||||
// Not tied to library
|
||||
const uint32_t mWidth;
|
||||
const uint32_t mHeight;
|
||||
bool mActive;
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
bool mActive = false;
|
||||
bool mResized = false;
|
||||
bool mMinimized = false;
|
||||
|
||||
// Vulkan
|
||||
VkInstance mInstance;
|
||||
@ -77,14 +81,14 @@ private:
|
||||
VkPipeline mGraphicsPipeline;
|
||||
|
||||
VkCommandPool mCommandPool;
|
||||
VkCommandBuffer mCommandBuffer;
|
||||
std::vector<VkCommandBuffer> mCommandBuffers;
|
||||
|
||||
VkQueue mGraphicsQueue;
|
||||
VkQueue mPresentQueue;
|
||||
|
||||
VkSemaphore mImageAvailableSemaphore;
|
||||
VkSemaphore mRenderFinishedSemaphore;
|
||||
VkFence mInFlightFence;
|
||||
std::vector<VkSemaphore> mImageAvailableSemaphores;
|
||||
std::vector<VkSemaphore> mRenderFinishedSemaphores;
|
||||
std::vector<VkFence> mInFlightFences;
|
||||
|
||||
|
||||
VkDebugUtilsMessengerEXT mDebugMessenger;
|
||||
@ -92,7 +96,11 @@ private:
|
||||
void createInstance();
|
||||
void selectPhysicalDevice();
|
||||
void createLogicalDevice();
|
||||
|
||||
void createSwapChain();
|
||||
void recreateSwapChain();
|
||||
void cleanupSwapChain();
|
||||
|
||||
void createImageViews();
|
||||
void createRenderPass();
|
||||
void createGraphicsPipeline();
|
||||
@ -118,7 +126,15 @@ private:
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) {
|
||||
fprintf(stderr, "Validation Layer: %s \n", pCallbackData->pMessage);
|
||||
(void)pUserData;
|
||||
|
||||
if(messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
|
||||
fprintf(stderr, "Validation Layer [Error/Warning]: %s \n", pCallbackData->pMessage);
|
||||
} else if(messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) {
|
||||
fprintf(stderr, "Validation Layer [General]: %s \n", pCallbackData->pMessage);
|
||||
} else {
|
||||
fprintf(stderr, "Validation Layer: %s \n", pCallbackData->pMessage);
|
||||
}
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
@ -2,13 +2,13 @@
|
||||
|
||||
layout(location = 0) out vec3 fragColor;
|
||||
|
||||
vec2 positions[3] = vec2[](
|
||||
const vec2 positions[3] = vec2[](
|
||||
vec2(0.0, -0.5),
|
||||
vec2(0.5, 0.5),
|
||||
vec2(-0.5, 0.5)
|
||||
);
|
||||
|
||||
vec3 colors[3] = vec3[](
|
||||
const vec3 colors[3] = vec3[](
|
||||
vec3(1.0, 0.0, 0.0),
|
||||
vec3(0.0, 1.0, 0.0),
|
||||
vec3(0.0, 0.0, 1.0)
|
||||
|
||||
181
src/vulkanapp.cc
181
src/vulkanapp.cc
@ -83,7 +83,7 @@ QueueFamilyIndices VulkanApp::findQueueFamilies(VkPhysicalDevice device) {
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
|
||||
|
||||
// Get queue families and check them
|
||||
for(int i=0;i<queueFamilies.size();i++) {
|
||||
for(size_t i=0;i<queueFamilies.size();i++) {
|
||||
const VkQueueFamilyProperties& queueFamily = queueFamilies[i];
|
||||
|
||||
VkBool32 presentSupport = false;
|
||||
@ -197,7 +197,7 @@ void VulkanApp::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imag
|
||||
renderPassInfo.renderArea.offset = {0, 0};
|
||||
renderPassInfo.renderArea.extent = mSwapChainExtent;
|
||||
|
||||
VkClearValue clearColor = {{{0.5f, 0.0f, 0.5f, 1.0f}}};
|
||||
VkClearValue clearColor = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
|
||||
renderPassInfo.clearValueCount = 1;
|
||||
renderPassInfo.pClearValues = &clearColor;
|
||||
|
||||
@ -218,6 +218,7 @@ void VulkanApp::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imag
|
||||
scissor.extent = mSwapChainExtent;
|
||||
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
||||
|
||||
// Actually draw the vertices
|
||||
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
|
||||
vkCmdEndRenderPass(commandBuffer);
|
||||
|
||||
@ -227,32 +228,48 @@ void VulkanApp::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imag
|
||||
}
|
||||
|
||||
void VulkanApp::drawFrame() {
|
||||
vkWaitForFences(mLogicalDevice, 1, &mInFlightFence, VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(mLogicalDevice, 1, &mInFlightFence);
|
||||
uint32_t currentFrame = 0;
|
||||
VkResult result = VK_SUCCESS;
|
||||
uint32_t imageIndex = 0;
|
||||
|
||||
uint32_t imageIndex;
|
||||
vkAcquireNextImageKHR(mLogicalDevice, mSwapChain, UINT64_MAX, mImageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
|
||||
vkWaitForFences(mLogicalDevice, 1, &mInFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(mLogicalDevice, 1, &mInFlightFences[currentFrame]);
|
||||
|
||||
vkResetCommandBuffer(mCommandBuffer, /*VkCommandBufferResetFlagBits*/ 0);
|
||||
recordCommandBuffer(mCommandBuffer, imageIndex);
|
||||
|
||||
result = vkAcquireNextImageKHR(mLogicalDevice,
|
||||
mSwapChain,
|
||||
UINT64_MAX,
|
||||
mImageAvailableSemaphores[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("Could not get Vulkan swap chain image!");
|
||||
}
|
||||
|
||||
vkResetFences(mLogicalDevice, 1, &mInFlightFences[currentFrame]);
|
||||
|
||||
vkResetCommandBuffer(mCommandBuffers[currentFrame], /*VkCommandBufferResetFlagBits*/ 0);
|
||||
recordCommandBuffer(mCommandBuffers[currentFrame], imageIndex);
|
||||
|
||||
VkSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
|
||||
VkSemaphore waitSemaphores[] = {mImageAvailableSemaphore};
|
||||
VkSemaphore waitSemaphores[] = {mImageAvailableSemaphores[currentFrame]};
|
||||
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
||||
submitInfo.waitSemaphoreCount = 1;
|
||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||
submitInfo.pWaitDstStageMask = waitStages;
|
||||
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &mCommandBuffer;
|
||||
submitInfo.pCommandBuffers = &mCommandBuffers[currentFrame];
|
||||
|
||||
VkSemaphore signalSemaphores[] = {mRenderFinishedSemaphore};
|
||||
VkSemaphore signalSemaphores[] = {mRenderFinishedSemaphores[currentFrame]};
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||
|
||||
if (vkQueueSubmit(mGraphicsQueue, 1, &submitInfo, mInFlightFence) != VK_SUCCESS) {
|
||||
if (vkQueueSubmit(mGraphicsQueue, 1, &submitInfo, mInFlightFences[currentFrame]) != VK_SUCCESS) {
|
||||
throw std::runtime_error("Could not submit Vulkan command buffer!");
|
||||
}
|
||||
|
||||
@ -268,7 +285,17 @@ void VulkanApp::drawFrame() {
|
||||
|
||||
presentInfo.pImageIndices = &imageIndex;
|
||||
|
||||
vkQueuePresentKHR(mPresentQueue, &presentInfo);
|
||||
result = vkQueuePresentKHR(mPresentQueue, &presentInfo);
|
||||
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || mResized) {
|
||||
mResized = false;
|
||||
recreateSwapChain();
|
||||
return;
|
||||
} else if (result != VK_SUCCESS) {
|
||||
throw std::runtime_error("Could not present Vulkan swap chain image!");
|
||||
}
|
||||
|
||||
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
||||
}
|
||||
|
||||
void VulkanApp::init() {
|
||||
@ -276,18 +303,13 @@ void VulkanApp::init() {
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
|
||||
//SDL_Vulkan_LoadLibrary(nullptr);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// I really hate GNOME
|
||||
SDL_VideoInit("x11");
|
||||
#endif
|
||||
|
||||
// Create the window
|
||||
mWin = SDL_CreateWindow("Vulkan+SDL2 Application",
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
mWidth,
|
||||
mHeight,
|
||||
SDL_WINDOW_SHOWN | SDL_WINDOW_VULKAN
|
||||
SDL_WINDOW_SHOWN | SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE
|
||||
);
|
||||
|
||||
if(mWin == nullptr) {
|
||||
@ -355,8 +377,12 @@ void VulkanApp::createInstance() {
|
||||
|
||||
debugCreateInfo = {};
|
||||
debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
debugCreateInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
debugCreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
debugCreateInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
debugCreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
debugCreateInfo.pfnUserCallback = debugCallback;
|
||||
|
||||
createInfo.pNext = reinterpret_cast<VkDebugUtilsMessengerCreateInfoEXT*>(&debugCreateInfo);
|
||||
@ -415,12 +441,17 @@ void VulkanApp::createLogicalDevice() {
|
||||
}
|
||||
|
||||
VkPhysicalDeviceFeatures deviceFeatures{};
|
||||
|
||||
vkGetPhysicalDeviceFeatures(mPhysicalDevice, &deviceFeatures);
|
||||
|
||||
VkDeviceCreateInfo createInfo{};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
|
||||
createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
|
||||
createInfo.pQueueCreateInfos = queueCreateInfos.data();
|
||||
|
||||
createInfo.pEnabledFeatures = &deviceFeatures;
|
||||
|
||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
|
||||
createInfo.ppEnabledExtensionNames = deviceExtensions.data();
|
||||
|
||||
@ -493,6 +524,28 @@ void VulkanApp::createSwapChain() {
|
||||
mSwapChainExtent = extent;
|
||||
}
|
||||
|
||||
void VulkanApp::recreateSwapChain() {
|
||||
vkDeviceWaitIdle(mLogicalDevice);
|
||||
|
||||
cleanupSwapChain();
|
||||
|
||||
createSwapChain();
|
||||
createImageViews();
|
||||
createFramebuffers();
|
||||
}
|
||||
|
||||
void VulkanApp::cleanupSwapChain() {
|
||||
for (VkFramebuffer framebuffer : mSwapChainFramebuffers) {
|
||||
vkDestroyFramebuffer(mLogicalDevice, framebuffer, nullptr);
|
||||
}
|
||||
|
||||
for (VkImageView imageView : mSwapChainImageViews) {
|
||||
vkDestroyImageView(mLogicalDevice, imageView, nullptr);
|
||||
}
|
||||
|
||||
vkDestroySwapchainKHR(mLogicalDevice, mSwapChain, nullptr);
|
||||
}
|
||||
|
||||
void VulkanApp::createImageViews() {
|
||||
mSwapChainImageViews.resize(mSwapChainImages.size());
|
||||
|
||||
@ -652,7 +705,12 @@ void VulkanApp::createGraphicsPipeline() {
|
||||
pipelineInfo.subpass = 0;
|
||||
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
|
||||
if (vkCreateGraphicsPipelines(mLogicalDevice, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &mGraphicsPipeline) != VK_SUCCESS) {
|
||||
if (vkCreateGraphicsPipelines(mLogicalDevice,
|
||||
VK_NULL_HANDLE,
|
||||
1,
|
||||
&pipelineInfo,
|
||||
nullptr,
|
||||
&mGraphicsPipeline) != VK_SUCCESS) {
|
||||
throw std::runtime_error("Could not create Vulkan graphics pipeline!");
|
||||
}
|
||||
|
||||
@ -699,18 +757,24 @@ void VulkanApp::createCommandPool() {
|
||||
}
|
||||
|
||||
void VulkanApp::createCommandBuffer() {
|
||||
mCommandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
|
||||
VkCommandBufferAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
allocInfo.commandPool = mCommandPool;
|
||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
allocInfo.commandBufferCount = 1;
|
||||
allocInfo.commandBufferCount = static_cast<uint32_t>(mCommandBuffers.size());
|
||||
|
||||
if (vkAllocateCommandBuffers(mLogicalDevice, &allocInfo, &mCommandBuffer) != VK_SUCCESS) {
|
||||
if (vkAllocateCommandBuffers(mLogicalDevice, &allocInfo, mCommandBuffers.data()) != VK_SUCCESS) {
|
||||
throw std::runtime_error("Could not allocate Vulkan command buffers!");
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanApp::createSyncObjects() {
|
||||
mImageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
mRenderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
mInFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
|
||||
VkSemaphoreCreateInfo semaphoreInfo{};
|
||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
|
||||
@ -718,14 +782,15 @@ void VulkanApp::createSyncObjects() {
|
||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
|
||||
VkResult imageAvailableResult = vkCreateSemaphore(mLogicalDevice, &semaphoreInfo, nullptr, &mImageAvailableSemaphore);
|
||||
VkResult renderFinishedResult = vkCreateSemaphore(mLogicalDevice, &semaphoreInfo, nullptr, &mRenderFinishedSemaphore);
|
||||
VkResult inFlightResult = vkCreateFence(mLogicalDevice, &fenceInfo, nullptr, &mInFlightFence);
|
||||
for(size_t i = 0;i<MAX_FRAMES_IN_FLIGHT;i++) {
|
||||
VkResult imageAvailableResult = vkCreateSemaphore(mLogicalDevice, &semaphoreInfo, nullptr, &mImageAvailableSemaphores[i]);
|
||||
VkResult renderFinishedResult = vkCreateSemaphore(mLogicalDevice, &semaphoreInfo, nullptr, &mRenderFinishedSemaphores[i]);
|
||||
VkResult inFlightResult = vkCreateFence(mLogicalDevice, &fenceInfo, nullptr, &mInFlightFences[i]);
|
||||
|
||||
if(imageAvailableResult != VK_SUCCESS || renderFinishedResult != VK_SUCCESS || inFlightResult != VK_SUCCESS) {
|
||||
throw std::runtime_error("Could not create needed semaphores or other memory handling objects for Vulkan!");
|
||||
if(imageAvailableResult != VK_SUCCESS || renderFinishedResult != VK_SUCCESS || inFlightResult != VK_SUCCESS) {
|
||||
throw std::runtime_error("Could not create needed semaphores or other memory handling objects for Vulkan!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool VulkanApp::checkDeviceExtensionSupport(VkPhysicalDevice device) {
|
||||
@ -775,8 +840,12 @@ void VulkanApp::setupDebugMessenger() {
|
||||
VkDebugUtilsMessengerCreateInfoEXT createInfo;
|
||||
createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
createInfo.pfnUserCallback = debugCallback;
|
||||
|
||||
if (CreateDebugUtilsMessengerEXT(mInstance, &createInfo, nullptr, &mDebugMessenger) != VK_SUCCESS) {
|
||||
@ -796,18 +865,37 @@ void VulkanApp::loop() {
|
||||
|
||||
// Main loop
|
||||
while(mActive) {
|
||||
while(SDL_PollEvent(&mEvent))
|
||||
if(mEvent.type == SDL_QUIT) {
|
||||
while(SDL_PollEvent(&mEvent)) {
|
||||
switch (mEvent.type) {
|
||||
case SDL_QUIT:
|
||||
mActive = false;
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
switch(mEvent.window.event) {
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
mResized = true;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MINIMIZED:
|
||||
mMinimized = true;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
mMinimized = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//SDL_SetRenderDrawColor(rend, 255, 0, 0, 255);
|
||||
//SDL_RenderClear(rend);
|
||||
|
||||
//SDL_RenderPresent(rend);
|
||||
drawFrame();
|
||||
SDL_ShowWindow(mWin);
|
||||
|
||||
if(!mMinimized) drawFrame();
|
||||
}
|
||||
|
||||
vkDeviceWaitIdle(mLogicalDevice);
|
||||
@ -815,30 +903,27 @@ void VulkanApp::loop() {
|
||||
}
|
||||
|
||||
void VulkanApp::cleanup() {
|
||||
vkDestroySemaphore(mLogicalDevice, mImageAvailableSemaphore, nullptr);
|
||||
vkDestroySemaphore(mLogicalDevice, mRenderFinishedSemaphore, nullptr);
|
||||
vkDestroyFence(mLogicalDevice, mInFlightFence, nullptr);
|
||||
|
||||
vkDestroyCommandPool(mLogicalDevice, mCommandPool, nullptr);
|
||||
|
||||
for (VkFramebuffer framebuffer : mSwapChainFramebuffers) {
|
||||
vkDestroyFramebuffer(mLogicalDevice, framebuffer, nullptr);
|
||||
}
|
||||
cleanupSwapChain();
|
||||
|
||||
vkDestroyPipeline(mLogicalDevice, mGraphicsPipeline, nullptr);
|
||||
vkDestroyPipelineLayout(mLogicalDevice, mPipelineLayout, nullptr);
|
||||
|
||||
vkDestroyRenderPass(mLogicalDevice, mRenderPass, nullptr);
|
||||
|
||||
for (VkImageView imageView : mSwapChainImageViews) {
|
||||
vkDestroyImageView(mLogicalDevice, imageView, nullptr);
|
||||
for(size_t i=0;i<MAX_FRAMES_IN_FLIGHT;i++) {
|
||||
vkDestroySemaphore(mLogicalDevice, mImageAvailableSemaphores[i], nullptr);
|
||||
vkDestroySemaphore(mLogicalDevice, mRenderFinishedSemaphores[i], nullptr);
|
||||
vkDestroyFence(mLogicalDevice, mInFlightFences[i], nullptr);
|
||||
}
|
||||
|
||||
vkDestroySwapchainKHR(mLogicalDevice, mSwapChain, nullptr);
|
||||
vkDestroyCommandPool(mLogicalDevice, mCommandPool, nullptr);
|
||||
|
||||
vkDestroyDevice(mLogicalDevice, nullptr);
|
||||
|
||||
if (enableValidationLayers) {
|
||||
DestroyDebugUtilsMessengerEXT(mInstance, mDebugMessenger, nullptr);
|
||||
}
|
||||
|
||||
vkDestroySurfaceKHR(mInstance, mSurface, nullptr);
|
||||
vkDestroyInstance(mInstance, nullptr);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user