Index: VulkanGame.vcxproj
===================================================================
--- VulkanGame.vcxproj	(revision b8777b71951e1e62f58596dcb0b1cab6239cd405)
+++ VulkanGame.vcxproj	(revision 5a0242e2ac582251271b63c0be3d2e8512eaeb9f)
@@ -135,5 +135,4 @@
     <ClCompile Include="FileStackWalker.cpp" />
     <ClCompile Include="game-gui-sdl.cpp" />
-    <ClCompile Include="graphics-pipeline_vulkan.cpp" />
     <ClCompile Include="logger.cpp" />
     <ClCompile Include="main-vulkan.cpp" />
Index: graphics-pipeline_vulkan.hpp
===================================================================
--- graphics-pipeline_vulkan.hpp	(revision b8777b71951e1e62f58596dcb0b1cab6239cd405)
+++ graphics-pipeline_vulkan.hpp	(revision 5a0242e2ac582251271b63c0be3d2e8512eaeb9f)
@@ -24,8 +24,10 @@
 };
 
+// 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>
 struct SceneObject {
    vector<VertexType> vertices;
-   vector<uint16_t> indices; // TODO: Create a typedef for index type so I can easily change uin16_t to something else later
+   vector<uint16_t> indices;
 };
 
@@ -35,16 +37,8 @@
       GraphicsPipeline_Vulkan();
       GraphicsPipeline_Vulkan(VkPhysicalDevice physicalDevice, VkDevice device, VkRenderPass renderPass,
-         Viewport viewport, int vertexSize);
+         Viewport viewport, size_t vertexCapacity, size_t indexCapacity);
       ~GraphicsPipeline_Vulkan();
 
       void updateRenderPass(VkRenderPass renderPass);
-
-      void bindData(const vector<VertexType>& vertices, const vector<uint16_t>& indices,
-         VkCommandPool commandPool, VkQueue graphicsQueue);
-
-      void createVertexBuffer(const void* bufferData, int vertexSize, VkCommandPool commandPool,
-         VkQueue graphicsQueue);
-      void createIndexBuffer(const void* bufferData, int indexSize, VkCommandPool commandPool,
-         VkQueue graphicsQueue);
 
       // Maybe I should rename these to addVertexAttribute (addVaryingAttribute) and addUniformAttribute
@@ -62,5 +56,5 @@
       void createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage);
 
-      bool addObject(const vector<VertexType>& vertices, vector<uint16_t>& indices, VkCommandPool commandPool,
+      bool addObject(const vector<VertexType>& vertices, vector<uint16_t> indices, VkCommandPool commandPool,
          VkQueue graphicsQueue);
 
@@ -100,5 +94,6 @@
       vector<char> readFile(const string& filename);
 
-      void resizeDataBuffers();
+      void resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
+      void resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
 };
 
@@ -111,5 +106,5 @@
 template<class VertexType>
 GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan(VkPhysicalDevice physicalDevice, VkDevice device,
-      VkRenderPass renderPass, Viewport viewport, int vertexSize) {
+      VkRenderPass renderPass, Viewport viewport, size_t vertexCapacity, size_t indexCapacity) {
    this->physicalDevice = physicalDevice;
    this->device = device;
@@ -121,6 +116,20 @@
    // I can calculate the stride myself given info about all the varying attributes
    this->bindingDescription.binding = 0;
-   this->bindingDescription.stride = vertexSize;
+   this->bindingDescription.stride = sizeof(VertexType);
    this->bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
+
+   this->numVertices = 0;
+   this->vertexCapacity = vertexCapacity;
+
+   VulkanUtils::createBuffer(device, physicalDevice, vertexCapacity * sizeof(VertexType),
+      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
+      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);
+
+   this->numIndices = 0;
+   this->indexCapacity = indexCapacity;
+
+   VulkanUtils::createBuffer(device, physicalDevice, indexCapacity * sizeof(uint16_t),
+      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
+      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory);
 }
 
