Index: new-game.cpp
===================================================================
--- new-game.cpp	(revision 7a55b499c14cd197b42fc3ab9e4ea6b1f2663edb)
+++ new-game.cpp	(revision 0414306f84f614c16d71251480e1d8ab474c7ecd)
@@ -143,4 +143,5 @@
 void addObjectToScene(SceneObject* obj,
                   map<GLuint, BufferInfo>& shaderBufferInfo,
+                  map<ObjectType, ShaderModelGroup>& modelGroups,
                   GLuint points_vbo,
                   GLuint colors_vbo,
@@ -148,6 +149,5 @@
                   GLuint normals_vbo,
                   GLuint ubo,
-                  GLuint model_mat_idx_vbo,
-                  GLuint asteroid_sp);
+                  GLuint model_mat_idx_vbo);
 void removeObjectFromScene(SceneObject& obj, GLuint ubo);
 
@@ -166,6 +166,7 @@
                   GLuint* model_mat_idx_vbo);
 
-ShaderModelGroup initializeParticleEffectBuffers(vec3 origin, mat4 proj, mat4 view, GLuint explosion_sp,
+void initializeParticleEffectBuffers(vec3 origin, mat4 proj, mat4 view,
                   map<GLuint, BufferInfo>& shaderBufferInfo,
+                  map<ObjectType, ShaderModelGroup>& modelGroups,
                   GLuint points_vbo,
                   GLuint colors_vbo,
@@ -177,4 +178,5 @@
 void populateBuffers(vector<SceneObject*>& objects,
                   map<GLuint, BufferInfo>& shaderBufferInfo,
+                  map<ObjectType, ShaderModelGroup>& modelGroups,
                   GLuint points_vbo,
                   GLuint colors_vbo,
@@ -182,9 +184,9 @@
                   GLuint normals_vbo,
                   GLuint ubo,
-                  GLuint model_mat_idx_vbo,
-                  GLuint asteroid_sp);
+                  GLuint model_mat_idx_vbo);
 
 void copyObjectDataToBuffers(SceneObject& obj,
                   map<GLuint, BufferInfo>& shaderBufferInfo,
+                  map<ObjectType, ShaderModelGroup>& modelGroups,
                   GLuint points_vbo,
                   GLuint colors_vbo,
@@ -192,6 +194,5 @@
                   GLuint normals_vbo,
                   GLuint ubo,
-                  GLuint model_mat_idx_vbo,
-                  GLuint asteroid_sp);
+                  GLuint model_mat_idx_vbo);
 
 void transformObject(SceneObject& obj, const mat4& transform, GLuint ubo);
@@ -210,8 +211,8 @@
 void renderMainMenuGui();
 
-void renderScene(map<GLuint, BufferInfo>& shaderBufferInfo, GLuint ubo,
-                  GLuint ship_sp, GLuint asteroid_sp, GLuint laser_sp,
-                  GLuint ship_vao, GLuint asteroid_vao, GLuint laser_vao,
-                  ShaderModelGroup& explosion_group);
+void renderScene(map<GLuint, BufferInfo>& shaderBufferInfo,
+                  map<ObjectType, ShaderModelGroup>& modelGroups, GLuint ubo,
+                  GLuint ship_sp, GLuint laser_sp,
+                  GLuint ship_vao, GLuint laser_vao);
 
 void renderSceneGui();
@@ -454,14 +455,18 @@
 
    map<GLuint, BufferInfo> shaderBufferInfo;
+   map<ObjectType, ShaderModelGroup> modelGroups;
 
    GLuint ship_sp = loadShaderProgram("./ship.vert", "./ship.frag");
-   GLuint asteroid_sp = loadShaderProgram("./asteroid.vert", "./asteroid.frag");
    GLuint laser_sp = loadShaderProgram("./laser.vert", "./laser.frag");
-   GLuint explosion_sp = loadShaderProgram("./explosion.vert", "./explosion.frag");
 
    shaderBufferInfo[ship_sp] = BufferInfo();
-   shaderBufferInfo[asteroid_sp] = BufferInfo();
    shaderBufferInfo[laser_sp] = BufferInfo();
