Index: new-game.cpp
===================================================================
--- new-game.cpp	(revision 0414306f84f614c16d71251480e1d8ab474c7ecd)
+++ new-game.cpp	(revision 4c7cd57c51f23b2c41f2448cb6f7470a65935378)
@@ -53,4 +53,6 @@
 };
 
+// TODO: Once all object types use ShaderModelGroup objects,, I should be able to remove the
+// shader_program field since it would be available via modelGroups[type].shaderProgram
 struct SceneObject {
    unsigned int id;
@@ -60,4 +62,6 @@
    // they need to be done when the object is at the origin. I should change this to have separate scale, rotate, and translate
    // matrices for each object that can be updated independently and then applied to the object in that order.
+   // TODO: Actually, to make this as generic as possible, each object should have a matrix stack to support,
+   // for instance, applying a rotate, then a translate, then another rotate. Think about and implement the best approach.
    mat4 model_mat, model_base, model_transform;
    mat4 translate_mat; // beginning of doing what's mentioned above
@@ -213,6 +217,5 @@
 void renderScene(map<GLuint, BufferInfo>& shaderBufferInfo,
                   map<ObjectType, ShaderModelGroup>& modelGroups, GLuint ubo,
-                  GLuint ship_sp, GLuint laser_sp,
-                  GLuint ship_vao, GLuint laser_vao);
+                  GLuint laser_sp, GLuint laser_vao);
 
 void renderSceneGui();
@@ -457,13 +460,16 @@
    map<ObjectType, ShaderModelGroup> modelGroups;
 
-   GLuint ship_sp = loadShaderProgram("./ship.vert", "./ship.frag");
    GLuint laser_sp = loadShaderProgram("./laser.vert", "./laser.frag");
 
-   shaderBufferInfo[ship_sp] = BufferInfo();
    shaderBufferInfo[laser_sp] = BufferInfo();
+
+   modelGroups[TYPE_SHIP] = createModelGroup(
+      loadShaderProgram("./ship.vert", "./ship.frag"));
+   shaderBufferInfo[modelGroups[TYPE_SHIP].shaderProgram] = BufferInfo(); // temporary
 
    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"));
@@ -475,5 +481,5 @@
 
    // player ship
-   SceneObject* ship = createShip(ship_sp);
+   SceneObject* ship = createShip(modelGroups[TYPE_SHIP].shaderProgram);
    objects.push_back(ship);
 
@@ -499,7 +505,5 @@
       model_mat_idx_vbo);
 
-   GLuint ship_vao = 0;
-   glGenVertexArrays(1, &ship_vao);
-   glBindVertexArray(ship_vao);
+   glBindVertexArray(modelGroups[TYPE_SHIP].vao);
 
    glEnableVertexAttribArray(0);
@@ -635,7 +639,7 @@
    GLuint ub_binding_point = 0;
 
-   GLuint ship_view_mat_loc = glGetUniformLocation(ship_sp, "view");
-   GLuint ship_proj_mat_loc = glGetUniformLocation(ship_sp, "proj");
-   GLuint ship_sp_models_ub_index = glGetUniformBlockIndex(ship_sp, "models");
+   GLuint ship_view_mat_loc = glGetUniformLocation(modelGroups[TYPE_SHIP].shaderProgram, "view");
+   GLuint ship_proj_mat_loc = glGetUniformLocation(modelGroups[TYPE_SHIP].shaderProgram, "proj");
+   GLuint ship_sp_models_ub_index = glGetUniformBlockIndex(modelGroups[TYPE_SHIP].shaderProgram, "models");
 
    GLuint asteroid_view_mat_loc = glGetUniformLocation(modelGroups[TYPE_ASTEROID].shaderProgram, "view");
