Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision cd487fb0c5641b29746b810d236ba7681bd75081)
+++ vulkan-game.cpp	(revision b8777b71951e1e62f58596dcb0b1cab6239cd405)
@@ -194,14 +194,14 @@
    createUniformBuffers();
 
-   vector<Vertex> sceneVertices = {
-      {{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
-      {{ 0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
-      {{ 0.5f,  0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
-      {{-0.5f,  0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-
-      {{-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}}
+   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 = {
@@ -210,22 +210,22 @@
    };
 
-   graphicsPipelines.push_back(GraphicsPipeline_Vulkan(physicalDevice, device, renderPass,
-      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, sizeof(Vertex)));
-
-   graphicsPipelines.back().bindData(sceneVertices, sceneIndices, commandPool, graphicsQueue);
-
-   graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&Vertex::pos));
-   graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&Vertex::color));
-   graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&Vertex::texCoord));
-
-   graphicsPipelines.back().addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+   modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>(physicalDevice, device, renderPass,
+      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, sizeof(ModelVertex));
+
+   modelPipeline.bindData(sceneVertices, sceneIndices, commandPool, graphicsQueue);
+
+   modelPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ModelVertex::pos));
+   modelPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ModelVertex::color));
+   modelPipeline.addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&ModelVertex::texCoord));
+
+   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
       VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList);
-   graphicsPipelines.back().addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
       VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor);
 
-   graphicsPipelines.back().createDescriptorSetLayout();
-   graphicsPipelines.back().createPipeline("shaders/scene-vert.spv", "shaders/scene-frag.spv");
-   graphicsPipelines.back().createDescriptorPool(swapChainImages);
-   graphicsPipelines.back().createDescriptorSets(swapChainImages);
+   modelPipeline.createDescriptorSetLayout();
+   modelPipeline.createPipeline("shaders/scene-vert.spv", "shaders/scene-frag.spv");
+   modelPipeline.createDescriptorPool(swapChainImages);
+   modelPipeline.createDescriptorSets(swapChainImages);
 
    vector<OverlayVertex> overlayVertices = {
@@ -239,21 +239,21 @@
    };
 
-   graphicsPipelines.push_back(GraphicsPipeline_Vulkan(physicalDevice, device, renderPass,
-      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, sizeof(OverlayVertex)));
-
-   graphicsPipelines.back().bindData(overlayVertices, overlayIndices, commandPool, graphicsQueue);
-
-   graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&OverlayVertex::pos));
-   graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&OverlayVertex::texCoord));
-
-   graphicsPipelines.back().addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+   overlayPipeline = GraphicsPipeline_Vulkan<OverlayVertex>(physicalDevice, device, renderPass,
+      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, sizeof(OverlayVertex));
+
+   overlayPipeline.bindData(overlayVertices, overlayIndices, commandPool, graphicsQueue);
+
+   overlayPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&OverlayVertex::pos));
+   overlayPipeline.addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&OverlayVertex::texCoord));
+
+   overlayPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
       VK_SHADER_STAGE_FRAGMENT_BIT, &sdlOverlayImageDescriptor);
 
-   graphicsPipelines.back().createDescriptorSetLayout();
-   graphicsPipelines.back().createPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv");
-   graphicsPipelines.back().createDescriptorPool(swapChainImages);
-   graphicsPipelines.back().createDescriptorSets(swapChainImages);
-
-   cout << "Created " << graphicsPipelines.size() << " graphics pipelines" << endl;
+   overlayPipeline.createDescriptorSetLayout();
+   overlayPipeline.createPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv");
+   overlayPipeline.createDescriptorPool(swapChainImages);
+   overlayPipeline.createDescriptorSets(swapChainImages);
+
+   cout << "Created all the graphics pipelines" << endl;
 
    numPlanes = 2;
@@ -290,6 +290,6 @@
                } else if (e.key.keycode == SDL_SCANCODE_SPACE) {
                   cout << "Adding a plane" << endl;
-                  float zOffset = -0.5f + (0.5f * numPlanes);
-                  vector<Vertex> vertices = {
+                  float zOffset = -2.0f + (0.5f * numPlanes);
+                  vector<ModelVertex> vertices = {
                      {{-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}},
@@ -301,10 +301,14 @@
                   };
 
-                  if (graphicsPipelines[0].addObject(vertices, indices, commandPool, graphicsQueue)) {
-                     vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
-                     createCommandBuffers();
-
-                     numPlanes++;
-                  }
+                  // 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);
+
+                  createCommandBuffers();
+
+                  numPlanes++;
                } else {
                   cout << "Key event detected" << endl;
@@ -429,7 +433,6 @@
    vkDestroySampler(device, textureSampler, nullptr);
 
-   for (GraphicsPipeline_Vulkan pipeline : graphicsPipelines) {
-      pipeline.cleanupBuffers();
-   }
+   modelPipeline.cleanupBuffers();
+   overlayPipeline.cleanupBuffers();
 
    for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
@@ -929,7 +932,6 @@
       vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
 
-      for (GraphicsPipeline_Vulkan pipeline : graphicsPipelines) {
-         pipeline.createRenderCommands(commandBuffers[i], i);
-      }
+      modelPipeline.createRenderCommands(commandBuffers[i], i);
+      overlayPipeline.createRenderCommands(commandBuffers[i], i);
 
       vkCmdEndRenderPass(commandBuffers[i]);
@@ -986,13 +988,13 @@
    createUniformBuffers();
 
-   graphicsPipelines[0].updateRenderPass(renderPass);
-   graphicsPipelines[0].createPipeline("shaders/scene-vert.spv", "shaders/scene-frag.spv");
-   graphicsPipelines[0].createDescriptorPool(swapChainImages);
-   graphicsPipelines[0].createDescriptorSets(swapChainImages);
-
-   graphicsPipelines[1].updateRenderPass(renderPass);
-   graphicsPipelines[1].createPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv");
-   graphicsPipelines[1].createDescriptorPool(swapChainImages);
-   graphicsPipelines[1].createDescriptorSets(swapChainImages);
+   modelPipeline.updateRenderPass(renderPass);
+   modelPipeline.createPipeline("shaders/scene-vert.spv", "shaders/scene-frag.spv");
+   modelPipeline.createDescriptorPool(swapChainImages);
+   modelPipeline.createDescriptorSets(swapChainImages);
+
+   overlayPipeline.updateRenderPass(renderPass);
+   overlayPipeline.createPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv");
+   overlayPipeline.createDescriptorPool(swapChainImages);
+   overlayPipeline.createDescriptorSets(swapChainImages);
 
    createCommandBuffers();
@@ -1026,7 +1028,6 @@
    vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
 
-   for (GraphicsPipeline_Vulkan pipeline : graphicsPipelines) {
-      pipeline.cleanup();
-   }
+   modelPipeline.cleanup();
+   overlayPipeline.cleanup();
 
    vkDestroyRenderPass(device, renderPass, nullptr);