-   shaderBufferInfo[explosion_sp] = BufferInfo();
+
+   modelGroups[TYPE_ASTEROID] = createModelGroup(
+      loadShaderProgram("./asteroid.vert", "./asteroid.frag"));
+   shaderBufferInfo[modelGroups[TYPE_ASTEROID].shaderProgram] = BufferInfo(); // temporary
+   modelGroups[TYPE_EXPLOSION] = createModelGroup(
+      loadShaderProgram("./explosion.vert", "./explosion.frag"));
+   shaderBufferInfo[modelGroups[TYPE_EXPLOSION].shaderProgram] = BufferInfo(); // temporary
 
    cam_pos = vec3(0.0f, 0.0f, 2.0f);
@@ -486,5 +491,5 @@
 
    populateBuffers(objects,
-      shaderBufferInfo,
+      shaderBufferInfo, modelGroups,
       points_vbo,
       colors_vbo,
@@ -492,6 +497,5 @@
       normals_vbo,
       ubo,
-      model_mat_idx_vbo,
-      asteroid_sp);
+      model_mat_idx_vbo);
 
    GLuint ship_vao = 0;
@@ -517,7 +521,5 @@
    glVertexAttribIPointer(3, 1, GL_UNSIGNED_INT, 0, NULL);
 
-   GLuint asteroid_vao = 0;
-   glGenVertexArrays(1, &asteroid_vao);
-   glBindVertexArray(asteroid_vao);
+   glBindVertexArray(modelGroups[TYPE_ASTEROID].vao);
 
    glEnableVertexAttribArray(0);
@@ -587,7 +589,7 @@
    proj_mat = make_mat4(proj_arr);
 
