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
RevLine 
[826df16]1#include <vulkan/vulkan.h>
[03f4c64]2
[826df16]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>
[03f4c64]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>
[826df16]14#include <vector>
[b3671b5]15#include <set>
[826df16]16#include <stdexcept>
17#include <cstdlib>
[909b51a]18#include <optional>
[bfd620e]19#include <algorithm>
[826df16]20
21#include "game-gui-sdl.hpp"
[03f4c64]22
23using namespace std;
[bfd620e]24//using namespace glm;
[03f4c64]25
[826df16]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
[bfd620e]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
[909b51a]43struct QueueFamilyIndices {
44 optional<uint32_t> graphicsFamily;
[b3671b5]45 optional<uint32_t> presentFamily;
[909b51a]46
47 bool isComplete() {
[b3671b5]48 return graphicsFamily.has_value() && presentFamily.has_value();
[909b51a]49 }
50};
51
[bfd620e]52struct SwapChainSupportDetails {
53 VkSurfaceCapabilitiesKHR capabilities;
54 vector<VkSurfaceFormatKHR> formats;
55 vector<VkPresentModeKHR> presentModes;
56};
57
[b6127d2]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
[80de39d]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
[826df16]93class VulkanGame {
94 public:
95 void run() {
96 if (initWindow() == RTWO_ERROR) {
97 return;
98 }
99 initVulkan();
100 mainLoop();
101 cleanup();
102 }
103 private:
[98f3232]104 GameGui* gui = new GameGui_SDL();
[80de39d]105 SDL_Window* window = nullptr;
[826df16]106
107 VkInstance instance;
[b6127d2]108 VkDebugUtilsMessengerEXT debugMessenger;
[b3671b5]109 VkSurfaceKHR surface;
[321272c]110 SDL_Surface* sdlSurface = nullptr;
[b3671b5]111
[909b51a]112 VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
113 VkDevice device;
[b3671b5]114
[909b51a]115 VkQueue graphicsQueue;
[b3671b5]116 VkQueue presentQueue;
[826df16]117
[bfd620e]118 VkSwapchainKHR swapChain;
119 vector<VkImage> swapChainImages;
120 VkFormat swapChainImageFormat;
121 VkExtent2D swapChainExtent;
122
123 vector<VkImageView> swapChainImageViews;
124
[826df16]125 // both SDL and GLFW create window functions return NULL on failure
126 bool initWindow() {
[98f3232]127 if (gui->Init() == RTWO_ERROR) {
[826df16]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
[80de39d]140 if (window == nullptr) {
[826df16]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();
[7dcd925]151 setupDebugMessenger();
[b3671b5]152 createSurface();
[909b51a]153 pickPhysicalDevice();
154 createLogicalDevice();
[bfd620e]155 createSwapChain();
156 createImageViews();
[4befb76]157 createGraphicsPipeline();
[826df16]158 }
159
160 void createInstance() {
[b6127d2]161 if (enableValidationLayers && !checkValidationLayerSupport()) {
162 throw runtime_error("validation layers requested, but not available!");
163 }
164
[826df16]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
[a8f0577]177 vector<const char*> extensions = getRequiredExtensions();
[b6127d2]178 createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
179 createInfo.ppEnabledExtensionNames = extensions.data();
[826df16]180
[b3671b5]181 cout << endl << "SDL extensions:" << endl;
182 for (const char* extensionName : extensions) {
183 cout << extensionName << endl;
184 }
185 cout << endl;
186
[80de39d]187 VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo;
[b6127d2]188 if (enableValidationLayers) {
189 createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
190 createInfo.ppEnabledLayerNames = validationLayers.data();
[80de39d]191
192 populateDebugMessengerCreateInfo(debugCreateInfo);
193 createInfo.pNext = &debugCreateInfo;
[b6127d2]194 } else {
195 createInfo.enabledLayerCount = 0;
[80de39d]196
197 createInfo.pNext = nullptr;
[b6127d2]198 }
[826df16]199
200 if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
201 throw runtime_error("failed to create instance!");
202 }
203 }
204
[80de39d]205 void setupDebugMessenger() {
206 if (!enableValidationLayers) return;
207
208 VkDebugUtilsMessengerCreateInfoEXT createInfo;
209 populateDebugMessengerCreateInfo(createInfo);
[b6127d2]210
211 if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) {
212 throw runtime_error("failed to setup debug messenger!");
213 }
214 }
215
[b3671b5]216 void createSurface() {
[321272c]217 sdlSurface = SDL_GetWindowSurface(window);
218
219 if (sdlSurface == nullptr) {
220 cout << "Could not get SDL Surface! =(" << endl;
221 }
[b3671b5]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
[909b51a]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
[bfd620e]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();
[909b51a]296 }
297
298 void createLogicalDevice() {
299 QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
300
[b3671b5]301 vector<VkDeviceQueueCreateInfo> queueCreateInfos;
302 set<uint32_t> uniqueQueueFamilies = {indices.graphicsFamily.value(), indices.presentFamily.value()};
[909b51a]303
304 float queuePriority = 1.0f;
[b3671b5]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 }
[909b51a]315
316 VkPhysicalDeviceFeatures deviceFeatures = {};
317
318 VkDeviceCreateInfo createInfo = {};
319 createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
320
[b3671b5]321 createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());;
322 createInfo.pQueueCreateInfos = queueCreateInfos.data();
[909b51a]323
324 createInfo.pEnabledFeatures = &deviceFeatures;
325
[bfd620e]326 createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
327 createInfo.ppEnabledExtensionNames = deviceExtensions.data();
[909b51a]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);
[b3671b5]343 vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
[909b51a]344 }
345
[a8f0577]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
[909b51a]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
[b3671b5]386 VkBool32 presentSupport = false;
387 vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
388
389 if (queueFamily.queueCount > 0 && presentSupport) {
390 indices.presentFamily = i;
391 }
392
[909b51a]393 if (indices.isComplete()) {
394 break;
395 }
396
397 i++;
398 }
399
400 return indices;
401 }
402
[bfd620e]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
[909b51a]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
[a8f0577]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
[bfd620e]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
[4befb76]569 void createGraphicsPipeline() {
570 }
571
[826df16]572 void mainLoop() {
573 // TODO: Create some generic event-handling functions in game-gui-*
574 SDL_Event e;
575 bool quit = false;
576
[7dcd925]577 while (!quit) {
[826df16]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 }
[321272c]588
[bfd620e]589 /*
590 SDL_FillRect(sdlSurface, nullptr, SDL_MapRGB(sdlSurface->format, 0xFF, 0xFF, 0xFF));
[321272c]591
[bfd620e]592 SDL_UpdateWindowSurface(window);
593 */
594 }
595 }
[826df16]596 }
597
598 void cleanup() {
[bfd620e]599 for (auto imageView : swapChainImageViews) {
600 vkDestroyImageView(device, imageView, nullptr);
601 }
602
603 vkDestroySwapchainKHR(device, swapChain, nullptr);
[909b51a]604 vkDestroyDevice(device, nullptr);
605
[80de39d]606 if (enableValidationLayers) {
607 DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
608 }
609
[b3671b5]610 vkDestroySurfaceKHR(instance, surface, nullptr);
[826df16]611 vkDestroyInstance(instance, nullptr);
612
613 // TODO: Move this into some generic method in game-gui-sdl
614 SDL_DestroyWindow(window);
615
[98f3232]616 gui->Shutdown();
617 delete gui;
[826df16]618 }
619};
620
[1c6cd5e]621int main(int argc, char* argv[]) {
[826df16]622
[b6127d2]623#ifdef NDEBUG
624 cout << "DEBUGGING IS OFF" << endl;
625#else
626 cout << "DEBUGGING IS ON" << endl;
627#endif
[a8f0577]628
[bfd620e]629 glm::mat4 matrix;
630 glm::vec4 vec;
631 glm::vec4 test = matrix * vec;
[826df16]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 }
[03f4c64]643
[826df16]644 cout << "Finished running the game" << endl;
[03f4c64]645
[826df16]646 return EXIT_SUCCESS;
[03f4c64]647}
Note: See TracBrowser for help on using the repository browser.