@@ -653,9 +657,9 @@
 
 
-   glUseProgram(ship_sp);
+   glUseProgram(modelGroups[TYPE_SHIP].shaderProgram);
    glUniformMatrix4fv(ship_view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
    glUniformMatrix4fv(ship_proj_mat_loc, 1, GL_FALSE, value_ptr(proj_mat));
 
-   glUniformBlockBinding(ship_sp, ship_sp_models_ub_index, ub_binding_point);
+   glUniformBlockBinding(modelGroups[TYPE_SHIP].shaderProgram, ship_sp_models_ub_index, ub_binding_point);
    glBindBufferRange(GL_UNIFORM_BUFFER, ub_binding_point, ubo, 0, GL_MAX_UNIFORM_BLOCK_SIZE);
 
@@ -946,5 +950,5 @@
          //printVector("cam pos", cam_pos);
 
-         glUseProgram(ship_sp);
+         glUseProgram(modelGroups[TYPE_SHIP].shaderProgram);
          glUniformMatrix4fv(ship_view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
 
@@ -969,6 +973,5 @@
          case STATE_GAME:
             renderScene(shaderBufferInfo, modelGroups, ubo,
-               ship_sp, laser_sp,
-               ship_vao, laser_vao);
+               laser_sp, laser_vao);
             renderSceneGui();
             break;
@@ -1333,5 +1336,8 @@
    BufferInfo* bufferInfo = &shaderBufferInfo[obj->shader_program];
 
-   unsigned int numPoints = obj->type == TYPE_ASTEROID || obj->type == TYPE_EXPLOSION ?
+   unsigned int numPoints =
+      obj->type == TYPE_SHIP ||
+      obj->type == TYPE_ASTEROID ||
+      obj->type == TYPE_EXPLOSION ?
       modelGroups[obj->type].numPoints :
       bufferInfo->vbo_offset;
@@ -2083,5 +2089,6 @@
       shaderBufferInfo[shaderCountIt->first].ubo_base = lastShaderUboCount * 2;
 
-      if (shaderCountIt->first != modelGroups[TYPE_ASTEROID].shaderProgram &&
+      if (shaderCountIt->first != modelGroups[TYPE_SHIP].shaderProgram &&
+         shaderCountIt->first != modelGroups[TYPE_ASTEROID].shaderProgram &&
          shaderCountIt->first != modelGroups[TYPE_EXPLOSION].shaderProgram) {
          shaderBufferInfo[shaderCountIt->first].vbo_offset = 0;
@@ -2096,6 +2103,12 @@
    }
 
-   modelGroups[TYPE_ASTEROID].numPoints = 0;
-   modelGroups[TYPE_EXPLOSION].numPoints = 0;
+   map<ObjectType, ShaderModelGroup>::iterator modelGroupIt;
+   for (modelGroupIt = modelGroups.begin(); modelGroupIt != modelGroups.end(); modelGroupIt++) {
+      if (modelGroupIt->first == TYPE_SHIP ||
+         modelGroupIt->first == TYPE_ASTEROID ||
+         modelGroupIt->first == TYPE_EXPLOSION) {
+         modelGroups[modelGroupIt->first].numPoints = 0;
+      }
+   }
 
    // Allocate all the buffers using the counts calculated above
@@ -2141,5 +2154,7 @@
    BufferInfo* bufferInfo = &shaderBufferInfo[obj.shader_program];
 
-   if (obj.type == TYPE_ASTEROID || obj.type == TYPE_EXPLOSION) {
+   if (obj.type == TYPE_SHIP ||
+      obj.type == TYPE_ASTEROID ||
+      obj.type == TYPE_EXPLOSION) {
       obj.vertex_vbo_offset = bufferInfo->vbo_base + modelGroups[obj.type].numPoints;
    } else {
@@ -2186,5 +2201,7 @@
    }
 
-   if (obj.type == TYPE_ASTEROID || obj.type == TYPE_EXPLOSION) {
+   if (obj.type == TYPE_SHIP ||
+      obj.type == TYPE_ASTEROID ||
+      obj.type == TYPE_EXPLOSION) {
       modelGroups[obj.type].numPoints += obj.num_points;
    } else {
@@ -2356,11 +2373,10 @@
 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);
-   glBindVertexArray(ship_vao);
-
-   glDrawArrays(GL_TRIANGLES, shaderBufferInfo[ship_sp].vbo_base, shaderBufferInfo[ship_sp].vbo_offset);
+                  GLuint laser_sp, GLuint laser_vao) {
+
+   glUseProgram(modelGroups[TYPE_SHIP].shaderProgram);
+   glBindVertexArray(modelGroups[TYPE_SHIP].vao);
+
+   glDrawArrays(GL_TRIANGLES, shaderBufferInfo[modelGroups[TYPE_SHIP].shaderProgram].vbo_base, modelGroups[TYPE_SHIP].numPoints);
 
    glUseProgram(modelGroups[TYPE_ASTEROID].shaderProgram);