-   ShaderModelGroup explosion_group = initializeParticleEffectBuffers(vec3(0.0f, -1.2f, 0.65f), proj_mat, view_mat,
-      explosion_sp,
+   initializeParticleEffectBuffers(vec3(0.0f, -1.2f, 0.65f), proj_mat, view_mat,
       shaderBufferInfo,
+      modelGroups,
       points_vbo,
       colors_vbo,
@@ -637,7 +639,7 @@
    GLuint ship_sp_models_ub_index = glGetUniformBlockIndex(ship_sp, "models");
 
-   GLuint asteroid_view_mat_loc = glGetUniformLocation(asteroid_sp, "view");
-   GLuint asteroid_proj_mat_loc = glGetUniformLocation(asteroid_sp, "proj");
-   GLuint asteroid_sp_models_ub_index = glGetUniformBlockIndex(asteroid_sp, "models");
+   GLuint asteroid_view_mat_loc = glGetUniformLocation(modelGroups[TYPE_ASTEROID].shaderProgram, "view");
+   GLuint asteroid_proj_mat_loc = glGetUniformLocation(modelGroups[TYPE_ASTEROID].shaderProgram, "proj");
+   GLuint asteroid_sp_models_ub_index = glGetUniformBlockIndex(modelGroups[TYPE_ASTEROID].shaderProgram, "models");
 
    GLuint laser_view_mat_loc = glGetUniformLocation(laser_sp, "view");
@@ -646,7 +648,7 @@
    GLuint laser_sp_models_ub_index = glGetUniformBlockIndex(laser_sp, "models");
 
-   GLuint explosion_start_time_loc = glGetUniformLocation(explosion_sp, "explosion_start_time");
-   GLuint cur_time_loc = glGetUniformLocation(explosion_sp, "cur_time");
-   GLuint explosion_sp_models_ub_index = glGetUniformBlockIndex(explosion_sp, "models");
+   GLuint explosion_start_time_loc = glGetUniformLocation(modelGroups[TYPE_EXPLOSION].shaderProgram, "explosion_start_time");
+   GLuint cur_time_loc = glGetUniformLocation(modelGroups[TYPE_EXPLOSION].shaderProgram, "cur_time");
+   GLuint explosion_sp_models_ub_index = glGetUniformBlockIndex(modelGroups[TYPE_EXPLOSION].shaderProgram, "models");
 
 
@@ -659,9 +661,9 @@
 
 
-   glUseProgram(asteroid_sp);
+   glUseProgram(modelGroups[TYPE_ASTEROID].shaderProgram);
    glUniformMatrix4fv(asteroid_view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
    glUniformMatrix4fv(asteroid_proj_mat_loc, 1, GL_FALSE, value_ptr(proj_mat));
 
-   glUniformBlockBinding(asteroid_sp, asteroid_sp_models_ub_index, ub_binding_point);
+   glUniformBlockBinding(modelGroups[TYPE_ASTEROID].shaderProgram, asteroid_sp_models_ub_index, ub_binding_point);
    glBindBufferRange(GL_UNIFORM_BUFFER, ub_binding_point, ubo, 0, GL_MAX_UNIFORM_BLOCK_SIZE);
 
@@ -676,6 +678,6 @@
 
 
-   glUseProgram(explosion_sp);
-   glUniformBlockBinding(explosion_sp, explosion_sp_models_ub_index, ub_binding_point);
+   glUseProgram(modelGroups[TYPE_EXPLOSION].shaderProgram);
+   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);
 
@@ -748,6 +750,6 @@
          elapsed_seconds_spawn += elapsed_seconds;
          if (elapsed_seconds_spawn > 0.5f) {
-            SceneObject* obj = createAsteroid(vec3(getRandomNum(-1.3f, 1.3f), -1.2f, getRandomNum(-5.5f, -4.5f)), asteroid_sp);
-            addObjectToScene(obj, shaderBufferInfo,
+            SceneObject* obj = createAsteroid(vec3(getRandomNum(-1.3f, 1.3f), -1.2f, getRandomNum(-5.5f, -4.5f)), modelGroups[TYPE_ASTEROID].shaderProgram);
+            addObjectToScene(obj, shaderBufferInfo, modelGroups,
                points_vbo,
                colors_vbo,
@@ -755,6 +757,5 @@
                normals_vbo,
                ubo,
-               model_mat_idx_vbo,
-               asteroid_sp);
+               model_mat_idx_vbo);
 
             elapsed_seconds_spawn -= 0.5f;
@@ -808,5 +809,5 @@
             leftLaser = createLaser(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_sp);
-            addObjectToScene(leftLaser, shaderBufferInfo,
+            addObjectToScene(leftLaser, shaderBufferInfo, modelGroups,
                points_vbo,
                colors_vbo,
@@ -814,6 +815,5 @@
                normals_vbo,
                ubo,
-               model_mat_idx_vbo,
-               asteroid_sp);
+               model_mat_idx_vbo);
          } else if (key_state[GLFW_KEY_Z] == GLFW_RELEASE) {
             removeObjectFromScene(*leftLaser, ubo);
@@ -825,5 +825,5 @@
             rightLaser = createLaser(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_sp);
-            addObjectToScene(rightLaser, shaderBufferInfo,
+            addObjectToScene(rightLaser, shaderBufferInfo, modelGroups,
                points_vbo,
                colors_vbo,
@@ -831,6 +831,5 @@
                normals_vbo,
                ubo,
-               model_mat_idx_vbo,
-               asteroid_sp);
+               model_mat_idx_vbo);
          } else if (key_state[GLFW_KEY_X] == GLFW_RELEASE) {
             removeObjectFromScene(*rightLaser, ubo);
@@ -859,7 +858,7 @@
 
                   // initiate an explosion
-                  glUseProgram(explosion_sp);
-
-                  GLuint model_mat_loc = glGetUniformLocation(explosion_sp, "model_mat");
+                  glUseProgram(modelGroups[TYPE_EXPLOSION].shaderProgram);
+
+                  GLuint model_mat_loc = glGetUniformLocation(modelGroups[TYPE_EXPLOSION].shaderProgram, "model_mat");
                   glUniformMatrix4fv(model_mat_loc, 1, GL_FALSE, value_ptr(objExplosion->model_mat));
 
@@ -870,8 +869,8 @@
 
          if (leftLaser != NULL && !leftLaser->deleted) {
-            updateLaserTarget(leftLaser, objects, points_vbo, asteroid_sp);
+            updateLaserTarget(leftLaser, objects, points_vbo, modelGroups[TYPE_ASTEROID].shaderProgram);
          }
          if (rightLaser != NULL && !rightLaser->deleted) {
-            updateLaserTarget(rightLaser, objects, points_vbo, asteroid_sp);
+            updateLaserTarget(rightLaser, objects, points_vbo, modelGroups[TYPE_ASTEROID].shaderProgram);
          }
       }
@@ -956,5 +955,5 @@
       }
 
-      glUseProgram(explosion_sp);
+      glUseProgram(modelGroups[TYPE_EXPLOSION].shaderProgram);
       glUniform1f(cur_time_loc, (GLfloat)current_seconds);
 
@@ -969,8 +968,7 @@
             break;
          case STATE_GAME:
-            renderScene(shaderBufferInfo, ubo,
-               ship_sp, asteroid_sp, laser_sp,
-               ship_vao, asteroid_vao, laser_vao,
-               explosion_group);
+            renderScene(shaderBufferInfo, modelGroups, ubo,
+               ship_sp, laser_sp,
+               ship_vao, laser_vao);
             renderSceneGui();
             break;
@@ -1324,4 +1322,5 @@
 void addObjectToScene(SceneObject* obj,
    map<GLuint, BufferInfo>& shaderBufferInfo,
+   map<ObjectType, ShaderModelGroup>& modelGroups,
    GLuint points_vbo,
    GLuint colors_vbo,
@@ -1329,13 +1328,16 @@
    GLuint normals_vbo,
    GLuint ubo,
-   GLuint model_mat_idx_vbo,
-   GLuint asteroid_sp) {
+   GLuint model_mat_idx_vbo) {
    objects.push_back(obj);
 
    BufferInfo* bufferInfo = &shaderBufferInfo[obj->shader_program];
+
+   unsigned int numPoints = obj->type == TYPE_ASTEROID || obj->type == TYPE_EXPLOSION ?
+      modelGroups[obj->type].numPoints :
+      bufferInfo->vbo_offset;
 
    // Check if the buffers aren't large enough to fit the new object and, if so, call
    // populateBuffers() to resize and repopupulate them
-   if (bufferInfo->vbo_capacity < (bufferInfo->vbo_offset + obj->num_points) ||
+   if (bufferInfo->vbo_capacity < (numPoints + obj->num_points) ||
       bufferInfo->ubo_capacity < (bufferInfo->ubo_offset + 1)) {
 
@@ -1347,5 +1349,5 @@
       }
 
-      populateBuffers(objects, shaderBufferInfo,
+      populateBuffers(objects, shaderBufferInfo, modelGroups,
          points_vbo,
          colors_vbo,
@@ -1353,8 +1355,7 @@
          normals_vbo,
          ubo,
-         model_mat_idx_vbo,
-         asteroid_sp);
+         model_mat_idx_vbo);
    } else {
-      copyObjectDataToBuffers(*objects.back(), shaderBufferInfo,
+      copyObjectDataToBuffers(*objects.back(), shaderBufferInfo, modelGroups,
          points_vbo,
          colors_vbo,
@@ -1362,6 +1363,5 @@
          normals_vbo,
          ubo,
-         model_mat_idx_vbo,
-         asteroid_sp);
+         model_mat_idx_vbo);
    }
 }
@@ -1908,4 +1908,6 @@
 
    smg.shaderProgram = shaderProgram;
+   glGenVertexArrays(1, &smg.vao);
+   smg.numPoints = 0;
 
    return smg;
@@ -1946,6 +1948,7 @@
 }
 
