source: opengl-game/vulkan-game.hpp@ 5a1ace0

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

In VulkanGame, add objIndex to scene objects, use it in the scene shader to index into the ssbo, and change the code that copies data to the ssbo to do so for each scene object, not just the first one

  • Property mode set to 100644
File size: 10.1 KB
Line 
1#ifndef _VULKAN_GAME_H
2#define _VULKAN_GAME_H
3
4#define GLM_FORCE_RADIANS
5#define GLM_FORCE_DEPTH_ZERO_TO_ONE // Since, in Vulkan, the depth range is 0 to 1 instead of -1 to 1
6#define GLM_FORCE_RIGHT_HANDED
7
8#include <glm/glm.hpp>
9#include <glm/gtc/matrix_transform.hpp>
10
11#include "game-gui-sdl.hpp"
12#include "graphics-pipeline_vulkan.hpp"
13
14#include "vulkan-utils.hpp"
15
16using namespace glm;
17
18#ifdef NDEBUG
19 const bool ENABLE_VALIDATION_LAYERS = false;
20#else
21 const bool ENABLE_VALIDATION_LAYERS = true;
22#endif
23
24struct OverlayVertex {
25 vec3 pos;
26 vec2 texCoord;
27};
28
29struct ModelVertex {
30 vec3 pos;
31 vec3 color;
32 vec2 texCoord;
33 unsigned int objIndex;
34};
35
36struct ShipVertex {
37 vec3 pos;
38 vec3 color;
39 vec3 normal;
40 unsigned int objIndex;
41};
42
43struct AsteroidVertex {
44 vec3 pos;
45 vec3 color;
46 vec3 normal;
47 unsigned int objIndex;
48};
49
50// TODO: Change the index type to uint32_t and check the Vulkan Tutorial loading model section as a reference
51// TODO: Create a typedef for index type so I can easily change uin16_t to something else later
52template<class VertexType>
53struct SceneObject {
54 vector<VertexType> vertices;
55 vector<uint16_t> indices;
56
57 mat4 model_base;
58 mat4 model_transform;
59};
60
61struct UBO_VP_mats {
62 alignas(16) mat4 view;
63 alignas(16) mat4 proj;
64};
65
66struct SBO_SceneObject {
67 alignas(16) mat4 model;
68};
69
70struct SBO_Asteroid {
71 alignas(16) mat4 model;
72 alignas(4) float hp;
73 alignas(4) unsigned int deleted;
74};
75
76class VulkanGame {
77 public:
78 VulkanGame(int maxFramesInFlight);
79 ~VulkanGame();
80
81 void run(int width, int height, unsigned char guiFlags);
82
83 private:
84 const int MAX_FRAMES_IN_FLIGHT;
85
86 const float NEAR_CLIP = 0.1f;
87 const float FAR_CLIP = 100.0f;
88 const float FOV_ANGLE = 67.0f; // means the camera lens goes from -33 deg to 33 def
89
90 vec3 cam_pos;
91
92 GameGui* gui;
93
94 SDL_version sdlVersion;
95 SDL_Window* window = nullptr;
96 SDL_Renderer* renderer = nullptr;
97
98 SDL_Texture* uiOverlay = nullptr;
99
100 VkInstance instance;
101 VkDebugUtilsMessengerEXT debugMessenger;
102 VkSurfaceKHR surface; // TODO: Change the variable name to vulkanSurface
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 vector<VkImageView> swapChainImageViews;
114 vector<VkFramebuffer> swapChainFramebuffers;
115
116 VkRenderPass renderPass;
117 VkCommandPool commandPool;
118 vector<VkCommandBuffer> commandBuffers;
119
120 VulkanImage depthImage;
121
122 VkSampler textureSampler;
123
124 VulkanImage floorTextureImage;
125 VkDescriptorImageInfo floorTextureImageDescriptor;
126
127 VulkanImage sdlOverlayImage;
128 VkDescriptorImageInfo sdlOverlayImageDescriptor;
129
130 TTF_Font* font;
131 SDL_Texture* fontSDLTexture;
132
133 SDL_Texture* imageSDLTexture;
134
135 vector<VkSemaphore> imageAvailableSemaphores;
136 vector<VkSemaphore> renderFinishedSemaphores;
137 vector<VkFence> inFlightFences;
138
139 size_t currentFrame;
140
141 bool framebufferResized;
142
143 // TODO: I should probably rename the uniformBuffer* and storageBuffer*
144 // variables to better reflect the data they hold
145
146 // TODO: Create a struct that holds the buffers, memory, and info objects (Probably in VulkanUtils)
147
148 GraphicsPipeline_Vulkan<OverlayVertex> overlayPipeline;
149
150 vector<SceneObject<OverlayVertex>> overlayObjects;
151
152 // TODO: Rename all the variables related to modelPipeline to use the same pipelie name
153
154 GraphicsPipeline_Vulkan<ModelVertex> modelPipeline;
155
156 vector<SceneObject<ModelVertex>> modelObjects;
157
158 vector<VkBuffer> uniformBuffers_scenePipeline;
159 vector<VkDeviceMemory> uniformBuffersMemory_scenePipeline;
160 vector<VkDescriptorBufferInfo> uniformBufferInfoList_scenePipeline;
161
162 vector<VkBuffer> storageBuffers_scenePipeline;
163 vector<VkDeviceMemory> storageBuffersMemory_scenePipeline;
164 vector<VkDescriptorBufferInfo> storageBufferInfoList_scenePipeline;
165
166 UBO_VP_mats object_VP_mats;
167 SBO_SceneObject so_Object;
168
169 GraphicsPipeline_Vulkan<ShipVertex> shipPipeline;
170
171 vector<SceneObject<ShipVertex>> shipObjects;
172
173 vector<VkBuffer> uniformBuffers_shipPipeline;
174 vector<VkDeviceMemory> uniformBuffersMemory_shipPipeline;
175 vector<VkDescriptorBufferInfo> uniformBufferInfoList_shipPipeline;
176
177 vector<VkBuffer> storageBuffers_shipPipeline;
178 vector<VkDeviceMemory> storageBuffersMemory_shipPipeline;
179 vector<VkDescriptorBufferInfo> storageBufferInfoList_shipPipeline;
180
181 UBO_VP_mats ship_VP_mats;
182 SBO_SceneObject so_Ship;
183
184 GraphicsPipeline_Vulkan<AsteroidVertex> asteroidPipeline;
185
186 vector<SceneObject<AsteroidVertex>> asteroidObjects;
187
188 vector<VkBuffer> uniformBuffers_asteroidPipeline;
189 vector<VkDeviceMemory> uniformBuffersMemory_asteroidPipeline;
190 vector<VkDescriptorBufferInfo> uniformBufferInfoList_asteroidPipeline;
191
192 vector<VkBuffer> storageBuffers_asteroidPipeline;
193 vector<VkDeviceMemory> storageBuffersMemory_asteroidPipeline;
194 vector<VkDescriptorBufferInfo> storageBufferInfoList_asteroidPipeline;
195
196 UBO_VP_mats asteroid_VP_mats;
197 SBO_Asteroid so_Asteroid;
198
199 Uint64 curTime, prevTime;
200 double elapsedTime;
201
202 bool initWindow(int width, int height, unsigned char guiFlags);
203 void initVulkan();
204 void initGraphicsPipelines();
205 void initMatrices();
206 void mainLoop();
207 void updateScene(uint32_t currentImage);
208 void renderUI();
209 void renderScene();
210 void cleanup();
211
212 void createVulkanInstance(const vector<const char*> &validationLayers);
213 void setupDebugMessenger();
214 void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo);
215 void createVulkanSurface();
216 void pickPhysicalDevice(const vector<const char*>& deviceExtensions);
217 bool isDeviceSuitable(VkPhysicalDevice physicalDevice, const vector<const char*>& deviceExtensions);
218 void createLogicalDevice(
219 const vector<const char*> validationLayers,
220 const vector<const char*>& deviceExtensions);
221 void createSwapChain();
222 void createImageViews();
223 void createRenderPass();
224 VkFormat findDepthFormat();
225 void createCommandPool();
226 void createImageResources();
227
228 void createTextureSampler();
229 void createFramebuffers();
230 void createCommandBuffers();
231 void createSyncObjects();
232
233 template<class VertexType>
234 void addObject(vector<SceneObject<VertexType>>& objects, GraphicsPipeline_Vulkan<VertexType>& pipeline,
235 const vector<VertexType>& vertices, vector<uint16_t> indices);
236
237 template<class VertexType>
238 vector<VertexType> addVertexNormals(vector<VertexType> vertices);
239
240 template<class VertexType>
241 vector<VertexType> addObjectIndex(unsigned int objIndex, vector<VertexType> vertices);
242
243 template<class VertexType>
244 vector<VertexType> centerObject(vector<VertexType> vertices);
245
246 template<class VertexType>
247 void transformObject(SceneObject<VertexType>& obj, mat4 mat);
248
249 void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags,
250 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, vector<VkDescriptorBufferInfo>& bufferInfoList);
251
252 void recreateSwapChain();
253
254 void cleanupSwapChain();
255
256 static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
257 VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
258 VkDebugUtilsMessageTypeFlagsEXT messageType,
259 const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
260 void* pUserData);
261};
262
263template<class VertexType>
264void VulkanGame::addObject(vector<SceneObject<VertexType>>& objects, GraphicsPipeline_Vulkan<VertexType>& pipeline,
265 const vector<VertexType>& vertices, vector<uint16_t> indices) {
266 size_t numVertices = pipeline.getNumVertices();
267
268 for (uint16_t& idx : indices) {
269 idx += numVertices;
270 }
271
272 objects.push_back({ vertices, indices, mat4(1.0f), mat4(1.0f) });
273
274 pipeline.addVertices(vertices, indices, commandPool, graphicsQueue);
275}
276
277template<class VertexType>
278vector<VertexType> VulkanGame::addVertexNormals(vector<VertexType> vertices) {
279 for (unsigned int i = 0; i < vertices.size(); i += 3) {
280 vec3 p1 = vertices[i].pos;
281 vec3 p2 = vertices[i+1].pos;
282 vec3 p3 = vertices[i+2].pos;
283
284 vec3 normal = normalize(cross(p2 - p1, p3 - p1));
285
286 // Add the same normal for all 3 vertices
287 vertices[i].normal = normal;
288 vertices[i+1].normal = normal;
289 vertices[i+2].normal = normal;
290 }
291
292 return vertices;
293}
294
295template<class VertexType>
296vector<VertexType> VulkanGame::addObjectIndex(unsigned int objIndex, vector<VertexType> vertices) {
297 for (VertexType& vertex : vertices) {
298 vertex.objIndex = objIndex;
299 }
300
301 return vertices;
302}
303
304template<class VertexType>
305vector<VertexType> VulkanGame::centerObject(vector<VertexType> vertices) {
306 float min_x = vertices[0].pos.x;
307 float max_x = vertices[0].pos.x;
308 float min_y = vertices[0].pos.y;
309 float max_y = vertices[0].pos.y;
310 float min_z = vertices[0].pos.z;
311 float max_z = vertices[0].pos.z;
312
313 // start from the second point
314 for (unsigned int i = 1; i < vertices.size(); i++) {
315 if (min_x > vertices[i].pos.x) {
316 min_x = vertices[i].pos.x;
317 } else if (max_x < vertices[i].pos.x) {
318 max_x = vertices[i].pos.x;
319 }
320
321 if (min_y > vertices[i].pos.y) {
322 min_y = vertices[i].pos.y;
323 } else if (max_y < vertices[i].pos.y) {
324 max_y = vertices[i].pos.y;
325 }
326
327 if (min_z > vertices[i].pos.z) {
328 min_z = vertices[i].pos.z;
329 } else if (max_z < vertices[i].pos.z) {
330 max_z = vertices[i].pos.z;
331 }
332 }
333
334 vec3 center = vec3(min_x + max_x, min_y + max_y, min_z + max_z) / 2.0f;
335
336 for (unsigned int i = 0; i < vertices.size(); i++) {
337 vertices[i].pos -= center;
338 }
339
340 return vertices;
341}
342
343template<class VertexType>
344void VulkanGame::transformObject(SceneObject<VertexType>& obj, mat4 mat) {
345 obj.model_transform = mat * obj.model_transform;
346}
347
348#endif // _VULKAN_GAME_H
Note: See TracBrowser for help on using the repository browser.