Index: new-game.cpp
===================================================================
--- new-game.cpp	(revision 52a02e69e392cc9a436263ac91bd0660624c2b95)
+++ new-game.cpp	(revision 4a9416a988cc9dbc7460f1c5db43de22e12258e7)
@@ -47,4 +47,5 @@
 };
 
+/*** START OF REFACTORED CODE ***/
 enum ObjectType {
    TYPE_SHIP,
@@ -67,4 +68,5 @@
    UNIFORM_3F,
 };
+/*** END OF REFACTORED CODE ***/
 
 enum UIValueType {
@@ -73,4 +75,5 @@
 };
 
+/*** START OF REFACTORED CODE ***/
 struct SceneObject {
    unsigned int id;
@@ -153,4 +156,5 @@
    unsigned int vboCapacity;
 };
+/*** END OF REFACTORED CODE ***/
 
 struct UIValue {
@@ -193,5 +197,4 @@
                   map<ObjectType, ShaderModelGroup>& modelGroups,
                   GLuint ubo);
-/*** END OF REFACTORED CODE ***/
 void removeObjectFromScene(SceneObject& obj, GLuint ubo);
 
@@ -200,5 +203,4 @@
 void addModelToGroup(ShaderModelGroup& modelGroup, SceneObject& model);
 
-/*** START OF REFACTORED CODE ***/
 void defineModelGroupAttrib(ShaderModelGroup& modelGroup, string name, AttribType attribType, GLint size, GLenum type, size_t fieldOffset);
 void defineModelGroupUniform(ShaderModelGroup& modelGroup, string name, AttribType attribType, GLint size, UniformType type, GLfloat* data);
@@ -206,5 +208,4 @@
 void bindUniformData(AttribInfo& attrib);
 void bindUniformData(AttribInfo& attrib, GLfloat* data);
-/*** END OF REFACTORED CODE ***/
 
 size_t GLsizeof(GLenum);
@@ -214,5 +215,4 @@
 void calculateObjectBoundingBox(SceneObject* obj);
 
-/*** START OF REFACTORED CODE ***/
 void populateBuffers(vector<SceneObject*>& objects,
                   map<GLuint, BufferInfo>& shaderBufferInfo,
@@ -231,8 +231,6 @@
 Asteroid* createAsteroid(vec3 pos);
 Laser* createLaser(vec3 start, vec3 end, vec3 color, GLfloat width);
-/*** END OF REFACTORED CODE ***/
 ParticleEffect* createExplosion(mat4 model_mat);
 
-/*** START OF REFACTORED CODE ***/
 void translateLaser(Laser* laser, const vec3& translation, GLuint ubo);
 void updateLaserTarget(Laser* laser, vector<SceneObject*>& objects, ShaderModelGroup& laserSmg, GLuint asteroid_sp);
@@ -254,7 +252,9 @@
 
 const int KEY_STATE_UNCHANGED = -1;
+/*** START OF REFACTORED CODE ***/
 const bool FULLSCREEN = false;
 const int EXPLOSION_PARTICLE_COUNT = 300;
 unsigned int MAX_UNIFORMS = 0; // Requires OpenGL constants only available at runtime, so it can't be const
+/*** END OF REFACTORED CODE ***/
 
 int key_state[NUM_KEYS];
@@ -381,5 +381,4 @@
       cout << "OpenGL debug message callback is not supported" << endl;
    }
-/*** END OF REFACTORED CODE ***/
 
    srand(time(0));
@@ -409,5 +408,4 @@
    cout << "MAX_UNIFORMS: " << MAX_UNIFORMS << endl;
 
-/*** START OF REFACTORED CODE ***/
    // Setup Dear ImGui binding
    IMGUI_CHECKVERSION();
@@ -489,4 +487,5 @@
     */
 
+/*** START OF REFACTORED CODE ***/
    GLfloat laserColor[3] = {0.2f, 1.0f, 0.2f};
    GLfloat curTime, prevTime, elapsedTime;
@@ -498,5 +497,4 @@
    map<ObjectType, ShaderModelGroup> modelGroups;
 
