Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision bb76950f0466dd9cdf091f103572dec02c0f07c8)
+++ vulkan-game.cpp	(revision b7fc3c2d25e78df182543b43a8d92c5666f1361a)
@@ -110,9 +110,14 @@
    vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties);
 
-   objects_modelPipeline = VulkanBuffer<SSBO_ModelObject>(10, deviceProperties.limits.minUniformBufferOffsetAlignment);
-   objects_shipPipeline = VulkanBuffer<SSBO_ModelObject>(10, deviceProperties.limits.minUniformBufferOffsetAlignment);
-   objects_asteroidPipeline = VulkanBuffer<SSBO_Asteroid>(10, deviceProperties.limits.minUniformBufferOffsetAlignment);
-   objects_laserPipeline = VulkanBuffer<SSBO_Laser>(2, deviceProperties.limits.minUniformBufferOffsetAlignment);
-   objects_explosionPipeline = VulkanBuffer<SSBO_Explosion>(2, deviceProperties.limits.minUniformBufferOffsetAlignment);
+   objects_modelPipeline = VulkanBuffer<SSBO_ModelObject>(10, deviceProperties.limits.maxStorageBufferRange,
+                                                          deviceProperties.limits.minStorageBufferOffsetAlignment);
+   objects_shipPipeline = VulkanBuffer<SSBO_ModelObject>(10, deviceProperties.limits.maxStorageBufferRange,
+                                                         deviceProperties.limits.minStorageBufferOffsetAlignment);
+   objects_asteroidPipeline = VulkanBuffer<SSBO_Asteroid>(10, deviceProperties.limits.maxStorageBufferRange,
+                                                          deviceProperties.limits.minStorageBufferOffsetAlignment);
+   objects_laserPipeline = VulkanBuffer<SSBO_Laser>(2, deviceProperties.limits.maxStorageBufferRange,
+                                                    deviceProperties.limits.minStorageBufferOffsetAlignment);
+   objects_explosionPipeline = VulkanBuffer<SSBO_Explosion>(2, deviceProperties.limits.maxStorageBufferRange,
+                                                            deviceProperties.limits.minStorageBufferOffsetAlignment);
 
    initImGuiOverlay();
