Index: graphics-pipeline_vulkan.hpp
===================================================================
--- graphics-pipeline_vulkan.hpp	(revision 0fe84333f0e448837677f6a2bd0c3f62b0a1d8c8)
+++ graphics-pipeline_vulkan.hpp	(revision d25381b88830bd62aa0ed8ef68e8641eff248736)
@@ -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;