-/*** START OF REFACTORED CODE ***/
    modelGroups[TYPE_SHIP] = createModelGroup(
       loadShaderProgram("gl-shaders/ship.vert", "gl-shaders/ship.frag"));
@@ -558,5 +556,4 @@
 
    initModelGroupAttribs(modelGroups[TYPE_LASER]);
-/*** END OF REFACTORED CODE ***/
 
    modelGroups[TYPE_EXPLOSION] = createModelGroup(
@@ -580,5 +577,4 @@
    initModelGroupAttribs(modelGroups[TYPE_EXPLOSION]);
 
-/*** START OF REFACTORED CODE ***/
    cam_pos = vec3(0.0f, 0.0f, 2.0f);
    float cam_yaw = 0.0f * 2.0f * 3.14159f / 360.0f;
@@ -666,10 +662,8 @@
 
    GLuint laser_sp_models_ub_index = glGetUniformBlockIndex(modelGroups[TYPE_LASER].shaderProgram, "models");
-/*** END OF REFACTORED CODE ***/
 
    GLuint explosion_sp_models_ub_index = glGetUniformBlockIndex(modelGroups[TYPE_EXPLOSION].shaderProgram, "models");
 
 
-/*** START OF REFACTORED CODE ***/
    glUseProgram(modelGroups[TYPE_SHIP].shaderProgram);
    bindUniformData(modelGroups[TYPE_SHIP].attribs["view"]);
@@ -698,5 +692,4 @@
    glUniformBlockBinding(modelGroups[TYPE_LASER].shaderProgram, laser_sp_models_ub_index, ub_binding_point);
    glBindBufferRange(GL_UNIFORM_BUFFER, ub_binding_point, ubo, 0, GL_MAX_UNIFORM_BLOCK_SIZE);
-/*** END OF REFACTORED CODE ***/
 
 
@@ -707,4 +700,5 @@
    glUniformBlockBinding(modelGroups[TYPE_EXPLOSION].shaderProgram, explosion_sp_models_ub_index, ub_binding_point);
    glBindBufferRange(GL_UNIFORM_BUFFER, ub_binding_point, ubo, 0, GL_MAX_UNIFORM_BLOCK_SIZE);
+/*** END OF REFACTORED CODE ***/
 
 
@@ -881,4 +875,5 @@
                      score++;
 
+/*** START OF REFACTORED CODE ***/
                      addObjectToScene(createExplosion(model_mat), shaderBufferInfo, modelGroups, ubo);
                   }
@@ -889,5 +884,4 @@
                   }
                }
-/*** START OF REFACTORED CODE ***/
             }
          }
@@ -977,10 +971,8 @@
          cam_moved = false;
       }
-/*** END OF REFACTORED CODE ***/
 
       glUseProgram(modelGroups[TYPE_EXPLOSION].shaderProgram);
       bindUniformData(modelGroups[TYPE_EXPLOSION].attribs["cur_time"]);
 
-/*** START OF REFACTORED CODE ***/
       // Render scene
 
@@ -1200,4 +1192,5 @@
 
 
+/*** START OF REFACTORED CODE ***/
 GLuint loadShader(GLenum type, string file) {
   cout << "Loading shader from file " << file << endl;
@@ -1279,4 +1272,5 @@
   return image_data;
 }
+/*** END OF REFACTORED CODE ***/
 
 bool faceClicked(array<vec3, 3> points, SceneObject* obj, vec4 world_ray, vec4 cam, vec4& click_point) {
@@ -1324,4 +1318,5 @@
 }
 
+/*** START OF REFACTORED CODE ***/
 // TODO: Pass a reference, not a pointer
 void initObject(SceneObject* obj) {
@@ -1446,5 +1441,4 @@
 }
 
-/*** START OF REFACTORED CODE ***/
 SceneObject* createShip() {
    SceneObject* ship = new SceneObject();
@@ -1917,5 +1911,4 @@
    return obj;
 }
-/*** END OF REFACTORED CODE ***/
 
 ShaderModelGroup createModelGroup(GLuint shaderProgram) {
@@ -1942,5 +1935,4 @@
 }
 
