Index: graphics_library/TextureFragmentShader.fragmentshader
===================================================================
--- graphics_library/TextureFragmentShader.fragmentshader	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
+++ graphics_library/TextureFragmentShader.fragmentshader	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
@@ -0,0 +1,16 @@
+#version 330 core
+
+// Interpolated values from the vertex shaders
+in vec2 UV;
+
+// Ouput data
+out vec3 color;
+
+// Values that stay constant for the whole mesh.
+uniform sampler2D myTextureSampler;
+
+void main(){
+
+	// Output color = color of the texture at the specified UV
+	color = texture2D( myTextureSampler, UV ).rgb;
+}
Index: graphics_library/TransformVertexShader.vertexshader
===================================================================
--- graphics_library/TransformVertexShader.vertexshader	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
+++ graphics_library/TransformVertexShader.vertexshader	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
@@ -0,0 +1,21 @@
+#version 330 core
+
+// Input vertex data, different for all executions of this shader.
+layout(location = 0) in vec3 vertexPosition_modelspace;
+layout(location = 1) in vec2 vertexUV;
+
+// Output data ; will be interpolated for each fragment.
+out vec2 UV;
+
+// Values that stay constant for the whole mesh.
+uniform mat4 MVP;
+
+void main(){
+
+	// Output position of the vertex, in clip space : MVP * position
+	gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
+	
+	// UV of the vertex. No special space for this one.
+	UV = vertexUV;
+}
+
Index: graphics_library/common/controls.cpp
===================================================================
--- graphics_library/common/controls.cpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
+++ graphics_library/common/controls.cpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
@@ -0,0 +1,104 @@
+// Include GLFW
+#include <GLFW/glfw3.h>
+extern GLFWwindow* window; // The "extern" keyword here is to access the variable "window" declared in tutorialXXX.cpp. This is a hack to keep the tutorials simple. Please avoid this.
+
+// Include GLM
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+using namespace glm;
+
+#include "controls.hpp"
+
+glm::mat4 ViewMatrix;
+glm::mat4 ProjectionMatrix;
+
+glm::mat4 getViewMatrix(){
+        return ViewMatrix;
+}
+glm::mat4 getProjectionMatrix(){
+        return ProjectionMatrix;
+}
+
+
+// Initial position : on +Z
+glm::vec3 position = glm::vec3( 0, 0, 5 ); 
+// Initial horizontal angle : toward -Z
+float horizontalAngle = 3.14f;
+// Initial vertical angle : none
+float verticalAngle = 0.0f;
+// Initial Field of View
+float initialFoV = 45.0f;
+
+float speed = 3.0f; // 3 units / second
+float mouseSpeed = 0.005f;
+
+
+
+void computeMatricesFromInputs(){
+
+        // glfwGetTime is called only once, the first time this function is called
+        static double lastTime = glfwGetTime();
+
+        // Compute time difference between current and last frame
+        double currentTime = glfwGetTime();
+        float deltaTime = float(currentTime - lastTime);
+
+        // Get mouse position
+        double xpos, ypos;
+        glfwGetCursorPos(window, &xpos, &ypos);
+
+        // Reset mouse position for next frame
+        glfwSetCursorPos(window, 1024/2, 768/2);
+
+        // Compute new orientation
+        horizontalAngle += mouseSpeed * float(1024/2 - xpos );
+        verticalAngle   += mouseSpeed * float( 768/2 - ypos );
+
+        // Direction : Spherical coordinates to Cartesian coordinates conversion
+        glm::vec3 direction(
+                cos(verticalAngle) * sin(horizontalAngle), 
+                sin(verticalAngle),
+                cos(verticalAngle) * cos(horizontalAngle)
+        );
+        
+        // Right vector
+        glm::vec3 right = glm::vec3(
+                sin(horizontalAngle - 3.14f/2.0f), 
+                0,
+                cos(horizontalAngle - 3.14f/2.0f)
+        );
+        
+        // Up vector
+        glm::vec3 up = glm::cross( right, direction );
+
+        // Move forward
+        if (glfwGetKey( window, GLFW_KEY_UP ) == GLFW_PRESS){
+                position += direction * deltaTime * speed;
+        }
+        // Move backward
+        if (glfwGetKey( window, GLFW_KEY_DOWN ) == GLFW_PRESS){
+                position -= direction * deltaTime * speed;
+        }
+        // Strafe right
+        if (glfwGetKey( window, GLFW_KEY_RIGHT ) == GLFW_PRESS){
+                position += right * deltaTime * speed;
+        }
+        // Strafe left
+        if (glfwGetKey( window, GLFW_KEY_LEFT ) == GLFW_PRESS){
+                position -= right * deltaTime * speed;
+        }
+
+        float FoV = initialFoV;// - 5 * glfwGetMouseWheel(); // Now GLFW 3 requires setting up a callback for this. It's a bit too complicated for this beginner's tutorial, so it's disabled instead.
+
+        // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
+        ProjectionMatrix = glm::perspective(FoV, 4.0f / 3.0f, 0.1f, 100.0f);
+        // Camera matrix
+        ViewMatrix       = glm::lookAt(
+                                                                position,           // Camera is here
+                                                                position+direction, // and looks here : at the same position, plus "direction"
+                                                                up                  // Head is up (set to 0,-1,0 to look upside-down)
+                                                   );
+
+        // For the next frame, the "last time" will be "now"
+        lastTime = currentTime;
+}
Index: graphics_library/common/controls.hpp
===================================================================
--- graphics_library/common/controls.hpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
+++ graphics_library/common/controls.hpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
@@ -0,0 +1,8 @@
+#ifndef CONTROLS_HPP
+#define CONTROLS_HPP
+
+void computeMatricesFromInputs();
+glm::mat4 getViewMatrix();
+glm::mat4 getProjectionMatrix();
+
+#endif
Index: graphics_library/common/shader.cpp
===================================================================
--- graphics_library/common/shader.cpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
+++ graphics_library/common/shader.cpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
@@ -0,0 +1,107 @@
+#include <stdio.h>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <algorithm>
+using namespace std;
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <GL/glew.h>
+
+#include "shader.hpp"
+
+GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
+
+        // Create the shaders
+        GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
+        GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
+
+        // Read the Vertex Shader code from the file
+        std::string VertexShaderCode;
+        std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
+        if(VertexShaderStream.is_open()){
+                std::string Line = "";
+                while(getline(VertexShaderStream, Line))
+                        VertexShaderCode += "\n" + Line;
+                VertexShaderStream.close();
+        }else{
+                printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
+                getchar();
+                return 0;
+        }
+
+        // Read the Fragment Shader code from the file
+        std::string FragmentShaderCode;
+        std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
+        if(FragmentShaderStream.is_open()){
+                std::string Line = "";
+                while(getline(FragmentShaderStream, Line))
+                        FragmentShaderCode += "\n" + Line;
+                FragmentShaderStream.close();
+        }
+
+
+
+        GLint Result = GL_FALSE;
+        int InfoLogLength;
+
+
+
+        // Compile Vertex Shader
+        printf("Compiling shader : %s\n", vertex_file_path);
+        char const * VertexSourcePointer = VertexShaderCode.c_str();
+        glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
+        glCompileShader(VertexShaderID);
+
+        // Check Vertex Shader
+        glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
+        glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
+        if ( InfoLogLength > 0 ){
+                std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
+                glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
+                printf("%s\n", &VertexShaderErrorMessage[0]);
+        }
+
+
+
+        // Compile Fragment Shader
+        printf("Compiling shader : %s\n", fragment_file_path);
+        char const * FragmentSourcePointer = FragmentShaderCode.c_str();
+        glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
+        glCompileShader(FragmentShaderID);
+
+        // Check Fragment Shader
+        glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
+        glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
+        if ( InfoLogLength > 0 ){
+                std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
+                glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
+                printf("%s\n", &FragmentShaderErrorMessage[0]);
+        }
+
+
+
+        // Link the program
+        printf("Linking program\n");
+        GLuint ProgramID = glCreateProgram();
+        glAttachShader(ProgramID, VertexShaderID);
+        glAttachShader(ProgramID, FragmentShaderID);
+        glLinkProgram(ProgramID);
+
+        // Check the program
+        glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
+        glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
+        if ( InfoLogLength > 0 ){
+                std::vector<char> ProgramErrorMessage(InfoLogLength+1);
+                glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
+                printf("%s\n", &ProgramErrorMessage[0]);
+        }
+
+        glDeleteShader(VertexShaderID);
+        glDeleteShader(FragmentShaderID);
+
+        return ProgramID;
+}
Index: graphics_library/common/shader.hpp
===================================================================
--- graphics_library/common/shader.hpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
+++ graphics_library/common/shader.hpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
@@ -0,0 +1,6 @@
+#ifndef SHADER_HPP
+#define SHADER_HPP
+
+GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path);
+
+#endif
Index: graphics_library/common/texture.cpp
===================================================================
--- graphics_library/common/texture.cpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
+++ graphics_library/common/texture.cpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
@@ -0,0 +1,211 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <GL/glew.h>
+
+#include <GLFW/glfw3.h>
+
+
+GLuint loadBMP_custom(const char * imagepath){
+
+        printf("Reading image %s\n", imagepath);
+
+        // Data read from the header of the BMP file
+        unsigned char header[54];
+        unsigned int dataPos;
+        unsigned int imageSize;
+        unsigned int width, height;
+        // Actual RGB data
+        unsigned char * data;
+
+        // Open the file
+        FILE * file = fopen(imagepath,"rb");
+        if (!file)                                                          {printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath); getchar(); return 0;}
+
+        // Read the header, i.e. the 54 first bytes
+
+        // If less than 54 bytes are read, problem
+        if ( fread(header, 1, 54, file)!=54 ){ 
+                printf("Not a correct BMP file\n");
+                return 0;
+        }
+        // A BMP files always begins with "BM"
+        if ( header[0]!='B' || header[1]!='M' ){
+                printf("Not a correct BMP file\n");
+                return 0;
+        }
+        // Make sure this is a 24bpp file
+        if ( *(int*)&(header[0x1E])!=0  )         {printf("Not a correct BMP file\n");    return 0;}
+        if ( *(int*)&(header[0x1C])!=24 )         {printf("Not a correct BMP file\n");    return 0;}
+
+        // Read the information about the image
+        dataPos    = *(int*)&(header[0x0A]);
+        imageSize  = *(int*)&(header[0x22]);
+        width      = *(int*)&(header[0x12]);
+        height     = *(int*)&(header[0x16]);
+
+        // Some BMP files are misformatted, guess missing information
+        if (imageSize==0)    imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component
+        if (dataPos==0)      dataPos=54; // The BMP header is done that way
+
+        // Create a buffer
+        data = new unsigned char [imageSize];
+
+        // Read the actual data from the file into the buffer
+        fread(data,1,imageSize,file);
+
+        // Everything is in memory now, the file wan be closed
+        fclose (file);
+
+        // Create one OpenGL texture
+        GLuint textureID;
+        glGenTextures(1, &textureID);
+        
+        // "Bind" the newly created texture : all future texture functions will modify this texture
+        glBindTexture(GL_TEXTURE_2D, textureID);
+
+        // Give the image to OpenGL
+        glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
+
+        // OpenGL has now copied the data. Free our own version
+        delete [] data;
+
+        // Poor filtering, or ...
+        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
+
+        // ... nice trilinear filtering.
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
+        glGenerateMipmap(GL_TEXTURE_2D);
+
+        // Return the ID of the texture we just created
+        return textureID;
+}
+
+// Since GLFW 3, glfwLoadTexture2D() has been removed. You have to use another texture loading library, 
+// or do it yourself (just like loadBMP_custom and loadDDS)
+//GLuint loadTGA_glfw(const char * imagepath){
+//
+//      // Create one OpenGL texture
+//      GLuint textureID;
+//      glGenTextures(1, &textureID);
+//
+//      // "Bind" the newly created texture : all future texture functions will modify this texture
+//      glBindTexture(GL_TEXTURE_2D, textureID);
+//
+//      // Read the file, call glTexImage2D with the right parameters
+//      glfwLoadTexture2D(imagepath, 0);
+//
+//      // Nice trilinear filtering.
+//      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+//      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+//      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+//      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
+//      glGenerateMipmap(GL_TEXTURE_2D);
+//
+//      // Return the ID of the texture we just created
+//      return textureID;
+//}
+
+
+
+#define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
+#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
+#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
+
+GLuint loadDDS(const char * imagepath){
+
+        unsigned char header[124];
+
+        FILE *fp; 
+ 
+        /* try to open the file */ 
+        fp = fopen(imagepath, "rb"); 
+        if (fp == NULL){
+                printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath); getchar(); 
+                return 0;
+        }
+   
+        /* verify the type of file */ 
+        char filecode[4]; 
+        fread(filecode, 1, 4, fp); 
+        if (strncmp(filecode, "DDS ", 4) != 0) { 
+                fclose(fp); 
+                return 0; 
+        }
+        
+        /* get the surface desc */ 
+        fread(&header, 124, 1, fp); 
+
+        unsigned int height      = *(unsigned int*)&(header[8 ]);
+        unsigned int width           = *(unsigned int*)&(header[12]);
+        unsigned int linearSize  = *(unsigned int*)&(header[16]);
+        unsigned int mipMapCount = *(unsigned int*)&(header[24]);
+        unsigned int fourCC      = *(unsigned int*)&(header[80]);
+
+ 
+        unsigned char * buffer;
+        unsigned int bufsize;
+        /* how big is it going to be including all mipmaps? */ 
+        bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize; 
+        buffer = (unsigned char*)malloc(bufsize * sizeof(unsigned char)); 
+        fread(buffer, 1, bufsize, fp); 
+        /* close the file pointer */ 
+        fclose(fp);
+
+        unsigned int components  = (fourCC == FOURCC_DXT1) ? 3 : 4; 
+        unsigned int format;
+        switch(fourCC) 
+        { 
+        case FOURCC_DXT1: 
+                format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; 
+                break; 
+        case FOURCC_DXT3: 
+                format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; 
+                break; 
+        case FOURCC_DXT5: 
+                format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; 
+                break; 
+        default: 
+                free(buffer); 
+                return 0; 
+        }
+
+        // Create one OpenGL texture
+        GLuint textureID;
+        glGenTextures(1, &textureID);
+
+        // "Bind" the newly created texture : all future texture functions will modify this texture
+        glBindTexture(GL_TEXTURE_2D, textureID);
+        glPixelStorei(GL_UNPACK_ALIGNMENT,1);   
+        
+        unsigned int blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16; 
+        unsigned int offset = 0;
+
+        /* load the mipmaps */ 
+        for (unsigned int level = 0; level < mipMapCount && (width || height); ++level) 
+        { 
+                unsigned int size = ((width+3)/4)*((height+3)/4)*blockSize; 
+                glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height,  
+                        0, size, buffer + offset); 
+         
+                offset += size; 
+                width  /= 2; 
+                height /= 2; 
+
+                // Deal with Non-Power-Of-Two textures. This code is not included in the webpage to reduce clutter.
+                if(width < 1) width = 1;
+                if(height < 1) height = 1;
+
+        } 
+
+        free(buffer); 
+
+        return textureID;
+
+
+}
Index: graphics_library/common/texture.hpp
===================================================================
--- graphics_library/common/texture.hpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
+++ graphics_library/common/texture.hpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
@@ -0,0 +1,16 @@
+#ifndef TEXTURE_HPP
+#define TEXTURE_HPP
+
+// Load a .BMP file using our custom loader
+GLuint loadBMP_custom(const char * imagepath);
+
+//// Since GLFW 3, glfwLoadTexture2D() has been removed. You have to use another texture loading library, 
+//// or do it yourself (just like loadBMP_custom and loadDDS)
+//// Load a .TGA file using GLFW's own loader
+//GLuint loadTGA_glfw(const char * imagepath);
+
+// Load a .DDS file using GLFW's own loader
+GLuint loadDDS(const char * imagepath);
+
+
+#endif
Index: graphics_library/main.cpp
===================================================================
--- graphics_library/main.cpp	(revision 2e5aa0c10e6bfc0b9ec6ae8ddb6ad30d043efa2d)
+++ graphics_library/main.cpp	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
@@ -7,5 +7,6 @@
 
 // Include GLFW
