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

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

Fix validation layer integration

  • Property mode set to 100644
File size: 8.0 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>
15#include <stdexcept>
16#include <cstdlib>
17
18#include "game-gui-sdl.hpp"
[03f4c64]19
20using namespace std;
21using namespace glm;
22
[826df16]23const int SCREEN_WIDTH = 800;
24const int SCREEN_HEIGHT = 600;
25
26const vector<const char*> validationLayers = {
27 "VK_LAYER_KHRONOS_validation"
28};
29
30#ifdef NDEBUG
31 const bool enableValidationLayers = false;
32#else
33 const bool enableValidationLayers = true;
34#endif
35
[b6127d2]36static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
37 VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
38 VkDebugUtilsMessageTypeFlagsEXT messageType,
39 const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
40 void* pUserData) {
41 cerr << "validation layer: " << pCallbackData->pMessage << endl;
42
43 return VK_FALSE;
44}
45
46VkResult CreateDebugUtilsMessengerEXT(VkInstance instance,
47 const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
48 const VkAllocationCallbacks* pAllocator,
49 VkDebugUtilsMessengerEXT* pDebugMessenger) {
50 auto func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(
51 instance, "vkCreateDebugUtilsMessengerEXT");
52
53 if (func != nullptr) {
54 return func(instance, pCreateInfo, pAllocator, pDebugMessenger);
55 } else {
56 return VK_ERROR_EXTENSION_NOT_PRESENT;
57 }
58}
59
[826df16]60class VulkanGame {
61 public:
62 void run() {
63 if (initWindow() == RTWO_ERROR) {
64 return;
65 }
66 initVulkan();
67 mainLoop();
68 cleanup();
69 }
70 private:
71 GameGui_SDL gui;
72 SDL_Window* window = NULL;
73
74 VkInstance instance;
[b6127d2]75 VkDebugUtilsMessengerEXT debugMessenger;
[826df16]76
77 // both SDL and GLFW create window functions return NULL on failure
78 bool initWindow() {
79 if (gui.Init() == RTWO_ERROR) {
80 cout << "UI library could not be initialized!" << endl;
81 return RTWO_ERROR;
82 } else {
83 // On Apple's OS X you must set the NSHighResolutionCapable Info.plist property to YES,
84 // otherwise you will not receive a High DPI OpenGL canvas.
85
86 // TODO: Move this into some generic method in game-gui-sdl
87 window = SDL_CreateWindow("Vulkan Game",
88 SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
89 SCREEN_WIDTH, SCREEN_HEIGHT,
90 SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN);
91
92 if (window == NULL) {
93 cout << "Window could not be created!" << endl;
94 return RTWO_ERROR;
95 } else {
96 return RTWO_SUCCESS;
97 }
98 }
99 }
100
101 void initVulkan() {
102 createInstance();
[7dcd925]103 setupDebugMessenger();
[826df16]104 }
105
106 void createInstance() {
[b6127d2]107 if (enableValidationLayers && !checkValidationLayerSupport()) {
108 throw runtime_error("validation layers requested, but not available!");
109 }
110
[826df16]111 VkApplicationInfo appInfo = {};
112 appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
113 appInfo.pApplicationName = "Vulkan Game";
114 appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
115 appInfo.pEngineName = "No Engine";
116 appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
117 appInfo.apiVersion = VK_API_VERSION_1_0;
118
119 VkInstanceCreateInfo createInfo = {};
120 createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
121 createInfo.pApplicationInfo = &appInfo;
122
[a8f0577]123 vector<const char*> extensions = getRequiredExtensions();
[b6127d2]124 createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
125 createInfo.ppEnabledExtensionNames = extensions.data();
[826df16]126
[b6127d2]127 if (enableValidationLayers) {
128 createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
129 createInfo.ppEnabledLayerNames = validationLayers.data();
130 } else {
131 createInfo.enabledLayerCount = 0;
132 }
[826df16]133
134 if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
135 throw runtime_error("failed to create instance!");
136 }
137 }
138
[b6127d2]139 void setupDebugMessenger() {
140 if (!enableValidationLayers) return;
141
142 VkDebugUtilsMessengerCreateInfoEXT createInfo = {};
143 createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
144 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;
145 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;
146 createInfo.pfnUserCallback = debugCallback;
147 createInfo.pUserData = nullptr;
148
149 if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) {
150 throw runtime_error("failed to setup debug messenger!");
151 }
152 }
153
[a8f0577]154 bool checkValidationLayerSupport() {
155 uint32_t layerCount;
156 vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
157
158 vector<VkLayerProperties> availableLayers(layerCount);
159 vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
160
161 for (const char* layerName : validationLayers) {
162 bool layerFound = false;
163
164 for (const auto& layerProperties : availableLayers) {
165 if (strcmp(layerName, layerProperties.layerName) == 0) {
166 layerFound = true;
167 break;
168 }
169 }
170
171 if (!layerFound) {
172 return false;
173 }
174 }
175
176 return true;
177 }
178
179 vector<const char*> getRequiredExtensions() {
180 uint32_t extensionCount = 0;
181 SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, nullptr);
182
183 vector<const char*> extensions(extensionCount);
184 SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, extensions.data());
185
186 if (enableValidationLayers) {
187 extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
188 }
189
190 return extensions;
191 }
192
[826df16]193 void mainLoop() {
194 // TODO: Create some generic event-handling functions in game-gui-*
195 SDL_Event e;
196 bool quit = false;
197
198 /*
199 SDL_Surface* screenSurface = nullptr;
200 VkSurfaceKHR surface;
201
202 if (!SDL_Vulkan_CreateSurface(window, instance, &surface)) {
203 cout << "Couild not create Vulkan surface" << endl;
204 }
205
206 screenSurface = SDL_GetWindowSurface(window);
207 cout << "Got here" << endl;
208 cout << (screenSurface == nullptr ? "true" : "false") << endl;
[03f4c64]209
[826df16]210 SDL_FillRect(screenSurface, nullptr, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF));
211 cout << "Filled" << endl;
212
213 SDL_UpdateWindowSurface(window);
214 cout << "Updated" << endl;
215 */
216
[7dcd925]217 while (!quit) {
[826df16]218 while (SDL_PollEvent(&e)) {
219 if (e.type == SDL_QUIT) {
220 quit = true;
221 }
222 if (e.type == SDL_KEYDOWN) {
223 quit = true;
224 }
225 if (e.type == SDL_MOUSEBUTTONDOWN) {
226 quit = true;
227 }
228 }
229 }
230 }
231
232 void cleanup() {
233 vkDestroyInstance(instance, nullptr);
234
235 // TODO: Move this into some generic method in game-gui-sdl
236 SDL_DestroyWindow(window);
237
238 gui.Shutdown();
239 }
240};
241
[b6127d2]242int main() {
[826df16]243
[b6127d2]244#ifdef NDEBUG
245 cout << "DEBUGGING IS OFF" << endl;
246#else
247 cout << "DEBUGGING IS ON" << endl;
248#endif
[a8f0577]249
[826df16]250 /*
251 mat4 matrix;
252 vec4 vec;
253 vec4 test = matrix * vec;
254 */
255
256 cout << "Starting Vulkan game..." << endl;
257
258 VulkanGame game;
259
260 try {
261 game.run();
262 } catch (const exception& e) {
263 cerr << e.what() << endl;
264 return EXIT_FAILURE;
265 }
[03f4c64]266
[826df16]267 cout << "Finished running the game" << endl;
[03f4c64]268
[826df16]269 return EXIT_SUCCESS;
[03f4c64]270}
Note: See TracBrowser for help on using the repository browser.