-/*** START OF REFACTORED CODE ***/
 void defineModelGroupAttrib(ShaderModelGroup& modelGroup, string name, AttribType attribType,
                   GLint size, GLenum type, size_t fieldOffset) {
@@ -2031,5 +2023,4 @@
    }
 }
-/*** END OF REFACTORED CODE ***/
 
 /* The purpose of this function is to replace the use of sizeof() when calling
@@ -2403,4 +2394,5 @@
    glDisable(GL_BLEND);
 }
+/*** END OF REFACTORED CODE ***/
 
 void renderSceneGui(map<string, vector<UIValue>> valueLists) {
@@ -2671,5 +2663,4 @@
    return obj;
 }
-/*** END OF REFACTORED CODE ***/
 
 // TODO: Maybe pass in startTime instead of calling glfwGetTime() here
@@ -2703,2 +2694,3 @@
    return obj;
 }
+/*** END OF REFACTORED CODE ***/
Index: shaders/explosion.frag
===================================================================
--- shaders/explosion.frag	(revision 4a9416a988cc9dbc7460f1c5db43de22e12258e7)
+++ shaders/explosion.frag	(revision 4a9416a988cc9dbc7460f1c5db43de22e12258e7)
@@ -0,0 +1,10 @@
+#version 450
+#extension GL_ARB_separate_shader_objects : enable
+
+layout(location = 0) in float opacity;
+
+layout(location = 0) out vec4 frag_color;
+
+void main() {
+   frag_color = vec4(1.0, opacity * opacity, 0.0, opacity);
+}
Index: shaders/explosion.vert
===================================================================
--- shaders/explosion.vert	(revision 4a9416a988cc9dbc7460f1c5db43de22e12258e7)
+++ shaders/explosion.vert	(revision 4a9416a988cc9dbc7460f1c5db43de22e12258e7)
@@ -0,0 +1,61 @@
+#version 450
+#extension GL_ARB_separate_shader_objects : enable
+
+struct Object {
+   mat4 model;
+   float explosion_start_time;
+   float explosion_duration;
+   bool deleted;
+};
+
+layout (binding = 0) uniform UniformBufferObject {
+   mat4 view;
+   mat4 proj;
+   float cur_time;
+} ubo;
+
+layout(binding = 1) readonly buffer StorageBufferObject {
+   Object objects[];
+} sbo;
+
+layout(location = 0) in vec3 particle_start_velocity;
+layout(location = 1) in float particle_start_time;
+layout(location = 2) in uint obj_index;
+
+layout(location = 0) out float opacity;
+
+void main() {
+   mat4 model = sbo.objects[obj_index].model;
+   float explosion_start_time = sbo.objects[obj_index].explosion_start_time;
+   float explosion_duration = sbo.objects[obj_index].explosion_duration;
+   bool deleted = sbo.objects[obj_index].deleted;
+
+   float t = ubo.cur_time - explosion_start_time - particle_start_time;
+
+   if (t < 0.0) {
+      opacity = 0.0;
+   } else {
+      // Need to find out the last time this particle was at the origin
+      // If that is greater than the duration, hide the particle
+      float cur = floor(t / explosion_duration);
+      float end = floor((explosion_duration - particle_start_time) / explosion_duration);
+      if (cur > end) {
+         opacity = 0.0;
+      } else {
+         opacity = 1.0 - (t / explosion_duration);
+      }
+   }
+
+   if (deleted) {
+      gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
+   } else {
+      //  this is the center of the explosion
+      vec3 p = vec3(0.0, 0.0, 0.0);
+
+      // allow time to loop around so particle emitter keeps going
+      p += normalize(particle_start_velocity) * mod(t, explosion_duration) / explosion_duration * 0.3;
+
+      gl_Position = ubo.proj * ubo.view * model * vec4(p, 1.0);
+   }
+   gl_PointSize = 10.0; // size in pixels
+}
Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 52a02e69e392cc9a436263ac91bd0660624c2b95)
+++ vulkan-game.cpp	(revision 4a9416a988cc9dbc7460f1c5db43de22e12258e7)
@@ -3,4 +3,5 @@
 #include <array>
 #include <iostream>
