Index: new-game.cpp
===================================================================
--- new-game.cpp	(revision a0eb547a52292720b00f8756cacd84e336ffd2f5)
+++ new-game.cpp	(revision 49db5fc3bf58103571921feba975a9450206b5bf)
@@ -57,4 +57,12 @@
    ATTRIB_OBJECT_VARYING,
    ATTRIB_POINT_VARYING,
+};
+
+// Add more types as I need them
+enum UniformType {
+   UNIFORM_NONE,
+   UNIFORM_MATRIX_4F,
+   UNIFORM_1F,
+   UNIFORM_3F,
 };
 
@@ -119,6 +127,8 @@
    GLint size;
    GLenum type;
-   GLuint buffer;
+   UniformType uniType;
+   GLuint buffer; // For uniforms, this is the uniform location
    size_t fieldOffset;
+   GLfloat* data; // pointer to data source for uniform attributes
 };
 
@@ -173,5 +183,7 @@
 
 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);
 void initModelGroupAttribs(ShaderModelGroup& modelGroup);
+void bindUniformData(AttribInfo& attrib);
 
 size_t GLsizeof(GLenum);
@@ -212,10 +224,5 @@
                   map<GLuint, BufferInfo>& shaderBufferInfo,
                   map<ObjectType, ShaderModelGroup>& modelGroups,
-                  GLuint points_vbo,
-                  GLuint colors_vbo,
-                  GLuint texcoords_vbo,
-                  GLuint normals_vbo,
-                  GLuint ubo,
-                  GLuint model_mat_idx_vbo);
+                  GLuint ubo);
 
 void transformObject(SceneObject& obj, const mat4& transform, GLuint ubo);
@@ -470,4 +477,6 @@
     */
 
+   GLfloat laserColor[3] = {0.2f, 1.0f, 0.2f};
+
    GLuint points_vbo, colors_vbo, texcoords_vbo, normals_vbo, ubo, model_mat_idx_vbo;
 
@@ -496,4 +505,9 @@
       1, GL_UNSIGNED_INT, offsetof(SceneObject, ubo_offset));
 
+   defineModelGroupUniform(modelGroups[TYPE_SHIP], "view", ATTRIB_UNIFORM,
+      1, UNIFORM_MATRIX_4F, value_ptr(view_mat));
+   defineModelGroupUniform(modelGroups[TYPE_SHIP], "proj", ATTRIB_UNIFORM,
+      1, UNIFORM_MATRIX_4F, value_ptr(proj_mat));
+
    initModelGroupAttribs(modelGroups[TYPE_SHIP]);
 
@@ -527,4 +541,9 @@
       1, GL_UNSIGNED_INT, offsetof(SceneObject, ubo_offset));
 
+   defineModelGroupUniform(modelGroups[TYPE_ASTEROID], "view", ATTRIB_UNIFORM,
+      1, UNIFORM_MATRIX_4F, value_ptr(view_mat));
+   defineModelGroupUniform(modelGroups[TYPE_ASTEROID], "proj", ATTRIB_UNIFORM,
+      1, UNIFORM_MATRIX_4F, value_ptr(proj_mat));
+
    initModelGroupAttribs(modelGroups[TYPE_ASTEROID]);
 
@@ -555,4 +574,11 @@
    defineModelGroupAttrib(modelGroups[TYPE_LASER], "ubo_index", ATTRIB_OBJECT_VARYING,
       1, GL_UNSIGNED_INT, offsetof(SceneObject, ubo_offset));
+
+   defineModelGroupUniform(modelGroups[TYPE_LASER], "view", ATTRIB_UNIFORM,
+      1, UNIFORM_MATRIX_4F, value_ptr(view_mat));
+   defineModelGroupUniform(modelGroups[TYPE_LASER], "proj", ATTRIB_UNIFORM,
+      1, UNIFORM_MATRIX_4F, value_ptr(proj_mat));
+    defineModelGroupUniform(modelGroups[TYPE_LASER], "laser_color", ATTRIB_UNIFORM,
+      1, UNIFORM_3F, laserColor);
 
    initModelGroupAttribs(modelGroups[TYPE_LASER]);
@@ -671,45 +697,38 @@
    GLuint ub_binding_point = 0;
 
-   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");
-   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_sp_models_ub_index = glGetUniformBlockIndex(modelGroups[TYPE_LASER].shaderProgram, "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");
+
+
+   glUseProgram(modelGroups[TYPE_SHIP].shaderProgram);
+   bindUniformData(modelGroups[TYPE_SHIP].attribs["view"]);
+   bindUniformData(modelGroups[TYPE_SHIP].attribs["proj"]);
+
+   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);
+
+
+   glUseProgram(modelGroups[TYPE_ASTEROID].shaderProgram);
+   bindUniformData(modelGroups[TYPE_ASTEROID].attribs["view"]);
+   bindUniformData(modelGroups[TYPE_ASTEROID].attribs["proj"]);
+
+   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);
+
 
    // may want to do initialization for basic_texture uniform here too
    // Right now, I think I'm getting away without getting that uniform location because I'm only
    // using one texture, so setting it to GL_TEXTURE0 once works
-   GLuint laser_view_mat_loc = glGetUniformLocation(modelGroups[TYPE_LASER].shaderProgram, "view");
-   GLuint laser_proj_mat_loc = glGetUniformLocation(modelGroups[TYPE_LASER].shaderProgram, "proj");
-   GLuint laser_color_loc = glGetUniformLocation(modelGroups[TYPE_LASER].shaderProgram, "laser_color");
-   GLuint laser_sp_models_ub_index = glGetUniformBlockIndex(modelGroups[TYPE_LASER].shaderProgram, "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");
-
-
-   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(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);
-
-
-   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(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);
-
-
    glUseProgram(modelGroups[TYPE_LASER].shaderProgram);