@@ -132,77 +141,4 @@
 void GraphicsPipeline_Vulkan<VertexType>::updateRenderPass(VkRenderPass renderPass) {
    this->renderPass = renderPass;
-}
-
-// TODO: Probably better to template the whole class
-// TODO: Change the index type to uint32_t and check the Vulkan Tutorial loading model section as a reference
-
-// TODO: combine this function and the constructor since I call this right after the constructor anyway
-// TODO: Creating the initial buffers could occur in the constructor and instead of calling this function
-// and passing in vertices and indices, addObject() could be called instead and this function could be
-// removed
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::bindData(const vector<VertexType>& vertices, const vector<uint16_t>& indices,
-      VkCommandPool commandPool, VkQueue graphicsQueue) {
-   numVertices = vertices.size();
-   vertexCapacity = numVertices * 2;
-   createVertexBuffer(vertices.data(), sizeof(VertexType), commandPool, graphicsQueue);
-
-   numIndices = indices.size();
-   indexCapacity = numIndices * 2;
-   createIndexBuffer(indices.data(), sizeof(uint16_t), commandPool, graphicsQueue);
-}
-
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::createVertexBuffer(const void* bufferData, int vertexSize,
-      VkCommandPool commandPool, VkQueue graphicsQueue) {
-   VkDeviceSize bufferSize = numVertices * vertexSize;
-   VkDeviceSize bufferCapacity = vertexCapacity * vertexSize;
-
-   VkBuffer stagingBuffer;
-   VkDeviceMemory stagingBufferMemory;
-   VulkanUtils::createBuffer(device, physicalDevice, bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
-      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-      stagingBuffer, stagingBufferMemory);
-
-   void* data;
-   vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
-   memcpy(data, bufferData, (size_t) bufferSize);
-   vkUnmapMemory(device, stagingBufferMemory);
-
-   VulkanUtils::createBuffer(device, physicalDevice, bufferCapacity,
-      VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
-      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);
-
-   VulkanUtils::copyBuffer(device, commandPool, stagingBuffer, vertexBuffer, 0, 0, bufferSize, graphicsQueue);
-
-   vkDestroyBuffer(device, stagingBuffer, nullptr);
-   vkFreeMemory(device, stagingBufferMemory, nullptr);
-}
-
-template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::createIndexBuffer(const void* bufferData, int indexSize,
-      VkCommandPool commandPool, VkQueue graphicsQueue) {
-   VkDeviceSize bufferSize = numIndices * indexSize;
-   VkDeviceSize bufferCapacity = indexCapacity * indexSize;
-
-   VkBuffer stagingBuffer;
-   VkDeviceMemory stagingBufferMemory;
-   VulkanUtils::createBuffer(device, physicalDevice, bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
-      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-      stagingBuffer, stagingBufferMemory);
-
-   void* data;
-   vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
-   memcpy(data, bufferData, (size_t) bufferSize);
-   vkUnmapMemory(device, stagingBufferMemory);
-
-   VulkanUtils::createBuffer(device, physicalDevice, bufferCapacity,
-      VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
-      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory);
-
-   VulkanUtils::copyBuffer(device, commandPool, stagingBuffer, indexBuffer, 0, 0, bufferSize, graphicsQueue);
-
-   vkDestroyBuffer(device, stagingBuffer, nullptr);
-   vkFreeMemory(device, stagingBufferMemory, nullptr);
 }
 
@@ -470,12 +406,12 @@
 
 template<class VertexType>
-bool GraphicsPipeline_Vulkan<VertexType>::addObject(const vector<VertexType>& vertices, vector<uint16_t>& indices,
+bool GraphicsPipeline_Vulkan<VertexType>::addObject(const vector<VertexType>& vertices, vector<uint16_t> indices,
       VkCommandPool commandPool, VkQueue graphicsQueue) {
 
-   if (numVertices + vertices.size() > vertexCapacity ||
-       numIndices + indices.size() > indexCapacity) {
-      resizeDataBuffers();
-
-      throw runtime_error("ERROR: Need to resize data buffers");
+   if (numVertices + vertices.size() > vertexCapacity) {
+      resizeVertexBuffer(commandPool, graphicsQueue);
+   }
+   if (numIndices + indices.size() > indexCapacity) {
+      resizeIndexBuffer(commandPool, graphicsQueue);
    }
 
@@ -483,4 +419,5 @@
       idx += numVertices;
    }
+   objects.push_back({vertices, indices });
 
    VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, vertices, vertexBuffer, numVertices,
@@ -549,21 +486,39 @@
 
 template<class VertexType>
-void GraphicsPipeline_Vulkan<VertexType>::resizeDataBuffers() {
-   
+void GraphicsPipeline_Vulkan<VertexType>::resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
+   VkBuffer newVertexBuffer;
+   VkDeviceMemory newVertexBufferMemory;
+   vertexCapacity *= 2;
+
+   VulkanUtils::createBuffer(device, physicalDevice, vertexCapacity * sizeof(VertexType),
+      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
+      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newVertexBuffer, newVertexBufferMemory);
+
+   VulkanUtils::copyBuffer(device, commandPool, vertexBuffer, newVertexBuffer, 0, 0, numVertices * sizeof(VertexType), graphicsQueue);
+
    vkDestroyBuffer(device, vertexBuffer, nullptr);
    vkFreeMemory(device, vertexBufferMemory, nullptr);
+
+   vertexBuffer = newVertexBuffer;
+   vertexBufferMemory = newVertexBufferMemory;
+}
+
+template<class VertexType>
+void GraphicsPipeline_Vulkan<VertexType>::resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
+   VkBuffer newIndexBuffer;
+   VkDeviceMemory newIndexBufferMemory;
+   indexCapacity *= 2;
+
+   VulkanUtils::createBuffer(device, physicalDevice, indexCapacity * sizeof(uint16_t),
+      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
+      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newIndexBuffer, newIndexBufferMemory);
+
+   VulkanUtils::copyBuffer(device, commandPool, indexBuffer, newIndexBuffer, 0, 0, numIndices * sizeof(uint16_t), graphicsQueue);
+
    vkDestroyBuffer(device, indexBuffer, nullptr);
    vkFreeMemory(device, indexBufferMemory, nullptr);
 
-   vertexCapacity *= 2;
-   indexCapacity *= 2;
-
-   VulkanUtils::createBuffer(device, physicalDevice, vertexCapacity * sizeof(VertexType),
-      VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
-      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);
-
-   VulkanUtils::createBuffer(device, physicalDevice, indexCapacity * sizeof(uint16_t),
-      VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
-      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory);
+   indexBuffer = newIndexBuffer;
+   indexBufferMemory = newIndexBufferMemory;
 }
 
Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision b8777b71951e1e62f58596dcb0b1cab6239cd405)
+++ vulkan-game.cpp	(revision 5a0242e2ac582251271b63c0be3d2e8512eaeb9f)
@@ -194,24 +194,24 @@
    createUniformBuffers();
 
