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

feature/imgui-sdl points-test
Last change on this file since e09ad38 was e09ad38, checked in by Dmitry Portnoy <dmp1488@…>, 6 years ago

Create the pipeline shader stage

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