source: opengl-game/vulkan-game.cpp@ 80de39d

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

Finish configuring validation layers

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