Changeset 4a777d2 in opengl-game for sdl-game.hpp
- Timestamp:
- Apr 11, 2021, 12:09:58 AM (4 years ago)
- Branches:
- feature/imgui-sdl
- Children:
- cb6fabb, e8445f0
- Parents:
- b8efa56
- git-author:
- Dmitry Portnoy <dportnoy@…> (04/11/21 00:09:49)
- git-committer:
- Dmitry Portnoy <dportnoy@…> (04/11/21 00:09:58)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sdl-game.hpp
rb8efa56 r4a777d2 10 10 #include <SDL2/SDL.h> 11 11 12 #define GLM_FORCE_RADIANS 13 #define GLM_FORCE_DEPTH_ZERO_TO_ONE // Since, in Vulkan, the depth range is 0 to 1 instead of -1 to 1 14 #define GLM_FORCE_RIGHT_HANDED 15 16 #include <glm/glm.hpp> 17 #include <glm/gtc/matrix_transform.hpp> 18 12 19 #include "IMGUI/imgui_impl_vulkan.h" 13 20 14 21 #include "consts.hpp" 15 22 #include "vulkan-utils.hpp" 16 23 #include "graphics-pipeline_vulkan.hpp" 17 24 #include "game-gui-sdl.hpp" 18 25 26 using namespace glm; 19 27 using namespace std; 20 28 using namespace std::chrono; … … 28 36 #endif 29 37 38 // TODO: Consider if there is a better way of dealing with all the vertex types and ssbo types, maybe 39 // by consolidating some and trying to keep new ones to a minimum 40 41 struct ModelVertex { 42 vec3 pos; 43 vec3 color; 44 vec2 texCoord; 45 vec3 normal; 46 unsigned int objIndex; 47 }; 48 49 struct LaserVertex { 50 vec3 pos; 51 vec2 texCoord; 52 unsigned int objIndex; 53 }; 54 55 struct ExplosionVertex { 56 vec3 particleStartVelocity; 57 float particleStartTime; 58 unsigned int objIndex; 59 }; 60 61 struct SSBO_ModelObject { 62 alignas(16) mat4 model; 63 }; 64 65 struct SSBO_Asteroid { 66 alignas(16) mat4 model; 67 alignas(4) float hp; 68 alignas(4) unsigned int deleted; 69 }; 70 71 struct UBO_VP_mats { 72 alignas(16) mat4 view; 73 alignas(16) mat4 proj; 74 }; 75 76 // TODO: Change the index type to uint32_t and check the Vulkan Tutorial loading model section as a reference 77 // TODO: Create a typedef for index type so I can easily change uin16_t to something else later 78 // TODO: Maybe create a typedef for each of the templated SceneObject types 79 template<class VertexType, class SSBOType> 80 struct SceneObject { 81 vector<VertexType> vertices; 82 vector<uint16_t> indices; 83 SSBOType ssbo; 84 85 mat4 model_base; 86 mat4 model_transform; 87 88 bool modified; 89 90 // TODO: Figure out if I should make child classes that have these fields instead of putting them in the 91 // parent class 92 vec3 center; // currently only matters for asteroids 93 float radius; // currently only matters for asteroids 94 SceneObject<ModelVertex, SSBO_Asteroid>* targetAsteroid; // currently only used for lasers 95 }; 96 97 // TODO: Have to figure out how to include an optional ssbo parameter for each object 98 // Could probably use the same approach to make indices optional 99 // Figure out if there are sufficient use cases to make either of these optional or is it fine to make 100 // them mamdatory 101 102 103 // TODO: Look into using dynamic_cast to check types of SceneObject and EffectOverTime 104 30 105 // TODO: Maybe move this to a different header 31 106 … … 60 135 void* pUserData); 61 136 137 // TODO: Maybe pass these in as parameters to some Camera class 138 const float NEAR_CLIP = 0.1f; 139 const float FAR_CLIP = 100.0f; 140 const float FOV_ANGLE = 67.0f; // means the camera lens goes from -33 deg to 33 deg 141 62 142 bool done; 143 144 vec3 cam_pos; 63 145 64 146 // TODO: Good place to start using smart pointers … … 110 192 bool shouldRecreateSwapChain; 111 193 194 VkSampler textureSampler; 195 196 VulkanImage floorTextureImage; 197 VkDescriptorImageInfo floorTextureImageDescriptor; 198 199 mat4 viewMat, projMat; 200 112 201 // Maybe at some point create an imgui pipeline class, but I don't think it makes sense right now 113 202 VkDescriptorPool imguiDescriptorPool; 203 204 // TODO: Probably restructure the GraphicsPipeline_Vulkan class based on what I learned about descriptors and textures 205 // while working on graphics-library. Double-check exactly what this was and note it down here. 206 // Basically, I think the point was that if I have several models that all use the same shaders and, therefore, 207 // the same pipeline, but use different textures, the approach I took when initially creating GraphicsPipeline_Vulkan 208 // wouldn't work since the whole pipeline couldn't have a common set of descriptors for the textures 209 GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject> modelPipeline; 210 211 // TODO: Maybe make the ubo objects part of the pipeline class since there's only one ubo 212 // per pipeline. 213 // Or maybe create a higher level wrapper around GraphicsPipeline_Vulkan to hold things like 214 // the objects vector, the ubo, and the ssbo 215 216 // TODO: Rename *_VP_mats to *_uniforms and possibly use different types for each one 217 // if there is a need to add other uniform variables to one or more of the shaders 218 219 vector<SceneObject<ModelVertex, SSBO_ModelObject>> modelObjects; 220 221 vector<VkBuffer> uniformBuffers_modelPipeline; 222 vector<VkDeviceMemory> uniformBuffersMemory_modelPipeline; 223 vector<VkDescriptorBufferInfo> uniformBufferInfoList_modelPipeline; 224 225 UBO_VP_mats object_VP_mats; 114 226 115 227 /*** High-level vars ***/ … … 133 245 bool initUI(int width, int height, unsigned char guiFlags); 134 246 void initVulkan(); 247 void initGraphicsPipelines(); 248 void initMatrices(); 135 249 void renderLoop(); 250 void updateScene(); 136 251 void cleanup(); 137 252 … … 156 271 void createSyncObjects(); 157 272 273 void createTextureSampler(); 274 158 275 void initImGuiOverlay(); 159 276 void cleanupImGuiOverlay(); 160 277 278 void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, 279 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, 280 vector<VkDescriptorBufferInfo>& bufferInfoList); 281 282 // TODO: Since addObject() returns a reference to the new object now, 283 // stop using objects.back() to access the object that was just created 284 template<class VertexType, class SSBOType> 285 SceneObject<VertexType, SSBOType>& addObject( 286 vector<SceneObject<VertexType, SSBOType>>& objects, 287 GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, 288 const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo, 289 bool pipelinesCreated); 290 291 template<class VertexType> 292 vector<VertexType> addObjectIndex(unsigned int objIndex, vector<VertexType> vertices); 293 294 template<class VertexType> 295 vector<VertexType> addVertexNormals(vector<VertexType> vertices); 296 297 template<class VertexType, class SSBOType> 298 void centerObject(SceneObject<VertexType, SSBOType>& object); 299 300 template<class VertexType, class SSBOType> 301 void updateObject(vector<SceneObject<VertexType, SSBOType>>& objects, 302 GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, size_t index); 303 161 304 void renderFrame(ImDrawData* draw_data); 162 305 void presentFrame(); … … 178 321 }; 179 322 323 // TODO: Right now, it's basically necessary to pass the identity matrix in for ssbo.model 324 // and to change the model matrix later by setting model_transform and then calling updateObject() 325 // Figure out a better way to allow the model matrix to be set during objecting creation 326 327 // TODO: Maybe return a reference to the object from this method if I decide that updating it 328 // immediately after creation is a good idea (such as setting model_base) 329 // Currently, model_base is set like this in a few places and the radius is set for asteroids 330 // to account for scaling 331 template<class VertexType, class SSBOType> 332 SceneObject<VertexType, SSBOType>& VulkanGame::addObject( 333 vector<SceneObject<VertexType, SSBOType>>& objects, 334 GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, 335 const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo, 336 bool pipelinesCreated) { 337 // TODO: Use the model field of ssbo to set the object's model_base 338 // currently, the passed in model is useless since it gets overridden in updateObject() anyway 339 size_t numVertices = pipeline.getNumVertices(); 340 341 for (uint16_t& idx : indices) { 342 idx += numVertices; 343 } 344 345 objects.push_back({ vertices, indices, ssbo, mat4(1.0f), mat4(1.0f), false }); 346 347 SceneObject<VertexType, SSBOType>& obj = objects.back(); 348 349 // TODO: Specify whether to center the object outside of this function or, worst case, maybe 350 // with a boolean being passed in here, so that I don't have to rely on checking the specific object 351 // type 352 if (!is_same_v<VertexType, LaserVertex> && !is_same_v<VertexType, ExplosionVertex>) { 353 centerObject(obj); 354 } 355 356 bool storageBufferResized = pipeline.addObject(obj.vertices, obj.indices, obj.ssbo, 357 resourceCommandPool, graphicsQueue); 358 359 if (pipelinesCreated) { 360 vkDeviceWaitIdle(device); 361 362 for (uint32_t i = 0; i < swapChainImageCount; i++) { 363 vkFreeCommandBuffers(device, commandPools[i], 1, &commandBuffers[i]); 364 } 365 366 // TODO: The pipeline recreation only has to be done once per frame where at least 367 // one SSBO is resized. 368 // Refactor the logic to check for any resized SSBOs after all objects for the frame 369 // are created and then recreate each of the corresponding pipelines only once per frame 370 if (storageBufferResized) { 371 pipeline.createPipeline(pipeline.vertShaderFile, pipeline.fragShaderFile); 372 pipeline.createDescriptorPool(swapChainImages); 373 pipeline.createDescriptorSets(swapChainImages); 374 } 375 376 createCommandBuffers(); 377 } 378 379 return obj; 380 } 381 382 template<class VertexType> 383 vector<VertexType> VulkanGame::addObjectIndex(unsigned int objIndex, vector<VertexType> vertices) { 384 for (VertexType& vertex : vertices) { 385 vertex.objIndex = objIndex; 386 } 387 388 return vertices; 389 } 390 391 template<class VertexType> 392 vector<VertexType> VulkanGame::addVertexNormals(vector<VertexType> vertices) { 393 for (unsigned int i = 0; i < vertices.size(); i += 3) { 394 vec3 p1 = vertices[i].pos; 395 vec3 p2 = vertices[i + 1].pos; 396 vec3 p3 = vertices[i + 2].pos; 397 398 vec3 normal = normalize(cross(p2 - p1, p3 - p1)); 399 400 // Add the same normal for all 3 vertices 401 vertices[i].normal = normal; 402 vertices[i + 1].normal = normal; 403 vertices[i + 2].normal = normal; 404 } 405 406 return vertices; 407 } 408 409 template<class VertexType, class SSBOType> 410 void VulkanGame::centerObject(SceneObject<VertexType, SSBOType>& object) { 411 vector<VertexType>& vertices = object.vertices; 412 413 float min_x = vertices[0].pos.x; 414 float max_x = vertices[0].pos.x; 415 float min_y = vertices[0].pos.y; 416 float max_y = vertices[0].pos.y; 417 float min_z = vertices[0].pos.z; 418 float max_z = vertices[0].pos.z; 419 420 // start from the second point 421 for (unsigned int i = 1; i < vertices.size(); i++) { 422 vec3& pos = vertices[i].pos; 423 424 if (min_x > pos.x) { 425 min_x = pos.x; 426 } 427 else if (max_x < pos.x) { 428 max_x = pos.x; 429 } 430 431 if (min_y > pos.y) { 432 min_y = pos.y; 433 } 434 else if (max_y < pos.y) { 435 max_y = pos.y; 436 } 437 438 if (min_z > pos.z) { 439 min_z = pos.z; 440 } 441 else if (max_z < pos.z) { 442 max_z = pos.z; 443 } 444 } 445 446 vec3 center = vec3(min_x + max_x, min_y + max_y, min_z + max_z) / 2.0f; 447 448 for (unsigned int i = 0; i < vertices.size(); i++) { 449 vertices[i].pos -= center; 450 } 451 452 object.radius = std::max(max_x - center.x, max_y - center.y); 453 object.radius = std::max(object.radius, max_z - center.z); 454 455 object.center = vec3(0.0f, 0.0f, 0.0f); 456 } 457 458 // TODO: Just pass in the single object instead of a list of all of them 459 template<class VertexType, class SSBOType> 460 void VulkanGame::updateObject(vector<SceneObject<VertexType, SSBOType>>& objects, 461 GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, size_t index) { 462 SceneObject<VertexType, SSBOType>& obj = objects[index]; 463 464 obj.ssbo.model = obj.model_transform * obj.model_base; 465 obj.center = vec3(obj.ssbo.model * vec4(0.0f, 0.0f, 0.0f, 1.0f)); 466 467 pipeline.updateObject(index, obj.ssbo); 468 469 obj.modified = false; 470 } 471 180 472 #endif // _SDL_GAME_H
Note:
See TracChangeset
for help on using the changeset viewer.