Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 8e02b6ba837700ee39877d03da5cd5112cf055d9)
+++ vulkan-game.cpp	(revision f97c5e78e8f533e4b803e95b4dbb4ec3f1358ff3)
@@ -184,10 +184,21 @@
 
    createImageResources();
-
    createFramebuffers();
-   createUniformBuffers();
-
-   modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>(physicalDevice, device, renderPass,
-      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 16, 24);
+
+   // TODO: Figure out how much of ubo creation and associated variables should be in the pipeline class
+   // Maybe combine the ubo-related objects into a new class
+
+   initGraphicsPipelines();
+
+   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));
+
+   createUniformBuffers<UBO_MvpMat>(uniformBuffers, uniformBuffersMemory, uniformBufferInfoList);
+
+   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+      VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList);
+   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+      VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor);
 
    modelPipeline.addObject({
@@ -209,13 +220,4 @@
       }, 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);
-   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-      VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor);
-
    modelPipeline.createDescriptorSetLayout();
    modelPipeline.createPipeline("shaders/scene-vert.spv", "shaders/scene-frag.spv");
@@ -223,6 +225,9 @@
    modelPipeline.createDescriptorSets(swapChainImages);
 
-   overlayPipeline = GraphicsPipeline_Vulkan<OverlayVertex>(physicalDevice, device, renderPass,
-      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 4, 6);
+   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);
 
    overlayPipeline.addObject({
@@ -235,10 +240,4 @@
       }, 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);
-
    overlayPipeline.createDescriptorSetLayout();
    overlayPipeline.createPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv");
@@ -253,4 +252,12 @@
 }
 
+void VulkanGame::initGraphicsPipelines() {
+   modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>(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);
+}
+
 // TODO: Maybe changes the name to initScene() or something similar
 void VulkanGame::initMatrices() {
@@ -263,11 +270,14 @@
    mat4 pitch_mat = rotate(mat4(1.0f), radians(-cam_pitch), vec3(1.0f, 0.0f, 0.0f));
 
-   mat4 R = pitch_mat * yaw_mat;
-   mat4 T = translate(mat4(1.0f), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
-
-   modelMvpMats.view = R * T;
-
-   modelMvpMats.proj = perspective(radians(FOV_ANGLE), (float)swapChainExtent.width / (float)swapChainExtent.height, NEAR_CLIP, FAR_CLIP);
-   modelMvpMats.proj[1][1] *= -1; // flip the y-axis so that +y is up
+   mat4 R_view = pitch_mat * yaw_mat;
+   mat4 T_view = translate(mat4(1.0f), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
+   mat4 view = R_view * T_view;
+
+   mat4 proj = perspective(radians(FOV_ANGLE), (float)swapChainExtent.width / (float)swapChainExtent.height, NEAR_CLIP, FAR_CLIP);
+   proj[1][1] *= -1; // flip the y-axis so that +y is up
+
+   modelMvpMats.model = mat4(1.0f);
+   modelMvpMats.view = view;
+   modelMvpMats.proj = proj;
 }
 
@@ -895,22 +905,4 @@
 }
 
-void VulkanGame::createUniformBuffers() {
-   VkDeviceSize bufferSize = sizeof(UBO_MvpMat);
-
-   uniformBuffers.resize(swapChainImages.size());
-   uniformBuffersMemory.resize(swapChainImages.size());
-   uniformBufferInfoList.resize(swapChainImages.size());
-
-   for (size_t i = 0; i < swapChainImages.size(); i++) {
-      VulkanUtils::createBuffer(device, physicalDevice, bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
-         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-         uniformBuffers[i], uniformBuffersMemory[i]);
-
-      uniformBufferInfoList[i].buffer = uniformBuffers[i];
-      uniformBufferInfoList[i].offset = 0;
-      uniformBufferInfoList[i].range = sizeof(UBO_MvpMat);
-   }
-}
-
 void VulkanGame::createCommandBuffers() {
    commandBuffers.resize(swapChainImages.size());
@@ -1006,5 +998,6 @@
       depthImage, graphicsQueue);
    createFramebuffers();
-   createUniformBuffers();
+
+   createUniformBuffers<UBO_MvpMat>(uniformBuffers, uniformBuffersMemory, uniformBufferInfoList);
 
    modelPipeline.updateRenderPass(renderPass);
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision 8e02b6ba837700ee39877d03da5cd5112cf055d9)
+++ vulkan-game.hpp	(revision f97c5e78e8f533e4b803e95b4dbb4ec3f1358ff3)
@@ -88,12 +88,11 @@
       VkSampler textureSampler;
 
-      vector<VkDescriptorBufferInfo> uniformBufferInfoList;
-
       // These are currently to store the MVP matrix
       // I should figure out if it makes sense to use them for other uniforms in the future
       // If not, I should rename them to better indicate their purpose.
-      // I should also decide if I can use these for all shaders, or if I need a separapte set of buffers for each one
       vector<VkBuffer> uniformBuffers;
       vector<VkDeviceMemory> uniformBuffersMemory;
+
+      vector<VkDescriptorBufferInfo> uniformBufferInfoList;
 
       VulkanImage floorTextureImage;
@@ -118,4 +117,5 @@
       bool initWindow(int width, int height, unsigned char guiFlags);
       void initVulkan();
+      void initGraphicsPipelines();
       void initMatrices();
       void mainLoop();
@@ -143,7 +143,10 @@
       void createTextureSampler();
       void createFramebuffers();
-      void createUniformBuffers();
       void createCommandBuffers();
       void createSyncObjects();
+
+      template<class UniformType>
+      void createUniformBuffers(vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
+         vector<VkDescriptorBufferInfo>& bufferInfoList);
 
       void recreateSwapChain();
@@ -158,3 +161,21 @@
 };
 
+template<class UniformType>
+void VulkanGame::createUniformBuffers(vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
+      vector<VkDescriptorBufferInfo>& bufferInfoList) {
+   buffers.resize(swapChainImages.size());
+   buffersMemory.resize(swapChainImages.size());
+   bufferInfoList.resize(swapChainImages.size());
+
+   for (size_t i = 0; i < swapChainImages.size(); i++) {
+      VulkanUtils::createBuffer(device, physicalDevice, sizeof(UniformType), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+         buffers[i], buffersMemory[i]);
+
+      bufferInfoList[i].buffer = buffers[i];
+      bufferInfoList[i].offset = 0;
+      bufferInfoList[i].range = sizeof(UniformType);
+   }
+}
+
 #endif // _VULKAN_GAME_H