-   glUniformMatrix4fv(laser_view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
-   glUniformMatrix4fv(laser_proj_mat_loc, 1, GL_FALSE, value_ptr(proj_mat));
-   glUniform3f(laser_color_loc, 0.2f, 1.0f, 0.2f);
+   bindUniformData(modelGroups[TYPE_LASER].attribs["view"]);
+   bindUniformData(modelGroups[TYPE_LASER].attribs["proj"]);
+   bindUniformData(modelGroups[TYPE_LASER].attribs["laser_color"]);
 
    glUniformBlockBinding(modelGroups[TYPE_LASER].shaderProgram, laser_sp_models_ub_index, ub_binding_point);
@@ -899,4 +918,5 @@
 
                   objExplosion->model_mat = model_mat;
+                  GLfloat curTime = glfwGetTime();
 
                   // initiate an explosion
@@ -988,8 +1008,8 @@
 
          glUseProgram(modelGroups[TYPE_SHIP].shaderProgram);
-         glUniformMatrix4fv(ship_view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
+         bindUniformData(modelGroups[TYPE_SHIP].attribs["view"]);
 
          glUseProgram(modelGroups[TYPE_LASER].shaderProgram);
-         glUniformMatrix4fv(laser_view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
+         bindUniformData(modelGroups[TYPE_LASER].attribs["view"]);
 
          cam_moved = false;
@@ -1392,11 +1412,5 @@
          model_mat_idx_vbo);
    } else {
-      copyObjectDataToBuffers(*objects.back(), shaderBufferInfo, modelGroups,
-         points_vbo,
-         colors_vbo,
-         texcoords_vbo,
-         normals_vbo,
-         ubo,
-         model_mat_idx_vbo);
+      copyObjectDataToBuffers(*objects.back(), shaderBufferInfo, modelGroups, ubo);
    }
 }
@@ -1973,4 +1987,16 @@
 }
 
+void defineModelGroupUniform(ShaderModelGroup& modelGroup, string name, AttribType attribType,
+                  GLint size, UniformType type, GLfloat* data) {
+   AttribInfo attribInfo;
+
+   attribInfo.attribType = attribType;
+   attribInfo.size = size;
+   attribInfo.uniType = type;
+   attribInfo.data = data;
+
+   modelGroup.attribs[name] = attribInfo;
+}
+
 void initModelGroupAttribs(ShaderModelGroup& modelGroup) {
    glBindVertexArray(modelGroup.vao);
@@ -1978,19 +2004,37 @@
    map<string, AttribInfo>::iterator it;
    for (it = modelGroup.attribs.begin(); it != modelGroup.attribs.end(); it++) {
-      glEnableVertexAttribArray(it->second.index);
-
-      glGenBuffers(1, &it->second.buffer);
-      glBindBuffer(GL_ARRAY_BUFFER, it->second.buffer);
-
-      switch (it->second.type) {
-         case GL_FLOAT: {
-            glVertexAttribPointer(it->second.index, it->second.size, it->second.type, GL_FALSE, 0, NULL);
-            break;
+      if (it->second.attribType == ATTRIB_UNIFORM) {
+         it->second.buffer = glGetUniformLocation(modelGroup.shaderProgram, it->first.c_str());
+      } else {
+         glEnableVertexAttribArray(it->second.index);
+
+         glGenBuffers(1, &it->second.buffer);
+         glBindBuffer(GL_ARRAY_BUFFER, it->second.buffer);
+
+         switch (it->second.type) {
+            case GL_FLOAT: {
+               glVertexAttribPointer(it->second.index, it->second.size, it->second.type, GL_FALSE, 0, NULL);
+               break;
+            }
+            case GL_UNSIGNED_INT: {
+               glVertexAttribIPointer(it->second.index, it->second.size, it->second.type, 0, NULL);
+               break;
+            }
          }
-         case GL_UNSIGNED_INT: {
-            glVertexAttribIPointer(it->second.index, it->second.size, it->second.type, 0, NULL);
-            break;
-         }
-      }
+      }
+   }
+}
+
+void bindUniformData(AttribInfo& attrib) {
+   switch(attrib.uniType) {
+      case UNIFORM_MATRIX_4F:
+         glUniformMatrix4fv(attrib.buffer, attrib.size, GL_FALSE, attrib.data);
+         break;
+      case UNIFORM_1F:
+         glUniform3fv(attrib.buffer, attrib.size, attrib.data);
+         break;
+      case UNIFORM_3F:
+         glUniform3fv(attrib.buffer, attrib.size, attrib.data);
+         break;
    }
 }
@@ -2241,11 +2285,5 @@
 
    for (it = objects.begin(); it != objects.end(); it++) {
-      copyObjectDataToBuffers(**it, shaderBufferInfo, modelGroups,
-         points_vbo,
-         colors_vbo,
-         texcoords_vbo,
-         normals_vbo,
-         ubo,
-         ubo_idx_vbo);
+      copyObjectDataToBuffers(**it, shaderBufferInfo, modelGroups, ubo);
    }
 }
@@ -2254,10 +2292,5 @@
                   map<GLuint, BufferInfo>& shaderBufferInfo,
                   map<ObjectType, ShaderModelGroup>& modelGroups,
-                  GLuint points_vbo,
-                  GLuint colors_vbo,
-                  GLuint texcoords_vbo,
-                  GLuint normals_vbo,
-                  GLuint ubo,
-                  GLuint model_mat_idx_vbo) {
+                  GLuint ubo) {
    BufferInfo* bufferInfo = &shaderBufferInfo[modelGroups[obj.type].shaderProgram];
 
