Index: graphics-pipeline_vulkan.hpp
===================================================================
--- graphics-pipeline_vulkan.hpp	(revision e8445f0578a1239a58166837998c25fe3ab0ecc3)
+++ graphics-pipeline_vulkan.hpp	(revision 9d21aac42227b516c5df135b6ff2266349c321e4)
@@ -21,14 +21,4 @@
 
 using namespace glm;
-
-// TODO: Maybe change the name of this struct so I can call the list something other than descriptorInfoList
-struct DescriptorInfo {
-   VkDescriptorType type;
-   VkShaderStageFlags stageFlags;
-
-   // Only one of the below properties should be set
-   vector<VkDescriptorBufferInfo>* bufferDataList;
-   VkDescriptorImageInfo* imageData;
-};
 
 // TODO: Use this struct for uniform buffers as well and rename it to VulkanBuffer (maybe move it to VulkanUtils)
@@ -41,8 +31,25 @@
 };
 
-template<class VertexType, class SSBOType>
+// TODO: Maybe change the name of this struct so I can call the list something other than descriptorInfoList
+struct DescriptorInfo {
+   VkDescriptorType type;
+   VkShaderStageFlags stageFlags;
+
+   // Only one of the below properties should be set
+   vector<VkDescriptorBufferInfo>* bufferDataList;
+   VkDescriptorImageInfo* imageData;
+};
+
+template<class VertexType>
 class GraphicsPipeline_Vulkan : public GraphicsPipeline {
    public:
       string vertShaderFile, fragShaderFile;
+
+      // TODO: Move this outside this classs, since it is no longer used here
+      StorageBufferSet storageBufferSet;
+
+      // Both of these are only used for managing the SSBO, so move them out as well
+      size_t objectCapacity;
+      size_t numObjects;
 
       GraphicsPipeline_Vulkan();
@@ -64,6 +71,4 @@
       void addAttribute(VkFormat format, size_t offset);
 
-      void addStorageDescriptor(VkShaderStageFlags stageFlags);
-
       // TODO: I might be able to use a single VkDescriptorBufferInfo here and reuse it when creating the descriptor sets
       void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags,
@@ -71,4 +76,7 @@
       void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData);
 
+      void updateDescriptorInfo(uint32_t index, vector<VkDescriptorBufferInfo>* bufferData);
+      // TODO: Maybe make an analogous one for updating image info
+
       void createPipeline(string vertShaderFile, string fragShaderFile);
       void createDescriptorSetLayout();
@@ -78,8 +86,6 @@
       void createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage);
 
-      bool addObject(const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType& ssbo,
-                     VkCommandPool commandPool, VkQueue graphicsQueue);
-
-      void updateObject(size_t objIndex, SSBOType& ssbo);
+      void addObject(const vector<VertexType>& vertices, vector<uint16_t> indices, VkCommandPool commandPool,
+                     VkQueue graphicsQueue);
 
       void updateObjectVertices(size_t objIndex, const vector<VertexType>& vertices, VkCommandPool commandPool,
@@ -117,9 +123,4 @@
       VkDeviceMemory indexBufferMemory;
 
-      size_t numObjects;
-      size_t objectCapacity;
-
-      StorageBufferSet storageBufferSet;
-
       VkShaderModule createShaderModule(const vector<char>& code);
       vector<char> readFile(const string& filename);
@@ -127,11 +128,10 @@
       void resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
       void resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
-      void resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue);
 };
 
 /*** PUBLIC METHODS ***/
 
