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

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

Create a bash script for compiling shaders to SPIR-V files

  • 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 createGraphicsPipeline();
158 }
159
160 void createInstance() {
161 if (enableValidationLayers && !checkValidationLayerSupport()) {
162 throw runtime_error("validation layers requested, but not available!");
163 }
164
165 VkApplicationInfo appInfo = {};
166 appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
167 appInfo.pApplicationName = "Vulkan Game";
168 appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
169 appInfo.pEngineName = "No Engine";
170 appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
171 appInfo.apiVersion = VK_API_VERSION_1_0;
172
173 VkInstanceCreateInfo createInfo = {};
174 createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
175 createInfo.pApplicationInfo = &appInfo;
176
177 vector<const char*> extensions = getRequiredExtensions();
178 createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
179 createInfo.ppEnabledExtensionNames = extensions.data();
180
181 cout << endl << "SDL extensions:" << endl;
182 for (const char* extensionName : extensions) {
183 cout << extensionName << endl;
184 }
185 cout << endl;
186
187 VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo;
188 if (enableValidationLayers) {
189 createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
190 createInfo.ppEnabledLayerNames = validationLayers.data();
191
192 populateDebugMessengerCreateInfo(debugCreateInfo);
193 createInfo.pNext = &debugCreateInfo;
194 } else {
195 createInfo.enabledLayerCount = 0;
196
197 createInfo.pNext = nullptr;
198 }
199
200 if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
201 throw runtime_error("failed to create instance!");
202 }
203 }
204
205 void setupDebugMessenger() {
206 if (!enableValidationLayers) return;
207
208 VkDebugUtilsMessengerCreateInfoEXT createInfo;
209 populateDebugMessengerCreateInfo(createInfo);
210
211 if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) {
212 throw runtime_error("failed to setup debug messenger!");
213 }
214 }
215
216 void createSurface() {
217 sdlSurface = SDL_GetWindowSurface(window);
218
219 if (sdlSurface == nullptr) {
220 cout << "Could not get SDL Surface! =(" << endl;
221 }
222
223 if (!SDL_Vulkan_CreateSurface(window, instance, &surface)) {
224 throw runtime_error("failed to create window surface!");
225 }
226
227 /*
228 if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) {
229 throw runtime_error("failed to create window surface!");
230 }
231 */
232 }
233
234 void pickPhysicalDevice() {
235 uint32_t deviceCount = 0;
236 vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
237
238 if (deviceCount == 0) {
239 throw runtime_error("failed to find GPUs with Vulkan support!");
240 }
241
242 vector<VkPhysicalDevice> devices(deviceCount);
243 vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
244
245 cout << endl << "Graphics cards:" << endl;
246 for (const VkPhysicalDevice& device : devices) {
247 if (isDeviceSuitable(device)) {
248 physicalDevice = device;
249 break;
250 }
251 }
252 cout << endl;
253
254 if (physicalDevice == VK_NULL_HANDLE) {
255 throw runtime_error("failed to find a suitable GPU!");
256 }
257 }
258
259 bool isDeviceSuitable(VkPhysicalDevice device) {
260 VkPhysicalDeviceProperties deviceProperties;
261 VkPhysicalDeviceFeatures deviceFeatures;
262
263 vkGetPhysicalDeviceProperties(device, &deviceProperties);
264 vkGetPhysicalDeviceFeatures(device, &deviceFeatures);
265
266 cout << "Device: " << deviceProperties.deviceName << endl;
267
268 QueueFamilyIndices indices = findQueueFamilies(device);
269
270 bool extensionsSupported = checkDeviceExtensionSupport(device);
271
272 bool swapChainAdequate = false;
273
274 if (extensionsSupported) {
275 SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device);
276 swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.presentModes.empty();
277 }
278
279 return indices.isComplete() && extensionsSupported && swapChainAdequate;
280 }
281
282 bool checkDeviceExtensionSupport(VkPhysicalDevice device) {
283 uint32_t extensionCount;
284 vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
285
286 vector<VkExtensionProperties> availableExtensions(extensionCount);
287 vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
288
289 set<string> requiredExtensions(deviceExtensions.begin(), deviceExtensions.end());
290
291 for (const auto& extension : availableExtensions) {
292 requiredExtensions.erase(extension.extensionName);
293 }
294
295 return requiredExtensions.empty();
296 }
297
298 void createLogicalDevice() {
299 QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
300
301 vector<VkDeviceQueueCreateInfo> queueCreateInfos;
302 set<uint32_t> uniqueQueueFamilies = {indices.graphicsFamily.value(), indices.presentFamily.value()};
303
304 float queuePriority = 1.0f;
305 for (uint32_t queueFamily : uniqueQueueFamilies) {
306 VkDeviceQueueCreateInfo queueCreateInfo = {};
307
308 queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
309 queueCreateInfo.queueFamilyIndex = queueFamily;
310 queueCreateInfo.queueCount = 1;
311 queueCreateInfo.pQueuePriorities = &queuePriority;
312
313 queueCreateInfos.push_back(queueCreateInfo);
314 }
315
316 VkPhysicalDeviceFeatures deviceFeatures = {};
317
318 VkDeviceCreateInfo createInfo = {};
319 createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
320
321 createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());;
322 createInfo.pQueueCreateInfos = queueCreateInfos.data();
323
324 createInfo.pEnabledFeatures = &deviceFeatures;
325
326 createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
327 createInfo.ppEnabledExtensionNames = deviceExtensions.data();
328
329 // These fields are ignored by up-to-date Vulkan implementations,
330 // but it's a good idea to set them for backwards compatibility
331 if (enableValidationLayers) {
332 createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
333 createInfo.ppEnabledLayerNames = validationLayers.data();
334 } else {
335 createInfo.enabledLayerCount = 0;
336 }
337
338 if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
339 throw runtime_error("failed to create logical device!");
340 }
341
342 vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
343 vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
344 }
345
346 bool checkValidationLayerSupport() {
347 uint32_t layerCount;
348 vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
349
350 vector<VkLayerProperties> availableLayers(layerCount);
351 vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
352
353 for (const char* layerName : validationLayers) {
354 bool layerFound = false;
355
356 for (const auto& layerProperties : availableLayers) {
357 if (strcmp(layerName, layerProperties.layerName) == 0) {
358 layerFound = true;
359 break;
360 }
361 }
362
363 if (!layerFound) {
364 return false;
365 }
366 }
367
368 return true;
369 }
370
371 QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) {
372 QueueFamilyIndices indices;
373
374 uint32_t queueFamilyCount = 0;
375 vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
376
377 vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
378 vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
379
380 int i = 0;
381 for (const auto& queueFamily : queueFamilies) {
382 if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
383 indices.graphicsFamily = i;
384 }
385
386 VkBool32 presentSupport = false;
387 vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
388
389 if (queueFamily.queueCount > 0 && presentSupport) {
390 indices.presentFamily = i;
391 }
392
393 if (indices.isComplete()) {
394 break;
395 }
396
397 i++;
398 }
399
400 return indices;
401 }
402
403 SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device) {
404 SwapChainSupportDetails details;
405
406 vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
407
408 uint32_t formatCount;
409 vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
410
411 if (formatCount != 0) {
412 details.formats.resize(formatCount);
413 vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
414 }
415
416 uint32_t presentModeCount;
417 vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr);
418
419 if (presentModeCount != 0) {
420 details.presentModes.resize(presentModeCount);
421 vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.presentModes.data());
422 }
423
424 return details;
425 }
426
427 VkSurfaceFormatKHR chooseSwapSurfaceFormat(const vector<VkSurfaceFormatKHR>& availableFormats) {
428 for (const auto& availableFormat : availableFormats) {
429 if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
430 return availableFormat;
431 }
432 }
433
434 return availableFormats[0];
435 }
436
437 VkPresentModeKHR chooseSwapPresentMode(const vector<VkPresentModeKHR>& availablePresentModes) {
438 VkPresentModeKHR bestMode = VK_PRESENT_MODE_FIFO_KHR;
439
440 for (const auto& availablePresentMode : availablePresentModes) {
441 if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
442 return availablePresentMode;
443 } else if (availablePresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
444 bestMode = availablePresentMode;
445 }
446 }
447
448 return bestMode;
449 }
450
451 VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) {
452 if (capabilities.currentExtent.width != numeric_limits<uint32_t>::max()) {
453 return capabilities.currentExtent;
454 } else {
455 VkExtent2D actualExtent = { SCREEN_WIDTH, SCREEN_HEIGHT };
456
457 actualExtent.width = max(capabilities.minImageExtent.width, min(capabilities.maxImageExtent.width, actualExtent.width));
458 actualExtent.height = max(capabilities.minImageExtent.height, min(capabilities.maxImageExtent.height, actualExtent.height));
459
460 return actualExtent;
461 }
462 }
463
464 void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo) {
465 createInfo = {};
466 createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
467 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;
468 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;
469 createInfo.pfnUserCallback = debugCallback;
470 }
471
472 vector<const char*> getRequiredExtensions() {
473 uint32_t extensionCount = 0;
474 SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, nullptr);
475
476 vector<const char*> extensions(extensionCount);
477 SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, extensions.data());
478
479 if (enableValidationLayers) {
480 extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
481 }
482
483 return extensions;
484 }
485
486 void createSwapChain() {
487 SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);
488
489 VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
490 VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes);
491 VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities);
492
493 uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
494 if (swapChainSupport.capabilities.maxImageCount > 0 &&
495 imageCount > swapChainSupport.capabilities.maxImageCount) {
496 imageCount = swapChainSupport.capabilities.maxImageCount;
497 }
498
499 VkSwapchainCreateInfoKHR createInfo = {};
500
501 createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
502 createInfo.surface = surface;
503 createInfo.minImageCount = imageCount;
504 createInfo.imageFormat = surfaceFormat.format;
505 createInfo.imageColorSpace = surfaceFormat.colorSpace;
506 createInfo.imageExtent = extent;
507 createInfo.imageArrayLayers = 1;
508 createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
509
510 QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
511 uint32_t queueFamilyIndices[] = {indices.graphicsFamily.value(), indices.presentFamily.value()};
512
513 if (indices.graphicsFamily != indices.presentFamily) {
514 createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
515 createInfo.queueFamilyIndexCount = 2;
516 createInfo.pQueueFamilyIndices = queueFamilyIndices;
517 } else {
518 createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
519 createInfo.queueFamilyIndexCount = 0; // Optional
520 createInfo.pQueueFamilyIndices = nullptr;
521 }
522
523 createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
524 createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
525 createInfo.presentMode = presentMode;
526 createInfo.clipped = VK_TRUE;
527 createInfo.oldSwapchain = VK_NULL_HANDLE;
528
529 if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain) != VK_SUCCESS) {
530 throw runtime_error("failed to create swap chain!");
531 }
532
533 vkGetSwapchainImagesKHR(device, swapChain, &imageCount, nullptr);
534 swapChainImages.resize(imageCount);
535 vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImages.data());
536
537 swapChainImageFormat = surfaceFormat.format;
538 swapChainExtent = extent;
539 }
540
541 void createImageViews() {
542 swapChainImageViews.resize(swapChainImages.size());
543
544 for (size_t i=0; i<swapChainImages.size(); i++) {
545 VkImageViewCreateInfo createInfo = {};
546 createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
547 createInfo.image = swapChainImages[i];
548
549 createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
550 createInfo.format = swapChainImageFormat;
551
552 createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
553 createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
554 createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
555 createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
556
557 createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
558 createInfo.subresourceRange.baseMipLevel = 0;
559 createInfo.subresourceRange.levelCount = 1;
560 createInfo.subresourceRange.baseArrayLayer = 0;
561 createInfo.subresourceRange.layerCount = 1;
562
563 if (vkCreateImageView(device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
564 throw runtime_error("failed to create image views!");
565 }
566 }
567 }
568
569 void createGraphicsPipeline() {
570 }
571
572 void mainLoop() {
573 // TODO: Create some generic event-handling functions in game-gui-*
574 SDL_Event e;
575 bool quit = false;
576
577 while (!quit) {
578 while (SDL_PollEvent(&e)) {
579 if (e.type == SDL_QUIT) {
580 quit = true;
581 }
582 if (e.type == SDL_KEYDOWN) {
583 quit = true;
584 }
585 if (e.type == SDL_MOUSEBUTTONDOWN) {
586 quit = true;
587 }
588
589 /*
590 SDL_FillRect(sdlSurface, nullptr, SDL_MapRGB(sdlSurface->format, 0xFF, 0xFF, 0xFF));
591
592 SDL_UpdateWindowSurface(window);
593 */
594 }
595 }
596 }
597
598 void cleanup() {
599 for (auto imageView : swapChainImageViews) {
600 vkDestroyImageView(device, imageView, nullptr);
601 }
602
603 vkDestroySwapchainKHR(device, swapChain, nullptr);
604 vkDestroyDevice(device, nullptr);
605
606 if (enableValidationLayers) {
607 DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
608 }
609
610 vkDestroySurfaceKHR(instance, surface, nullptr);
611 vkDestroyInstance(instance, nullptr);
612
613 // TODO: Move this into some generic method in game-gui-sdl
614 SDL_DestroyWindow(window);
615
616 gui->Shutdown();
617 delete gui;
618 }
619};
620
621int main(int argc, char* argv[]) {
622
623#ifdef NDEBUG
624 cout << "DEBUGGING IS OFF" << endl;
625#else
626 cout << "DEBUGGING IS ON" << endl;
627#endif
628
629 glm::mat4 matrix;
630 glm::vec4 vec;
631 glm::vec4 test = matrix * vec;
632
633 cout << "Starting Vulkan game..." << endl;
634
635 VulkanGame game;
636
637 try {
638 game.run();
639 } catch (const exception& e) {
640 cerr << e.what() << endl;
641 return EXIT_FAILURE;
642 }
643
644 cout << "Finished running the game" << endl;
645
646 return EXIT_SUCCESS;
647}
Note: See TracBrowser for help on using the repository browser.