@@ -941,60 +946,4 @@
 // where it will run just once per frame
 void VulkanGame::updateScene() {
-   // Rotate the textured squares
-   for (SceneObject<ModelVertex, SSBO_ModelObject>& model : this->modelObjects) {
-      model.model_transform =
-         translate(mat4(1.0f), vec3(0.0f, -2.0f, -0.0f)) *
-         rotate(mat4(1.0f), curTime * radians(90.0f), vec3(0.0f, 0.0f, 1.0f));
-      model.modified = true;
-   }
-
-   if (leftLaserIdx != -1) {
-      updateLaserTarget(leftLaserIdx);
-   }
-   if (rightLaserIdx != -1) {
-      updateLaserTarget(rightLaserIdx);
-   }
-
-   for (vector<BaseEffectOverTime*>::iterator it = effects.begin(); it != effects.end(); ) {
-      if ((*it)->deleted) {
-         delete *it;
-         it = effects.erase(it);
-      } else {
-         BaseEffectOverTime* eot = *it;
-
-         eot->applyEffect(curTime);
-
-         it++;
-      }
-   }
-
-   for (SceneObject<ModelVertex, SSBO_Asteroid>& asteroid : this->asteroidObjects) {
-      if (!asteroid.ssbo.deleted) {
-         vec3 objCenter = vec3(viewMat * vec4(asteroid.center, 1.0f));
-
-         if (asteroid.ssbo.hp <= 0.0f) {
-            asteroid.ssbo.deleted = true;
-
-            // 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);
-
-            this->score++;
-         } else if ((objCenter.z - asteroid.radius) > -NEAR_CLIP) {
-            asteroid.ssbo.deleted = true;
-         } else {
-            asteroid.model_transform =
-               translate(mat4(1.0f), vec3(0.0f, 0.0f, this->asteroidSpeed * this->elapsedTime)) *
-               asteroid.model_transform;
-         }
-
-         asteroid.modified = true;
-      }
-   }
-
    if (curTime - this->lastSpawn_asteroid > this->spawnRate_asteroid) {
       this->lastSpawn_asteroid = curTime;
@@ -1080,102 +1029,185 @@
    }
 
-   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;
+   // TODO: Probably move the resizing to the VulkanBuffer class
+
+   // TODO: Replace updateBufferSet to one call to copyDataToMemory, using VulkanBuffer to provide the data source
+   // TODO: Figure out a way to make updateDescriptorInfo easier to use, maybe store the binding index in the buffer set
+
+   if (objects_modelPipeline.resized) {
+      resizeBufferSet(storageBuffers_modelPipeline, objects_modelPipeline.memorySize(), resourceCommandPool,
+                      graphicsQueue, true);
+
+      objects_modelPipeline.resize();
+
+      modelPipeline.updateDescriptorInfo(1, &storageBuffers_modelPipeline.infoSet, swapChainImages.size());
+   }
+
+   for (size_t i = 0; i < modelObjects.size(); i++) {
+      SceneObject<ModelVertex, SSBO_ModelObject>& obj = modelObjects[i];
+      SSBO_ModelObject& objData = obj.ssbo;
+
+      // Rotate the textured squares
+      obj.model_transform =
+         translate(mat4(1.0f), vec3(0.0f, -2.0f, -0.0f)) *
+         rotate(mat4(1.0f), curTime * radians(90.0f), vec3(0.0f, 0.0f, 1.0f));
+      obj.modified = true;
+
+      if (obj.modified) {
+         objData.model = obj.model_transform * obj.model_base;
+         obj.center = vec3(objData.model * vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+         obj.modified = false;
+
+         updateBufferSet(storageBuffers_modelPipeline, i, objData);
+      }
+   }
+
+   if (objects_shipPipeline.resized) {
+      resizeBufferSet(storageBuffers_shipPipeline, objects_shipPipeline.memorySize(), resourceCommandPool,
+                      graphicsQueue, true);
+
+      objects_shipPipeline.resize();
+
+      shipPipeline.updateDescriptorInfo(1, &storageBuffers_shipPipeline.infoSet, swapChainImages.size());
+   }
+
+   // TODO: Move ship position updates from the ui event handling code into this function
+   for (size_t i = 0; i < shipObjects.size(); i++) {
+      SceneObject<ModelVertex, SSBO_ModelObject>& obj = shipObjects[i];
+      SSBO_ModelObject& objData = obj.ssbo;
+
+      if (obj.modified) {
+         objData.model = obj.model_transform * obj.model_base;
+         obj.center = vec3(objData.model * vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+         obj.modified = false;
+
+         updateBufferSet(storageBuffers_shipPipeline, i, objData);
+      }
+   }
+
+   if (objects_asteroidPipeline.resized) {
+      resizeBufferSet(storageBuffers_asteroidPipeline, objects_asteroidPipeline.memorySize(), resourceCommandPool,
+                      graphicsQueue, true);
+
+      objects_asteroidPipeline.resize();
+
+      asteroidPipeline.updateDescriptorInfo(1, &storageBuffers_asteroidPipeline.infoSet, swapChainImages.size());
+   }
+
+   for (size_t i = 0; i < asteroidObjects.size(); i++) {
+      SceneObject<ModelVertex, SSBO_Asteroid>& obj = asteroidObjects[i];
+      SSBO_Asteroid& objData = obj.ssbo;
+
+      if (!objData.deleted) {
+         vec3 objCenter = vec3(viewMat * vec4(obj.center, 1.0f));
+
+         if (objData.hp <= 0.0f) {
+            objData.deleted = true;
+
+            // 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), obj.center) * pitch_mat;
+
+            addExplosion(model_mat, 0.5f, curTime);
+
+            this->score++;
+         } else if ((objCenter.z - obj.radius) > -NEAR_CLIP) {
+            objData.deleted = true;
+         } else {
+            obj.model_transform =
+               translate(mat4(1.0f), vec3(0.0f, 0.0f, this->asteroidSpeed * this->elapsedTime)) *
+               obj.model_transform;
+         }
+
+         obj.modified = true;
+      }
+
+      if (obj.modified) {
+         objData.model = obj.model_transform * obj.model_base;
+         obj.center = vec3(objData.model * vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+         obj.modified = false;
+
+         updateBufferSet(storageBuffers_asteroidPipeline, i, objData);
+      }
+   }
+
+   if (objects_laserPipeline.resized) {
+      resizeBufferSet(storageBuffers_laserPipeline, objects_laserPipeline.memorySize(), resourceCommandPool,
+                      graphicsQueue, true);
+
+      objects_laserPipeline.resize();
+
+      laserPipeline.updateDescriptorInfo(1, &storageBuffers_laserPipeline.infoSet, swapChainImages.size());
+   }
+
+   if (leftLaserIdx != -1) {
+      updateLaserTarget(leftLaserIdx);
+   }
+   if (rightLaserIdx != -1) {
+      updateLaserTarget(rightLaserIdx);
+   }
+
+   for (size_t i = 0; i < laserObjects.size(); i++) {
+      SceneObject<LaserVertex, SSBO_Laser>& obj = laserObjects[i];
+      SSBO_Laser& objData = obj.ssbo;
+
+      if (obj.modified) {
+         objData.model = obj.model_transform * obj.model_base;
+         obj.center = vec3(objData.model * vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+         obj.modified = false;
+
+         updateBufferSet(storageBuffers_laserPipeline, i, objData);
+      }
+   }
+
+   if (objects_explosionPipeline.resized) {
+      resizeBufferSet(storageBuffers_explosionPipeline, objects_explosionPipeline.memorySize(), resourceCommandPool,
+                      graphicsQueue, true);
+
+      objects_explosionPipeline.resize();
+
+      explosionPipeline.updateDescriptorInfo(1, &storageBuffers_explosionPipeline.infoSet, swapChainImages.size());
+   }
+
+   for (size_t i = 0; i < explosionObjects.size(); i++) {
+      SceneObject<ExplosionVertex, SSBO_Explosion>& obj = explosionObjects[i];
+      SSBO_Explosion& objData = obj.ssbo;
+
+      if (!objData.deleted) {
+         if (curTime > (objData.explosionStartTime + objData.explosionDuration)) {
+            objData.deleted = true;
+            obj.modified = true;
          }
       }
-   }
-
-   // TODO: Replace updateBufferSet to one call to copyDataToMemory, using VulkanBuffer to provide the data source
-   // TODO: Figure out a way to make updateDescriptorInfo easier to use, maybe store the binding index in the buffer set
-   // TODO: Probably move the resizing to the VulkanBuffer class
-
-   if (objects_modelPipeline.resized) {
-      resizeBufferSet(storageBuffers_modelPipeline, objects_modelPipeline.capacity * sizeof(SSBO_ModelObject),
-                      resourceCommandPool, graphicsQueue, true);
-
-      objects_modelPipeline.resize();
-
-      modelPipeline.updateDescriptorInfo(1, &storageBuffers_modelPipeline.infoSet, swapChainImages.size());
-   }
-
-   for (size_t i = 0; i < modelObjects.size(); i++) {
-      if (modelObjects[i].modified) {
-         updateObject(modelObjects[i]);
-         updateBufferSet(storageBuffers_modelPipeline, i, modelObjects[i].ssbo);
+
+      if (obj.modified) {
+         objData.model = obj.model_transform * obj.model_base;
+         obj.center = vec3(objData.model * vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+         obj.modified = false;
+
+         updateBufferSet(storageBuffers_explosionPipeline, i, objData);
       }
    }
 
-   // TODO: Probably move the resizing to the VulkanBuffer class
-   if (objects_shipPipeline.resized) {
-      resizeBufferSet(storageBuffers_shipPipeline, objects_shipPipeline.capacity * sizeof(SSBO_ModelObject),
-                      resourceCommandPool, graphicsQueue, true);
-
-      objects_shipPipeline.resize();
-
-      shipPipeline.updateDescriptorInfo(1, &storageBuffers_shipPipeline.infoSet, swapChainImages.size());
-   }
-
-   for (size_t i = 0; i < shipObjects.size(); i++) {
-      if (shipObjects[i].modified) {
-         updateObject(shipObjects[i]);
-         updateBufferSet(storageBuffers_shipPipeline, i, shipObjects[i].ssbo);
+   explosion_UBO.cur_time = curTime;
+
+   for (vector<BaseEffectOverTime*>::iterator it = effects.begin(); it != effects.end(); ) {
+      if ((*it)->deleted) {
+         delete *it;
+         it = effects.erase(it);
+      } else {
+         BaseEffectOverTime* eot = *it;
+
+         eot->applyEffect(curTime);
+
+         it++;
       }
    }
-
-   // TODO: Probably move the resizing to the VulkanBuffer class
-   if (objects_asteroidPipeline.resized) {
-      resizeBufferSet(storageBuffers_asteroidPipeline, objects_asteroidPipeline.capacity * sizeof(SSBO_Asteroid),
-                      resourceCommandPool, graphicsQueue, true);
-
-      objects_asteroidPipeline.resize();
-
-      asteroidPipeline.updateDescriptorInfo(1, &storageBuffers_asteroidPipeline.infoSet, swapChainImages.size());
-   }
-
-   for (size_t i = 0; i < asteroidObjects.size(); i++) {
-      if (asteroidObjects[i].modified) {
-         updateObject(asteroidObjects[i]);
-         updateBufferSet(storageBuffers_asteroidPipeline, i, asteroidObjects[i].ssbo);
-      }
-   }
-
-   // TODO: Probably move the resizing to the VulkanBuffer class
-   if (objects_laserPipeline.resized) {
-      resizeBufferSet(storageBuffers_laserPipeline, objects_laserPipeline.capacity * sizeof(SSBO_Laser),
-                      resourceCommandPool, graphicsQueue, true);
-
-      objects_laserPipeline.resize();
-
-      laserPipeline.updateDescriptorInfo(1, &storageBuffers_laserPipeline.infoSet, swapChainImages.size());
-   }
-
-   for (size_t i = 0; i < laserObjects.size(); i++) {
-      if (laserObjects[i].modified) {
-         updateObject(laserObjects[i]);
-         updateBufferSet(storageBuffers_laserPipeline, i, laserObjects[i].ssbo);
-      }
-   }
-
-   // TODO: Probably move the resizing to the VulkanBuffer class
-   if (objects_explosionPipeline.resized) {
-      resizeBufferSet(storageBuffers_explosionPipeline, objects_explosionPipeline.capacity * sizeof(SSBO_Explosion),
-                      resourceCommandPool, graphicsQueue, true);
-
-      objects_explosionPipeline.resize();
-
-      explosionPipeline.updateDescriptorInfo(1, &storageBuffers_explosionPipeline.infoSet, swapChainImages.size());
-   }
-
-   for (size_t i = 0; i < explosionObjects.size(); i++) {
-      if (explosionObjects[i].modified) {
-         updateObject(explosionObjects[i]);
-         updateBufferSet(storageBuffers_explosionPipeline, i, explosionObjects[i].ssbo);
-      }
-   }
-
-   explosion_UBO.cur_time = curTime;
 
    VulkanUtils::copyDataToMemory(device, &object_VP_mats, uniformBuffers_modelPipeline.memory[imageIndex], 0,