-ShaderModelGroup initializeParticleEffectBuffers(vec3 origin, mat4 proj, mat4 view, GLuint explosion_sp,
+void initializeParticleEffectBuffers(vec3 origin, mat4 proj, mat4 view,
                   map<GLuint, BufferInfo>& shaderBufferInfo,
+                  map<ObjectType, ShaderModelGroup>& modelGroups,
                   GLuint points_vbo,
                   GLuint colors_vbo,
@@ -1971,16 +1974,13 @@
    mat4 model_mat = translate(mat4(1.0f), origin);
 
-   ShaderModelGroup modelGroup;
-   modelGroup.shaderProgram = explosion_sp;
-
-   glUseProgram(modelGroup.shaderProgram);
-
-   GLuint proj_mat_loc = glGetUniformLocation(explosion_sp, "proj");
-   GLuint view_mat_loc = glGetUniformLocation(explosion_sp, "view");
+   glUseProgram(modelGroups[TYPE_EXPLOSION].shaderProgram);
+
+   GLuint proj_mat_loc = glGetUniformLocation(modelGroups[TYPE_EXPLOSION].shaderProgram, "proj");
+   GLuint view_mat_loc = glGetUniformLocation(modelGroups[TYPE_EXPLOSION].shaderProgram, "view");
 
    glUniformMatrix4fv(proj_mat_loc, 1, GL_FALSE, value_ptr(proj));
    glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, value_ptr(view));
 
-   GLuint model_mat_loc = glGetUniformLocation(explosion_sp, "model_mat");
+   GLuint model_mat_loc = glGetUniformLocation(modelGroups[TYPE_EXPLOSION].shaderProgram, "model_mat");
 
    glUniformMatrix4fv(model_mat_loc, 1, GL_FALSE, value_ptr(model_mat));
@@ -1996,6 +1996,5 @@
    glBufferData(GL_ARRAY_BUFFER, sizeof(vt), vt, GL_STATIC_DRAW);
 
-   glGenVertexArrays(1, &modelGroup.vao);
-   glBindVertexArray(modelGroup.vao);
+   glBindVertexArray(modelGroups[TYPE_EXPLOSION].vao);
 
    glEnableVertexAttribArray(0);
@@ -2008,6 +2007,6 @@
    glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, NULL);
 
-   objExplosion = createExplosion(modelGroup.shaderProgram);
-   addObjectToScene(objExplosion, shaderBufferInfo,
+   objExplosion = createExplosion(modelGroups[TYPE_EXPLOSION].shaderProgram);
+   addObjectToScene(objExplosion, shaderBufferInfo, modelGroups,
       points_vbo,
       colors_vbo,
@@ -2015,12 +2014,10 @@
       normals_vbo,
       ubo,
-      model_mat_idx_vbo,
-      0);
-
-   return modelGroup;
+      model_mat_idx_vbo);
 }
 
 void populateBuffers(vector<SceneObject*>& objects,
                   map<GLuint, BufferInfo>& shaderBufferInfo,
+                  map<ObjectType, ShaderModelGroup>& modelGroups,
                   GLuint points_vbo,
                   GLuint colors_vbo,
@@ -2028,6 +2025,5 @@
                   GLuint normals_vbo,
                   GLuint ubo,
-                  GLuint ubo_idx_vbo,
-                  GLuint asteroid_sp) {
+                  GLuint ubo_idx_vbo) {
    GLsizeiptr num_points = 0;
    GLsizeiptr num_objects = 0;
@@ -2087,5 +2083,8 @@
       shaderBufferInfo[shaderCountIt->first].ubo_base = lastShaderUboCount * 2;
 
-      shaderBufferInfo[shaderCountIt->first].vbo_offset = 0;
+      if (shaderCountIt->first != modelGroups[TYPE_ASTEROID].shaderProgram &&
+         shaderCountIt->first != modelGroups[TYPE_EXPLOSION].shaderProgram) {
+         shaderBufferInfo[shaderCountIt->first].vbo_offset = 0;
+      }
       shaderBufferInfo[shaderCountIt->first].ubo_offset = 0;
 
@@ -2097,4 +2096,7 @@
    }
 
+   modelGroups[TYPE_ASTEROID].numPoints = 0;
+   modelGroups[TYPE_EXPLOSION].numPoints = 0;
+
    // Allocate all the buffers using the counts calculated above
 
@@ -2118,5 +2120,5 @@
 
    for (it = objects.begin(); it != objects.end(); it++) {
-      copyObjectDataToBuffers(**it, shaderBufferInfo,
+      copyObjectDataToBuffers(**it, shaderBufferInfo, modelGroups,
          points_vbo,
          colors_vbo,
@@ -2124,6 +2126,5 @@
          normals_vbo,
          ubo,
-         ubo_idx_vbo,
-         asteroid_sp);
+         ubo_idx_vbo);
    }
 }
@@ -2131,4 +2132,5 @@
 void copyObjectDataToBuffers(SceneObject& obj,
                   map<GLuint, BufferInfo>& shaderBufferInfo,
+                  map<ObjectType, ShaderModelGroup>& modelGroups,
                   GLuint points_vbo,
                   GLuint colors_vbo,
@@ -2136,9 +2138,13 @@
                   GLuint normals_vbo,
                   GLuint ubo,
-                  GLuint model_mat_idx_vbo,
-                  GLuint asteroid_sp) {
+                  GLuint model_mat_idx_vbo) {
    BufferInfo* bufferInfo = &shaderBufferInfo[obj.shader_program];
 
-   obj.vertex_vbo_offset = bufferInfo->vbo_base + bufferInfo->vbo_offset;
+   if (obj.type == TYPE_ASTEROID || obj.type == TYPE_EXPLOSION) {
+      obj.vertex_vbo_offset = bufferInfo->vbo_base + modelGroups[obj.type].numPoints;
+   } else {
+      obj.vertex_vbo_offset = bufferInfo->vbo_base + bufferInfo->vbo_offset;
+   }
+   
    obj.ubo_offset = bufferInfo->ubo_base + bufferInfo->ubo_offset;
 
@@ -2172,13 +2178,17 @@
 
       if (obj.type == TYPE_ASTEROID) {
-         glUseProgram(asteroid_sp);
+         glUseProgram(modelGroups[TYPE_ASTEROID].shaderProgram);
 
          ostringstream oss;
          oss << "hp[" << obj.ubo_offset << "]";
-         glUniform1f(glGetUniformLocation(asteroid_sp, oss.str().c_str()), ((Asteroid*)&obj)->hp);
-      }
-   }
-
-   bufferInfo->vbo_offset += obj.num_points;
+         glUniform1f(glGetUniformLocation(modelGroups[TYPE_ASTEROID].shaderProgram, oss.str().c_str()), ((Asteroid*)&obj)->hp);
+      }
+   }
+
+   if (obj.type == TYPE_ASTEROID || obj.type == TYPE_EXPLOSION) {
+      modelGroups[obj.type].numPoints += obj.num_points;
+   } else {
+      bufferInfo->vbo_offset += obj.num_points;
+   }
    bufferInfo->ubo_offset++;
 }
@@ -2344,8 +2354,8 @@
 }
 
-void renderScene(map<GLuint, BufferInfo>& shaderBufferInfo, GLuint ubo,
-                  GLuint ship_sp, GLuint asteroid_sp, GLuint laser_sp,
-                  GLuint ship_vao, GLuint asteroid_vao, GLuint laser_vao,
-                  ShaderModelGroup& explosion_group) {
+void renderScene(map<GLuint, BufferInfo>& shaderBufferInfo,
+                  map<ObjectType, ShaderModelGroup>& modelGroups, GLuint ubo,
+                  GLuint ship_sp, GLuint laser_sp,
+                  GLuint ship_vao, GLuint laser_vao) {
 
    glUseProgram(ship_sp);
@@ -2354,8 +2364,8 @@
    glDrawArrays(GL_TRIANGLES, shaderBufferInfo[ship_sp].vbo_base, shaderBufferInfo[ship_sp].vbo_offset);
 
-   glUseProgram(asteroid_sp);
-   glBindVertexArray(asteroid_vao);
-
-   glDrawArrays(GL_TRIANGLES, shaderBufferInfo[asteroid_sp].vbo_base, shaderBufferInfo[asteroid_sp].vbo_offset);
+   glUseProgram(modelGroups[TYPE_ASTEROID].shaderProgram);
+   glBindVertexArray(modelGroups[TYPE_ASTEROID].vao);
+
+   glDrawArrays(GL_TRIANGLES, shaderBufferInfo[modelGroups[TYPE_ASTEROID].shaderProgram].vbo_base, modelGroups[TYPE_ASTEROID].numPoints);
 
    glEnable(GL_BLEND);
@@ -2366,16 +2376,13 @@
    glDrawArrays(GL_TRIANGLES, shaderBufferInfo[laser_sp].vbo_base, shaderBufferInfo[laser_sp].vbo_offset);
 
-   // To render explosions, my new shader descriptor object needs to have a reference to the shader and the vao
-   // and know the number of points to render.
-
-   glUseProgram(explosion_group.shaderProgram);
+   glUseProgram(modelGroups[TYPE_EXPLOSION].shaderProgram);
+   glBindVertexArray(modelGroups[TYPE_EXPLOSION].vao);
 
    glEnable(GL_PROGRAM_POINT_SIZE);
-   glBindVertexArray(explosion_group.vao);
 
    glBindBuffer(GL_UNIFORM_BUFFER, ubo);
    glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(mat4), value_ptr(objExplosion->model_mat));
 
-   glDrawArrays(GL_POINTS, 0, shaderBufferInfo[explosion_group.shaderProgram].vbo_offset);
+   glDrawArrays(GL_POINTS, 0, modelGroups[TYPE_EXPLOSION].numPoints);
 
    glBindBuffer(GL_UNIFORM_BUFFER, ubo);