+#include <numeric>
 #include <set>
 
@@ -28,4 +29,5 @@
    this->asteroid_VP_mats = {};
    this->laser_VP_mats = {};
+   this->explosion_UBO = {};
 }
 
@@ -564,4 +566,20 @@
    laserPipeline.createDescriptorSets(swapChainImages);
 
+   explosionPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ExplosionVertex::particleStartVelocity));
+   explosionPipeline.addAttribute(VK_FORMAT_R32_SFLOAT, offset_of(&ExplosionVertex::particleStartTime));
+   explosionPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ExplosionVertex::objIndex));
+
+   createBufferSet(sizeof(UBO_Explosion), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+      uniformBuffers_explosionPipeline, uniformBuffersMemory_explosionPipeline, uniformBufferInfoList_explosionPipeline);
+
+   explosionPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+      VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_explosionPipeline);
+   explosionPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
+
+   explosionPipeline.createDescriptorSetLayout();
+   explosionPipeline.createPipeline("shaders/explosion-vert.spv", "shaders/explosion-frag.spv");
+   explosionPipeline.createDescriptorPool(swapChainImages);
+   explosionPipeline.createDescriptorSets(swapChainImages);
+
    cout << "Created all the graphics pipelines" << endl;
 
@@ -591,4 +609,9 @@
       VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
       { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 8, 18, 2);
+
+   explosionPipeline = GraphicsPipeline_Vulkan<ExplosionVertex, SSBO_Explosion>(
+      VK_PRIMITIVE_TOPOLOGY_POINT_LIST, physicalDevice, device, renderPass,
+      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height },
+      swapChainImages, EXPLOSION_PARTICLE_COUNT, EXPLOSION_PARTICLE_COUNT, 2);
 }
 
@@ -621,4 +644,7 @@
    laser_VP_mats.view = viewMat;
    laser_VP_mats.proj = projMat;
+
+   explosion_UBO.view = viewMat;
+   explosion_UBO.proj = projMat;
 }
 
@@ -691,5 +717,5 @@
                      vec3(-0.21f, -1.19f, 1.76f) + offset,
                      vec3(-0.21f, -1.19f, -3.0f) + offset,
-                     vec3(1.0f, 0.0f, 0.0f), 0.03f);
+                     LASER_COLOR, 0.03f);
 
                   leftLaserIdx = laserObjects.size() - 1;
@@ -700,5 +726,5 @@
                      vec3(0.21f, -1.19f, 1.76f) + offset,
                      vec3(0.21f, -1.19f, -3.0f) + offset,
-                     vec3(0.0f, 1.0f, 0.0f), 0.03f);
+                     LASER_COLOR, 0.03f);
 
                   rightLaserIdx = laserObjects.size() - 1;
@@ -818,8 +844,18 @@
          vec3 objCenter = vec3(viewMat * vec4(asteroid.center, 1.0f));
 
-         if ((objCenter.z - asteroid.radius) > -NEAR_CLIP || asteroid.ssbo.hp <= 0.0f) {
+         if (asteroid.ssbo.hp <= 0.0f) {
             asteroid.ssbo.deleted = true;
 
-            // TODO: Create explosion here
+            // TODO: Optimize this so I don't recalculate the camera rotation every time
+            // TODO: Also, avoid re-declaring cam_pitch
+            float cam_pitch = -50.0f;
+            mat4 pitch_mat = rotate(mat4(1.0f), radians(cam_pitch), vec3(1.0f, 0.0f, 0.0f));
+            mat4 model_mat = translate(mat4(1.0f), asteroid.center) * pitch_mat;
+
+            addExplosion(model_mat, 0.5f, curTime);
+
+            // TODO: Increment player's score here
+         } else if ((objCenter.z - asteroid.radius) > -NEAR_CLIP) {
+            asteroid.ssbo.deleted = true;
          } else {
             asteroid.model_transform =
@@ -914,4 +950,13 @@
    }
 
+   for (SceneObject<ExplosionVertex, SSBO_Explosion>& explosion : this->explosionObjects) {
+      if (!explosion.ssbo.deleted) {
+         if (curTime > (explosion.ssbo.explosionStartTime + explosion.ssbo.explosionDuration)) {
+            explosion.ssbo.deleted = true;
+            explosion.modified = true;
+         }
+      }
+   }
+
    for (size_t i = 0; i < shipObjects.size(); i++) {
       if (shipObjects[i].modified) {
@@ -938,4 +983,12 @@
    }
 
+   for (size_t i = 0; i < explosionObjects.size(); i++) {
+      if (explosionObjects[i].modified) {
+         updateObject(explosionObjects, explosionPipeline, i);
+      }
+   }
+
+   explosion_UBO.cur_time = curTime;
+
    VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_modelPipeline[currentImage], 0, object_VP_mats);
 
@@ -945,4 +998,6 @@
 
    VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_laserPipeline[currentImage], 0, laser_VP_mats);
+
+   VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_explosionPipeline[currentImage], 0, explosion_UBO);
 }
 
@@ -1051,4 +1106,5 @@
    asteroidPipeline.cleanupBuffers();
    laserPipeline.cleanupBuffers();
+   explosionPipeline.cleanupBuffers();
 
    for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
@@ -1543,4 +1599,5 @@
       asteroidPipeline.createRenderCommands(commandBuffers[i], i);
       laserPipeline.createRenderCommands(commandBuffers[i], i);
+      explosionPipeline.createRenderCommands(commandBuffers[i], i);
 
       // Always render this pipeline last
@@ -1797,4 +1854,41 @@
 }
 
+void VulkanGame::addExplosion(mat4 model_mat, float duration, float cur_time) {
+   vector<ExplosionVertex> vertices;
+   vertices.reserve(EXPLOSION_PARTICLE_COUNT);
+
+   float particle_start_time = 0.0f;
+
+   for (int i = 0; i < EXPLOSION_PARTICLE_COUNT; i++) {
+      float randx = ((float)rand() / (float)RAND_MAX) - 0.5f;
+      float randy = ((float)rand() / (float)RAND_MAX) - 0.5f;
+
+      vertices.push_back({ vec3(randx, randy, 0.0f), particle_start_time});
+
+      particle_start_time += .01f;
+      // TODO: Get this working
+      // particle_start_time += 1.0f * EXPLOSION_PARTICLE_COUNT / duration
+   }
+
+   // Fill the indices with the the first EXPLOSION_PARTICLE_COUNT ints
+   vector<uint16_t> indices(EXPLOSION_PARTICLE_COUNT);
+   iota(indices.begin(), indices.end(), 0);
+
+   SceneObject<ExplosionVertex, SSBO_Explosion>& explosion = addObject(
+      explosionObjects, explosionPipeline,
+      addObjectIndex(explosionObjects.size(), vertices),
+      indices, {
+         mat4(1.0f),
+         cur_time,
+         duration,
+         false
+      }, true);
+
+   explosion.model_base = model_mat;
+   explosion.model_transform = mat4(1.0f);
+
+   explosion.modified = true;
+}
+
 // TODO: Fix the crash that happens when alt-tabbing
 void VulkanGame::recreateSwapChain() {
@@ -1858,4 +1952,12 @@
    laserPipeline.createDescriptorPool(swapChainImages);
    laserPipeline.createDescriptorSets(swapChainImages);
+
+   createBufferSet(sizeof(UBO_Explosion), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+      uniformBuffers_explosionPipeline, uniformBuffersMemory_explosionPipeline, uniformBufferInfoList_explosionPipeline);
+
+   explosionPipeline.updateRenderPass(renderPass);
+   explosionPipeline.createPipeline("shaders/explosion-vert.spv", "shaders/explosion-frag.spv");
+   explosionPipeline.createDescriptorPool(swapChainImages);
+   explosionPipeline.createDescriptorSets(swapChainImages);
 
    createCommandBuffers();
@@ -1876,4 +1978,5 @@
    asteroidPipeline.cleanup();
    laserPipeline.cleanup();
+   explosionPipeline.cleanup();
 
    for (size_t i = 0; i < uniformBuffers_modelPipeline.size(); i++) {
@@ -1897,4 +2000,9 @@
    }
 
+   for (size_t i = 0; i < uniformBuffers_explosionPipeline.size(); i++) {
+      vkDestroyBuffer(device, uniformBuffers_explosionPipeline[i], nullptr);
+      vkFreeMemory(device, uniformBuffersMemory_explosionPipeline[i], nullptr);
+   }
+
    vkDestroyRenderPass(device, renderPass, nullptr);
 
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision 52a02e69e392cc9a436263ac91bd0660624c2b95)
+++ vulkan-game.hpp	(revision 4a9416a988cc9dbc7460f1c5db43de22e12258e7)
@@ -57,4 +57,10 @@
 };
 
