Index: new-game.cpp
===================================================================
--- new-game.cpp	(revision 201e2f8cf64b9ad7cb915d25da198bdfa7d7ba86)
+++ new-game.cpp	(revision 485424b115047116d3e57c15d4a4583a1018a048)
@@ -1,5 +1,5 @@
-// NEXT STEP; Modify the vertex shader
-
 #include "logger.h"
+
+#include "stb_image.h"
 
 #include <glm/mat4x4.hpp> // glm::mat4
@@ -21,8 +21,9 @@
 
 #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444
+const bool FULLSCREEN = false;
 
 GLuint loadShader(GLenum type, string file);
-
-const bool FULLSCREEN = false;
+GLuint loadShaderProgram(string vertexShaderPath, string fragmentShaderPath);
+unsigned char* loadImage(string file_name, int* x, int* y);
 
 void glfw_error_callback(int error, const char* description) {
@@ -92,4 +93,24 @@
    // glFrontFace(GL_CW);
 
+   int x, y;
+   unsigned char* texImage = loadImage("test.png", &x, &y);
+   if (texImage) {
+     cout << "Yay, I loaded an image!" << endl;
+     cout << x << endl;
+     cout << y << endl;
+     printf ("first 4 bytes are: %i %i %i %i\n", texImage[0], texImage[1], texImage[2], texImage[3]);
+   }
+
+   GLuint tex = 0;
+   glGenTextures(1, &tex);
+   glActiveTexture(GL_TEXTURE0);
+   glBindTexture(GL_TEXTURE_2D, tex);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, texImage);
+
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
    GLfloat points[] = {
       0.0f,  0.5f,  0.0f,
@@ -110,7 +131,46 @@
    };
 
+   // Each point is made of 3 floats
+   int numPoints = (sizeof(points) / sizeof(float)) / 3;
+
+   GLfloat points2[] = {
+      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.5f, -0.5f,  0.0f,
+      0.5f, -0.5f,  0.0f,
+   };
+
+   /*
+   GLfloat colors2[] = {
+     0.0, 0.9, 0.9,
+     0.0, 0.9, 0.9,
+     0.0, 0.9, 0.9,
+     0.0, 0.9, 0.9,
+     0.0, 0.9, 0.9,
+     0.0, 0.9, 0.9,
+   };
+   */
+
+   GLfloat texcoords[] = {
+     1.0f, 1.0f,
+     0.0f, 1.0f,
+     0.0, 0.0,
+     1.0, 1.0,
+     0.0, 0.0,
+     1.0, 0.0
+   };
+
+   // Each point is made of 3 floats
+   int numPoints2 = (sizeof(points2) / sizeof(float)) / 3;
+
    mat4 T_model = translate(mat4(), vec3(0.5f, 0.0f, 0.0f));
    mat4 R_model = rotate(mat4(), 4.0f, vec3(0.0f, 1.0f, 0.0f));
    mat4 model_mat = T_model*R_model;
