source: opengl-game/vulkan-game.cpp@ bfd620e

feature/imgui-sdl points-test
Last change on this file since bfd620e was bfd620e, checked in by Dmitry Portnoy <dmitry.portnoy@…>, 5 years ago

Create the swap chain

  • Property mode set to 100644
File size: 22.1 KB
Line 
1#include <vulkan/vulkan.h>
2
3#include <SDL2/SDL.h>
4#include <SDL2/SDL_vulkan.h>
5
6//#define _USE_MATH_DEFINES // Will be needed when/if I need to # include <cmath>
7
8#define GLM_FORCE_RADIANS
9#define GLM_FORCE_DEPTH_ZERO_TO_ONE
10#include <glm/vec4.hpp>
11#include <glm/mat4x4.hpp>
12
13#include <iostream>
14#include <vector>
15#include <set>
16#include <stdexcept>
17#include <cstdlib>
18#include <optional>
19#include <algorithm>
20
21#include "game-gui-sdl.hpp"
22
23using namespace std;
24//using namespace glm;
25
26const int SCREEN_WIDTH = 800;
27const int SCREEN_HEIGHT = 600;
28
29#ifdef NDEBUG
30 const bool enableValidationLayers = false;
31#else
32 const bool enableValidationLayers = true;
33#endif
34
35const vector<const char*> validationLayers = {
36 "VK_LAYER_KHRONOS_validation"
37};
38
39const vector<const char*> deviceExtensions = {
40 VK_KHR_SWAPCHAIN_EXTENSION_NAME
41};
42
43struct QueueFamilyIndices {
44 optional<uint32_t> graphicsFamily;
45 optional<uint32_t> presentFamily;
46
47 bool isComplete() {
48 return graphicsFamily.has_value() && presentFamily.has_value();
49 }
50};
51
52struct SwapChainSupportDetails {
53 VkSurfaceCapabilitiesKHR capabilities;
54 vector<VkSurfaceFormatKHR> formats;
55 vector<VkPresentModeKHR> presentModes;
56};
57
58static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
59 VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
60 VkDebugUtilsMessageTypeFlagsEXT messageType,
61 const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
62 void* pUserData) {
63 cerr << "validation layer: " << pCallbackData->pMessage << endl;
64
65 return VK_FALSE;
66}
67
68VkResult CreateDebugUtilsMessengerEXT(VkInstance instance,
69 const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
70 const VkAllocationCallbacks* pAllocator,
71 VkDebugUtilsMessengerEXT* pDebugMessenger) {
72 auto func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(
73 instance, "vkCreateDebugUtilsMessengerEXT");
74
75 if (func != nullptr) {
76 return func(instance, pCreateInfo, pAllocator, pDebugMessenger);
77 } else {
78 return VK_ERROR_EXTENSION_NOT_PRESENT;
79 }
80}
81
82void DestroyDebugUtilsMessengerEXT(VkInstance instance,
83 VkDebugUtilsMessengerEXT debugMessenger,
84 const VkAllocationCallbacks* pAllocator) {
85 auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(
86 instance, "vkDestroyDebugUtilsMessengerEXT");
87
88 if (func != nullptr) {
89 func(instance, debugMessenger, pAllocator);
90 }
91}
92
93class VulkanGame {
94 public:
95 void run() {
96 if (initWindow() == RTWO_ERROR) {
97 return;
98 }
99 initVulkan();
100 mainLoop();
101 cleanup();
102 }
103 private:
104 GameGui* gui = new GameGui_SDL();
105 SDL_Window* window = nullptr;
106
107 VkInstance instance;
108 VkDebugUtilsMessengerEXT debugMessenger;
109 VkSurfaceKHR surface;
110 SDL_Surface* sdlSurface = nullptr;
111
112 VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
113 VkDevice device;
114
115 VkQueue graphicsQueue;
116 VkQueue presentQueue;
117
118 VkSwapchainKHR swapChain;
119 vector<VkImage> swapChainImages;
120 VkFormat swapChainImageFormat;
121 VkExtent2D swapChainExtent;
122
123 vector<VkImageView> swapChainImageViews;
124
125 // both SDL and GLFW create window functions return NULL on failure
126 bool initWindow() {
127 if (gui->Init() == RTWO_ERROR) {
128 cout << "UI library could not be initialized!" << endl;
129 return RTWO_ERROR;
130 } else {
131 // On Apple's OS X you must set the NSHighResolutionCapable Info.plist property to YES,
132 // otherwise you will not receive a High DPI OpenGL canvas.
133
134 // TODO: Move this into some generic method in game-gui-sdl
135 window = SDL_CreateWindow("Vulkan Game",
136 SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
137 SCREEN_WIDTH, SCREEN_HEIGHT,
138 SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN);
139
140 if (window == nullptr) {
141 cout << "Window could not be created!" << endl;
142 return RTWO_ERROR;
143 } else {
144 return RTWO_SUCCESS;
145 }
146 }
147 }
148
149 void initVulkan() {
150 createInstance();
151 setupDebugMessenger();
152 createSurface();
153 pickPhysicalDevice();
154 createLogicalDevice();
155 createSwapChain();
156 createImageViews();
157 }
158
159 void createInstance() {
160 if (enableValidationLayers && !checkValidationLayerSupport()) {
161 throw runtime_error("validation layers requested, but not available!");
162 }
163
164 VkApplicationInfo appInfo = {};
165 appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
166 appInfo.pApplicationName = "Vulkan Game";
167 appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
168 appInfo.pEngineName = "No Engine";
169 appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
170 appInfo.apiVersion = VK_API_VERSION_1_0;
171
172 VkInstanceCreateInfo createInfo = {};
173 createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
174 createInfo.pApplicationInfo = &appInfo;
175
176 vector<const char*> extensions = getRequiredExtensions();
177 createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
178 createInfo.ppEnabledExtensionNames = extensions.data();
179
180 cout << endl << "SDL extensions:" << endl;
181 for (const char* extensionName : extensions) {
182 cout << extensionName << endl;
183 }
184 cout << endl;
185
186 VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo;
187 if (enableValidationLayers) {
188 createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
189 createInfo.ppEnabledLayerNames = validationLayers.data();
190
191 populateDebugMessengerCreateInfo(debugCreateInfo);
192 createInfo.pNext = &debugCreateInfo;
193 } else {
194 createInfo.enabledLayerCount = 0;
195
196 createInfo.pNext = nullptr;
197 }
198
199 if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
200 throw runtime_error("failed to create instance!");
201 }
202 }
203
204 void setupDebugMessenger() {
205 if (!enableValidationLayers) return;
206
207 VkDebugUtilsMessengerCreateInfoEXT createInfo;
208 populateDebugMessengerCreateInfo(createInfo);
209
210 if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) {
211 throw runtime_error("failed to setup debug messenger!");
212 }
213 }
214
215 void createSurface() {
216 sdlSurface = SDL_GetWindowSurface(window);
217
218 if (sdlSurface == nullptr) {
219 cout << "Could not get SDL Surface! =(" << endl;
220 }
221
222 if (!SDL_Vulkan_CreateSurface(window, instance, &surface)) {
223 throw runtime_error("failed to create window surface!");
224 }
225
226 /*
227 if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) {
228 throw runtime_error("failed to create window surface!");
229 }
230 */
231 }
232
233 void pickPhysicalDevice() {
234 uint32_t deviceCount = 0;
235 vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
236
237 if (deviceCount == 0) {
238 throw runtime_error("failed to find GPUs with Vulkan support!");
239 }
240
241 vector<VkPhysicalDevice> devices(deviceCount);
242 vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
243
244 cout << endl << "Graphics cards:" << endl;
245 for (const VkPhysicalDevice& device : devices) {
246 if (isDeviceSuitable(device)) {
247 physicalDevice = device;
248 break;
249 }
250 }
251 cout << endl;
252
253 if (physicalDevice == VK_NULL_HANDLE) {
254 throw runtime_error("failed to find a suitable GPU!");
255 }
256 }
257
258 bool isDeviceSuitable(VkPhysicalDevice device) {
259 VkPhysicalDeviceProperties deviceProperties;
260 VkPhysicalDeviceFeatures deviceFeatures;
261
262 vkGetPhysicalDeviceProperties(device, &deviceProperties);
263 vkGetPhysicalDeviceFeatures(device, &deviceFeatures);
264
265 cout << "Device: " << deviceProperties.deviceName << endl;
266
267 QueueFamilyIndices indices = findQueueFamilies(device);
268
269 bool extensionsSupported = checkDeviceExtensionSupport(device);
270
271 bool swapChainAdequate = false;
272
273 if (extensionsSupported) {
274 SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device);
275 swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.presentModes.empty();
276 }
277
278 return indices.isComplete() && extensionsSupported && swapChainAdequate;
279 }
280
281 bool checkDeviceExtensionSupport(VkPhysicalDevice device) {
282 uint32_t extensionCount;
283 vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
284
285 vector<VkExtensionProperties> availableExtensions(extensionCount);
286 vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
287
288 set<string> requiredExtensions(deviceExtensions.begin(), deviceExtensions.end());
289
290 for (const auto& extension : availableExtensions) {
291 requiredExtensions.erase(extension.extensionName);
292 }
293
294 return requiredExtensions.empty();
295 }
296
297 void createLogicalDevice() {
298 QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
299
300 vector<VkDeviceQueueCreateInfo> queueCreateInfos;
301 set<uint32_t> uniqueQueueFamilies = {indices.graphicsFamily.value(), indices.presentFamily.value()};
302
303 float queuePriority = 1.0f;
304 for (uint32_t queueFamily : uniqueQueueFamilies) {
305 VkDeviceQueueCreateInfo queueCreateInfo = {};
306
307 queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
308 queueCreateInfo.queueFamilyIndex = queueFamily;
309 queueCreateInfo.queueCount = 1;
310 queueCreateInfo.pQueuePriorities = &queuePriority;
311
312 queueCreateInfos.push_back(queueCreateInfo);
313 }
314
315 VkPhysicalDeviceFeatures deviceFeatures = {};
316
317 VkDeviceCreateInfo createInfo = {};
318 createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
319
320 createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());;
321 createInfo.pQueueCreateInfos = queueCreateInfos.data();
322
323 createInfo.pEnabledFeatures = &deviceFeatures;
324
325 createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
326 createInfo.ppEnabledExtensionNames = deviceExtensions.data();
327
328 // These fields are ignored by up-to-date Vulkan implementations,
329 // but it's a good idea to set them for backwards compatibility
330 if (enableValidationLayers) {
331 createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
332 createInfo.ppEnabledLayerNames = validationLayers.data();
333 } else {
334 createInfo.enabledLayerCount = 0;
335 }
336
337 if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
338 throw runtime_error("failed to create logical device!");
339 }
340
341 vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
342 vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
343 }
344
345 bool checkValidationLayerSupport() {
346 uint32_t layerCount;
347 vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
348
349 vector<VkLayerProperties> availableLayers(layerCount);
350 vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
351
352 for (const char* layerName : validationLayers) {
353 bool layerFound = false;
354
355 for (const auto& layerProperties : availableLayers) {
356 if (strcmp(layerName, layerProperties.layerName) == 0) {
357 layerFound = true;
358 break;
359 }
360 }
361
362 if (!layerFound) {
363 return false;
364 }
365 }
366
367 return true;
368 }
369
370 QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) {
371 QueueFamilyIndices indices;
372
373 uint32_t queueFamilyCount = 0;
374 vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
375
376 vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
377 vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
378
379 int i = 0;
380 for (const auto& queueFamily : queueFamilies) {
381 if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
382 indices.graphicsFamily = i;
383 }
384
385 VkBool32 presentSupport = false;
386 vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
387
388 if (queueFamily.queueCount > 0 && presentSupport) {
389 indices.presentFamily = i;
390 }
391
392 if (indices.isComplete()) {
393 break;
394 }
395
396 i++;
397 }
398
399 return indices;
400 }
401
402 SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device) {
403 SwapChainSupportDetails details;
404
405 vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
406
407 uint32_t formatCount;
408 vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
409
410 if (formatCount != 0) {
411 details.formats.resize(formatCount);
412 vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
413 }
414
415 uint32_t presentModeCount;
416 vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr);
417
418 if (presentModeCount != 0) {
419 details.presentModes.resize(presentModeCount);
420 vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.presentModes.data());
421 }
422
423 return details;
424 }
425
426 VkSurfaceFormatKHR chooseSwapSurfaceFormat(const vector<VkSurfaceFormatKHR>& availableFormats) {
427 for (const auto& availableFormat : availableFormats) {
428 if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
429 return availableFormat;
430 }
431 }
432
433 return availableFormats[0];
434 }
435
436 VkPresentModeKHR chooseSwapPresentMode(const vector<VkPresentModeKHR>& availablePresentModes) {
437 VkPresentModeKHR bestMode = VK_PRESENT_MODE_FIFO_KHR;
438
439 for (const auto& availablePresentMode : availablePresentModes) {
440 if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
441 return availablePresentMode;
442 } else if (availablePresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
443 bestMode = availablePresentMode;
444 }
445 }
446
447 return bestMode;
448 }
449
450 VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) {
451 if (capabilities.currentExtent.width != numeric_limits<uint32_t>::max()) {
452 return capabilities.currentExtent;
453 } else {
454 VkExtent2D actualExtent = { SCREEN_WIDTH, SCREEN_HEIGHT };
455
456 actualExtent.width = max(capabilities.minImageExtent.width, min(capabilities.maxImageExtent.width, actualExtent.width));
457 actualExtent.height = max(capabilities.minImageExtent.height, min(capabilities.maxImageExtent.height, actualExtent.height));
458
459 return actualExtent;
460 }
461 }
462
463 void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo) {
464 createInfo = {};
465 createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
466 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;
467 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;
468 createInfo.pfnUserCallback = debugCallback;
469 }
470
471 vector<const char*> getRequiredExtensions() {
472 uint32_t extensionCount = 0;
473 SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, nullptr);
474
475 vector<const char*> extensions(extensionCount);
476 SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, extensions.data());
477
478 if (enableValidationLayers) {
479 extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
480 }
481
482 return extensions;
483 }
484
485 void createSwapChain() {
486 SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);
487
488 VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
489 VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes);
490 VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities);
491
492 uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
493 if (swapChainSupport.capabilities.maxImageCount > 0 &&
494 imageCount > swapChainSupport.capabilities.maxImageCount) {
495 imageCount = swapChainSupport.capabilities.maxImageCount;
496 }
497
498 VkSwapchainCreateInfoKHR createInfo = {};
499
500 createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
501 createInfo.surface = surface;
502 createInfo.minImageCount = imageCount;
503 createInfo.imageFormat = surfaceFormat.format;
504 createInfo.imageColorSpace = surfaceFormat.colorSpace;
505 createInfo.imageExtent = extent;
506 createInfo.imageArrayLayers = 1;
507 createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
508
509 QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
510 uint32_t queueFamilyIndices[] = {indices.graphicsFamily.value(), indices.presentFamily.value()};
511
512 if (indices.graphicsFamily != indices.presentFamily) {
513 createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
514 createInfo.queueFamilyIndexCount = 2;
515 createInfo.pQueueFamilyIndices = queueFamilyIndices;
516 } else {
517 createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
518 createInfo.queueFamilyIndexCount = 0; // Optional
519 createInfo.pQueueFamilyIndices = nullptr;
520 }
521
522 createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
523 createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
524 createInfo.presentMode = presentMode;
525 createInfo.clipped = VK_TRUE;
526 createInfo.oldSwapchain = VK_NULL_HANDLE;
527
528 if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain) != VK_SUCCESS) {
529 throw runtime_error("failed to create swap chain!");
530 }
531
532 vkGetSwapchainImagesKHR(device, swapChain, &imageCount, nullptr);
533 swapChainImages.resize(imageCount);
534 vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImages.data());
535
536 swapChainImageFormat = surfaceFormat.format;
537 swapChainExtent = extent;
538 }
539
540 void createImageViews() {
541 swapChainImageViews.resize(swapChainImages.size());
542
543 for (size_t i=0; i<swapChainImages.size(); i++) {
544 VkImageViewCreateInfo createInfo = {};
545 createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
546 createInfo.image = swapChainImages[i];
547
548 createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
549 createInfo.format = swapChainImageFormat;
550
551 createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
552 createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
553 createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
554 createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
555
556 createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
557 createInfo.subresourceRange.baseMipLevel = 0;
558 createInfo.subresourceRange.levelCount = 1;
559 createInfo.subresourceRange.baseArrayLayer = 0;
560 createInfo.subresourceRange.layerCount = 1;
561
562 if (vkCreateImageView(device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
563 throw runtime_error("failed to create image views!");
564 }
565 }
566 }
567
568 void mainLoop() {
569 // TODO: Create some generic event-handling functions in game-gui-*
570 SDL_Event e;
571 bool quit = false;
572
573 while (!quit) {
574 while (SDL_PollEvent(&e)) {
575 if (e.type == SDL_QUIT) {
576 quit = true;
577 }
578 if (e.type == SDL_KEYDOWN) {
579 quit = true;
580 }
581 if (e.type == SDL_MOUSEBUTTONDOWN) {
582 quit = true;
583 }
584
585 /*
586 SDL_FillRect(sdlSurface, nullptr, SDL_MapRGB(sdlSurface->format, 0xFF, 0xFF, 0xFF));
587
588 SDL_UpdateWindowSurface(window);
589 */
590 }
591 }
592 }
593
594 void cleanup() {
595 for (auto imageView : swapChainImageViews) {
596 vkDestroyImageView(device, imageView, nullptr);
597 }
598
599 vkDestroySwapchainKHR(device, swapChain, nullptr);
600 vkDestroyDevice(device, nullptr);
601
602 if (enableValidationLayers) {
603 DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
604 }
605
606 vkDestroySurfaceKHR(instance, surface, nullptr);
607 vkDestroyInstance(instance, nullptr);
608
609 // TODO: Move this into some generic method in game-gui-sdl
610 SDL_DestroyWindow(window);
611
612 gui->Shutdown();
613 delete gui;
614 }
615};
616
617int main(int argc, char* argv[]) {
618
619#ifdef NDEBUG
620 cout << "DEBUGGING IS OFF" << endl;
621#else
622 cout << "DEBUGGING IS ON" << endl;
623#endif
624
625 glm::mat4 matrix;
626 glm::vec4 vec;
627 glm::vec4 test = matrix * vec;
628
629 cout << "Starting Vulkan game..." << endl;
630
631 VulkanGame game;
632
633 try {
634 game.run();
635 } catch (const exception& e) {
636 cerr << e.what() << endl;
637 return EXIT_FAILURE;
638 }
639
640 cout << "Finished running the game" << endl;
641
642 return EXIT_SUCCESS;
643}
Note: See TracBrowser for help on using the repository browser.