Index: new-game.cpp
===================================================================
--- new-game.cpp	(revision c62eee67d1b1bb7ea638fbbb17aa6b5bf8a110a6)
+++ new-game.cpp	(revision 33a9664784e4b64ee8985d3b0932af1397b81a35)
@@ -31,6 +31,11 @@
 vec3 face_point1, face_point2, face_point3;
 
+bool clicked = false;
+int colors_i = 0;
+
 mat4 view_mat;
 mat4 proj_mat;
+
+bool insideTriangle(vec3 p, vec3 v1, vec3 v2, vec3 v3);
 
 GLuint loadShader(GLenum type, string file);
@@ -51,9 +56,28 @@
       float x = (2.0f*mouse_x) / width - 1.0f;
       float y = 1.0f - (2.0f*mouse_y) / height;
-
-      vec4 ray_clip = vec4(x, y, -1.0f, 1.0f);
+      cout << "x: " << x << ", y: " << y << endl;
+
+      // Since the projection matrix gets applied before the view matrix,
+      // treat the initial camera position (aka origin of the ray) as (0, 0, 0)
+
+      // When getting the ray direction, you can use near and fov to get the
+      // coordinates
+
+      vec4 ray_clip = vec4(x, y, -1.0f, 1.0f); // this should have a z equal to the near clipping plane
       vec4 ray_eye = inverse(proj_mat) * ray_clip;
       ray_eye = vec4(ray_eye.xy(), -1.0f, 0.0f);
       vec3 ray_world = normalize((inverse(view_mat) * ray_eye).xyz());
+
+      /* LATEST NOTES:
+       *
+       * Normalizing the world ray caused issues, although it should make sense with the projection
+       * matrix, since the z coordinate has meaning there.
+       *
+       * Now, I need to figure out the correct intersection test in 2D space
+       * Also, need to check that the global triangle points are correct
+       */
+
+      // since ray_world is the end result we want anyway, we probably don't need to add cam_pos to
+      // it, only to subtract it later
 
       vec3 click_point = cam_pos + ray_world;
@@ -67,4 +91,6 @@
        */
 
+      // upper right corner is 1, 1 in opengl
+
       cout << "Converted -> (" << ray_world.x << "," << ray_world.y << "," << ray_world.z << ")" << endl << endl;;
       cout << "Camera -> (" << cam_pos.x << "," << cam_pos.y << "," << cam_pos.z << ")" << endl;
@@ -84,10 +110,143 @@
        */
 
+      vec3 fp1 = face_point1;
+      vec3 fp2 = face_point2;
+      vec3 fp3 = face_point3;
+
       cout << "Points on the plane" << endl;
-      cout << "(" << face_point1.x << "," << face_point1.y << "," << face_point1.z << ")" << endl;
-      cout << "(" << face_point2.x << "," << face_point2.y << "," << face_point2.z << ")" << endl;
-      cout << "(" << face_point3.x << "," << face_point3.y << "," << face_point3.z << ")" << endl;
+      cout << "(" << fp1.x << ", " << fp1.y << ", " << fp1.z << ")" << endl;
+      cout << "(" << fp2.x << ", " << fp2.y << ", " << fp2.z << ")" << endl;
+      cout << "(" << fp3.x << ", " << fp3.y << ", " << fp3.z << ")" << endl;
+
+      float pa = (fp2.y-fp1.y)*(fp3.z-fp1.z) - (fp3.y-fp1.y)*(fp2.z-fp1.z);
+      float pb = (fp2.z-fp1.z)*(fp3.x-fp1.x) - (fp3.z-fp1.z)*(fp2.x-fp1.x);
+      float pc = (fp2.x-fp1.x)*(fp3.y-fp1.y) - (fp3.x-fp1.x)*(fp2.y-fp1.y);
+      float pd = -(pa*fp1.x+pb*fp1.y+pc*fp1.z);
+
+      cout << pa << "x+" << pb << "y+" << pc << "z+" << pd << "=0" << endl;
 
       // get intersection