-   vector<ModelVertex> sceneVertices = {
-      {{-0.5f, -0.5f, -2.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
-      {{ 0.5f, -0.5f, -2.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
-      {{ 0.5f,  0.5f, -2.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
-      {{-0.5f,  0.5f, -2.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-
-      {{-0.5f, -0.5f, -1.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
-      {{ 0.5f, -0.5f, -1.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
-      {{ 0.5f,  0.5f, -1.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
-      {{-0.5f,  0.5f, -1.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
-   };
-   vector<uint16_t> sceneIndices = {
-      0, 1, 2, 2, 3, 0,
-      4, 5, 6, 6, 7, 4
-   };
-
    modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>(physicalDevice, device, renderPass,
-      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, sizeof(ModelVertex));
-
-   modelPipeline.bindData(sceneVertices, sceneIndices, commandPool, graphicsQueue);
+      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 16, 24);
+
+   modelPipeline.addObject({
+         {{-0.5f, -0.5f, -2.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
+         {{ 0.5f, -0.5f, -2.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
+         {{ 0.5f,  0.5f, -2.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
+         {{-0.5f,  0.5f, -2.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
+      }, {
+         0, 1, 2, 2, 3, 0
+      }, commandPool, graphicsQueue);
+
+   modelPipeline.addObject({
+         {{-0.5f, -0.5f, -1.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
+         {{ 0.5f, -0.5f, -1.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
+         {{ 0.5f,  0.5f, -1.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
+         {{-0.5f,  0.5f, -1.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
+      }, {
+         0, 1, 2, 2, 3, 0
+      }, commandPool, graphicsQueue);
 
    modelPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ModelVertex::pos));
@@ -229,18 +229,15 @@
    modelPipeline.createDescriptorSets(swapChainImages);
 
-   vector<OverlayVertex> overlayVertices = {
-      {{-1.0f,  1.0f,  0.0f}, {0.0f, 1.0f}},
-      {{ 1.0f,  1.0f,  0.0f}, {1.0f, 1.0f}},
-      {{ 1.0f, -1.0f,  0.0f}, {1.0f, 0.0f}},
-      {{-1.0f, -1.0f,  0.0f}, {0.0f, 0.0f}}
-   };
-   vector<uint16_t> overlayIndices = {
-      0, 1, 2, 2, 3, 0
-   };
-
    overlayPipeline = GraphicsPipeline_Vulkan<OverlayVertex>(physicalDevice, device, renderPass,
-      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, sizeof(OverlayVertex));
-
-   overlayPipeline.bindData(overlayVertices, overlayIndices, commandPool, graphicsQueue);
+      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 4, 6);
+
+   overlayPipeline.addObject({
+         {{-1.0f,  1.0f,  0.0f}, {0.0f, 1.0f}},
+         {{ 1.0f,  1.0f,  0.0f}, {1.0f, 1.0f}},
+         {{ 1.0f, -1.0f,  0.0f}, {1.0f, 0.0f}},
+         {{-1.0f, -1.0f,  0.0f}, {0.0f, 0.0f}}
+      }, {
+         0, 1, 2, 2, 3, 0
+      }, commandPool, graphicsQueue);
 
    overlayPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&OverlayVertex::pos));
@@ -291,20 +288,16 @@
                   cout << "Adding a plane" << endl;
                   float zOffset = -2.0f + (0.5f * numPlanes);
-                  vector<ModelVertex> vertices = {
+
+                  vkDeviceWaitIdle(device);
+                  vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
+
+                  modelPipeline.addObject({
                      {{-0.5f, -0.5f,  zOffset}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
                      {{ 0.5f, -0.5f,  zOffset}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
                      {{ 0.5f,  0.5f,  zOffset}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
                      {{-0.5f,  0.5f,  zOffset}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
-                  };
-                  vector<uint16_t> indices = {
+                  }, {
                      0, 1, 2, 2, 3, 0
-                  };
-
-                  // TODO: Encapsulate these lines into an addObject() function in vulkan-game
-
-                  vkDeviceWaitIdle(device);
-                  vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
-
-                  modelPipeline.addObject(vertices, indices, commandPool, graphicsQueue);
+                  }, commandPool, graphicsQueue);
 
                   createCommandBuffers();
@@ -314,4 +307,6 @@
                   cout << "Key event detected" << endl;
                }
+               break;
+            case UI_EVENT_KEYUP:
                break;
             case UI_EVENT_MOUSEBUTTONDOWN:
