Index: new-game.cpp
===================================================================
--- new-game.cpp	(revision fe5e3ca6a77a5b0bca064bb258065b3bd70d7e7a)
+++ new-game.cpp	(revision 646f3f23c788c9af8bbfaddee73fd4fb874cd3ff)
@@ -50,4 +50,5 @@
    TYPE_ASTEROID,
    TYPE_LASER,
+   TYPE_EXPLOSION,
 };
 
@@ -157,5 +158,13 @@
                   GLuint* model_mat_idx_vbo);
 
-GLuint initializeParticleEffectBuffers(vec3 origin, mat4 proj, mat4 view, GLuint explosion_sp);
+GLuint initializeParticleEffectBuffers(vec3 origin, mat4 proj, mat4 view, GLuint explosion_sp,
+                  map<GLuint, BufferInfo>& shaderBufferInfo,
+                  GLuint points_vbo,
+                  GLuint colors_vbo,
+                  GLuint selected_colors_vbo,
+                  GLuint texcoords_vbo,
+                  GLuint normals_vbo,
+                  GLuint ubo,
+                  GLuint model_mat_idx_vbo);
 
 void populateBuffers(vector<SceneObject*>& objects,
@@ -183,7 +192,9 @@
 void transformObject(SceneObject& obj, const mat4& transform, GLuint ubo);
 
+// TODO: instead of using these methods, create constructors for these
 SceneObject* createShip(GLuint shader);
 Asteroid* createAsteroid(vec3 pos, GLuint shader);
 Laser* createLaser(vec3 start, vec3 end, vec3 color, GLfloat width, GLuint laser_sp);
+SceneObject* createExplosion(GLuint shader);
 
 void translateLaser(Laser* laser, const vec3& translation, GLuint ubo);
@@ -197,7 +208,6 @@
                   GLuint color_sp, GLuint asteroid_sp, GLuint texture_sp, GLuint laser_sp, GLuint explosion_sp,
                   GLuint color_vao, GLuint asteroid_vao, GLuint texture_vao, GLuint laser_vao, GLuint explosion_vao,
-                  GLuint colors_vbo, GLuint selected_colors_vbo,
+                  GLuint colors_vbo, GLuint selected_colors_vbo, GLuint ubo,
                   SceneObject* selectedObject);
-void renderExplosion(GLuint explosion_sp, GLuint explosion_vao, GLuint tex);
 
 void renderSceneGui();
@@ -248,4 +258,7 @@
 Laser* rightLaser = NULL;
 EffectOverTime* rightLaserEffect = NULL;
+
+SceneObject* objExplosion;
+SceneObject* objFirst;
 
 /*
@@ -450,4 +463,5 @@
    shaderBufferInfo[texture_sp] = BufferInfo();
    shaderBufferInfo[laser_sp] = BufferInfo();
+   shaderBufferInfo[explosion_sp] = BufferInfo();
 
    cam_pos = vec3(0.0f, 0.0f, 2.0f);
@@ -494,15 +508,15 @@
 
    glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
-   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
    // Comment these two lines out when I want to use selected colors
    glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
-   glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
+   glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
    glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
-   glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);
+   glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
    glBindBuffer(GL_ARRAY_BUFFER, model_mat_idx_vbo);
-   glVertexAttribIPointer(3, 1, GL_UNSIGNED_INT, 0, 0);
+   glVertexAttribIPointer(3, 1, GL_UNSIGNED_INT, 0, NULL);
 
    GLuint asteroid_vao = 0;
@@ -516,14 +530,14 @@
 
    glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
-   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
    glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
-   glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
+   glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
    glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
-   glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);
+   glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
    glBindBuffer(GL_ARRAY_BUFFER, model_mat_idx_vbo);
-   glVertexAttribIPointer(3, 1, GL_UNSIGNED_INT, 0, 0);
+   glVertexAttribIPointer(3, 1, GL_UNSIGNED_INT, 0, NULL);
 
    GLuint texture_vao = 0;
@@ -537,14 +551,14 @@
 
    glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
-   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
    glBindBuffer(GL_ARRAY_BUFFER, texcoords_vbo);
-   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
+   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
 
    glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
-   glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);
+   glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
    glBindBuffer(GL_ARRAY_BUFFER, model_mat_idx_vbo);
-   glVertexAttribIPointer(3, 1, GL_UNSIGNED_INT, 0, 0);
+   glVertexAttribIPointer(3, 1, GL_UNSIGNED_INT, 0, NULL);
 
    GLuint laser_vao = 0;
@@ -557,11 +571,11 @@
 
    glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
-   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
    glBindBuffer(GL_ARRAY_BUFFER, texcoords_vbo);
-   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
+   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
 
    glBindBuffer(GL_ARRAY_BUFFER, model_mat_idx_vbo);
-   glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, 0, 0);
+   glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, 0, NULL);
 
    float cam_speed = 1.0f;
@@ -597,5 +611,14 @@
    proj_mat = make_mat4(proj_arr);
 
-   GLuint explosion_vao = initializeParticleEffectBuffers(vec3(0.0f, -1.2f, 0.65f), proj_mat, view_mat, explosion_sp);
+   GLuint explosion_vao = initializeParticleEffectBuffers(vec3(0.0f, -1.2f, 0.65f), proj_mat, view_mat,
+      explosion_sp,
+      shaderBufferInfo,
+      points_vbo,
+      colors_vbo,
+      selected_colors_vbo,
+      texcoords_vbo,
+      normals_vbo,
+      ubo,
+      model_mat_idx_vbo);
 
    GLuint ub_binding_point = 0;
@@ -621,4 +644,5 @@
    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");
 
 
@@ -653,4 +677,9 @@
 
    glUniformBlockBinding(laser_sp, laser_sp_models_ub_index, ub_binding_point);
+   glBindBufferRange(GL_UNIFORM_BUFFER, ub_binding_point, ubo, 0, GL_MAX_UNIFORM_BLOCK_SIZE);
+
+
+   glUseProgram(explosion_sp);
+   glUniformBlockBinding(explosion_sp, explosion_sp_models_ub_index, ub_binding_point);
    glBindBufferRange(GL_UNIFORM_BUFFER, ub_binding_point, ubo, 0, GL_MAX_UNIFORM_BLOCK_SIZE);
 
@@ -825,13 +854,23 @@
                   removeObjectFromScene(*objects[i], ubo);
                }
+               // MARKER: Continue code review from here
                if (((Asteroid*)objects[i])->hp <= 0) {
+                  // TODO: Optimize this so I don't recalculate the camera rotation every time
+                  float cam_pitch = -50.0f * 2.0f * 3.14159f / 360.0f;
+                  mat4 pitch_mat = rotate(mat4(1.0f), cam_pitch, vec3(1.0f, 0.0f, 0.0f));
+                  mat4 model_mat = translate(mat4(1.0f), objects[i]->bounding_center + vec3(0.0f, 0.0f, 0.0f)) * pitch_mat;
+
                   removeObjectFromScene(*objects[i], ubo);
                   score++;
 
-                  // render an explosion
+                  objExplosion->model_mat = model_mat;
+
+                  // initiate an explosion
                   glUseProgram(explosion_sp);
+
+                  GLuint model_mat_loc = glGetUniformLocation(explosion_sp, "model_mat");
+                  glUniformMatrix4fv(model_mat_loc, 1, GL_FALSE, value_ptr(objExplosion->model_mat));
+
                   glUniform1f(explosion_start_time_loc, (GLfloat)glfwGetTime());
-                  cout << "REMOVED" << endl;
-                  cout << i << endl;
                }
             }
@@ -944,5 +983,5 @@
                color_sp, asteroid_sp, texture_sp, laser_sp, explosion_sp,
                color_vao, asteroid_vao, texture_vao, laser_vao, explosion_vao,
-               colors_vbo, selected_colors_vbo,
+               colors_vbo, selected_colors_vbo, ubo,
                selectedObject);
             renderSceneGui();
@@ -1288,5 +1327,5 @@
    }
 
-   if (obj->type != TYPE_LASER) {
+   if (obj->type == TYPE_SHIP || obj->type == TYPE_ASTEROID) {
       calculateObjectBoundingBox(obj);
 
@@ -1311,5 +1350,5 @@
    // 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->ubo_offset + obj->num_points) ||
+   if (bufferInfo->vbo_capacity < (bufferInfo->vbo_offset + obj->num_points) ||
       bufferInfo->ubo_capacity < (bufferInfo->ubo_offset + 1)) {
 
@@ -1805,5 +1844,4 @@
 */
 // TODO: Make the color parameter have an effect
-// TODO: Come up with a better way of passing the object back than copying it
 Laser* createLaser(vec3 start, vec3 end, vec3 color, GLfloat width, GLuint laser_sp) {
    Laser* obj = new Laser();
@@ -1912,7 +1950,13 @@
 }
 
-GLuint initializeParticleEffectBuffers(vec3 origin, mat4 proj, mat4 view, GLuint explosion_sp) {
-   //unsigned int num_explosions = 1;
-
+GLuint initializeParticleEffectBuffers(vec3 origin, mat4 proj, mat4 view, GLuint explosion_sp,
+                  map<GLuint, BufferInfo>& shaderBufferInfo,
+                  GLuint points_vbo,
+                  GLuint colors_vbo,
+                  GLuint selected_colors_vbo,
+                  GLuint texcoords_vbo,
+                  GLuint normals_vbo,
+                  GLuint ubo,
+                  GLuint model_mat_idx_vbo) {
    float vv[EXPLOSION_PARTICLE_COUNT * 3]; // initial velocities vec3
    float vt[EXPLOSION_PARTICLE_COUNT]; // initial times
@@ -1944,15 +1988,4 @@
    glUniformMatrix4fv(model_mat_loc, 1, GL_FALSE, value_ptr(model_mat));
 
-   /*
-   GLuint model_ubo = 0;
-   glGenBuffers(1, &model_ubo);
-
-   glBindBuffer(GL_UNIFORM_BUFFER, model_ubo);
-   glBufferData(GL_UNIFORM_BUFFER, num_explosions * sizeof(mat4), NULL, GL_DYNAMIC_DRAW);
-
-   //glBindBuffer(GL_UNIFORM_BUFFER, ubo);
-   glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(mat4), value_ptr(model_mat));
-   */
-
    GLuint velocity_vbo;
    glGenBuffers(1, &velocity_vbo);
@@ -1969,4 +2002,7 @@
    glBindVertexArray(vao);
 
+   glEnableVertexAttribArray(0);
+   glEnableVertexAttribArray(1);
+
    glBindBuffer(GL_ARRAY_BUFFER, velocity_vbo);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
@@ -1975,6 +2011,14 @@
    glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, NULL);
 
-   glEnableVertexAttribArray(0);
-   glEnableVertexAttribArray(1);
+   objExplosion = createExplosion(explosion_sp);
+   addObjectToScene(objExplosion, shaderBufferInfo,
+      points_vbo,
+      colors_vbo,
+      selected_colors_vbo,
+      texcoords_vbo,
+      normals_vbo,
+      ubo,
+      model_mat_idx_vbo,
+      0);
 
    return vao;
@@ -1996,4 +2040,11 @@
    map<GLuint, unsigned int> shaderCounts;
    map<GLuint, unsigned int> shaderUboCounts;
+
+   map<GLuint, BufferInfo>::iterator shaderIt;
+
+   for (shaderIt = shaderBufferInfo.begin(); shaderIt != shaderBufferInfo.end(); shaderIt++) {
+      shaderCounts[shaderIt->first] = 0;
+      shaderUboCounts[shaderIt->first] = 0;
+   }
 
    vector<SceneObject*>::iterator it;
@@ -2013,11 +2064,6 @@
          num_objects++;
 
-         if (shaderCounts.count((*it)->shader_program) == 0) {
-            shaderCounts[(*it)->shader_program] = (*it)->num_points;
-            shaderUboCounts[(*it)->shader_program] = 1;
-         } else {
-            shaderCounts[(*it)->shader_program] += (*it)->num_points;
-            shaderUboCounts[(*it)->shader_program]++;
-         }
+         shaderCounts[(*it)->shader_program] += (*it)->num_points;
+         shaderUboCounts[(*it)->shader_program]++;
 
          it++;
@@ -2029,5 +2075,5 @@
    num_objects *= 2;
 
-   map<GLuint, unsigned int>::iterator shaderIt;
+   map<GLuint, unsigned int>::iterator shaderCountIt;
    unsigned int lastShaderCount = 0;
    unsigned int lastShaderUboCount = 0;
@@ -2040,26 +2086,18 @@
    * object being added.
    */
-   for (shaderIt = shaderCounts.begin(); shaderIt != shaderCounts.end(); shaderIt++) {
+   for (shaderCountIt = shaderCounts.begin(); shaderCountIt != shaderCounts.end(); shaderCountIt++) {
       // When populating the buffers, leave as much empty space as space taken up by existing objects
       // to allow new objects to be added without immediately having to resize the buffers
-      shaderBufferInfo[shaderIt->first].vbo_base = lastShaderCount * 2;
-      shaderBufferInfo[shaderIt->first].ubo_base = lastShaderUboCount * 2;
-
-      /*
-      cout << "shader: " << shaderIt->first << endl;
-      cout << "point counts: " << shaderCounts[shaderIt->first] << endl;
-      cout << "object counts: " << shaderUboCounts[shaderIt->first] << endl;
-      cout << "vbo_base: " << shaderBufferInfo[shaderIt->first].vbo_base << endl;
-      cout << "ubo_base: " << shaderBufferInfo[shaderIt->first].ubo_base << endl;
-      */
-
-      shaderBufferInfo[shaderIt->first].vbo_offset = 0;
-      shaderBufferInfo[shaderIt->first].ubo_offset = 0;
-
-      shaderBufferInfo[shaderIt->first].vbo_capacity = shaderCounts[shaderIt->first] * 2;
-      shaderBufferInfo[shaderIt->first].ubo_capacity = shaderUboCounts[shaderIt->first] * 2;
-
-      lastShaderCount += shaderCounts[shaderIt->first];
-      lastShaderUboCount += shaderUboCounts[shaderIt->first];
+      shaderBufferInfo[shaderCountIt->first].vbo_base = lastShaderCount * 2;
+      shaderBufferInfo[shaderCountIt->first].ubo_base = lastShaderUboCount * 2;
+
+      shaderBufferInfo[shaderCountIt->first].vbo_offset = 0;
+      shaderBufferInfo[shaderCountIt->first].ubo_offset = 0;
+
+      shaderBufferInfo[shaderCountIt->first].vbo_capacity = shaderCounts[shaderCountIt->first] * 2;
+      shaderBufferInfo[shaderCountIt->first].ubo_capacity = shaderUboCounts[shaderCountIt->first] * 2;
+
+      lastShaderCount += shaderCounts[shaderCountIt->first];
+      lastShaderUboCount += shaderUboCounts[shaderCountIt->first];
    }
 
@@ -2115,36 +2153,42 @@
    obj.ubo_offset = bufferInfo->ubo_base + bufferInfo->ubo_offset;
 
-   glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
-   glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.points.size() * sizeof(GLfloat), &obj.points[0]);
-
-   glBindBuffer(GL_ARRAY_BUFFER, texcoords_vbo);
-   glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 2, obj.texcoords.size() * sizeof(GLfloat), &obj.texcoords[0]);
-
-   glBindBuffer(GL_ARRAY_BUFFER, model_mat_idx_vbo);
-   for (unsigned int i = 0; i < obj.num_points; i++) {
-      glBufferSubData(GL_ARRAY_BUFFER, (obj.vertex_vbo_offset + i) * sizeof(GLuint), sizeof(GLuint), &obj.ubo_offset);
-   }
-
-   if (obj.type != TYPE_LASER) {
-      glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
-      glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.colors.size() * sizeof(GLfloat), &obj.colors[0]);
-
-      glBindBuffer(GL_ARRAY_BUFFER, selected_colors_vbo);
-      glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.selected_colors.size() * sizeof(GLfloat), &obj.selected_colors[0]);
-
-      glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
-      glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.normals.size() * sizeof(GLfloat), &obj.normals[0]);
-   }
-
-   obj.model_mat = obj.model_transform * obj.model_base;
-   glBindBuffer(GL_UNIFORM_BUFFER, ubo);
-   glBufferSubData(GL_UNIFORM_BUFFER, obj.ubo_offset * sizeof(mat4), sizeof(mat4), value_ptr(obj.model_mat));
-
-   if (obj.type == TYPE_ASTEROID) {
-      glUseProgram(asteroid_sp);
-
-      ostringstream oss;
-      oss << "hp[" << obj.ubo_offset << "]";
-      glUniform1f(glGetUniformLocation(asteroid_sp, oss.str().c_str()), ((Asteroid*)&obj)->hp);
+   if (obj.ubo_offset == 0) {
+      objFirst = &obj;
+   }
+
+   if (obj.type != TYPE_EXPLOSION) {
+      glBindBuffer(GL_ARRAY_BUFFER, model_mat_idx_vbo);
+      for (unsigned int i = 0; i < obj.num_points; i++) {
+         glBufferSubData(GL_ARRAY_BUFFER, (obj.vertex_vbo_offset + i) * sizeof(GLuint), sizeof(GLuint), &obj.ubo_offset);
+      }
+
+      glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
+      glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.points.size() * sizeof(GLfloat), &obj.points[0]);
+
+      glBindBuffer(GL_ARRAY_BUFFER, texcoords_vbo);
+      glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 2, obj.texcoords.size() * sizeof(GLfloat), &obj.texcoords[0]);
+
+      if (obj.type != TYPE_LASER) {
+         glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
+         glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.colors.size() * sizeof(GLfloat), &obj.colors[0]);
+
+         glBindBuffer(GL_ARRAY_BUFFER, selected_colors_vbo);
+         glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.selected_colors.size() * sizeof(GLfloat), &obj.selected_colors[0]);
+
+         glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
+         glBufferSubData(GL_ARRAY_BUFFER, obj.vertex_vbo_offset * sizeof(GLfloat) * 3, obj.normals.size() * sizeof(GLfloat), &obj.normals[0]);
+      }
+
+      obj.model_mat = obj.model_transform * obj.model_base;
+      glBindBuffer(GL_UNIFORM_BUFFER, ubo);
+      glBufferSubData(GL_UNIFORM_BUFFER, obj.ubo_offset * sizeof(mat4), sizeof(mat4), value_ptr(obj.model_mat));
+
+      if (obj.type == TYPE_ASTEROID) {
+         glUseProgram(asteroid_sp);
+
+         ostringstream oss;
+         oss << "hp[" << obj.ubo_offset << "]";
+         glUniform1f(glGetUniformLocation(asteroid_sp, oss.str().c_str()), ((Asteroid*)&obj)->hp);
+      }
    }
 
@@ -2316,5 +2360,5 @@
                   GLuint color_sp, GLuint asteroid_sp, GLuint texture_sp, GLuint laser_sp, GLuint explosion_sp,
                   GLuint color_vao, GLuint asteroid_vao, GLuint texture_vao, GLuint laser_vao, GLuint explosion_vao,
-                  GLuint colors_vbo, GLuint selected_colors_vbo,
+                  GLuint colors_vbo, GLuint selected_colors_vbo, GLuint ubo,
                   SceneObject* selectedObject) {
 
@@ -2325,5 +2369,5 @@
    if (selectedObject != NULL) {
       glBindBuffer(GL_ARRAY_BUFFER, selected_colors_vbo);
-      glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
+      glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
       glDrawArrays(GL_TRIANGLES, selectedObject->vertex_vbo_offset, selectedObject->num_points);
@@ -2333,5 +2377,5 @@
    // Uncomment this code when I want to use selected colors again
    // glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
-   // glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
+   // glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
    glDrawArrays(GL_TRIANGLES, shaderBufferInfo[color_sp].vbo_base, shaderBufferInfo[color_sp].vbo_offset);
@@ -2354,20 +2398,16 @@
    glDrawArrays(GL_TRIANGLES, shaderBufferInfo[laser_sp].vbo_base, shaderBufferInfo[laser_sp].vbo_offset);
 
-   glDisable(GL_BLEND);
-
-   renderExplosion(explosion_sp, explosion_vao, 0);
-}
-
-void renderExplosion(GLuint explosion_sp, GLuint explosion_vao, GLuint tex) {
-   glEnable(GL_BLEND);
+   glUseProgram(explosion_sp);
+
    glEnable(GL_PROGRAM_POINT_SIZE);
-
-   //glActiveTexture(GL_TEXTURE1);
-   //glBindTexture(GL_TEXTURE_2D, tex);
-   glUseProgram(explosion_sp);
-
    glBindVertexArray(explosion_vao);
 
-   glDrawArrays(GL_POINTS, 0, EXPLOSION_PARTICLE_COUNT);
+   glBindBuffer(GL_UNIFORM_BUFFER, ubo);
+   glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(mat4), value_ptr(objExplosion->model_mat));
+
+   glDrawArrays(GL_POINTS, 0, shaderBufferInfo[explosion_sp].vbo_offset);
+
+   glBindBuffer(GL_UNIFORM_BUFFER, ubo);
+   glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(mat4), value_ptr(objFirst->model_mat));
 
    glDisable(GL_PROGRAM_POINT_SIZE);
@@ -2474,6 +2514,6 @@
    Asteroid* obj = new Asteroid();
    obj->type = TYPE_ASTEROID;
+   obj->shader_program = shader;
    obj->hp = 10.0f;
-   obj->shader_program = shader;
 
    obj->points = {
@@ -2595,4 +2635,18 @@
 }
 
+SceneObject* createExplosion(GLuint shader) {
+   SceneObject* obj = new SceneObject();
+   obj->type = TYPE_EXPLOSION;
+   obj->shader_program = shader;
+
+   obj->points = {};
+   obj->colors = {};
+
+   initObject(obj);
+   obj->num_points = EXPLOSION_PARTICLE_COUNT;
+
+   return obj;
+}
+
 float getRandomNum(float low, float high) {
    return low + ((float)rand()/RAND_MAX) * (high-low);