+struct ExplosionVertex {
+   vec3 particleStartVelocity;
+   float particleStartTime;
+   unsigned int objIndex;
+};
+
 struct SSBO_ModelObject {
    alignas(16) mat4 model;
@@ -73,7 +79,20 @@
 };
 
+struct SSBO_Explosion {
+   alignas(16) mat4 model;
+   alignas(4) float explosionStartTime;
+   alignas(4) float explosionDuration;
+   alignas(4) unsigned int deleted;
+};
+
 struct UBO_VP_mats {
    alignas(16) mat4 view;
    alignas(16) mat4 proj;
+};
+
+struct UBO_Explosion {
+   alignas(16) mat4 view;
+   alignas(16) mat4 proj;
+   alignas(4) float cur_time;
 };
 
@@ -183,4 +202,7 @@
       const float FOV_ANGLE = 67.0f; // means the camera lens goes from -33 deg to 33 def
 
+      const int EXPLOSION_PARTICLE_COUNT = 300;
+      const vec3 LASER_COLOR = vec3(0.2f, 1.0f, 0.2f);
+
       vec3 cam_pos;
 
@@ -287,4 +309,13 @@
 
       UBO_VP_mats laser_VP_mats;
+
+      GraphicsPipeline_Vulkan<ExplosionVertex, SSBO_Explosion> explosionPipeline;
+      vector<SceneObject<ExplosionVertex, SSBO_Explosion>> explosionObjects;
+
+      vector<VkBuffer> uniformBuffers_explosionPipeline;
+      vector<VkDeviceMemory> uniformBuffersMemory_explosionPipeline;
+      vector<VkDescriptorBufferInfo> uniformBufferInfoList_explosionPipeline;
+
+      UBO_Explosion explosion_UBO;
 
       vector<BaseEffectOverTime*> effects;
@@ -368,4 +399,6 @@
             vec3& start, vec3& end, vec3& intersection);
 
+      void addExplosion(mat4 model_mat, float duration, float cur_time);
+
       void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags,
             vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
@@ -382,4 +415,12 @@
             void* pUserData);
 };
+
+// Start of specialized no-op functions
+
+template<>
+inline void VulkanGame::centerObject(SceneObject<ExplosionVertex, SSBO_Explosion>& object) {
+}
+
+// End of specialized no-op functions
 
 // TODO: Right now, it's basically necessary to pass the identity matrix in for ssbo.model
@@ -409,5 +450,5 @@
    SceneObject<VertexType, SSBOType>& obj = objects.back();
 
-   if (!is_same_v<VertexType, LaserVertex>) {
+   if (!is_same_v<VertexType, LaserVertex> && !is_same_v<VertexType, ExplosionVertex>) {
       centerObject(obj);
    }
Index: vulkan-utils.cpp
===================================================================
--- vulkan-utils.cpp	(revision 52a02e69e392cc9a436263ac91bd0660624c2b95)
+++ vulkan-utils.cpp	(revision 4a9416a988cc9dbc7460f1c5db43de22e12258e7)
@@ -257,4 +257,6 @@
 void VulkanUtils::createVulkanImageFromFile(VkDevice device, VkPhysicalDevice physicalDevice,
       VkCommandPool commandPool, string filename, VulkanImage& image, VkQueue graphicsQueue) {
+   // TODO: Since the image loaded here will be used as a texture, display a warning if it has
+   // non power-of-two dimensions
    int texWidth, texHeight, texChannels;
 
