Index: VulkanGame.vcxproj
===================================================================
--- VulkanGame.vcxproj	(revision d2d9286a6d366401699becfa31a552c8c937ef7b)
+++ VulkanGame.vcxproj	(revision f98523128ff364e28235a14ad9eb901f7007b641)
@@ -158,4 +158,10 @@
     <ClInclude Include="vulkan-utils.hpp" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="shaders\overlay.frag" />
+    <None Include="shaders\overlay.vert" />
+    <None Include="shaders\scene.frag" />
+    <None Include="shaders\scene.vert" />
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision d2d9286a6d366401699becfa31a552c8c937ef7b)
+++ vulkan-game.cpp	(revision f98523128ff364e28235a14ad9eb901f7007b641)
@@ -2,4 +2,5 @@
 
 #include <array>
+#include <chrono>
 #include <iostream>
 #include <set>
@@ -297,4 +298,6 @@
    }
 
+   updateUniformBuffer(imageIndex);
+
    VkSubmitInfo submitInfo = {};
    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@@ -887,4 +890,22 @@
 }
 
+void VulkanGame::updateUniformBuffer(uint32_t currentImage) {
+   static auto startTime = chrono::high_resolution_clock::now();
+
+   auto currentTime = chrono::high_resolution_clock::now();
+   float time = chrono::duration<float, chrono::seconds::period>(currentTime - startTime).count();
+
+   UniformBufferObject ubo = {};
+   ubo.model = rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
+   ubo.view = lookAt(glm::vec3(0.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
+   ubo.proj = perspective(radians(45.0f), swapChainExtent.width / (float)swapChainExtent.height, 0.1f, 10.0f);
+   ubo.proj[1][1] *= -1; // flip the y-axis so that +y is up
+
+   void* data;
+   vkMapMemory(device, uniformBuffersMemory[currentImage], 0, sizeof(ubo), 0, &data);
+   memcpy(data, &ubo, sizeof(ubo));
+   vkUnmapMemory(device, uniformBuffersMemory[currentImage]);
+}
+
 void VulkanGame::cleanupSwapChain() {
    VulkanUtils::destroyVulkanImage(device, depthImage);
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision d2d9286a6d366401699becfa31a552c8c937ef7b)
+++ vulkan-game.hpp	(revision f98523128ff364e28235a14ad9eb901f7007b641)
@@ -125,4 +125,5 @@
 
       void recreateSwapChain();
+      void updateUniformBuffer(uint32_t currentImage);
 
       void cleanupSwapChain();
Index: vulkan-ref.cpp
===================================================================
--- vulkan-ref.cpp	(revision d2d9286a6d366401699becfa31a552c8c937ef7b)
+++ vulkan-ref.cpp	(revision f98523128ff364e28235a14ad9eb901f7007b641)
@@ -1794,9 +1794,7 @@
             throw runtime_error("failed to acquire swap chain image!");
          }
-/*** END OF REFACTORED CODE ***/
 
          updateUniformBuffer(imageIndex);
 
-/*** START OF REFACTORED CODE ***/
          VkSubmitInfo submitInfo = {};
          submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@@ -1876,5 +1874,4 @@
          populateImageFromSDLTexture(uiOverlay, sdlOverlayImage);
       }
-/*** END OF REFACTORED CODE ***/
 
       void updateUniformBuffer(uint32_t currentImage) {
@@ -1896,5 +1893,4 @@
       }
 
-/*** START OF REFACTORED CODE ***/
       void recreateSwapChain() {
          gui->refreshWindowSize();