+
+      // the intersection this computes is incorrect
+      // it doesn't match the equation of the plane
+      vec3 i;
+      i.z = -cam_pos.z - pc*pd/(pa*a+pb*b);
+      i.x = cam_pos.x + a * (i.z-cam_pos.z) / c;
+      i.y = cam_pos.y + b * (i.z-cam_pos.z) / c;
+
+      cout << "The holy grail?" << endl;
+      cout << "(" << i.x << "," << i.y << "," << i.z << ")" << endl;
+
+      bool hit = insideTriangle(i, fp1, fp2, fp3);
+      cout << (hit ? "true" : "false")  << endl;
+
+      if (hit) {
+         clicked = true;
+      }
+   }
+}
+
+void mouse_button_callback_new(GLFWwindow* window, int button, int action, int mods) {
+   double mouse_x, mouse_y;
+   glfwGetCursorPos(window, &mouse_x, &mouse_y);
+
+   if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
+      cout << "Mouse clicked (" << mouse_x << "," << mouse_y << ")" << endl;
+
+      float x = (2.0f*mouse_x) / width - 1.0f;
+      float y = 1.0f - (2.0f*mouse_y) / height;
+      cout << "x: " << x << ", y: " << y << endl;
+
+      // CHECK: Looks good up to here
+
+      // Since the projection matrix gets applied before the view matrix,
+      // treat the initial camera position (aka origin of the ray) as (0, 0, 0)
+
+      // When getting the ray direction, you can use near and fov to get the
+      // coordinates
+
+      // vec4 ray_clip = vec4(x, y, -1.0f, 1.0f); // this should have a z equal to the near clipping plane
+      // vec4 ray_eye = inverse(proj_mat) * ray_clip;
+      // ray_eye = vec4(ray_eye.xy(), -1.0f, 0.0f);
+      // vec3 ray_world = normalize((inverse(view_mat) * ray_eye).xyz());
+
+      vec4 ray_clip = vec4(x, y, 1.0f, 1.0f); // this should have a z equal to the near clipping plane
+      vec3 ray_world = (inverse(view_mat) * ray_clip).xyz();
+
+      /* LATEST NOTES:
+       *
+       * Normalizing the world ray caused issues, although it should make sense with the projection
+       * matrix, since the z coordinate has meaning there.
+       *
+       * Now, I need to figure out the correct intersection test in 2D space
+       * Also, need to check that the global triangle points are correct
+       */
+
+      // since ray_world is the end result we want anyway, we probably don't need to add cam_pos to
+      // it, only to subtract it later
+
+      vec3 click_point = cam_pos + ray_world;
+
+      /* Now, we need to generate the constants for the equations describing
+       * a 3D line:
+       *   (x - x0) / a = (y - y0) / b = (z - z0) / c
+       *
+       * The line goes through the camera position, so
+       * cam_pos = <x0, y0, z0>
+       */
+
+      // upper right corner is 1, 1 in opengl
+
+      cout << "Converted -> (" << ray_world.x << "," << ray_world.y << "," << ray_world.z << ")" << endl << endl;;
+      cout << "Camera -> (" << cam_pos.x << "," << cam_pos.y << "," << cam_pos.z << ")" << endl;
+      cout << "Click point -> (" << click_point.x << "," << click_point.y << "," << click_point.z << ")" << endl;
+
+      float a = 1.0f;
+      float b = a * (click_point.y - cam_pos.y) / (click_point.x - cam_pos.x);
+      float c = a * (click_point.z - cam_pos.z) / (click_point.x - cam_pos.x);
+
+      cout << "(x - " << cam_pos.x << ") / " << a << " = ";
+      cout << "(y - " << cam_pos.y << ") / " << b << " = ";
+      cout << "(z - " << cam_pos.z << ") / " << c << endl;;
+
+      /* Now, we need to generate the constants for the equations describing
+       * a 3D plane:
+       * dx + ey +fz +g = 0
+       */
+
+      vec3 fp1 = face_point1;
+      vec3 fp2 = face_point2;
+      vec3 fp3 = face_point3;
+
+      cout << "Points on the plane" << endl;
+      cout << "(" << fp1.x << ", " << fp1.y << ", " << fp1.z << ")" << endl;
+      cout << "(" << fp2.x << ", " << fp2.y << ", " << fp2.z << ")" << endl;
+      cout << "(" << fp3.x << ", " << fp3.y << ", " << fp3.z << ")" << endl;
+
+      float pa = (fp2.y-fp1.y)*(fp3.z-fp1.z) - (fp3.y-fp1.y)*(fp2.z-fp1.z);
+      float pb = (fp2.z-fp1.z)*(fp3.x-fp1.x) - (fp3.z-fp1.z)*(fp2.x-fp1.x);
+      float pc = (fp2.x-fp1.x)*(fp3.y-fp1.y) - (fp3.x-fp1.x)*(fp2.y-fp1.y);
+      float pd = -(pa*fp1.x+pb*fp1.y+pc*fp1.z);
+
+      cout << pa << "x+" << pb << "y+" << pc << "z+" << pd << "=0" << endl;
+
+      // get intersection
+
+      // the intersection this computes is incorrect
+      // it doesn't match the equation of the plane
+      vec3 i;
+      i.z = -cam_pos.z - pc*pd/(pa*a+pb*b);
+      i.x = cam_pos.x + a * (i.z-cam_pos.z) / c;
+      i.y = cam_pos.y + b * (i.z-cam_pos.z) / c;
+
+      cout << "The holy grail?" << endl;
+      cout << "(" << i.x << "," << i.y << "," << i.z << ")" << endl;
+
+      bool hit = insideTriangle(i, fp1, fp2, fp3);
+      cout << (hit ? "true" : "false")  << endl;
+
+      if (hit) {
+         clicked = true;
+      }
    }
 }