-template<class VertexType, class SSBOType>
-GraphicsPipeline_Vulkan<VertexType, SSBOType>::GraphicsPipeline_Vulkan() {
+template<class VertexType>
+GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan() {
 }
 
@@ -139,6 +139,6 @@
 // TODO: See if it would be feasible to move code in the createPipeline method
 // into the constructor. That way, I can also put relevant cleanup code into the destructor
-template<class VertexType, class SSBOType>
-GraphicsPipeline_Vulkan<VertexType, SSBOType>::GraphicsPipeline_Vulkan(
+template<class VertexType>
+GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan(
       VkPrimitiveTopology topology, VkPhysicalDevice physicalDevice, VkDevice device,
       VkRenderPass renderPass, Viewport viewport, vector<VkImage>& swapChainImages,
@@ -173,45 +173,23 @@
    this->numObjects = 0;
    this->objectCapacity = objectCapacity;
-
-   // Hacky way to allow an SSBO to be optional
-   // Specifying void* as the SSBOType will skip allocating the related buffers
-   if (!is_same_v<SSBOType, void*>) {
-      VkDeviceSize bufferSize = objectCapacity * sizeof(SSBOType);
-      cout << "NUM SWAP CHAIN IMAGES: " << swapChainImages.size() << endl;
-
-      storageBufferSet.buffers.resize(swapChainImages.size());
-      storageBufferSet.memory.resize(swapChainImages.size());
-      storageBufferSet.infoSet.resize(swapChainImages.size());
-
-      for (size_t i = 0; i < swapChainImages.size(); i++) {
-         VulkanUtils::createBuffer(this->device, this->physicalDevice, bufferSize,
-            VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
-            VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-            storageBufferSet.buffers[i], storageBufferSet.memory[i]);
-
-         storageBufferSet.infoSet[i].buffer = storageBufferSet.buffers[i];
-         storageBufferSet.infoSet[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now
-         storageBufferSet.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE
-      }
-   }
 }
 
 // TODO: Move as much cleanup as I can into the destructor
-template<class VertexType, class SSBOType>
-GraphicsPipeline_Vulkan<VertexType, SSBOType>::~GraphicsPipeline_Vulkan() {
-}
-
-template<class VertexType, class SSBOType>
-size_t GraphicsPipeline_Vulkan<VertexType, SSBOType>::getNumVertices() {
+template<class VertexType>
+GraphicsPipeline_Vulkan<VertexType>::~GraphicsPipeline_Vulkan() {
+}
+
+template<class VertexType>
+size_t GraphicsPipeline_Vulkan<VertexType>::getNumVertices() {
    return numVertices;
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::updateRenderPass(VkRenderPass renderPass) {
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::updateRenderPass(VkRenderPass renderPass) {
    this->renderPass = renderPass;
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addAttribute(VkFormat format, size_t offset) {
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::addAttribute(VkFormat format, size_t offset) {
    VkVertexInputAttributeDescription attributeDesc = {};
 
@@ -224,27 +202,24 @@
 }
 
-// TODO: The SSBOType check isn't really needed since I call this function in VulkanGame explicitly
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addStorageDescriptor(VkShaderStageFlags stageFlags) {
-   if (!is_same_v<SSBOType, void*>) {
-      addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-         stageFlags, &storageBufferSet.infoSet);
-   }
-}
-
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addDescriptorInfo(VkDescriptorType type,
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::addDescriptorInfo(VkDescriptorType type,
       VkShaderStageFlags stageFlags, vector<VkDescriptorBufferInfo>* bufferData) {
    this->descriptorInfoList.push_back({ type, stageFlags, bufferData, nullptr });
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addDescriptorInfo(VkDescriptorType type,
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::addDescriptorInfo(VkDescriptorType type,
       VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData) {
    this->descriptorInfoList.push_back({ type, stageFlags, nullptr, imageData });
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createPipeline(string vertShaderFile, string fragShaderFile) {
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::updateDescriptorInfo(uint32_t index,
+                                                                         vector<VkDescriptorBufferInfo>* bufferData) {
+   this->descriptorInfoList[index].bufferDataList = bufferData;
+}
+
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::createPipeline(string vertShaderFile, string fragShaderFile) {
    this->vertShaderFile = vertShaderFile;
    this->fragShaderFile = fragShaderFile;
@@ -386,6 +361,6 @@
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorSetLayout() {
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::createDescriptorSetLayout() {
    vector<VkDescriptorSetLayoutBinding> bindings(this->descriptorInfoList.size());
 
@@ -408,6 +383,6 @@
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorPool(vector<VkImage>& swapChainImages) {
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::createDescriptorPool(vector<VkImage>& swapChainImages) {
    vector<VkDescriptorPoolSize> poolSizes(this->descriptorInfoList.size());
 
@@ -429,6 +404,6 @@
 
 // TODO: Since I only need the size of the swapChainImages array, I should just pass that in instead of the whole array
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorSets(vector<VkImage>& swapChainImages) {
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::createDescriptorSets(vector<VkImage>& swapChainImages) {
    vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), this->descriptorSetLayout);
 
@@ -476,8 +451,6 @@
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createRenderCommands(VkCommandBuffer& commandBuffer,
-      uint32_t currentImage) {
-
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage) {
    vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
 
@@ -494,9 +467,7 @@
 }
 
-template<class VertexType, class SSBOType>
-bool GraphicsPipeline_Vulkan<VertexType, SSBOType>::addObject(
-      const vector<VertexType>& vertices, vector<uint16_t> indices,
-      SSBOType& ssbo, VkCommandPool commandPool, VkQueue graphicsQueue) {
-
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::addObject(const vector<VertexType>& vertices, vector<uint16_t> indices,
+                                                    VkCommandPool commandPool, VkQueue graphicsQueue) {
    // TODO: When resizing the vertex or index buffer, take deleted objects into account.
    // Remove their data from the buffer and determine the new size of the bufer based on # of remining objects
@@ -522,46 +493,9 @@
       this->indexBuffer, this->numIndices, graphicsQueue);
    this->numIndices += indices.size();
-
-   bool resizedStorageBuffer = false;
-
-   if (!is_same_v<SSBOType, void*>) {
-      if (this->numObjects == this->objectCapacity) {
-         resizeStorageBufferSet(storageBufferSet, commandPool, graphicsQueue);
-         cleanup();
-
-         // Assume the SSBO is always the 2nd binding
-         this->descriptorInfoList[1].bufferDataList = &storageBufferSet.infoSet;
-         resizedStorageBuffer = true;
-
-         cout << "SSBO resized, New object capacity: " << this->objectCapacity << endl;
-
-         // TODO: I'll need to correctly update the descriptor set array instead of appending to it
-         // Then, I'll have to call createDescriptorSets() and finally createCommandBuffers() (from vulkan-game)
-         // This isn't too bad actually, since I have to call createCommandBuffers() every time I add a newobject
-         // anyway. So, in this function, I'll just have to call createDescriptorSets()
-      }
-
-      updateObject(this->numObjects, ssbo);
-   }
-
-   this->numObjects++;
-
-   return resizedStorageBuffer;
-}
-
-// TODO: Allow a swapchain index to be passed in instead of updating all of them
-// Actually, since I'm in the process of replacing SSBOs with dynamic UBOs, I can ignore that for this function
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::updateObject(size_t objIndex, SSBOType& ssbo) {
-   if (!is_same_v<SSBOType, void*>) {
-      for (size_t i = 0; i < storageBufferSet.memory.size(); i++) {
-         VulkanUtils::copyDataToMemory(this->device, ssbo, storageBufferSet.memory[i], objIndex * sizeof(SSBOType));
-      }
-   }
 }
 
 // Should only be used if the number of vertices has not changed
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::updateObjectVertices(size_t objIndex,
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::updateObjectVertices(size_t objIndex,
       const vector<VertexType>& vertices, VkCommandPool commandPool, VkQueue graphicsQueue) {
    VulkanUtils::copyDataToBuffer(this->device, this->physicalDevice, commandPool, vertices,
@@ -569,6 +503,6 @@
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::cleanup() {
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::cleanup() {
    vkDestroyPipeline(device, pipeline, nullptr);
    vkDestroyDescriptorPool(device, descriptorPool, nullptr);
@@ -579,6 +513,6 @@
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::cleanupBuffers() {
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::cleanupBuffers() {
    vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
 
@@ -587,17 +521,10 @@
    vkDestroyBuffer(device, indexBuffer, nullptr);
    vkFreeMemory(device, indexBufferMemory, nullptr);
-
-   if (!is_same_v<SSBOType, void*>) {
-      for (size_t i = 0; i < storageBufferSet.buffers.size(); i++) {
-         vkDestroyBuffer(device, storageBufferSet.buffers[i], nullptr);
-         vkFreeMemory(device, storageBufferSet.memory[i], nullptr);
-      }
-   }
 }
 
 /*** PRIVATE METHODS ***/
 
-template<class VertexType, class SSBOType>
-VkShaderModule GraphicsPipeline_Vulkan<VertexType, SSBOType>::createShaderModule(const vector<char>& code) {
+template<class VertexType>
+VkShaderModule GraphicsPipeline_Vulkan<VertexType>::createShaderModule(const vector<char>& code) {
    VkShaderModuleCreateInfo createInfo = {};
    createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
@@ -613,6 +540,6 @@
 }
 
-template<class VertexType, class SSBOType>
-vector<char> GraphicsPipeline_Vulkan<VertexType, SSBOType>::readFile(const string& filename) {
+template<class VertexType>
+vector<char> GraphicsPipeline_Vulkan<VertexType>::readFile(const string& filename) {
    ifstream file(filename, ios::ate | ios::binary);
 
@@ -632,7 +559,6 @@
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeVertexBuffer(VkCommandPool commandPool,
-      VkQueue graphicsQueue) {
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
    VkBuffer newVertexBuffer;
    VkDeviceMemory newVertexBufferMemory;
@@ -652,7 +578,6 @@
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeIndexBuffer(VkCommandPool commandPool,
-      VkQueue graphicsQueue) {
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
    VkBuffer newIndexBuffer;
    VkDeviceMemory newIndexBufferMemory;
@@ -672,33 +597,3 @@
 }
 
-template<class VertexType, class SSBOType>
-void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeStorageBufferSet(StorageBufferSet& set,
-      VkCommandPool commandPool, VkQueue graphicsQueue) {
-   this->objectCapacity *= 2;
-   VkDeviceSize bufferSize = objectCapacity * sizeof(SSBOType);
-
-   for (size_t i = 0; i < set.buffers.size(); i++) {
-      VkBuffer newStorageBuffer;
-      VkDeviceMemory newStorageBufferMemory;
-
-      VulkanUtils::createBuffer(this->device, this->physicalDevice, bufferSize,
-         VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
-         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-         newStorageBuffer, newStorageBufferMemory);
-
-      VulkanUtils::copyBuffer(this->device, commandPool, set.buffers[i], newStorageBuffer,
-         0, 0, this->numObjects * sizeof(SSBOType), graphicsQueue);
-
-      vkDestroyBuffer(this->device, set.buffers[i], nullptr);
-      vkFreeMemory(this->device, set.memory[i], nullptr);
-
-      set.buffers[i] = newStorageBuffer;
-      set.memory[i] = newStorageBufferMemory;
-
-      set.infoSet[i].buffer = set.buffers[i];
-      set.infoSet[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now
-      set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE
-   }
-}
-
 #endif // _GRAPHICS_PIPELINE_VULKAN_H
