Index: main-vulkan.cpp
===================================================================
--- main-vulkan.cpp	(revision 6385d0fc26b91c4fd374b040aab658c97b4ad708)
+++ main-vulkan.cpp	(revision 4994692c43ddba22f532c23a33d0e66fa41c6ece)
@@ -11,4 +11,5 @@
 
 int main(int argc, char* argv[]) {
+   // TODO: Add date & time to the crash log
    CrashLogger logger(__main, argc, argv);
 
Index: new-game.cpp
===================================================================
--- new-game.cpp	(revision 6385d0fc26b91c4fd374b040aab658c97b4ad708)
+++ new-game.cpp	(revision 4994692c43ddba22f532c23a33d0e66fa41c6ece)
@@ -501,5 +501,4 @@
    defineModelGroupAttrib(modelGroups[TYPE_SHIP], "ubo_index", ATTRIB_OBJECT_VARYING,
       1, GL_UNSIGNED_INT, offset_of(&SceneObject::ubo_offset));
-/*** END OF REFACTORED CODE ***/
 
    defineModelGroupUniform(modelGroups[TYPE_SHIP], "view", ATTRIB_UNIFORM,
@@ -510,5 +509,4 @@
    initModelGroupAttribs(modelGroups[TYPE_SHIP]);
 
-/*** START OF REFACTORED CODE ***/
    modelGroups[TYPE_ASTEROID] = createModelGroup(
       loadShaderProgram("gl-shaders/asteroid.vert", "gl-shaders/asteroid.frag"));
@@ -523,5 +521,4 @@
    defineModelGroupAttrib(modelGroups[TYPE_ASTEROID], "ubo_index", ATTRIB_OBJECT_VARYING,
       1, GL_UNSIGNED_INT, offset_of(&SceneObject::ubo_offset));
-/*** END OF REFACTORED CODE ***/
 
    defineModelGroupUniform(modelGroups[TYPE_ASTEROID], "view", ATTRIB_UNIFORM,
@@ -532,5 +529,4 @@
    initModelGroupAttribs(modelGroups[TYPE_ASTEROID]);
 
-/*** START OF REFACTORED CODE ***/
    modelGroups[TYPE_LASER] = createModelGroup(
       loadShaderProgram("gl-shaders/laser.vert", "gl-shaders/laser.frag"));
@@ -543,5 +539,4 @@
    defineModelGroupAttrib(modelGroups[TYPE_LASER], "ubo_index", ATTRIB_OBJECT_VARYING,
       1, GL_UNSIGNED_INT, offset_of(&SceneObject::ubo_offset));
-/*** END OF REFACTORED CODE ***/
 
    defineModelGroupUniform(modelGroups[TYPE_LASER], "view", ATTRIB_UNIFORM,
@@ -553,6 +548,6 @@
 
    initModelGroupAttribs(modelGroups[TYPE_LASER]);
-
-/*** START OF REFACTORED CODE ***/
+/*** END OF REFACTORED CODE ***/
+
    modelGroups[TYPE_EXPLOSION] = createModelGroup(
       loadShaderProgram("gl-shaders/explosion.vert", "gl-shaders/explosion.frag"));
@@ -565,5 +560,4 @@
    defineModelGroupAttrib(modelGroups[TYPE_EXPLOSION], "ubo_index", ATTRIB_OBJECT_VARYING,
       1, GL_UNSIGNED_INT, offset_of(&SceneObject::ubo_offset));
-/*** END OF REFACTORED CODE ***/
 
    defineModelGroupUniform(modelGroups[TYPE_EXPLOSION], "cur_time", ATTRIB_UNIFORM,
@@ -829,6 +823,6 @@
 
             leftLaser = createLaser(
-               vec3(-0.21f, -1.19f, 1.76f)+offset,
-               vec3(-0.21f, -1.19f, -3.0f)+offset,
+               vec3(-0.21f, -1.19f, 1.76f) + offset,
+               vec3(-0.21f, -1.19f, -3.0f) + offset,
                vec3(0.0f, 1.0f, 0.0f), 0.03f);
             addObjectToScene(leftLaser, shaderBufferInfo, modelGroups, ubo);
@@ -1887,5 +1881,5 @@
    // To project point P onto line AB:
    // projection = A + dot(AP,AB) / dot(AB,AB) * AB
-   vec3 projOnLaser = start + glm::dot(cam_pos-start, ray) / (length*length) * ray;
+   vec3 projOnLaser = start + glm::dot(cam_pos - start, ray) / (length * length) * ray;
    vec3 laserToCam = cam_pos - projOnLaser;
 
@@ -1944,4 +1938,5 @@
 }
 
+/*** START OF REFACTORED CODE ***/
 void defineModelGroupUniform(ShaderModelGroup& modelGroup, string name, AttribType attribType,
                   GLint size, UniformType type, GLfloat* data) {
@@ -1957,13 +1952,10 @@
 
 void initModelGroupAttribs(ShaderModelGroup& modelGroup) {
-/*** START OF REFACTORED CODE ***/
    glBindVertexArray(modelGroup.vao);
 
    map<string, AttribInfo>::iterator it;
    for (it = modelGroup.attribs.begin(); it != modelGroup.attribs.end(); it++) {
-/*** END OF REFACTORED CODE ***/
       if (it->second.attribType == ATTRIB_UNIFORM) {
          it->second.buffer = glGetUniformLocation(modelGroup.shaderProgram, it->first.c_str());
-/*** START OF REFACTORED CODE ***/
       } else {
          glEnableVertexAttribArray(it->second.index);
@@ -1984,6 +1976,6 @@
       }
    }
-/*** START OF REFACTORED CODE ***/
-}
+}
+/*** END OF REFACTORED CODE ***/
 
 void bindUniformData(AttribInfo& attrib) {
Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 6385d0fc26b91c4fd374b040aab658c97b4ad708)
+++ vulkan-game.cpp	(revision 4994692c43ddba22f532c23a33d0e66fa41c6ece)
@@ -12,17 +12,19 @@
 using namespace std;
 
+// TODO: Update all occurances of instance variables to use this->
+
 VulkanGame::VulkanGame(int maxFramesInFlight) : MAX_FRAMES_IN_FLIGHT(maxFramesInFlight) {
-   gui = nullptr;
-   window = nullptr;
-   font = nullptr;
-   fontSDLTexture = nullptr;
-   imageSDLTexture = nullptr;
-
-   currentFrame = 0;
-   framebufferResized = false;
-
-   object_VP_mats = {};
-   ship_VP_mats = {};
-   asteroid_VP_mats = {};
+   this->gui = nullptr;
+   this->window = nullptr;
+   this->font = nullptr;
+   this->fontSDLTexture = nullptr;
+   this->imageSDLTexture = nullptr;
+
+   this->currentFrame = 0;
+   this->framebufferResized = false;
+
+   this->object_VP_mats = {};
+   this->ship_VP_mats = {};
+   this->asteroid_VP_mats = {};
 }
 
@@ -226,10 +228,11 @@
    modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_modelPipeline);
-   modelPipeline.addStorageDescriptor();
-
+   modelPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
    modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
       VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor);
 
-   addObject(modelObjects, modelPipeline,
+   SceneObject<ModelVertex, SSBO_ModelObject>* texturedSquare = nullptr;
+
+   texturedSquare = &addObject(modelObjects, modelPipeline,
       addObjectIndex<ModelVertex>(modelObjects.size(), {
          {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
@@ -243,10 +246,9 @@
       }, false);
 
-   modelObjects.back().model_base =
+   texturedSquare->model_base =
       translate(mat4(1.0f), vec3(0.0f, 0.0f, -2.0f));
-
    updateObject(modelObjects, modelPipeline, modelObjects.size() - 1);
 
-   addObject(modelObjects, modelPipeline,
+   texturedSquare = &addObject(modelObjects, modelPipeline,
       addObjectIndex<ModelVertex>(modelObjects.size(), {
          {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
@@ -260,7 +262,6 @@
       }, false);
 
-   modelObjects.back().model_base =
+   texturedSquare->model_base =
       translate(mat4(1.0f), vec3(0.0f, 0.0f, -1.5f));
-
    updateObject(modelObjects, modelPipeline, modelObjects.size() - 1);
 
@@ -280,9 +281,9 @@
    shipPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_shipPipeline);
-   shipPipeline.addStorageDescriptor();
+   shipPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
 
    // TODO: With the normals, indexing basically becomes pointless since no vertices will have exactly
    // the same data. Add an option to make some pipelines not use indexing
-   addObject(shipObjects, shipPipeline,
+   SceneObject<ShipVertex, SSBO_ModelObject>& ship = addObject(shipObjects, shipPipeline,
       addObjectIndex<ShipVertex>(shipObjects.size(),
       addVertexNormals<ShipVertex>({
@@ -532,5 +533,5 @@
    asteroidPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_asteroidPipeline);
-   asteroidPipeline.addStorageDescriptor();
+   asteroidPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
 
    asteroidPipeline.createDescriptorSetLayout();
@@ -545,8 +546,7 @@
    createSyncObjects();
 
-   shipObjects[0].model_base =
+   ship.model_base =
       translate(mat4(1.0f), vec3(0.0f, -1.2f, 1.65f)) *
       scale(mat4(1.0f), vec3(0.1f, 0.1f, 0.1f));
-
    updateObject(shipObjects, shipPipeline, 0);
 }
@@ -568,5 +568,5 @@
 // TODO: Maybe changes the name to initScene() or something similar
 void VulkanGame::initMatrices() {
-   cam_pos = vec3(0.0f, 0.0f, 2.0f);
+   this->cam_pos = vec3(0.0f, 0.0f, 2.0f);
 
    float cam_yaw = 0.0f;
@@ -577,5 +577,5 @@
 
    mat4 R_view = pitch_mat * yaw_mat;
-   mat4 T_view = translate(mat4(1.0f), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
+   mat4 T_view = translate(mat4(1.0f), vec3(-this->cam_pos.x, -this->cam_pos.y, -this->cam_pos.z));
    viewMat = R_view * T_view;
 
@@ -625,4 +625,8 @@
                break;
             case UI_EVENT_KEYDOWN:
+               if (e.key.repeat) {
+                  break;
+               }
+
                if (e.key.keycode == SDL_SCANCODE_ESCAPE) {
                   quit = true;
@@ -631,19 +635,19 @@
                   float zOffset = -2.0f + (0.5f * modelObjects.size());
 
-                  addObject(modelObjects, modelPipeline,
-                     addObjectIndex<ModelVertex>(modelObjects.size(), {
-                        {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
-                        {{ 0.5f, -0.5f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
-                        {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
-                        {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
-                     }), {
-                        0, 1, 2, 2, 3, 0
-                     }, {
-                        mat4(1.0f)
-                     }, true);
-
-                  modelObjects.back().model_base =
+                  SceneObject<ModelVertex, SSBO_ModelObject>& texturedSquare =
+                     addObject(modelObjects, modelPipeline,
+                        addObjectIndex<ModelVertex>(modelObjects.size(), {
+                           {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
+                           {{ 0.5f, -0.5f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
+                           {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
+                           {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
+                        }), {
+                           0, 1, 2, 2, 3, 0
+                        }, {
+                           mat4(1.0f)
+                        }, true);
+
+                  texturedSquare.model_base =
                      translate(mat4(1.0f), vec3(0.0f, 0.0f, zOffset));
-
                   updateObject(modelObjects, modelPipeline, modelObjects.size() - 1);
                } else {
@@ -671,11 +675,17 @@
       // Check which keys are held down
 
+      SceneObject<ShipVertex, SSBO_ModelObject>& ship = shipObjects[0];
+
       if (gui->keyPressed(SDL_SCANCODE_LEFT)) {
-         shipObjects[0].model_transform = translate(mat4(1.0f), vec3(-this->shipSpeed * this->elapsedTime, 0.0f, 0.0f))
+         float distance = -this->shipSpeed * this->elapsedTime;
+
+         ship.model_transform = translate(mat4(1.0f), vec3(distance, 0.0f, 0.0f))
             * shipObjects[0].model_transform;
 
          updateObject(shipObjects, shipPipeline, 0);
       } else if (gui->keyPressed(SDL_SCANCODE_RIGHT)) {
-         shipObjects[0].model_transform = translate(mat4(1.0f), vec3(this->shipSpeed * this->elapsedTime, 0.0f, 0.0f))
+         float distance = this->shipSpeed * this->elapsedTime;
+
+         ship.model_transform = translate(mat4(1.0f), vec3(distance, 0.0f, 0.0f))
             * shipObjects[0].model_transform;
 
@@ -721,5 +731,6 @@
       this->lastSpawn_asteroid = this->curTime;
 
-      addObject(asteroidObjects, asteroidPipeline,
+      SceneObject<AsteroidVertex, SSBO_Asteroid>& asteroid = addObject(
+         asteroidObjects, asteroidPipeline,
          addObjectIndex<AsteroidVertex>(asteroidObjects.size(),
             addVertexNormals<AsteroidVertex>({
@@ -782,5 +793,5 @@
             mat4(1.0f),
             10.0f,
-            0
+            false
          }, true);
 
@@ -790,7 +801,7 @@
       // TODO: Figure out the best way to take scaling into account when calculating the radius
       // Keep in mind that the main complicating factor is the currently poor radius calculation
-      asteroidObjects.back().radius /= 8.0f;
-
-      asteroidObjects.back().model_base =
+      asteroid.radius /= 8.0f;
+
+      asteroid.model_base =
          translate(mat4(1.0f), vec3(getRandomNum(-1.3f, 1.3f), -1.2f, getRandomNum(-5.5f, -4.5f))) *
          rotate(mat4(1.0f), radians(60.0f), vec3(1.0f, 1.0f, -1.0f)) *
@@ -900,6 +911,6 @@
    cleanupSwapChain();
 
+   VulkanUtils::destroyVulkanImage(device, sdlOverlayImage);
    VulkanUtils::destroyVulkanImage(device, floorTextureImage);
-   VulkanUtils::destroyVulkanImage(device, sdlOverlayImage);
 
    vkDestroySampler(device, textureSampler, nullptr);
@@ -1282,4 +1293,13 @@
    createTextureSampler();
 
+   // TODO: Move all images/textures somewhere into the assets folder
+
+   VulkanUtils::createVulkanImageFromSDLTexture(device, physicalDevice, uiOverlay, sdlOverlayImage);
+
+   sdlOverlayImageDescriptor = {};
+   sdlOverlayImageDescriptor.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+   sdlOverlayImageDescriptor.imageView = sdlOverlayImage.imageView;
+   sdlOverlayImageDescriptor.sampler = textureSampler;
+
    VulkanUtils::createVulkanImageFromFile(device, physicalDevice, commandPool, "textures/texture.jpg",
       floorTextureImage, graphicsQueue);
@@ -1289,11 +1309,4 @@
    floorTextureImageDescriptor.imageView = floorTextureImage.imageView;
    floorTextureImageDescriptor.sampler = textureSampler;
-
-   VulkanUtils::createVulkanImageFromSDLTexture(device, physicalDevice, uiOverlay, sdlOverlayImage);
-
-   sdlOverlayImageDescriptor = {};
-   sdlOverlayImageDescriptor.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
-   sdlOverlayImageDescriptor.imageView = sdlOverlayImage.imageView;
-   sdlOverlayImageDescriptor.sampler = textureSampler;
 }
 
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision 6385d0fc26b91c4fd374b040aab658c97b4ad708)
+++ vulkan-game.hpp	(revision 4994692c43ddba22f532c23a33d0e66fa41c6ece)
@@ -51,6 +51,22 @@
 };
 
+struct UBO_VP_mats {
+   alignas(16) mat4 view;
+   alignas(16) mat4 proj;
+};
+
+struct SSBO_ModelObject {
+   alignas(16) mat4 model;
+};
+
+struct SSBO_Asteroid {
+   alignas(16) mat4 model;
+   alignas(4) float hp;
+   alignas(4) unsigned int deleted;
+};
+
 // TODO: Change the index type to uint32_t and check the Vulkan Tutorial loading model section as a reference
 // TODO: Create a typedef for index type so I can easily change uin16_t to something else later
+// TODO: Maybe create a typedef for each of the templated SceneObject types
 template<class VertexType, class SSBOType>
 struct SceneObject {
@@ -61,25 +77,15 @@
    mat4 model_base;
    mat4 model_transform;
+
+   // TODO: Figure out if I should make child classes that have these fields instead of putting them in the
+   // parent class
    vec3 center; // currently only matters for asteroids
    float radius; // currently only matters for asteroids
 };
 
-struct UBO_VP_mats {
-   alignas(16) mat4 view;
-   alignas(16) mat4 proj;
-};
-
-struct SSBO_ModelObject {
-   alignas(16) mat4 model;
-};
-
-struct SSBO_Asteroid {
-   alignas(16) mat4 model;
-   alignas(4) float hp;
-   alignas(4) unsigned int deleted;
-};
-
-// Have to figure out how to include an optional ssbo parameter for each object
+// TODO: Have to figure out how to include an optional ssbo parameter for each object
 // Could probably use the same approach to make indices optional
+// Figure out if there are sufficient use cases to make either of these optional or is it fine to make
+// them mamdatory
 
 class VulkanGame {
@@ -131,9 +137,9 @@
       VkSampler textureSampler;
 
+      VulkanImage sdlOverlayImage;
+      VkDescriptorImageInfo sdlOverlayImageDescriptor;
+
       VulkanImage floorTextureImage;
       VkDescriptorImageInfo floorTextureImageDescriptor;
-
-      VulkanImage sdlOverlayImage;
-      VkDescriptorImageInfo sdlOverlayImageDescriptor;
 
       TTF_Font* font;
@@ -230,13 +236,16 @@
       void createSyncObjects();
 
+      // TODO: Since addObject() returns a reference to the new object now,
+      // stop using objects.back() to access the object that was just created
       template<class VertexType, class SSBOType>
-      void addObject(vector<SceneObject<VertexType, SSBOType>>& objects,
-         GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline,
-         const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo,
-         bool pipelinesCreated);
+      SceneObject<VertexType, SSBOType>& addObject(
+            vector<SceneObject<VertexType, SSBOType>>& objects,
+            GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline,
+            const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo,
+            bool pipelinesCreated);
 
       template<class VertexType, class SSBOType>
       void updateObject(vector<SceneObject<VertexType, SSBOType>>& objects,
-         GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, size_t index);
+            GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, size_t index);
 
       template<class VertexType>
@@ -250,5 +259,6 @@
 
       void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags,
-         vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, vector<VkDescriptorBufferInfo>& bufferInfoList);
+            vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
+            vector<VkDescriptorBufferInfo>& bufferInfoList);
 
       void recreateSwapChain();
@@ -272,5 +282,6 @@
 // to account for scaling
 template<class VertexType, class SSBOType>
-void VulkanGame::addObject(vector<SceneObject<VertexType, SSBOType>>& objects,
+SceneObject<VertexType, SSBOType>& VulkanGame::addObject(
+      vector<SceneObject<VertexType, SSBOType>>& objects,
       GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline,
       const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo,
@@ -289,5 +300,6 @@
    centerObject(obj);
 
-   bool storageBufferResized = pipeline.addObject(obj.vertices, obj.indices, obj.ssbo, commandPool, graphicsQueue);
+   bool storageBufferResized = pipeline.addObject(obj.vertices, obj.indices, obj.ssbo,
+      this->commandPool, this->graphicsQueue);
 
    if (pipelinesCreated) {
@@ -307,4 +319,6 @@
       createCommandBuffers();
    }
+
+   return obj;
 }
 