@@ -176,11 +335,21 @@
 
    GLfloat points[] = {
-      0.0f,  0.5f,  0.0f,
+      0.0f,  0.5f, -0.001f,
      -0.5f, -0.5f,  0.0f,
       0.5f, -0.5f,  0.0f,
       0.5f, -0.5f,  0.0f,
      -0.5f, -0.5f,  0.0f,
-      0.0f,  0.5f,  0.0f,
-   };
+      0.0f,  0.5f, -0.001f,
+   };
+   /*
+   GLfloat points[] = {
+      0.0f,  1.0f,  0.0f,
+     -1.0f,  0.0f,  0.0f,
+      1.0f,  0.0f,  0.0f,
+      1.0f,  0.0f,  0.0f,
+     -1.0f,  0.0f,  0.0f,
+      0.0f,  1.0f,  0.0f,
+   };
+   */
 
    // initialize global variables for click intersection test
@@ -196,4 +365,13 @@
      0.0, 0.0, 1.0,
      1.0, 0.0, 0.0,
+   };
+
+   GLfloat colors_new[] = {
+     0.0, 1.0, 0.0,
+     0.0, 1.0, 0.0,
+     0.0, 1.0, 0.0,
+     0.0, 1.0, 0.0,
+     0.0, 1.0, 0.0,
+     0.0, 1.0, 0.0,
    };
 
@@ -242,4 +420,5 @@
 
    mat4 T_model2 = translate(mat4(), vec3(-1.0f, 0.0f, 0.0f));
+   // mat4 T_model2 = translate(mat4(), vec3(0.0f, 0.0f, 0.0f));
    mat4 R_model2 = rotate(mat4(), 0.0f, vec3(0.0f, 1.0f, 0.0f));
    mat4 model_mat2 = T_model2*R_model2;
@@ -306,8 +485,13 @@
 
    cam_pos = vec3(0.0f, 0.0f, 2.0f);