+
+   mat4 T_model2 = translate(mat4(), vec3(-1.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;
 
    GLuint points_vbo = 0;
@@ -135,12 +195,36 @@
    glEnableVertexAttribArray(1);
 
-   GLuint vs = loadShader(GL_VERTEX_SHADER, "./test.vert");
-   GLuint fs = loadShader(GL_FRAGMENT_SHADER, "./test.frag");
-
-   GLuint shader_program = glCreateProgram();
-   glAttachShader(shader_program, vs);
-   glAttachShader(shader_program, fs);
-
-   glLinkProgram(shader_program);
+   GLuint points2_vbo = 0;
+   glGenBuffers(1, &points2_vbo);
+   glBindBuffer(GL_ARRAY_BUFFER, points2_vbo);
+   glBufferData(GL_ARRAY_BUFFER, sizeof(points2), points2, GL_STATIC_DRAW);
+
+   /*
+   GLuint colors2_vbo = 0;
+   glGenBuffers(1, &colors2_vbo);
+   glBindBuffer(GL_ARRAY_BUFFER, colors2_vbo);
+   glBufferData(GL_ARRAY_BUFFER, sizeof(colors2), colors2, GL_STATIC_DRAW);
+   */
+
+   GLuint vt_vbo;
+   glGenBuffers(1, &vt_vbo);
+   glBindBuffer(GL_ARRAY_BUFFER, vt_vbo);
+   glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords, GL_STATIC_DRAW);
+
+   GLuint vao2 = 0;
+   glGenVertexArrays(1, &vao2);
+   glBindVertexArray(vao2);
+   glBindBuffer(GL_ARRAY_BUFFER, points2_vbo);
+   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
+   // glBindBuffer(GL_ARRAY_BUFFER, colors2_vbo);
+   // glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
+   glBindBuffer(GL_ARRAY_BUFFER, vt_vbo);
+   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+
+   glEnableVertexAttribArray(0);
+   glEnableVertexAttribArray(1);
+
+   GLuint shader_program = loadShaderProgram("./color.vert", "./color.frag");
+   GLuint shader_program2 = loadShaderProgram("./texture.vert", "./texture.frag");
 
    float speed = 1.0f;
@@ -175,12 +259,21 @@
    };
 
-   GLint model_mat_loc = glGetUniformLocation(shader_program, "model");
-   GLint view_mat_loc = glGetUniformLocation(shader_program, "view");
-   GLint proj_mat_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");
+
+   GLint model_test_loc = glGetUniformLocation(shader_program, "model");
+   GLint view_test_loc = glGetUniformLocation(shader_program, "view");
+   GLint proj_test_loc = glGetUniformLocation(shader_program, "proj");
 
    glUseProgram(shader_program);
-   glUniformMatrix4fv(model_mat_loc, 1, GL_FALSE, value_ptr(model_mat));
-   glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
+   glUniformMatrix4fv(model_test_loc, 1, GL_FALSE, value_ptr(model_mat));
+   glUniformMatrix4fv(proj_test_loc, 1, GL_FALSE, proj_mat);
+
+   glUseProgram(shader_program2);
+   glUniformMatrix4fv(model_mat_loc, 1, GL_FALSE, value_ptr(model_mat2));
    glUniformMatrix4fv(proj_mat_loc, 1, GL_FALSE, proj_mat);
+
+   // glUniform1i(tex_loc, 0);
 
    bool cam_moved = false;
@@ -202,9 +295,18 @@
 
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+      glUseProgram(shader_program);
+      glUniformMatrix4fv(view_test_loc, 1, GL_FALSE, value_ptr(view_mat));
+
       glBindVertexArray(vao);
 
-      // Each point is made of 3 floats
-      int numPoints = (sizeof(points) / sizeof(float)) / 3;
       glDrawArrays(GL_TRIANGLES, 0, numPoints);
+
+      glUseProgram(shader_program2);
+      glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
+
+      glBindVertexArray(vao2);
+
+      glDrawArrays(GL_TRIANGLES, 0, numPoints2);
 
       glfwPollEvents();
@@ -284,2 +386,25 @@
   return shaderId;
 }
+
+GLuint loadShaderProgram(string vertexShaderPath, string fragmentShaderPath) {
+   GLuint vs = loadShader(GL_VERTEX_SHADER, vertexShaderPath);
+   GLuint fs = loadShader(GL_FRAGMENT_SHADER, fragmentShaderPath);
+
+   GLuint shader_program = glCreateProgram();
+   glAttachShader(shader_program, vs);
+   glAttachShader(shader_program, fs);
+
+   glLinkProgram(shader_program);
+
+   return shader_program;
+}
+
+unsigned char* loadImage(string file_name, int* x, int* y) {
+  int n;
+  int force_channels = 4;
+  unsigned char* image_data = stbi_load(file_name.c_str(), x, y, &n, force_channels);
+  if (!image_data) {
+    fprintf(stderr, "ERROR: could not load %s\n", file_name.c_str());
+  }
+  return image_data;
+}
