Index: new-game.cpp
===================================================================
--- new-game.cpp	(revision f0cc877d6d141d1aaa41ba4c736acf2b40569970)
+++ new-game.cpp	(revision 93462c63c09dfecba8961ea1f1953ff3fb181647)
@@ -31,4 +31,5 @@
 #include <array>
 #include <vector>
+#include <queue>
 
 using namespace std;
@@ -51,4 +52,15 @@
 };
 
+enum State {
+   STATE_MAIN_MENU,
+   STATE_GAME,
+};
+
+enum Event {
+   EVENT_GO_TO_MAIN_MENU,
+   EVENT_GO_TO_GAME,
+   EVENT_QUIT,
+};
+
 const bool FULLSCREEN = false;
 int width = 640;
@@ -63,4 +75,5 @@
 
 vector<SceneObject> objects;
+queue<Event> events;
 
 SceneObject* clickedObject = NULL;
@@ -85,5 +98,15 @@
 void print4DVector(string label, vec4 v);
 
-void renderGui();
+void renderMainMenu();
+void renderMainMenuGui();
+
+void renderScene(vector<SceneObject>& objects,
+                  GLuint shader_program1, GLuint shader_program2,
+                  GLuint vao1, GLuint vao2,
+                  GLuint shader1_mat_loc, GLuint shader2_mat_loc,
+                  GLuint points_vbo, GLuint normals_vbo,
+                  GLuint colors_vbo, GLuint texcoords_vbo, GLuint selected_colors_vbo,
+                  SceneObject* selectedObject);
+void renderSceneGui();
 
 void glfw_error_callback(int error, const char* description) {
@@ -485,11 +508,11 @@
    proj_mat = make_mat4(proj_arr);
 
-   GLint model_test_loc = glGetUniformLocation(shader_program, "model");
-   GLint view_test_loc = glGetUniformLocation(shader_program, "view");
-   GLint proj_test_loc = glGetUniformLocation(shader_program, "proj");
-
-   GLint model_mat_loc = glGetUniformLocation(shader_program2, "model");
-   GLint view_mat_loc = glGetUniformLocation(shader_program2, "view");
-   GLint proj_mat_loc = glGetUniformLocation(shader_program2, "proj");
+   GLuint model_test_loc = glGetUniformLocation(shader_program, "model");
+   GLuint view_test_loc = glGetUniformLocation(shader_program, "view");
+   GLuint proj_test_loc = glGetUniformLocation(shader_program, "proj");
+
+   GLuint model_mat_loc = glGetUniformLocation(shader_program2, "model");
+   GLuint view_mat_loc = glGetUniformLocation(shader_program2, "view");
+   GLuint proj_mat_loc = glGetUniformLocation(shader_program2, "proj");
 
    glUseProgram(shader_program);
@@ -506,7 +529,4 @@
    objects[1].shader_program = shader_program2;
 
-   vector<int> program1_objects, program2_objects;
-   vector<int>::iterator it;
-
    bool cam_moved = false;
 
@@ -520,4 +540,6 @@
    // disable vsync to see real framerate
    //glfwSwapInterval(0);
+
+   State curState = STATE_MAIN_MENU;
 
    while (!glfwWindowShouldClose(window) && isRunning) {
@@ -541,7 +563,4 @@
       }
 
-      program1_objects.clear();
-      program2_objects.clear();
-
       // Handle events (Ideally, move all event-handling code
       // before the render code)
@@ -550,9 +569,26 @@
       glfwPollEvents();
 
-      if (clickedObject == &objects[0]) {
-         selectedObject = &objects[0];
-      }
-      if (clickedObject == &objects[1]) {
-         selectedObject = &objects[1];
+      while (!events.empty()) {
+         switch (events.front()) {
+            case EVENT_GO_TO_MAIN_MENU:
+               curState = STATE_MAIN_MENU;
+               break;
+            case EVENT_GO_TO_GAME:
+               curState = STATE_GAME;
+               break;
+            case EVENT_QUIT:
+               isRunning = false;
+               break;
+         }
+         events.pop();
+      }
+
+      if (curState == STATE_GAME) {
+         if (clickedObject == &objects[0]) {
+            selectedObject = &objects[0];
+         }
+         if (clickedObject == &objects[1]) {
+            selectedObject = &objects[1];
+         }
       }
 
@@ -565,13 +601,4 @@
       }
 
-      // group scene objects by shader
-      for (unsigned int i=0; i < objects.size(); i++) {
-         if (objects[i].shader_program == shader_program) {
-            program1_objects.push_back(i);
-         } else if (objects[i].shader_program == shader_program2) {
-            program2_objects.push_back(i);
-         }
-      }
-
       /*
       model[12] = last_position + speed*elapsed_seconds;
@@ -581,45 +608,20 @@
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
-      glUseProgram(shader_program);
-      glBindVertexArray(vao);
-
-      for (it=program1_objects.begin(); it != program1_objects.end(); it++) {
-         glUniformMatrix4fv(model_test_loc, 1, GL_FALSE, value_ptr(objects[*it].model_mat));
-
-         glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
-         glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, objects[*it].vertex_vbo_offset);
-
-         if (selectedObject == &objects[*it]) {
-            glBindBuffer(GL_ARRAY_BUFFER, selected_colors_vbo);
-         } else {
-            glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
-         }
-         glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, objects[*it].vertex_vbo_offset);
-
-         glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
-         glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, objects[*it].vertex_vbo_offset);
-
-         glDrawArrays(GL_TRIANGLES, 0, objects[*it].num_points);
-      }
-
-      glUseProgram(shader_program2);
-      glBindVertexArray(vao2);
-
-      for (it = program2_objects.begin(); it != program2_objects.end(); it++) {
-         glUniformMatrix4fv(model_mat_loc, 1, GL_FALSE, value_ptr(objects[*it].model_mat));
-
-         glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
-         glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, objects[*it].vertex_vbo_offset);
-
-         glBindBuffer(GL_ARRAY_BUFFER, texcoords_vbo);
-         glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, objects[*it].texture_vbo_offset);
-
-         glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
-         glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, objects[*it].vertex_vbo_offset);
-
-         glDrawArrays(GL_TRIANGLES, 0, objects[*it].num_points);
-      }
-
-      renderGui();
+      switch (curState) {
+         case STATE_MAIN_MENU:
+            renderMainMenu();
+            renderMainMenuGui();
+            break;
+         case STATE_GAME:
+            renderScene(objects,
+               shader_program, shader_program2,
+               vao, vao2,
+               model_test_loc, model_mat_loc,
+               points_vbo, normals_vbo,
+               colors_vbo, texcoords_vbo, selected_colors_vbo,
+               selectedObject);
+            renderSceneGui();
+            break;
+      }
 
       glfwSwapBuffers(window);
@@ -815,5 +817,73 @@
 }
 
-void renderGui() {
+void renderScene(vector<SceneObject>& objects,
+                  GLuint shader_program1, GLuint shader_program2,
+                  GLuint vao1, GLuint vao2,
+                  GLuint shader1_mat_loc, GLuint shader2_mat_loc,
+                  GLuint points_vbo, GLuint normals_vbo,
+                  GLuint colors_vbo, GLuint texcoords_vbo, GLuint selected_colors_vbo,
+                  SceneObject* selectedObject) {
+   if (selectedObject == &objects[1]) {
+      objects[1].shader_program = shader_program1;
+   } else if (selectedObject != &objects[1]) {
+      objects[1].shader_program = shader_program2;
+   }
+
+   vector<int> program1_objects, program2_objects;
+
+   // group scene objects by shader
+   for (unsigned int i = 0; i < objects.size(); i++) {
+      if (objects[i].shader_program == shader_program1) {
+         program1_objects.push_back(i);
+      }
+      else if (objects[i].shader_program == shader_program2) {
+         program2_objects.push_back(i);
+      }
+   }
+
+   vector<int>::iterator it;
+
+   glUseProgram(shader_program1);
+   glBindVertexArray(vao1);
+
+   for (it = program1_objects.begin(); it != program1_objects.end(); it++) {
+      glUniformMatrix4fv(shader1_mat_loc, 1, GL_FALSE, value_ptr(objects[*it].model_mat));
+
+      glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
+      glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, objects[*it].vertex_vbo_offset);
+
+      if (selectedObject == &objects[*it]) {
+         glBindBuffer(GL_ARRAY_BUFFER, selected_colors_vbo);
+      } else {
+         glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
+      }
+      glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, objects[*it].vertex_vbo_offset);
+
+      glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
+      glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, objects[*it].vertex_vbo_offset);
+
+      glDrawArrays(GL_TRIANGLES, 0, objects[*it].num_points);
+   }
+
+   glUseProgram(shader_program2);
+   glBindVertexArray(vao2);
+
+   for (it = program2_objects.begin(); it != program2_objects.end(); it++) {
+      glUniformMatrix4fv(shader2_mat_loc, 1, GL_FALSE, value_ptr(objects[*it].model_mat));
+
+      glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
+      glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, objects[*it].vertex_vbo_offset);
+
+      glBindBuffer(GL_ARRAY_BUFFER, texcoords_vbo);
+      glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, objects[*it].texture_vbo_offset);
+
+      glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
+      glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, objects[*it].vertex_vbo_offset);
+
+      glDrawArrays(GL_TRIANGLES, 0, objects[*it].num_points);
+   }
+}
+
+void renderSceneGui() {
    ImGui_ImplGlfwGL3_NewFrame();
 
@@ -858,25 +928,47 @@
          ImGuiWindowFlags_NoResize |
          ImGuiWindowFlags_NoMove);
-      ImGui::InvisibleButton("", ImVec2(190, 18));
+      ImGui::InvisibleButton("", ImVec2(155, 18));
       ImGui::SameLine();
-      if (ImGui::Button("Quit")) {
-         isRunning = false;
+      if (ImGui::Button("Main Menu")) {
+         events.push(EVENT_GO_TO_MAIN_MENU);
       }
       ImGui::End();
    }
 
-   // Main Menu
-   /*
+   ImGui::Render();
+   ImGui_ImplGlfwGL3_RenderDrawData(ImGui::GetDrawData());
+}
+
+void renderMainMenu() {
+}
+
+void renderMainMenuGui() {
+   ImGui_ImplGlfwGL3_NewFrame();
+
    {
       int padding = 4;
       ImGui::SetNextWindowPos(ImVec2(-padding, -padding), ImGuiCond_Once);
-      ImGui::SetNextWindowSize(ImVec2(width+2*padding, height+2*padding), ImGuiCond_Once);
+      ImGui::SetNextWindowSize(ImVec2(width + 2 * padding, height + 2 * padding), ImGuiCond_Once);
       ImGui::Begin("WndMain", NULL,
          ImGuiWindowFlags_NoTitleBar |
          ImGuiWindowFlags_NoResize |
          ImGuiWindowFlags_NoMove);
+
+      ImGui::InvisibleButton("", ImVec2(10, 80));
+      ImGui::InvisibleButton("", ImVec2(285, 18));
+      ImGui::SameLine();
+      if (ImGui::Button("New Game")) {
+         events.push(EVENT_GO_TO_GAME);
+      }
+
+      ImGui::InvisibleButton("", ImVec2(10, 15));
+      ImGui::InvisibleButton("", ImVec2(300, 18));
+      ImGui::SameLine();
+      if (ImGui::Button("Quit")) {
+         events.push(EVENT_QUIT);
+      }
+
       ImGui::End();
    }
-   */
 
    ImGui::Render();