-#include <GL/glfw.h>
+#include <GLFW/glfw3.h>
+GLFWwindow* window;
 
 // Include GLM
@@ -27,16 +28,17 @@
         }
 
-        glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4);
-        glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
-        glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
-        glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+        glfwWindowHint(GLFW_SAMPLES, 4);
+        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
+        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
 
         // Open a window and create its OpenGL context
-        if( !glfwOpenWindow( 1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW ) )
-        {
+        window = glfwCreateWindow( 1024, 768, "Tutorial 0 - Keyboard and Mouse", NULL, NULL);
+        if( window == NULL ){
                 fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
                 glfwTerminate();
                 return -1;
         }
+        glfwMakeContextCurrent(window);
 
         // Initialize GLEW
@@ -47,9 +49,7 @@
         }
 
-        glfwSetWindowTitle( "Tutorial 06" );
-
         // Ensure we can capture the escape key being pressed below
-        glfwEnable( GLFW_STICKY_KEYS );
-        glfwSetMousePos(1024/2, 768/2);
+        glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
+        glfwSetCursorPos(window, 1024/2, 768/2);
 
         // Dark blue background
@@ -227,9 +227,10 @@
 
                 // Swap buffers
-                glfwSwapBuffers();
+                glfwSwapBuffers(window);
+                glfwPollEvents();
 
         } // Check if the ESC key was pressed or the window was closed
-        while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&
-                   glfwGetWindowParam( GLFW_OPENED ) );
+        while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
+                   glfwWindowShouldClose(window) == 0 );
 
         // Cleanup VBO and shader
Index: graphics_library/makefile
===================================================================
--- graphics_library/makefile	(revision 2e5aa0c10e6bfc0b9ec6ae8ddb6ad30d043efa2d)
+++ graphics_library/makefile	(revision a9e808ebaff20b055dc96307b932b1d66697aba7)
@@ -1,6 +1,6 @@
 CC = g++
-LIB_FLAGS = -lGL -lglut -lGLEW -lglfw
+LIB_FLAGS = -lGL -lglut -lGLEW `pkg-config glfw3 --static --cflags --libs`
 FLAGS = -Wall
-DEPENDENCIES =
+DEPENDENCIES = common/texture.o common/controls.o common/shader.o
 
 graphics_engine : main.cpp $(DEPENDENCIES)
@@ -11,4 +11,5 @@
 
 clean:
-	rm graphics_engine
-	rm *.o
+	rm -f *.o
+	rm -f common/*.o
+	rm -f graphics_engine