+   //cam_pos = vec3(0.0f, 0.0f, 0.0f);
    float cam_yaw = 0.0f;
 
    mat4 T = translate(mat4(), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
    mat4 R = rotate(mat4(), -cam_yaw, vec3(0.0f, 1.0f, 0.0f));
+   /*
+   mat4 T = translate(mat4(), vec3(0.0f, 0.0f, 0.0f));
+   mat4 R = rotate(mat4(), 0.0f, vec3(0.0f, 1.0f, 0.0f));
+   */
    view_mat = R*T;
 
@@ -329,4 +513,12 @@
      0.0f, 0.0f, Pz, 0.0f,
    };
+   /*
+   float proj_arr[] = {
+     1.0f, 0.0f, 0.0f, 0.0f,
+     0.0f, 1.0f, 0.0f, 0.0f,
+     0.0f, 0.0f, 1.0f, 0.0f,
+     0.0f, 0.0f, 0.0f, 1.0f,
+   };
+   */
    proj_mat = make_mat4(proj_arr);
 
@@ -361,4 +553,18 @@
       }
 
+     if (clicked) {
+        glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
+
+        if (colors_i == 0) {
+           glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors_new, GL_STATIC_DRAW);
+           colors_i = 1;
+        } else {
+           glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
+           colors_i = 0;
+        }
+
+        clicked = false;
+     }
+
       /*
       model[12] = last_position + speed*elapsed_seconds;
@@ -380,5 +586,7 @@
       glBindVertexArray(vao2);
 
-      glDrawArrays(GL_TRIANGLES, 0, numPoints2);
+      int numPoints3 = numPoints2;
+      numPoints2 = numPoints3;
+      // glDrawArrays(GL_TRIANGLES, 0, numPoints2);
 
       glfwPollEvents();
@@ -421,5 +629,5 @@
          T = translate(mat4(), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
          R = rotate(mat4(), -cam_yaw, vec3(0.0f, 1.0f, 0.0f));
-         view_mat = R*T;
+         // view_mat = R*T;
 
          glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
@@ -481,2 +689,15 @@
   return image_data;
 }
+
+bool insideTriangle(vec3 p, vec3 v1, vec3 v2, vec3 v3) {
+   vec3 v21 = v2-v1;
+   vec3 v31 = v3-v1;
+   vec3 pv1 = p-v1;
+
+   float y = (pv1.y*v21.x - pv1.x*v21.y) / (v31.y*v21.x - v31.x*v21.y);
+   float x = (pv1.x-y*v31.x) / v21.x;
+
+   cout << "(" << x << ", " << y << ")" << endl;
+
+   return x > 0.0f && y > 0.0f && x+y < 1.0f;
+}
Index: opengl-notes.txt
===================================================================
--- opengl-notes.txt	(revision 33a9664784e4b64ee8985d3b0932af1397b81a35)
+++ opengl-notes.txt	(revision 33a9664784e4b64ee8985d3b0932af1397b81a35)
@@ -0,0 +1,41 @@
+Default bounds
+
+           1   1
+          |   /
+          |  /
+          | /
+          |/      
+-1 --------------- 1
+         /|
+        / |
+       /  |
+      /   |
+     -1   -1
+
+Matrices
+
+model: transforms each object separately
+view: transforms the whole world
+
+for instance, a positive x translation moves either one object or all objects on the screen to the right a certain distance.
+
+If you want to transform the camera position or rotation, it should be the inverse of the transformations the view matrix is applying.
+
+projection: Here's where the fun stuff begins
+Viewing Frustum diagram is on page 99
+
+I need to first implement the click detection function without applying the projection matrix
+
+The click detection function uses ray tracing to figure out which object we hit
+
+First, we need to generate the equation for the ray that starts at the camera position and through the point the user clicked. To do that, we need to turn the 2d point of the click into a 3d point on the near clipping plane.
+
+Ray Equation:
+R(t) = O+Dt
+
+where R(t) defines all the points on the ray, O is the camera origin,
+and D is the direction of the ray.
+
+In this case, D = P-O, where P is the point the user clicked on in 3D space
+
+Camera position = (0, 0, 0)
