Index: graphics-pipeline_vulkan.hpp
===================================================================
--- graphics-pipeline_vulkan.hpp	(revision 5a1ace07fab99988e1cc16659663dd54921b15f4)
+++ graphics-pipeline_vulkan.hpp	(revision 2d8729794fc0b2af68f5b1a9b152e2e96258b598)
@@ -31,5 +31,5 @@
 };
 
-template<class VertexType>
+template<class VertexType, class SSBOType>
 class GraphicsPipeline_Vulkan : public GraphicsPipeline {
    public:
@@ -99,11 +99,12 @@
 /*** PUBLIC METHODS ***/
 
-template<class VertexType>
-GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan() {
+template<class VertexType, class SSBOType>
+GraphicsPipeline_Vulkan<VertexType, SSBOType>::GraphicsPipeline_Vulkan() {
 }
 
 // TODO: Verify that vertex capacity and index capacity are both > 0
-template<class VertexType>
-GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan(VkPhysicalDevice physicalDevice, VkDevice device,
+template<class VertexType, class SSBOType>
+GraphicsPipeline_Vulkan<VertexType, SSBOType>::GraphicsPipeline_Vulkan(
+      VkPhysicalDevice physicalDevice, VkDevice device,
       VkRenderPass renderPass, Viewport viewport, size_t vertexCapacity, size_t indexCapacity) {
    this->physicalDevice = physicalDevice;
@@ -134,20 +135,20 @@
 }
 
-template<class VertexType>
-GraphicsPipeline_Vulkan<VertexType>::~GraphicsPipeline_Vulkan() {
-}
-
-template<class VertexType>
-size_t GraphicsPipeline_Vulkan<VertexType>::getNumVertices() {
+template<class VertexType, class SSBOType>
+GraphicsPipeline_Vulkan<VertexType, SSBOType>::~GraphicsPipeline_Vulkan() {
+}
+
+template<class VertexType, class SSBOType>
+size_t GraphicsPipeline_Vulkan<VertexType, SSBOType>::getNumVertices() {
    return numVertices;
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::updateRenderPass(VkRenderPass renderPass) {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::updateRenderPass(VkRenderPass renderPass) {
    this->renderPass = renderPass;
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::addAttribute(VkFormat format, size_t offset) {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addAttribute(VkFormat format, size_t offset) {
    VkVertexInputAttributeDescription attributeDesc = {};
 
@@ -160,16 +161,16 @@
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, vector<VkDescriptorBufferInfo>* bufferData) {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, vector<VkDescriptorBufferInfo>* bufferData) {
    this->descriptorInfoList.push_back({ type, stageFlags, bufferData, nullptr });
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData) {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData) {
    this->descriptorInfoList.push_back({ type, stageFlags, nullptr, imageData });
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::createPipeline(string vertShaderFile, string fragShaderFile) {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createPipeline(string vertShaderFile, string fragShaderFile) {
    vector<char> vertShaderCode = readFile(vertShaderFile);
    vector<char> fragShaderCode = readFile(fragShaderFile);
@@ -308,6 +309,6 @@
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::createDescriptorSetLayout() {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorSetLayout() {
    vector<VkDescriptorSetLayoutBinding> bindings(this->descriptorInfoList.size());
 
@@ -330,6 +331,6 @@
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::createDescriptorPool(vector<VkImage>& swapChainImages) {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorPool(vector<VkImage>& swapChainImages) {
    vector<VkDescriptorPoolSize> poolSizes(this->descriptorInfoList.size());
 
@@ -350,6 +351,6 @@
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::createDescriptorSets(vector<VkImage>& swapChainImages) {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorSets(vector<VkImage>& swapChainImages) {
    vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), this->descriptorSetLayout);
 
@@ -396,6 +397,6 @@
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage) {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage) {
    vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
    vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1,
@@ -411,6 +412,6 @@
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::addVertices(const vector<VertexType>& vertices, vector<uint16_t> indices,
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addVertices(const vector<VertexType>& vertices, vector<uint16_t> indices,
       VkCommandPool commandPool, VkQueue graphicsQueue) {
 
@@ -431,6 +432,6 @@
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::cleanup() {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::cleanup() {
    vkDestroyPipeline(device, pipeline, nullptr);
    vkDestroyDescriptorPool(device, descriptorPool, nullptr);
@@ -438,6 +439,6 @@
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::cleanupBuffers() {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::cleanupBuffers() {
    vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
 
@@ -450,6 +451,6 @@
 /*** PRIVATE METHODS ***/
 
-template<class VertexType>
-VkShaderModule GraphicsPipeline_Vulkan<VertexType>::createShaderModule(const vector<char>& code) {
+template<class VertexType, class SSBOType>
+VkShaderModule GraphicsPipeline_Vulkan<VertexType, SSBOType>::createShaderModule(const vector<char>& code) {
    VkShaderModuleCreateInfo createInfo = {};
    createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
@@ -465,6 +466,6 @@
 }
 
-template<class VertexType>
-vector<char> GraphicsPipeline_Vulkan<VertexType>::readFile(const string& filename) {
+template<class VertexType, class SSBOType>
+vector<char> GraphicsPipeline_Vulkan<VertexType, SSBOType>::readFile(const string& filename) {
    ifstream file(filename, ios::ate | ios::binary);
 
@@ -484,6 +485,6 @@
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
    VkBuffer newVertexBuffer;
    VkDeviceMemory newVertexBufferMemory;
@@ -503,6 +504,6 @@
 }
 
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
+template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
    VkBuffer newIndexBuffer;
    VkDeviceMemory newIndexBufferMemory;
Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 5a1ace07fab99988e1cc16659663dd54921b15f4)
+++ vulkan-game.cpp	(revision 2d8729794fc0b2af68f5b1a9b152e2e96258b598)
@@ -202,5 +202,5 @@
       uniformBuffers_scenePipeline, uniformBuffersMemory_scenePipeline, uniformBufferInfoList_scenePipeline);
    // TODO: Calculate the size of this buffer (and all the other SSBOs) based on the number of objects
-   createBufferSet(10 * sizeof(SBO_SceneObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+   createBufferSet(10 * sizeof(SSBO_ModelObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
       storageBuffers_scenePipeline, storageBuffersMemory_scenePipeline, storageBufferInfoList_scenePipeline);
 
@@ -221,4 +221,6 @@
       }), {
          0, 1, 2, 2, 3, 0
+      }, {
+         mat4(1.0f)
       });
 
@@ -231,4 +233,6 @@
       }), {
          0, 1, 2, 2, 3, 0
+      }, {
+         mat4(1.0f)
       });
 
@@ -252,5 +256,5 @@
       }, {
          0, 1, 2, 2, 3, 0
-      });
+      }, {});
 
    overlayPipeline.createDescriptorSetLayout();
@@ -266,5 +270,5 @@
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_shipPipeline, uniformBuffersMemory_shipPipeline, uniformBufferInfoList_shipPipeline);
-   createBufferSet(10 * sizeof(SBO_SceneObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+   createBufferSet(10 * sizeof(SSBO_ModelObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
       storageBuffers_shipPipeline, storageBuffersMemory_shipPipeline, storageBufferInfoList_shipPipeline);
 
@@ -506,4 +510,6 @@
          132, 133, 134,
          135, 136, 137,
+      }, {
+         mat4(1.0f)
       });
 
@@ -520,5 +526,5 @@
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_asteroidPipeline, uniformBuffersMemory_asteroidPipeline, uniformBufferInfoList_asteroidPipeline);
-   createBufferSet(10 * sizeof(SBO_Asteroid), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+   createBufferSet(10 * sizeof(SSBO_Asteroid), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
       storageBuffers_asteroidPipeline, storageBuffersMemory_asteroidPipeline, storageBufferInfoList_asteroidPipeline);
 
@@ -587,4 +593,8 @@
          24, 25, 26, 27, 28, 29,
          30, 31, 32, 33, 34, 35,
+      }, {
+         mat4(1.0f),
+         10.0f,
+         0
       });
 
@@ -620,14 +630,14 @@
 
 void VulkanGame::initGraphicsPipelines() {
-   modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>(physicalDevice, device, renderPass,
+   overlayPipeline = GraphicsPipeline_Vulkan<OverlayVertex, void*>(physicalDevice, device, renderPass,
+      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 4, 6);
+
+   modelPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject>(physicalDevice, device, renderPass,
       { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 16, 24);
 
-   overlayPipeline = GraphicsPipeline_Vulkan<OverlayVertex>(physicalDevice, device, renderPass,
-      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 4, 6);
-
-   shipPipeline = GraphicsPipeline_Vulkan<ShipVertex>(physicalDevice, device, renderPass,
+   shipPipeline = GraphicsPipeline_Vulkan<ShipVertex, SSBO_ModelObject>(physicalDevice, device, renderPass,
       { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 138, 138);
 
-   asteroidPipeline = GraphicsPipeline_Vulkan<AsteroidVertex>(physicalDevice, device, renderPass,
+   asteroidPipeline = GraphicsPipeline_Vulkan<AsteroidVertex, SSBO_Asteroid>(physicalDevice, device, renderPass,
       { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 24, 36);
 }
@@ -707,4 +717,6 @@
                      }), {
                         0, 1, 2, 2, 3, 0
+                     }, {
+                        mat4(1.0f)
                      });
 
@@ -1449,5 +1461,5 @@
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_scenePipeline, uniformBuffersMemory_scenePipeline, uniformBufferInfoList_scenePipeline);
-   createBufferSet(10 * sizeof(SBO_SceneObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+   createBufferSet(10 * sizeof(SSBO_ModelObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
       storageBuffers_scenePipeline, storageBuffersMemory_scenePipeline, storageBufferInfoList_scenePipeline);
 
@@ -1464,5 +1476,5 @@
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_shipPipeline, uniformBuffersMemory_shipPipeline, uniformBufferInfoList_shipPipeline);
-   createBufferSet(10 * sizeof(SBO_SceneObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+   createBufferSet(10 * sizeof(SSBO_ModelObject), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
       storageBuffers_shipPipeline, storageBuffersMemory_shipPipeline, storageBufferInfoList_shipPipeline);
 
@@ -1474,5 +1486,5 @@
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_asteroidPipeline, uniformBuffersMemory_asteroidPipeline, uniformBufferInfoList_asteroidPipeline);
-   createBufferSet(10 * sizeof(SBO_Asteroid), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+   createBufferSet(10 * sizeof(SSBO_Asteroid), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
       storageBuffers_asteroidPipeline, storageBuffersMemory_asteroidPipeline, storageBufferInfoList_asteroidPipeline);
 
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision 5a1ace07fab99988e1cc16659663dd54921b15f4)
+++ vulkan-game.hpp	(revision 2d8729794fc0b2af68f5b1a9b152e2e96258b598)
@@ -50,8 +50,9 @@
 // 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
-template<class VertexType>
+template<class VertexType, class SSBOType>
 struct SceneObject {
    vector<VertexType> vertices;
    vector<uint16_t> indices;
+   SSBOType ssbo;
 
    mat4 model_base;
@@ -64,9 +65,9 @@
 };
 
-struct SBO_SceneObject {
+struct SSBO_ModelObject {
    alignas(16) mat4 model;
 };
 
-struct SBO_Asteroid {
+struct SSBO_Asteroid {
    alignas(16) mat4 model;
    alignas(4) float hp;
@@ -146,13 +147,13 @@
       // TODO: Create a struct that holds the buffers, memory, and info objects (Probably in VulkanUtils)
 
-      GraphicsPipeline_Vulkan<OverlayVertex> overlayPipeline;
-
-      vector<SceneObject<OverlayVertex>> overlayObjects;
+      GraphicsPipeline_Vulkan<OverlayVertex, void*> overlayPipeline;
+
+      vector<SceneObject<OverlayVertex, void*>> overlayObjects;
 
       // TODO: Rename all the variables related to modelPipeline to use the same pipelie name
 
-      GraphicsPipeline_Vulkan<ModelVertex> modelPipeline;
-
-      vector<SceneObject<ModelVertex>> modelObjects;
+      GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject> modelPipeline;
+
+      vector<SceneObject<ModelVertex, SSBO_ModelObject>> modelObjects;
 
       vector<VkBuffer> uniformBuffers_scenePipeline;
@@ -165,9 +166,9 @@
 
       UBO_VP_mats object_VP_mats;
-      SBO_SceneObject so_Object;
-
-      GraphicsPipeline_Vulkan<ShipVertex> shipPipeline;
-
-      vector<SceneObject<ShipVertex>> shipObjects;
+      SSBO_ModelObject so_Object;
+
+      GraphicsPipeline_Vulkan<ShipVertex, SSBO_ModelObject> shipPipeline;
+
+      vector<SceneObject<ShipVertex, SSBO_ModelObject>> shipObjects;
 
       vector<VkBuffer> uniformBuffers_shipPipeline;
@@ -180,9 +181,9 @@
 
       UBO_VP_mats ship_VP_mats;
-      SBO_SceneObject so_Ship;
-
-      GraphicsPipeline_Vulkan<AsteroidVertex> asteroidPipeline;
-
-      vector<SceneObject<AsteroidVertex>> asteroidObjects;
+      SSBO_ModelObject so_Ship;
+
+      GraphicsPipeline_Vulkan<AsteroidVertex, SSBO_Asteroid> asteroidPipeline;
+
+      vector<SceneObject<AsteroidVertex, SSBO_Asteroid>> asteroidObjects;
 
       vector<VkBuffer> uniformBuffers_asteroidPipeline;
@@ -195,5 +196,5 @@
 
       UBO_VP_mats asteroid_VP_mats;
-      SBO_Asteroid so_Asteroid;
+      SSBO_Asteroid so_Asteroid;
 
       Uint64 curTime, prevTime;
@@ -231,7 +232,8 @@
       void createSyncObjects();
 
-      template<class VertexType>
-      void addObject(vector<SceneObject<VertexType>>& objects, GraphicsPipeline_Vulkan<VertexType>& pipeline,
-         const vector<VertexType>& vertices, vector<uint16_t> indices);
+      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);
 
       template<class VertexType>
@@ -244,6 +246,6 @@
       vector<VertexType> centerObject(vector<VertexType> vertices);
 
-      template<class VertexType>
-      void transformObject(SceneObject<VertexType>& obj, mat4 mat);
+      template<class VertexType, class SSBOType>
+      void transformObject(SceneObject<VertexType, SSBOType>& obj, mat4 mat);
 
       void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags,
@@ -261,7 +263,8 @@
 };
 
-template<class VertexType>
-void VulkanGame::addObject(vector<SceneObject<VertexType>>& objects, GraphicsPipeline_Vulkan<VertexType>& pipeline,
-      const vector<VertexType>& vertices, vector<uint16_t> indices) {
+template<class VertexType, class SSBOType>
+void VulkanGame::addObject(vector<SceneObject<VertexType, SSBOType>>& objects,
+      GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline,
+      const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo) {
    size_t numVertices = pipeline.getNumVertices();
 
@@ -270,5 +273,5 @@
    }
 
-   objects.push_back({ vertices, indices, mat4(1.0f), mat4(1.0f) });
+   objects.push_back({ vertices, indices, ssbo, mat4(1.0f), mat4(1.0f) });
 
    pipeline.addVertices(vertices, indices, commandPool, graphicsQueue);
@@ -341,6 +344,6 @@
 }
 
-template<class VertexType>
-void VulkanGame::transformObject(SceneObject<VertexType>& obj, mat4 mat) {
+template<class VertexType, class SSBOType>
+void VulkanGame::transformObject(SceneObject<VertexType, SSBOType>& obj, mat4 mat) {
    obj.model_transform = mat * obj.model_transform;
 }
