diff --git a/lab3.0/README.md b/lab3.0/README.md
deleted file mode 100644
index 37ef2aa3ab4fd9c2b71f611152904fdda1564d14..0000000000000000000000000000000000000000
--- a/lab3.0/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Lab3 IHM
-
-* **docs**: contains the lab's statement
-* **libs**: contains WebGL libraries and utilities
-* **src**: contains the source code of the lab2 that you should complete (`main()` function in **lab3.js** file)
-* **DO NOT CHANGE** the name of the file `lab3.html`, however, you are free to change its content.
diff --git a/lab3.0/docs/Cours 3D Labo 3.pdf b/lab3.0/docs/Cours 3D Labo 3.pdf
deleted file mode 100644
index 95be1783746c753299fd5ae3d412b90a2c39ad9d..0000000000000000000000000000000000000000
Binary files a/lab3.0/docs/Cours 3D Labo 3.pdf and /dev/null differ
diff --git a/lab3.0/src/lab3.html b/lab3.0/src/lab3.html
deleted file mode 100644
index eb19ba33f176350230f8eca6134f53a54ac4b6a3..0000000000000000000000000000000000000000
--- a/lab3.0/src/lab3.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-
-<head>
-    <meta charset="UTF-8">
-    <title>Lab 3</title>
-</head>
-
-<body onload="main()">
-    <canvas width="400" height="600" id="my-canvas">
-  Please use a browser that supports "canvas"
-</canvas>
-    <script src="../lib/webgl-utils.js"></script>
-    <script src="../lib/webgl-debug.js"></script>
-    <script src="../lib/cuon-matrix.js"></script>
-    <script src="../lib/cuon-utils.js"></script>
-    <script src="lab3.js"></script>
-</body>
-
-</html>
\ No newline at end of file
diff --git a/lab3.0/src/lab3.js b/lab3.0/src/lab3.js
deleted file mode 100644
index 24f9a232a73c25df465e849b87115534e8c8d1c3..0000000000000000000000000000000000000000
--- a/lab3.0/src/lab3.js
+++ /dev/null
@@ -1,293 +0,0 @@
-//author : QUentin Berthet
-const VSHADER_SOURCE =
-    'attribute vec4 a_Position;\n' +
-    'attribute vec3 a_normal;\n' +
-    'attribute vec4 a_Color;\n' +
-
-    'uniform mat4 u_worldViewProjection;\n' +
-    'uniform mat4 u_worldInverseTranspose;\n' +
-
-    'varying vec3 v_normal;\n' +
-    'varying vec4 v_Color;\n' +
-
-
-    'void main() {\n' +
-    '  gl_Position = u_worldViewProjection * a_Position ;\n' +
-    '  v_normal = mat3(u_worldInverseTranspose) * a_normal;\n' +
-    '  v_Color = a_Color;\n' +
-    '}\n';
-
-
-const FSHADER_SOURCE =
-    'precision mediump float;\n' +
-
-    'varying vec4 v_Color;\n' +
-    'varying vec3 v_normal;\n' +
-    'uniform vec3 u_reverseLightDirection;\n' +
-
-    'void main() {\n' +
-    '  vec3 normal = normalize(v_normal);\n' +
-    '  float light = dot(normal, u_reverseLightDirection);\n' +
-
-    '  gl_FragColor = v_Color;\n' +
-    '  gl_FragColor.rgb *= light;\n' +
-    '}\n'
-
-function main() {
-
-    const canvas = document.getElementById('my-canvas');
-
-
-    const gl = getWebGLContext(canvas);
-    if (!gl) {
-        console.log('Failed to get the displaying context for WebGL');
-        return;
-    }
-
-
-    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
-        console.log('Failed to intialize shaders.');
-        return;
-    }
-
-
-    const len = initVertexBuffers(gl);
-    if (len < 0) {
-        console.log('Failed to set the positions of the vertices');
-        return;
-    }
-
-    gl.clearColor(0.75, 0.85, 0.8, 1.0);
-    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-    gl.enable(gl.DEPTH_TEST);
-    gl.frontFace(gl.CCW);
-    gl.cullFace(gl.BACK);
-
-
-    var u_mat = gl.getUniformLocation(gl.program, 'u_mat');
-
-    var mat = new Matrix4();
-
-
-    var viewProjMatrix = new Matrix4();
-    viewProjMatrix.setPerspective(100.0, 1.0, 1.0, 1000.0);
-    viewProjMatrix.lookAt(1.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
-
-    var vals = [0.0, 0.0];
-    ObjectManager(vals);
-
-    var display = function() {
-        mat.set(viewProjMatrix);
-        mat.rotate(vals[0], 1.0, 0.0, 0.0);
-        mat.rotate(vals[1], 0.0, 1.0, 0.0);
-        gl.uniformMatrix4fv(u_mat, false, mat.elements);
-
-
-        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-
-        gl.drawArrays(gl.TRIANGLES, 0, len);
-
-        mat.translate(0, 3.0, -4)
-        mat.rotate(180, 1.0, 0.0, 0.0);
-        gl.uniformMatrix4fv(u_mat, false, mat.elements);
-        gl.drawArrays(gl.TRIANGLES, 0, len);
-
-
-        requestAnimationFrame(display);
-    };
-    display();
-}
-
-function ObjectManager(values) {
-    document.onkeydown = (ev) => {
-        v = 10;
-        switch (ev.key) {
-            case 'ArrowDown':
-                values[0] += v;
-                break;
-            case 'ArrowUp':
-                values[0] -= v;
-                break;
-            case 'ArrowRight':
-                values[1] += v;
-                break;
-            case 'ArrowLeft':
-                values[1] -= v;
-                break;
-        }
-    };
-}
-
-
-function CreateNormals(gl) {
-    var normales = new Float32Array(
-        [ //front
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-
-            // back
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-
-
-            // left
-            -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0,
-
-            // right
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-
-            // top
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-
-            // ground
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-        ]);
-    gl.bufferData(gl.ARRAY_BUFFER, normales, gl.STATIC_DRAW);
-
-}
-
-
-function initVertexBuffers(gl) {
-
-    let vertices = new Float32Array([
-
-        // Front
-        -2, -1.5, 0, 0, 1, 0, -1, 1.5, -1, 0, 1, 0,
-        0, -1.5, 0, 0, 1, 0,
-
-        -1, 1.5, -1, 0, 1, 0,
-        0, -1.5, 0, 0, 1, 0,
-        1, 1.5, -1, 0, 1, 0,
-
-        0, -1.5, 0, 0, 1, 0,
-        1, 1.5, -1, 0, 1, 0,
-        2, -1.5, 0, 0, 1, 0,
-
-        // Back
-        -2, -1.5, -4, 0, 1, 0, -1, 1.5, -3, 0, 1, 0,
-        0, -1.5, -4, 0, 1, 0,
-
-        -1, 1.5, -3, 0, 1, 0,
-        0, -1.5, -4, 0, 1, 0,
-        1, 1.5, -3, 0, 1, 0,
-
-        0, -1.5, -4, 0, 1, 0,
-        1, 1.5, -3, 0, 1, 0,
-        2, -1.5, -4, 0, 1, 0,
-
-        // Left
-        -2, -1.5, -4, 0, 1, 0, -1, 1.5, -3, 0, 1, 0, -2, -1.5, -2, 0, 1, 0,
-
-        -1, 1.5, -3, 0, 1, 0, -2, -1.5, -2, 0, 1, 0, -1, 1.5, -1, 0, 1, 0,
-
-        -2, -1.5, -2, 0, 1, 0, -1, 1.5, -1, 0, 1, 0, -2, -1.5, 0, 0, 1, 0,
-
-        // Right
-        2, -1.5, -4, 0, 1, 0,
-        1, 1.5, -3, 0, 1, 0,
-        2, -1.5, -2, 0, 1, 0,
-
-        1, 1.5, -3, 0, 1, 0,
-        2, -1.5, -2, 0, 1, 0,
-        1, 1.5, -1, 0, 1, 0,
-
-        2, -1.5, -2, 0, 1, 0,
-        1, 1.5, -1, 0, 1, 0,
-        2, -1.5, -0, 0, 1, 0,
-
-        // top
-        -1, 1.5, -1, 0, 1, 0, -1, 1.5, -3, 0, 1, 0,
-        0, 1.5, -1, 0, 1, 0,
-
-        -1, 1.5, -3, 0, 1, 0,
-        0, 1.5, -1, 0, 1, 0,
-        1, 1.5, -3, 0, 1, 0,
-
-        0, 1.5, -1, 0, 1, 0,
-        1, 1.5, -3, 0, 1, 0,
-        1, 1.5, -1, 0, 1, 0,
-
-        // ground
-        -2, -1.5, 0, 0, 1, 0, -2, -1.5, -4, 0, 1, 0,
-        0, -1.5, 0, 0, 1, 0,
-
-        -2, -1.5, -4, 0, 1, 0,
-        0, -1.5, 0, 0, 1, 0,
-        2, -1.5, -4, 0, 1, 0,
-
-        0, -1.5, 0, 0, 1, 0,
-        2, -1.5, -4, 0, 1, 0,
-        2, -1.5, 0, 0, 1, 0
-
-    ]);
-
-    const len = vertices.length / 6;
-
-    const vertexBuffer = gl.createBuffer();
-    if (!vertexBuffer) {
-        console.log('Failed to create the buffer object');
-        return -1;
-    }
-
-    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
-    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
-
-
-    const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
-    if (a_Position < 0) {
-        console.log('Failed to get the storage location of a_Position');
-        return -1;
-    }
-    gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 24, 0);
-    gl.enableVertexAttribArray(a_Position);
-
-    var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
-    if (a_Color < 0) {
-        console.log('Failed to get the storage location of a_Color');
-        return -1;
-    }
-
-    gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 24, 12);
-    gl.enableVertexAttribArray(a_Color);
-    gl.bindBuffer(gl.ARRAY_BUFFER, null);
-
-    return len;
-}
\ No newline at end of file
diff --git a/lab3.1/README.md b/lab3.1/README.md
deleted file mode 100644
index 37ef2aa3ab4fd9c2b71f611152904fdda1564d14..0000000000000000000000000000000000000000
--- a/lab3.1/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Lab3 IHM
-
-* **docs**: contains the lab's statement
-* **libs**: contains WebGL libraries and utilities
-* **src**: contains the source code of the lab2 that you should complete (`main()` function in **lab3.js** file)
-* **DO NOT CHANGE** the name of the file `lab3.html`, however, you are free to change its content.
diff --git a/lab3.1/docs/Cours 3D Labo 3.pdf b/lab3.1/docs/Cours 3D Labo 3.pdf
deleted file mode 100644
index 95be1783746c753299fd5ae3d412b90a2c39ad9d..0000000000000000000000000000000000000000
Binary files a/lab3.1/docs/Cours 3D Labo 3.pdf and /dev/null differ
diff --git a/lab3.1/lib/cuon-utils.js b/lab3.1/lib/cuon-utils.js
deleted file mode 100644
index dc08b2ef1ee96304e68dafa7caed57f7e80894bb..0000000000000000000000000000000000000000
--- a/lab3.1/lib/cuon-utils.js
+++ /dev/null
@@ -1,113 +0,0 @@
-// cuon-utils.js (c) 2012 kanda and matsuda
-/**
- * Create a program object and make current
- * @param gl GL context
- * @param vshader a vertex shader program (string)
- * @param fshader a fragment shader program (string)
- * @return true, if the program object was created and successfully made current 
- */
-function initShaders(gl, vshader, fshader) {
-  var program = createProgram(gl, vshader, fshader);
-  if (!program) {
-    console.log('Failed to create program');
-    return false;
-  }
-
-  gl.useProgram(program);
-  gl.program = program;
-
-  return true;
-}
-
-/**
- * Create the linked program object
- * @param gl GL context
- * @param vshader a vertex shader program (string)
- * @param fshader a fragment shader program (string)
- * @return created program object, or null if the creation has failed
- */
-function createProgram(gl, vshader, fshader) {
-  // Create shader object
-  var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
-  var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
-  if (!vertexShader || !fragmentShader) {
-    return null;
-  }
-
-  // Create a program object
-  var program = gl.createProgram();
-  if (!program) {
-    return null;
-  }
-
-  // Attach the shader objects
-  gl.attachShader(program, vertexShader);
-  gl.attachShader(program, fragmentShader);
-
-  // Link the program object
-  gl.linkProgram(program);
-
-  // Check the result of linking
-  var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
-  if (!linked) {
-    var error = gl.getProgramInfoLog(program);
-    console.log('Failed to link program: ' + error);
-    gl.deleteProgram(program);
-    gl.deleteShader(fragmentShader);
-    gl.deleteShader(vertexShader);
-    return null;
-  }
-  return program;
-}
-
-/**
- * Create a shader object
- * @param gl GL context
- * @param type the type of the shader object to be created
- * @param source shader program (string)
- * @return created shader object, or null if the creation has failed.
- */
-function loadShader(gl, type, source) {
-  // Create shader object
-  var shader = gl.createShader(type);
-  if (shader == null) {
-    console.log('unable to create shader');
-    return null;
-  }
-
-  // Set the shader program
-  gl.shaderSource(shader, source);
-
-  // Compile the shader
-  gl.compileShader(shader);
-
-  // Check the result of compilation
-  var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
-  if (!compiled) {
-    var error = gl.getShaderInfoLog(shader);
-    console.log('Failed to compile shader: ' + error);
-    gl.deleteShader(shader);
-    return null;
-  }
-
-  return shader;
-}
-
-/** 
- * Initialize and get the rendering for WebglInstance
- * @param canvas <cavnas> element
- * @param opt_debug flag to initialize the context for debugging
- * @return the rendering context for WebglInstance
- */
-function getWebGLContext(canvas, opt_debug) {
-  // Get the rendering context for WebglInstance
-  var gl = WebGLUtils.setupWebGL(canvas);
-  if (!gl) return null;
-
-  // if opt_debug is explicitly false, create the context for debugging
-  if (arguments.length < 2 || opt_debug) {
-    gl = WebGLDebugUtils.makeDebugContext(gl);
-  }
-
-  return gl;
-}
diff --git a/lab3.1/lib/webgl-debug.js b/lab3.1/lib/webgl-debug.js
deleted file mode 100644
index 685868dc61347ea10c0376520f1e20ed57a765c7..0000000000000000000000000000000000000000
--- a/lab3.1/lib/webgl-debug.js
+++ /dev/null
@@ -1,677 +0,0 @@
-//Copyright (c) 2009 The Chromium Authors. All rights reserved.
-//Use of this source code is governed by a BSD-style license that can be
-//found in the LICENSE file.
-
-// Various functions for helping debug WebglInstance apps.
-
-WebGLDebugUtils = function() {
-
-/**
- * Wrapped logging function.
- * @param {string} msg Message to log.
- */
-var log = function(msg) {
-  if (window.console && window.console.log) {
-    window.console.log(msg);
-  }
-};
-
-/**
- * Which arguements are enums.
- * @type {!Object.<number, string>}
- */
-var glValidEnumContexts = {
-
-  // Generic setters and getters
-
-  'enable': { 0:true },
-  'disable': { 0:true },
-  'getParameter': { 0:true },
-
-  // Rendering
-
-  'drawArrays': { 0:true },
-  'drawElements': { 0:true, 2:true },
-
-  // Shaders
-
-  'createShader': { 0:true },
-  'getShaderParameter': { 1:true },
-  'getProgramParameter': { 1:true },
-
-  // Vertex attributes
-
-  'getVertexAttrib': { 1:true },
-  'vertexAttribPointer': { 2:true },
-
-  // Textures
-
-  'bindTexture': { 0:true },
-  'activeTexture': { 0:true },
-  'getTexParameter': { 0:true, 1:true },
-  'texParameterf': { 0:true, 1:true },
-  'texParameteri': { 0:true, 1:true, 2:true },
-  'texImage2D': { 0:true, 2:true, 6:true, 7:true },
-  'texSubImage2D': { 0:true, 6:true, 7:true },
-  'copyTexImage2D': { 0:true, 2:true },
-  'copyTexSubImage2D': { 0:true },
-  'generateMipmap': { 0:true },
-
-  // Buffer objects
-
-  'bindBuffer': { 0:true },
-  'bufferData': { 0:true, 2:true },
-  'bufferSubData': { 0:true },
-  'getBufferParameter': { 0:true, 1:true },
-
-  // Renderbuffers and framebuffers
-
-  'pixelStorei': { 0:true, 1:true },
-  'readPixels': { 4:true, 5:true },
-  'bindRenderbuffer': { 0:true },
-  'bindFramebuffer': { 0:true },
-  'checkFramebufferStatus': { 0:true },
-  'framebufferRenderbuffer': { 0:true, 1:true, 2:true },
-  'framebufferTexture2D': { 0:true, 1:true, 2:true },
-  'getFramebufferAttachmentParameter': { 0:true, 1:true, 2:true },
-  'getRenderbufferParameter': { 0:true, 1:true },
-  'renderbufferStorage': { 0:true, 1:true },
-
-  // Frame buffer operations (clear, blend, depth test, stencil)
-
-  'clear': { 0:true },
-  'depthFunc': { 0:true },
-  'blendFunc': { 0:true, 1:true },
-  'blendFuncSeparate': { 0:true, 1:true, 2:true, 3:true },
-  'blendEquation': { 0:true },
-  'blendEquationSeparate': { 0:true, 1:true },
-  'stencilFunc': { 0:true },
-  'stencilFuncSeparate': { 0:true, 1:true },
-  'stencilMaskSeparate': { 0:true },
-  'stencilOp': { 0:true, 1:true, 2:true },
-  'stencilOpSeparate': { 0:true, 1:true, 2:true, 3:true },
-
-  // Culling
-
-  'cullFace': { 0:true },
-  'frontFace': { 0:true },
-};
-
-/**
- * Map of numbers to names.
- * @type {Object}
- */
-var glEnums = null;
-
-/**
- * Initializes this module. Safe to call more than once.
- * @param {!WebGLRenderingContext} ctx A WebglInstance context. If
- *    you have more than one context it doesn't matter which one
- *    you pass in, it is only used to pull out constants.
- */
-function init(ctx) {
-  if (glEnums == null) {
-    glEnums = { };
-    for (var propertyName in ctx) {
-      if (typeof ctx[propertyName] == 'number') {
-        glEnums[ctx[propertyName]] = propertyName;
-      }
-    }
-  }
-}
-
-/**
- * Checks the utils have been initialized.
- */
-function checkInit() {
-  if (glEnums == null) {
-    throw 'WebGLDebugUtils.init(ctx) not called';
-  }
-}
-
-/**
- * Returns true or false if value matches any WebglInstance enum
- * @param {*} value Value to check if it might be an enum.
- * @return {boolean} True if value matches one of the WebglInstance defined enums
- */
-function mightBeEnum(value) {
-  checkInit();
-  return (glEnums[value] !== undefined);
-}
-
-/**
- * Gets an string version of an WebglInstance enum.
- *
- * Example:
- *   var str = WebGLDebugUtil.glEnumToString(ctx.getError());
- *
- * @param {number} value Value to return an enum for
- * @return {string} The string version of the enum.
- */
-function glEnumToString(value) {
-  checkInit();
-  var name = glEnums[value];
-  return (name !== undefined) ? name :
-      ("*UNKNOWN WebglInstance ENUM (0x" + value.toString(16) + ")");
-}
-
-/**
- * Returns the string version of a WebglInstance argument.
- * Attempts to convert enum arguments to strings.
- * @param {string} functionName the name of the WebglInstance function.
- * @param {number} argumentIndx the index of the argument.
- * @param {*} value The value of the argument.
- * @return {string} The value as a string.
- */
-function glFunctionArgToString(functionName, argumentIndex, value) {
-  var funcInfo = glValidEnumContexts[functionName];
-  if (funcInfo !== undefined) {
-    if (funcInfo[argumentIndex]) {
-      return glEnumToString(value);
-    }
-  }
-  return value.toString();
-}
-
-/**
- * Given a WebglInstance context returns a wrapped context that calls
- * gl.getError after every command and calls a function if the
- * result is not gl.NO_ERROR.
- *
- * @param {!WebGLRenderingContext} ctx The webgl context to
- *        wrap.
- * @param {!function(err, funcName, args): void} opt_onErrorFunc
- *        The function to call when gl.getError returns an
- *        error. If not specified the default function calls
- *        console.log with a message.
- */
-function makeDebugContext(ctx, opt_onErrorFunc) {
-  init(ctx);
-  opt_onErrorFunc = opt_onErrorFunc || function(err, functionName, args) {
-        // apparently we can't do args.join(",");
-        var argStr = "";
-        for (var ii = 0; ii < args.length; ++ii) {
-          argStr += ((ii == 0) ? '' : ', ') +
-              glFunctionArgToString(functionName, ii, args[ii]);
-        }
-        log("WebglInstance error "+ glEnumToString(err) + " in "+ functionName +
-            "(" + argStr + ")");
-      };
-
-  // Holds booleans for each GL error so after we get the error ourselves
-  // we can still return it to the client app.
-  var glErrorShadow = { };
-
-  // Makes a function that calls a WebglInstance function and then calls getError.
-  function makeErrorWrapper(ctx, functionName) {
-    return function() {
-      var result = ctx[functionName].apply(ctx, arguments);
-      var err = ctx.getError();
-      if (err != 0) {
-        glErrorShadow[err] = true;
-        opt_onErrorFunc(err, functionName, arguments);
-      }
-      return result;
-    };
-  }
-
-  // Make a an object that has a copy of every property of the WebglInstance context
-  // but wraps all functions.
-  var wrapper = {};
-  for (var propertyName in ctx) {
-    if (typeof ctx[propertyName] == 'function') {
-       wrapper[propertyName] = makeErrorWrapper(ctx, propertyName);
-     } else {
-       wrapper[propertyName] = ctx[propertyName];
-     }
-  }
-
-  // Override the getError function with one that returns our saved results.
-  wrapper.getError = function() {
-    for (var err in glErrorShadow) {
-      if (glErrorShadow[err]) {
-        glErrorShadow[err] = false;
-        return err;
-      }
-    }
-    return ctx.NO_ERROR;
-  };
-
-  return wrapper;
-}
-
-function resetToInitialState(ctx) {
-  var numAttribs = ctx.getParameter(ctx.MAX_VERTEX_ATTRIBS);
-  var tmp = ctx.createBuffer();
-  ctx.bindBuffer(ctx.ARRAY_BUFFER, tmp);
-  for (var ii = 0; ii < numAttribs; ++ii) {
-    ctx.disableVertexAttribArray(ii);
-    ctx.vertexAttribPointer(ii, 4, ctx.FLOAT, false, 0, 0);
-    ctx.vertexAttrib1f(ii, 0);
-  }
-  ctx.deleteBuffer(tmp);
-
-  var numTextureUnits = ctx.getParameter(ctx.MAX_TEXTURE_IMAGE_UNITS);
-  for (var ii = 0; ii < numTextureUnits; ++ii) {
-    ctx.activeTexture(ctx.TEXTURE0 + ii);
-    ctx.bindTexture(ctx.TEXTURE_CUBE_MAP, null);
-    ctx.bindTexture(ctx.TEXTURE_2D, null);
-  }
-
-  ctx.activeTexture(ctx.TEXTURE0);
-  ctx.useProgram(null);
-  ctx.bindBuffer(ctx.ARRAY_BUFFER, null);
-  ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null);
-  ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
-  ctx.bindRenderbuffer(ctx.RENDERBUFFER, null);
-  ctx.disable(ctx.BLEND);
-  ctx.disable(ctx.CULL_FACE);
-  ctx.disable(ctx.DEPTH_TEST);
-  ctx.disable(ctx.DITHER);
-  ctx.disable(ctx.SCISSOR_TEST);
-  ctx.blendColor(0, 0, 0, 0);
-  ctx.blendEquation(ctx.FUNC_ADD);
-  ctx.blendFunc(ctx.ONE, ctx.ZERO);
-  ctx.clearColor(0, 0, 0, 0);
-  ctx.clearDepth(1);
-  ctx.clearStencil(-1);
-  ctx.colorMask(true, true, true, true);
-  ctx.cullFace(ctx.BACK);
-  ctx.depthFunc(ctx.LESS);
-  ctx.depthMask(true);
-  ctx.depthRange(0, 1);
-  ctx.frontFace(ctx.CCW);
-  ctx.hint(ctx.GENERATE_MIPMAP_HINT, ctx.DONT_CARE);
-  ctx.lineWidth(1);
-  ctx.pixelStorei(ctx.PACK_ALIGNMENT, 4);
-  ctx.pixelStorei(ctx.UNPACK_ALIGNMENT, 4);
-  ctx.pixelStorei(ctx.UNPACK_FLIP_Y_WEBGL, false);
-  ctx.pixelStorei(ctx.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
-  // TODO: Delete this IF.
-  if (ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL) {
-    ctx.pixelStorei(ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL, ctx.BROWSER_DEFAULT_WEBGL);
-  }
-  ctx.polygonOffset(0, 0);
-  ctx.sampleCoverage(1, false);
-  ctx.scissor(0, 0, ctx.canvas.width, ctx.canvas.height);
-  ctx.stencilFunc(ctx.ALWAYS, 0, 0xFFFFFFFF);
-  ctx.stencilMask(0xFFFFFFFF);
-  ctx.stencilOp(ctx.KEEP, ctx.KEEP, ctx.KEEP);
-  ctx.viewport(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
-  ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT);
-
-  // TODO: This should NOT be needed but Firefox fails with 'hint'
-  while(ctx.getError());
-}
-
-function makeLostContextSimulatingContext(ctx) {
-  var wrapper_ = {};
-  var contextId_ = 1;
-  var contextLost_ = false;
-  var resourceId_ = 0;
-  var resourceDb_ = [];
-  var onLost_ = undefined;
-  var onRestored_ = undefined;
-  var nextOnRestored_ = undefined;
-
-  // Holds booleans for each GL error so can simulate errors.
-  var glErrorShadow_ = { };
-
-  function isWebGLObject(obj) {
-    //return false;
-    return (obj instanceof WebGLBuffer ||
-            obj instanceof WebGLFramebuffer ||
-            obj instanceof WebGLProgram ||
-            obj instanceof WebGLRenderbuffer ||
-            obj instanceof WebGLShader ||
-            obj instanceof WebGLTexture);
-  }
-
-  function checkResources(args) {
-    for (var ii = 0; ii < args.length; ++ii) {
-      var arg = args[ii];
-      if (isWebGLObject(arg)) {
-        return arg.__webglDebugContextLostId__ == contextId_;
-      }
-    }
-    return true;
-  }
-
-  function clearErrors() {
-    var k = Object.keys(glErrorShadow_);
-    for (var ii = 0; ii < k.length; ++ii) {
-      delete glErrorShdow_[k];
-    }
-  }
-
-  // Makes a function that simulates WebglInstance when out of context.
-  function makeLostContextWrapper(ctx, functionName) {
-    var f = ctx[functionName];
-    return function() {
-      // Only call the functions if the context is not lost.
-      if (!contextLost_) {
-        if (!checkResources(arguments)) {
-          glErrorShadow_[ctx.INVALID_OPERATION] = true;
-          return;
-        }
-        var result = f.apply(ctx, arguments);
-        return result;
-      }
-    };
-  }
-
-  for (var propertyName in ctx) {
-    if (typeof ctx[propertyName] == 'function') {
-       wrapper_[propertyName] = makeLostContextWrapper(ctx, propertyName);
-     } else {
-       wrapper_[propertyName] = ctx[propertyName];
-     }
-  }
-
-  function makeWebGLContextEvent(statusMessage) {
-    return {statusMessage: statusMessage};
-  }
-
-  function freeResources() {
-    for (var ii = 0; ii < resourceDb_.length; ++ii) {
-      var resource = resourceDb_[ii];
-      if (resource instanceof WebGLBuffer) {
-        ctx.deleteBuffer(resource);
-      } else if (resource instanceof WebctxFramebuffer) {
-        ctx.deleteFramebuffer(resource);
-      } else if (resource instanceof WebctxProgram) {
-        ctx.deleteProgram(resource);
-      } else if (resource instanceof WebctxRenderbuffer) {
-        ctx.deleteRenderbuffer(resource);
-      } else if (resource instanceof WebctxShader) {
-        ctx.deleteShader(resource);
-      } else if (resource instanceof WebctxTexture) {
-        ctx.deleteTexture(resource);
-      }
-    }
-  }
-
-  wrapper_.loseContext = function() {
-    if (!contextLost_) {
-      contextLost_ = true;
-      ++contextId_;
-      while (ctx.getError());
-      clearErrors();
-      glErrorShadow_[ctx.CONTEXT_LOST_WEBGL] = true;
-      setTimeout(function() {
-          if (onLost_) {
-            onLost_(makeWebGLContextEvent("context lost"));
-          }
-        }, 0);
-    }
-  };
-
-  wrapper_.restoreContext = function() {
-    if (contextLost_) {
-      if (onRestored_) {
-        setTimeout(function() {
-            freeResources();
-            resetToInitialState(ctx);
-            contextLost_ = false;
-            if (onRestored_) {
-              var callback = onRestored_;
-              onRestored_ = nextOnRestored_;
-              nextOnRestored_ = undefined;
-              callback(makeWebGLContextEvent("context restored"));
-            }
-          }, 0);
-      } else {
-        throw "You can not restore the context without a listener"
-      }
-    }
-  };
-
-  // Wrap a few functions specially.
-  wrapper_.getError = function() {
-    if (!contextLost_) {
-      var err;
-      while (err = ctx.getError()) {
-        glErrorShadow_[err] = true;
-      }
-    }
-    for (var err in glErrorShadow_) {
-      if (glErrorShadow_[err]) {
-        delete glErrorShadow_[err];
-        return err;
-      }
-    }
-    return ctx.NO_ERROR;
-  };
-
-  var creationFunctions = [
-    "createBuffer",
-    "createFramebuffer",
-    "createProgram",
-    "createRenderbuffer",
-    "createShader",
-    "createTexture"
-  ];
-  for (var ii = 0; ii < creationFunctions.length; ++ii) {
-    var functionName = creationFunctions[ii];
-    wrapper_[functionName] = function(f) {
-      return function() {
-        if (contextLost_) {
-          return null;
-        }
-        var obj = f.apply(ctx, arguments);
-        obj.__webglDebugContextLostId__ = contextId_;
-        resourceDb_.push(obj);
-        return obj;
-      };
-    }(ctx[functionName]);
-  }
-
-  var functionsThatShouldReturnNull = [
-    "getActiveAttrib",
-    "getActiveUniform",
-    "getBufferParameter",
-    "getContextAttributes",
-    "getAttachedShaders",
-    "getFramebufferAttachmentParameter",
-    "getParameter",
-    "getProgramParameter",
-    "getProgramInfoLog",
-    "getRenderbufferParameter",
-    "getShaderParameter",
-    "getShaderInfoLog",
-    "getShaderSource",
-    "getTexParameter",
-    "getUniform",
-    "getUniformLocation",
-    "getVertexAttrib"
-  ];
-  for (var ii = 0; ii < functionsThatShouldReturnNull.length; ++ii) {
-    var functionName = functionsThatShouldReturnNull[ii];
-    wrapper_[functionName] = function(f) {
-      return function() {
-        if (contextLost_) {
-          return null;
-        }
-        return f.apply(ctx, arguments);
-      }
-    }(wrapper_[functionName]);
-  }
-
-  var isFunctions = [
-    "isBuffer",
-    "isEnabled",
-    "isFramebuffer",
-    "isProgram",
-    "isRenderbuffer",
-    "isShader",
-    "isTexture"
-  ];
-  for (var ii = 0; ii < isFunctions.length; ++ii) {
-    var functionName = isFunctions[ii];
-    wrapper_[functionName] = function(f) {
-      return function() {
-        if (contextLost_) {
-          return false;
-        }
-        return f.apply(ctx, arguments);
-      }
-    }(wrapper_[functionName]);
-  }
-
-  wrapper_.checkFramebufferStatus = function(f) {
-    return function() {
-      if (contextLost_) {
-        return ctx.FRAMEBUFFER_UNSUPPORTED;
-      }
-      return f.apply(ctx, arguments);
-    };
-  }(wrapper_.checkFramebufferStatus);
-
-  wrapper_.getAttribLocation = function(f) {
-    return function() {
-      if (contextLost_) {
-        return -1;
-      }
-      return f.apply(ctx, arguments);
-    };
-  }(wrapper_.getAttribLocation);
-
-  wrapper_.getVertexAttribOffset = function(f) {
-    return function() {
-      if (contextLost_) {
-        return 0;
-      }
-      return f.apply(ctx, arguments);
-    };
-  }(wrapper_.getVertexAttribOffset);
-
-  wrapper_.isContextLost = function() {
-    return contextLost_;
-  };
-
-  function wrapEvent(listener) {
-    if (typeof(listener) == "function") {
-      return listener;
-    } else {
-      return function(info) {
-        listener.handleEvent(info);
-      }
-    }
-  }
-
-  wrapper_.registerOnContextLostListener = function(listener) {
-    onLost_ = wrapEvent(listener);
-  };
-
-  wrapper_.registerOnContextRestoredListener = function(listener) {
-    if (contextLost_) {
-      nextOnRestored_ = wrapEvent(listener);
-    } else {
-      onRestored_ = wrapEvent(listener);
-    }
-  }
-
-  return wrapper_;
-}
-
-return {
-  /**
-   * Initializes this module. Safe to call more than once.
-   * @param {!WebGLRenderingContext} ctx A WebglInstance context. If
-   *    you have more than one context it doesn't matter which one
-   *    you pass in, it is only used to pull out constants.
-   */
-  'init': init,
-
-  /**
-   * Returns true or false if value matches any WebglInstance enum
-   * @param {*} value Value to check if it might be an enum.
-   * @return {boolean} True if value matches one of the WebglInstance defined enums
-   */
-  'mightBeEnum': mightBeEnum,
-
-  /**
-   * Gets an string version of an WebglInstance enum.
-   *
-   * Example:
-   *   WebGLDebugUtil.init(ctx);
-   *   var str = WebGLDebugUtil.glEnumToString(ctx.getError());
-   *
-   * @param {number} value Value to return an enum for
-   * @return {string} The string version of the enum.
-   */
-  'glEnumToString': glEnumToString,
-
-  /**
-   * Converts the argument of a WebglInstance function to a string.
-   * Attempts to convert enum arguments to strings.
-   *
-   * Example:
-   *   WebGLDebugUtil.init(ctx);
-   *   var str = WebGLDebugUtil.glFunctionArgToString('bindTexture', 0, gl.TEXTURE_2D);
-   *
-   * would return 'TEXTURE_2D'
-   *
-   * @param {string} functionName the name of the WebglInstance function.
-   * @param {number} argumentIndx the index of the argument.
-   * @param {*} value The value of the argument.
-   * @return {string} The value as a string.
-   */
-  'glFunctionArgToString': glFunctionArgToString,
-
-  /**
-   * Given a WebglInstance context returns a wrapped context that calls
-   * gl.getError after every command and calls a function if the
-   * result is not NO_ERROR.
-   *
-   * You can supply your own function if you want. For example, if you'd like
-   * an exception thrown on any GL error you could do this
-   *
-   *    function throwOnGLError(err, funcName, args) {
-   *      throw WebGLDebugUtils.glEnumToString(err) + " was caused by call to" +
-   *            funcName;
-   *    };
-   *
-   *    ctx = WebGLDebugUtils.makeDebugContext(
-   *        canvas.getContext("webgl"), throwOnGLError);
-   *
-   * @param {!WebGLRenderingContext} ctx The webgl context to wrap.
-   * @param {!function(err, funcName, args): void} opt_onErrorFunc The function
-   *     to call when gl.getError returns an error. If not specified the default
-   *     function calls console.log with a message.
-   */
-  'makeDebugContext': makeDebugContext,
-
-  /**
-   * Given a WebglInstance context returns a wrapped context that adds 4
-   * functions.
-   *
-   * ctx.loseContext:
-   *   simulates a lost context event.
-   *
-   * ctx.restoreContext:
-   *   simulates the context being restored.
-   *
-   * ctx.registerOnContextLostListener(listener):
-   *   lets you register a listener for context lost. Use instead
-   *   of addEventListener('webglcontextlostevent', listener);
-   *
-   * ctx.registerOnContextRestoredListener(listener):
-   *   lets you register a listener for context restored. Use
-   *   instead of addEventListener('webglcontextrestored',
-   *   listener);
-   *
-   * @param {!WebGLRenderingContext} ctx The webgl context to wrap.
-   */
-  'makeLostContextSimulatingContext': makeLostContextSimulatingContext,
-
-  /**
-   * Resets a context to the initial state.
-   * @param {!WebGLRenderingContext} ctx The webgl context to
-   *     reset.
-   */
-  'resetToInitialState': resetToInitialState
-};
-
-}();
-
diff --git a/lab3.1/lib/webgl-utils.js b/lab3.1/lib/webgl-utils.js
deleted file mode 100644
index 26ed37e0d6adf469edabfa17b0c9e3d00199e744..0000000000000000000000000000000000000000
--- a/lab3.1/lib/webgl-utils.js
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 2010, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains functions every webgl program will need
- * a version of one way or another.
- *
- * Instead of setting up a context manually it is recommended to
- * use. This will check for success or failure. On failure it
- * will attempt to present an approriate message to the user.
- *
- *       gl = WebGLUtils.setupWebGL(canvas);
- *
- * For animated WebglInstance apps use of setTimeout or setInterval are
- * discouraged. It is recommended you structure your rendering
- * loop like this.
- *
- *       function render() {
- *         window.requestAnimationFrame(render, canvas);
- *
- *         // do rendering
- *         ...
- *       }
- *       render();
- *
- * This will call your rendering function up to the refresh rate
- * of your display but will stop rendering if your app is not
- * visible.
- */
-
-WebGLUtils = function() {
-
-/**
- * Creates the HTLM for a failure message
- * @param {string} canvasContainerId id of container of th
- *        canvas.
- * @return {string} The html.
- */
-var makeFailHTML = function(msg) {
-  return '' +
-        '<div style="margin: auto; width:500px;z-index:10000;margin-top:20em;text-align:center;">' + msg + '</div>';
-  return '' +
-    '<table style="background-color: #8CE; width: 100%; height: 100%;"><tr>' +
-    '<td align="center">' +
-    '<div style="display: table-cell; vertical-align: middle;">' +
-    '<div style="">' + msg + '</div>' +
-    '</div>' +
-    '</td></tr></table>';
-};
-
-/**
- * Mesasge for getting a webgl browser
- * @type {string}
- */
-var GET_A_WEBGL_BROWSER = '' +
-  'This page requires a browser that supports WebglInstance.<br/>' +
-  '<a href="http://get.webgl.org">Click here to upgrade your browser.</a>';
-
-/**
- * Mesasge for need better hardware
- * @type {string}
- */
-var OTHER_PROBLEM = '' +
-  "It doesn't appear your computer can support WebglInstance.<br/>" +
-  '<a href="http://get.webgl.org">Click here for more information.</a>';
-
-/**
- * Creates a webgl context. If creation fails it will
- * change the contents of the container of the <canvas>
- * tag to an error message with the correct links for WebglInstance.
- * @param {Element} canvas. The canvas element to create a
- *     context from.
- * @param {WebGLContextCreationAttirbutes} opt_attribs Any
- *     creation attributes you want to pass in.
- * @param {function:(msg)} opt_onError An function to call
- *     if there is an error during creation.
- * @return {WebGLRenderingContext} The created context.
- */
-var setupWebGL = function(canvas, opt_attribs, opt_onError) {
-  function handleCreationError(msg) {
-      var container = document.getElementsByTagName("body")[0];
-    //var container = canvas.parentNode;
-    if (container) {
-      var str = window.WebGLRenderingContext ?
-           OTHER_PROBLEM :
-           GET_A_WEBGL_BROWSER;
-      if (msg) {
-        str += "<br/><br/>Status: " + msg;
-      }
-      container.innerHTML = makeFailHTML(str);
-    }
-  };
-
-  opt_onError = opt_onError || handleCreationError;
-
-  if (canvas.addEventListener) {
-    canvas.addEventListener("webglcontextcreationerror", function(event) {
-          opt_onError(event.statusMessage);
-        }, false);
-  }
-  var context = create3DContext(canvas, opt_attribs);
-  if (!context) {
-    if (!window.WebGLRenderingContext) {
-      opt_onError("");
-    } else {
-      opt_onError("");
-    }
-  }
-
-  return context;
-};
-
-/**
- * Creates a webgl context.
- * @param {!Canvas} canvas The canvas tag to get context
- *     from. If one is not passed in one will be created.
- * @return {!WebGLContext} The created context.
- */
-var create3DContext = function(canvas, opt_attribs) {
-  var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
-  var context = null;
-  for (var ii = 0; ii < names.length; ++ii) {
-    try {
-      context = canvas.getContext(names[ii], opt_attribs);
-    } catch(e) {}
-    if (context) {
-      break;
-    }
-  }
-  return context;
-}
-
-return {
-  create3DContext: create3DContext,
-  setupWebGL: setupWebGL
-};
-}();
-
-/**
- * Provides requestAnimationFrame in a cross browser
- * way.
- */
-if (!window.requestAnimationFrame) {
-  window.requestAnimationFrame = (function() {
-    return window.requestAnimationFrame ||
-           window.webkitRequestAnimationFrame ||
-           window.mozRequestAnimationFrame ||
-           window.oRequestAnimationFrame ||
-           window.msRequestAnimationFrame ||
-           function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
-             window.setTimeout(callback, 1000/60);
-           };
-  })();
-}
-
-/** * ERRATA: 'cancelRequestAnimationFrame' renamed to 'cancelAnimationFrame' to reflect an update to the W3C Animation-Timing Spec. 
- * 
- * Cancels an animation frame request. 
- * Checks for cross-browser support, falls back to clearTimeout. 
- * @param {number}  Animation frame request. */
-if (!window.cancelAnimationFrame) {
-  window.cancelAnimationFrame = (window.cancelRequestAnimationFrame ||
-                                 window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame ||
-                                 window.mozCancelAnimationFrame || window.mozCancelRequestAnimationFrame ||
-                                 window.msCancelAnimationFrame || window.msCancelRequestAnimationFrame ||
-                                 window.oCancelAnimationFrame || window.oCancelRequestAnimationFrame ||
-                                 window.clearTimeout);
-}
\ No newline at end of file
diff --git a/lab3.1/src/lab3.html b/lab3.1/src/lab3.html
deleted file mode 100644
index defa2c632dbb41c642f65389b5871a127ec697b4..0000000000000000000000000000000000000000
--- a/lab3.1/src/lab3.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-
-<head>
-    <meta charset="UTF-8">
-    <title>Lab 3</title>
-</head>
-
-<body onload="main()">
-    <canvas width="400" height="600" id="my-canvas">
-Please use a browser that supports "canvas"
-</canvas>
-    <script src="../lib/webgl-utils.js"></script>
-    <script src="../lib/webgl-debug.js"></script>
-    <script src="../lib/cuon-matrix.js"></script>
-    <script src="../lib/cuon-utils.js"></script>
-    <script src="lab3.js"></script>
-</body>
-
-</html>
\ No newline at end of file
diff --git a/lab3.1/src/lab3.js b/lab3.1/src/lab3.js
deleted file mode 100644
index 08d08dfcc941a9ebb8c1d094d8308ba8a2d2f0ee..0000000000000000000000000000000000000000
--- a/lab3.1/src/lab3.js
+++ /dev/null
@@ -1,470 +0,0 @@
-//author : QUentin Berthet
-const VSHADER_SOURCE =
-    'attribute vec4 a_position;\n' +
-    'attribute vec4 a_Color;\n' +
-    'attribute vec3 a_normal;\n' +
-
-
-    'uniform vec3 u_lightWorldPosition;\n' +
-    'uniform vec3 u_viewWorldPosition;\n' +
-
-
-    'uniform mat4 u_world;\n' +
-    'uniform mat4 u_worldViewProjection;\n' +
-    'uniform mat4 u_worldInverseTranspose;\n' +
-
-    'varying vec3 v_normal;\n' +
-
-    'varying vec3 v_surfaceToLight;\n' +
-    'varying vec3 v_surfaceToView;\n' +
-
-    'void main() {\n' +
-    '  gl_Position = u_worldViewProjection * a_position ;\n' +
-    '  v_normal = mat3(u_worldInverseTranspose) * a_normal;\n' +
-    '  vec3 surfaceWorldPosition = (u_world * a_position).xyz;\n' +
-    '  v_surfaceToLight = u_lightWorldPosition - surfaceWorldPosition;\n' +
-    '  v_surfaceToView = u_viewWorldPosition - surfaceWorldPosition;\n' +
-    '}\n';
-
-
-const FSHADER_SOURCE =
-    'precision mediump float;\n' +
-    'varying vec3 v_normal;\n' +
-    'varying vec3 v_surfaceToLight;\n' +
-    'varying vec3 v_surfaceToView;\n' +
-    'uniform vec4 u_Color;\n' +
-    'uniform float u_shininess;\n' +
-
-    'void main() {\n' +
-    '  vec3 normal = normalize(v_normal);\n' +
-    '  vec3 surfaceToLightDirection = normalize(v_surfaceToLight);\n' +
-    '  vec3 surfaceToViewDirection = normalize(v_surfaceToView);\n' +
-    '  vec3 halfVector = normalize(surfaceToLightDirection + surfaceToViewDirection);\n' +
-    '  float light = dot(normal, surfaceToLightDirection);\n' +
-    '  float specular = 0.0;\n' +
-    '  if (light > 0.0) {specular = pow(dot(normal, halfVector), u_shininess);}\n' +
-    '  gl_FragColor = u_Color;\n' +
-    '  gl_FragColor.rgb *= light;\n' +
-    '  gl_FragColor.rgb += specular;\n' +
-    '}\n';
-
-
-
-function main() {
-
-    console.log("hello<");
-    const canvas = document.getElementById('my-canvas');
-
-
-    const gl = canvas.getContext('webgl');
-    if (!gl) {
-        console.log('Failed to get the displaying context for WebGL');
-        return;
-    }
-
-
-    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
-        console.log('Failed to intialize shaders.');
-        return;
-    }
-
-    // look up where the vertex data needs to go.
-    var positionLocation = gl.getAttribLocation(gl.program, "a_position");
-    var normalLocation = gl.getAttribLocation(gl.program, "a_normal");
-
-    // lookup uniforms
-    var worldViewProjectionLocation = gl.getUniformLocation(gl.program, "u_worldViewProjection");
-    var worldInverseTransposeLocation = gl.getUniformLocation(gl.program, "u_worldInverseTranspose");
-    var colorLocation = gl.getUniformLocation(gl.program, "u_Color");
-    var shininessLocation = gl.getUniformLocation(gl.program, "u_shininess");
-    var lightWorldPositionLocation =
-        gl.getUniformLocation(gl.program, "u_lightWorldPosition");
-    var viewWorldPositionLocation =
-        gl.getUniformLocation(gl.program, "u_viewWorldPosition");
-    var worldLocation =
-        gl.getUniformLocation(gl.program, "u_world");
-
-
-
-    // Create a buffer to put positions in    
-    var positionBuffer = gl.createBuffer();
-    // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
-    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
-    // Put geometry data into buffer    
-
-    const len = initVertexBuffers(gl);
-
-    if (len < 0) {
-        console.log('Failed to set the positions of the vertices');
-        return;
-    }
-
-    // Create a buffer to put normals in
-    var normalBuffer = gl.createBuffer();
-    // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = normalBuffer)
-    gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
-    // Put normals data into buffer
-
-
-    CreateNormals(gl);
-    var shininess = 150;
-
-    function updateShininess(event, ui) {
-        shininess = ui.value;
-        drawScene();
-    }
-
-
-
-
-    function drawScene() {
-
-        gl.clearColor(0.75, 0.85, 0.8, 1.0);
-        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-        gl.enable(gl.DEPTH_TEST);
-        gl.frontFace(gl.CCW);
-        gl.cullFace(gl.BACK);
-        // Turn on the position attribute
-
-        const projMatrix = new Matrix4();
-        projMatrix.setPerspective(45, gl.canvas.clientWidth / gl.canvas.clientHeight, 1, 100);
-
-        const cameraMatrix = new Matrix4();
-        let angle = 1;
-        let X = 5 * Math.cos(angle);
-        let Y = 0;
-        let Z = 5 * Math.sin(angle);
-
-        cameraMatrix.setLookAt(X, Y, Z, 0, 0, 0, 0, 1, 0);
-        const viewMatrix = new Matrix4(cameraMatrix);
-
-        const viewProjectionMatrix = new Matrix4(projMatrix).multiply(new Matrix4(viewMatrix));
-
-        const worldMatrix = new Matrix4();
-
-
-        const worldViewProjectionMatrix = new Matrix4(viewProjectionMatrix).multiply(worldMatrix);
-        const worldInverseMatrix = new Matrix4(worldMatrix).invert();
-        const worldInverseTransposeMatrix = new Matrix4(worldInverseMatrix).transpose();
-
-
-
-        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
-        gl.enableVertexAttribArray(positionLocation);
-        var size = 3; // 3 components per iteration
-        var type = gl.FLOAT; // the data is 32bit floats
-        var normalize = false; // don't normalize the data
-        var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
-        var offset = 0; // start at the beginning of the buffer
-        gl.vertexAttribPointer(positionLocation, size, type, normalize, stride, offset);
-
-
-
-
-
-        // Turn on the normal attribute
-        gl.enableVertexAttribArray(normalLocation);
-        // Bind the normal buffer.
-        gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
-        // Tell the attribute how to get data out of normalBuffer (ARRAY_BUFFER)
-        var size = 3; // 3 components per iteration
-        var type = gl.FLOAT; // the data is 32bit floating point values
-        var normalize = false; // normalize the data (convert from 0-255 to 0-1)
-        var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
-        var offset = 0; // start at the beginning of the buffer
-        gl.vertexAttribPointer(
-            normalLocation, size, type, normalize, stride, offset);
-
-
-        // Set the matrices
-        gl.uniformMatrix4fv(worldViewProjectionLocation, false, worldViewProjectionMatrix);
-        gl.uniformMatrix4fv(worldInverseTransposeLocation, false, worldInverseTransposeMatrix);
-        gl.uniformMatrix4fv(worldLocation, false, worldMatrix);
-        // Set the color to use
-        gl.uniform4fv(colorLocation, [0.2, 1, 0.2, 1]); // green
-        // set the light position
-        gl.uniform3fv(lightWorldPositionLocation, [20, 30, 60]);
-        // set the camera/view position
-        gl.uniform3fv(viewWorldPositionLocation, camera);
-        // set the shininess
-        gl.uniform1f(shininessLocation, shininess);
-
-
-
-
-
-
-        // var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
-        // if (a_Color < 0) {
-        //     console.log('Failed to get the storage location of a_Color');
-        //     return -1;
-        // }
-
-        // gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 24, 12);
-        // gl.enableVertexAttribArray(a_Color);
-        // gl.bindBuffer(gl.ARRAY_BUFFER, null);
-
-
-
-
-        var viewProjMatrix = new Matrix4();
-        viewProjMatrix.setPerspective(100.0, 1.0, 1.0, 1000.0);
-        viewProjMatrix.lookAt(1.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
-
-        var vals = [0.0, 0.0];
-        ObjectManager(vals);
-
-        var display = function() {
-            let count = 42;
-            // Don't render the upper surface because we duplicate frustum + surface
-            if (i === 1) {
-                count -= 6;
-            }
-            cameraMatrix.set(viewProjMatrix);
-            cameraMatrix.rotate(vals[0], 1.0, 0.0, 0.0);
-            cameraMatrix.rotate(vals[1], 0.0, 1.0, 0.0);
-            gl.uniformMatrix4fv(u_worldViewProjection, false, cameraMatrix.elements);
-
-
-            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-
-            gl.drawElements(gl.TRIANGLES, count, gl.UNSIGNED_SHORT, 0);
-
-            cameraMatrix.translate(0, 3.0, -4)
-            cameraMatrix.rotate(180, 1.0, 0.0, 0.0);
-            gl.uniformMatrix4fv(u_worldViewProjection, false, cameraMatrix.elements);
-
-            gl.drawElements(gl.TRIANGLES, count, gl.UNSIGNED_SHORT, 0);
-
-
-            requestAnimationFrame(display);
-        };
-        display();
-    }
-
-}
-
-function ObjectManager(values) {
-    document.onkeydown = (ev) => {
-        v = 10;
-        switch (ev.key) {
-            case 'ArrowDown':
-                values[0] += v;
-                break;
-            case 'ArrowUp':
-                values[0] -= v;
-                break;
-            case 'ArrowRight':
-                values[1] += v;
-                break;
-            case 'ArrowLeft':
-                values[1] -= v;
-                break;
-        }
-    };
-}
-
-
-
-function initVertexBuffers(gl) {
-
-    let vertices = new Float32Array([
-
-        // Front
-        -2, -1.5, 0, -1, 1.5, -1,
-        0, -1.5, 0,
-
-        -1, 1.5, -1,
-        0, -1.5, 0,
-        1, 1.5, -1,
-
-        0, -1.5, 0,
-        1, 1.5, -1,
-        2, -1.5, 0,
-
-        // Back
-        -2, -1.5, -4, -1, 1.5, -3,
-        0, -1.5, -4,
-
-        -1, 1.5, -3,
-        0, -1.5, -4,
-        1, 1.5, -3,
-
-        0, -1.5, -4,
-        1, 1.5, -3,
-        2, -1.5, -4,
-
-        // Left
-        -2, -1.5, -4, -1, 1.5, -3, -2, -1.5, -2,
-
-        -1, 1.5, -3, -2, -1.5, -2, -1, 1.5, -1,
-
-        -2, -1.5, -2, -1, 1.5, -1, -2, -1.5, 0,
-
-        // Right
-        2, -1.5, -4,
-        1, 1.5, -3,
-        2, -1.5, -2,
-
-        1, 1.5, -3,
-        2, -1.5, -2,
-        1, 1.5, -1,
-
-        2, -1.5, -2,
-        1, 1.5, -1,
-        2, -1.5, -0,
-
-        // top
-        -1, 1.5, -1, -1, 1.5, -3,
-        0, 1.5, -1,
-
-        -1, 1.5, -3,
-        0, 1.5, -1,
-        1, 1.5, -3,
-
-        0, 1.5, -1,
-        1, 1.5, -3,
-        1, 1.5, -1,
-
-        // ground
-        -2, -1.5, 0, -2, -1.5, -4,
-        0, -1.5, 0,
-
-        -2, -1.5, -4,
-        0, -1.5, 0,
-        2, -1.5, -4,
-
-        0, -1.5, 0,
-        2, -1.5, -4,
-        2, -1.5, 0,
-
-
-    ]);
-
-    const len = vertices.length / 6;
-    const vertexBuffer = gl.createBuffer();
-    if (!vertexBuffer) {
-        console.log('Failed to create the buffer object');
-        return -1;
-    }
-
-    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
-    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
-
-    return len;
-}
-
-function normalizedCrossWith3Points(a0, a1, a2, b0, b1, b2, c0, c1, c2) {
-    const u = [b0 - a0, b1 - a1, b2 - a2];
-    const v = [c0 - a0, c1 - a1, c2 - a2];
-    const rawNormal = [
-        u[1] * v[2] - u[2] * v[1],
-        u[2] * v[0] - u[0] * v[2],
-        u[0] * v[1] - u[1] * v[0]
-    ];
-    const norm = Math.hypot(...rawNormal);
-    return rawNormal.map((n) => n / norm);
-}
-
-const Normal_f = normalizedCrossWith3Points(-1, 1.5, -1,
-    0, -1.5, 0,
-    1, 1.5, -1
-
-);
-const Normal_b = normalizedCrossWith3Points(-1, 1.5, -3,
-    0, -1.5, -4,
-    1, 1.5, -3
-);
-const Normal_t = normalizedCrossWith3Points(-1, 1.5, -3,
-    0, 1.5, -1,
-    1, 1.5, -3
-);
-const Normal_g = normalizedCrossWith3Points(-2, -1.5, -4,
-    0, -1.5, 0,
-    2, -1.5, -4
-);
-const Normal_r = normalizedCrossWith3Points(
-    1, 1.5, -3,
-    2, -1.5, -2,
-    1, 1.5, -1
-);
-
-const leftNormal = normalizedCrossWith3Points(-1, 1.5, -3, -2, -1.5, -2, -1, 1.5, -1);
-
-// const surfaceNormal = normalizedCrossWith3Points(-2.5, -0.501, -2.5,
-//     2.5, -0.501, -2.5,
-//     2.5, -0.501, 2.5
-// );
-
-
-function CreateNormals(gl, bottomNormal) {
-    var vertexNormals = new Float32Array(
-        [ //front
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-
-
-            // back
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-
-
-            // left
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            // right
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-
-            // top
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-
-            // ground
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2]
-        ]);
-    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW);
-}
\ No newline at end of file
diff --git a/lab3/README.md b/lab3/README.md
index 073809a6c19bc9fcd95b3207f7de74ad0bb24279..37ef2aa3ab4fd9c2b71f611152904fdda1564d14 100644
--- a/lab3/README.md
+++ b/lab3/README.md
@@ -1,6 +1,6 @@
-# Lab2 IHM
+# Lab3 IHM
 
 * **docs**: contains the lab's statement
 * **libs**: contains WebGL libraries and utilities
-* **src**: contains the source code of the lab2 that you should complete (`main()` function in **lab2.js** file)
-* **DO NOT CHANGE** the name of the file `lab2.html`, however, you are free to change its content.
+* **src**: contains the source code of the lab2 that you should complete (`main()` function in **lab3.js** file)
+* **DO NOT CHANGE** the name of the file `lab3.html`, however, you are free to change its content.
diff --git a/lab3/src/lab3.html b/lab3/src/lab3.html
index eb19ba33f176350230f8eca6134f53a54ac4b6a3..f7b6c12b8eb74bda2ca59540f6a2bd21cbd2e343 100644
--- a/lab3/src/lab3.html
+++ b/lab3/src/lab3.html
@@ -7,9 +7,20 @@
 </head>
 
 <body onload="main()">
+
     <canvas width="400" height="600" id="my-canvas">
   Please use a browser that supports "canvas"
 </canvas>
+    <p>Point light position:</p>
+    <p id="pLX">x: 0</p>
+    <p id="pLY">y: 2</p>
+    <p id="pLZ">z: 0</p>
+
+    <p>Directional light direction:</p>
+    <p id="dLX">x: 0</p>
+    <p id="dLY">y: 2</p>
+    <p id="dLZ">z: 0</p>
+
     <script src="../lib/webgl-utils.js"></script>
     <script src="../lib/webgl-debug.js"></script>
     <script src="../lib/cuon-matrix.js"></script>
diff --git a/lab3/src/lab3.js b/lab3/src/lab3.js
index f65bab93736c6c376e3af79a78347e3fbe155cf4..d5d72d47d196c1118f5bdac90782308b64ecb09a 100644
--- a/lab3/src/lab3.js
+++ b/lab3/src/lab3.js
@@ -1,20 +1,29 @@
-//author : QUentin Berthet
-const VSHADER_SOURCE =
+/**
+ * title : LABO3
+ * author : Quentin Berthet
+ */
+
+
+var VSHADER_SOURCE =
+    'attribute vec3 a_Normal;\n' + // Normal
     'attribute vec4 a_Position;\n' +
-    'attribute vec3 a_normal;\n' +
     'attribute vec4 a_Color;\n' +
 
-    'uniform mat4 u_worldViewProjection;\n' +
-    'uniform mat4 u_worldInverseTranspose;\n' +
+    'uniform mat4 u_viewMatrix;\n' +
+    'uniform mat4 u_Matrix;\n' +
+    'uniform mat4 u_MatrixInverseTransposee;\n' +
 
-    'varying vec3 v_normal;\n' +
+    'uniform vec3 u_LightPosition;\n' +
     'varying vec4 v_Color;\n' +
-
+    'varying vec3 v_Normal;\n' +
+    'varying vec3 v_LightDirection;\n' +
 
     'void main() {\n' +
-    '  gl_Position = u_worldViewProjection * a_Position ;\n' +
-    '  v_normal = mat3(u_worldInverseTranspose) * a_normal;\n' +
+    '  gl_Position = u_viewMatrix * a_Position ;\n' +
     '  v_Color = a_Color;\n' +
+    '  v_Normal = mat3(u_MatrixInverseTransposee) * a_Normal;\n' +
+    '  vec3 currentPosition = (u_Matrix * a_Position).xyz;\n' +
+    '  v_LightDirection = u_LightPosition - currentPosition;\n' +
     '}\n';
 
 
@@ -22,480 +31,277 @@ const FSHADER_SOURCE =
     'precision mediump float;\n' +
 
     'varying vec4 v_Color;\n' +
-    'varying vec3 v_normal;\n' +
-    'uniform vec3 u_reverseLightDirection;\n' +
-
-    'void main() {\n' +
-    '  vec3 normal = normalize(v_normal);\n' +
-    '  float light = dot(normal, u_reverseLightDirection);\n' +
-
-    '  gl_FragColor = v_Color;\n' +
-    '  gl_FragColor.rgb *= light;\n' +
-    '}\n';
-
+    'varying vec3 v_Normal;\n' +
+    'varying vec3 v_LightDirection;\n' +
 
-let angleLight = 1;
-let angle = 1;
-let onOff = true;
-let lightWorldPositionX = 1 * Math.cos(angleLight);
-let lightWorldPositionY = 1;
-let lightWorldPositionZ = 1 * Math.sin(angleLight);
-let X = 15 * Math.cos(angle);
-let Y = 0;
-let Z = 15 * Math.sin(angle);
-
-function main() {
-
-    const canvas = document.getElementById('my-canvas');
-
-
-    const gl = canvas.getContext('webgl');
-    if (!gl) {
-        console.log('Failed to get the displaying context for WebGL');
-        return;
-    }
+    'uniform vec3 u_LightDirection;\n' +
+    'uniform vec3 u_LightDirectional;\n' +
+    'uniform vec3 u_LightPoint;\n' +
 
+    'void main() {\n' +
+    '  vec3 normal = normalize(v_Normal.xyz);\n' +
 
-    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
-        console.log('Failed to intialize shaders.');
-        return;
-    }
+    '  float lightDirectional = dot(normal, u_LightDirection);\n' +
+    '  float lightPoint = dot(normal, normalize(v_LightDirection));\n' +
 
+    '  gl_FragColor = vec4((u_LightPoint * v_Color.rgb * lightPoint) + (u_LightDirectional * v_Color.rgb * lightDirectional), v_Color.a);\n' +
+    '}\n';
 
-    const retour = initVertexBuffers(gl);
-    const len = retour[0]
-    const vertices = retour[1]
-    if (len < 0) {
-        console.log('Failed to set the positions of the vertices');
-        return;
-    }
+function initVertexBuffers(gl) {
+    // This is the model
+    let normals = new Float32Array([
+        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+    ]);
 
+    const colors = new Float32Array([
+        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, 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, 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, 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, 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, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
+    ]);
+    let vertices = new Float32Array([-0.4, -0.4, -0.4, -0.4, -0.4, 0.4, 0.4, -0.4, -0.4, 0.4, -0.4, 0.4, -0.2, 0.4, -0.2, -0.2, 0.4, 0.2, 0.2, 0.4, -0.2, 0.2, 0.4, 0.2, -0.4, -0.4, 0.4, -0.2, 0.4, 0.2, 0.0, -0.4, 0.4, 0.2, 0.4, 0.2,
+        0.4, -0.4, 0.4, -0.4, -0.4, 0.4, -0.2, 0.4, 0.2, -0.4, -0.4, 0.0, -0.2, 0.4, -0.2, -0.4, -0.4, -0.4, 0.4, -0.4, -0.4, 0.2, 0.4, -0.2,
+        0.4, -0.4, 0.0, 0.2, 0.4, 0.2, 0.4, -0.4, 0.4, -0.4, -0.4, -0.4, -0.2, 0.4, -0.2, 0.0, -0.4, -0.4, 0.2, 0.4, -0.2, 0.4, -0.4, -0.4, -2.0, -0.5, -2.0, -2.0, -0.5, 2.0, 2.0, -0.5, -2.0, 2.0, -0.5, 2.0
+    ]);
 
+    let indices = new Uint8Array([
+        0, 2, 1, 2, 3, 1, 4, 5, 6, 5, 7, 6,
+        8, 10, 9, 10, 11, 9, 10, 12, 11, 13, 14, 15,
+        14, 16, 15, 16, 17, 15, 18, 19, 20, 19, 21, 20,
+        21, 22, 20, 23, 24, 25, 24, 26, 25, 26, 27, 25,
+        28, 29, 30, 29, 31, 30
+    ]);
 
     const vertexBuffer = gl.createBuffer();
-    if (!vertexBuffer) {
-        console.log('Failed to create the buffer object');
-        return -1;
-    }
-
-    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
+    calculeNormal(vertices, normals, indices);
+    // copie les info coordonnée, color et normal au buffer
+    var bufferV = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, bufferV);
     gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
-    var worldViewProjectionLocation = gl.getUniformLocation(gl.program, "u_worldViewProjection");
-
-    const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
-    if (a_Position < 0) {
-        console.log('Failed to get the storage location of a_Position');
-        return -1;
-    }
-    gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 24, 0);
-    gl.enableVertexAttribArray(a_Position);
+    var a_attrV = gl.getAttribLocation(gl.program, 'a_Position');
+    gl.vertexAttribPointer(a_attrV, 3, gl.FLOAT, false, 0, 0);
+    gl.enableVertexAttribArray(a_attrV);
+    var bufferC = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, bufferC);
+    gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
+    var c_attrC = gl.getAttribLocation(gl.program, 'a_Color');
+    gl.vertexAttribPointer(c_attrC, 3, gl.FLOAT, false, 0, 0);
+    gl.enableVertexAttribArray(c_attrC);
+    var bufferN = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, bufferN);
+    gl.bufferData(gl.ARRAY_BUFFER, normals, gl.STATIC_DRAW);
+    var c_attrN = gl.getAttribLocation(gl.program, 'a_Normal');
+    gl.vertexAttribPointer(c_attrN, 3, gl.FLOAT, false, 0, 0);
+    gl.enableVertexAttribArray(c_attrN);
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexBuffer);
+    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
+
+    return indices.length;
+}
 
-    var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
-    if (a_Color < 0) {
-        console.log('Failed to get the storage location of a_Color');
-        return -1;
+function computeNormal(array1, array2, norm, indices, i) {
+    for (let j = 0; j < 3; j++) {
+        norm[indices[i + j] * 3] = (array1[1] * array2[2] - array1[2] * array2[1]);
+        norm[indices[i + j] * 3 + 1] = (array1[2] * array2[0] - array1[0] * array2[2]);
+        norm[indices[i + j] * 3 + 2] = (array1[0] * array2[1] - array1[1] * array2[0]);
     }
+}
 
-    gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 24, 12);
-    gl.enableVertexAttribArray(a_Color);
-    gl.bindBuffer(gl.ARRAY_BUFFER, null);
-
-    var normalLocation = gl.getAttribLocation(gl.program, "a_normal");
-    var worldInverseTransposeLocation = gl.getUniformLocation(gl.program, "u_worldInverseTranspose");
-    var reverseLightDirectionLocation = gl.getUniformLocation(gl.program, "u_reverseLightDirection");
-
-    // Create a buffer to put normals in
-    var normalBuffer = gl.createBuffer();
-    // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = normalBuffer)
-    gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
-    // Put normals data into buffer
-    Createnormals(gl);
-    // Turn on the normal attribute
-    gl.enableVertexAttribArray(normalLocation);
-
-    // Bind the normal buffer.
-    gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
-
-    // Tell the attribute how to get data out of normalBuffer (ARRAY_BUFFER)
-    var size = 3; // 3 components per iteration
-    var type = gl.FLOAT; // the data is 32bit floating point values
-    var normalize = false; // normalize the data (convert from 0-255 to 0-1)
-    var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
-    var offset = 0; // start at the beginning of the buffer
-    gl.vertexAttribPointer(normalLocation, size, type, normalize, stride, offset);
+function calculeNormal(vert, norm, indice) {
 
+    for (let i = 0; i < indice.length; i += 3) {
+        let index1 = 3 * indice[i]
+        let index2 = 3 * indice[i + 1]
+        let index3 = 3 * indice[i + 2]
 
+        let el1 = [vert[index1], vert[index1 + 1], vert[index1 + 2]];
+        let el2 = [vert[index2], vert[index2 + 1], vert[index2 + 2]];
+        let el3 = [vert[index3], vert[index3 + 1], vert[index3 + 2]];
 
-    function radToDeg(r) {
-        return r * 180 / Math.PI;
-    }
+        let result1 = [];
+        for (let i = 0; i < el2.length; i++) {
+            result1.push(el2[i] - el1[i]);
+        }
+        let result2 = [];
+        for (let i = 0; i < el3.length; i++) {
+            result2.push(el3[i] - el1[i]);
+        }
+        computeNormal(result1, result2, norm, indice, i)
 
-    function degToRad(d) {
-        return d * Math.PI / 180;
     }
 
-    var fieldOfViewRadians = degToRad(60);
-
-
+}
 
 
-    gl.clearColor(0.75, 0.85, 0.8, 1.0);
-    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+function main() {
+    const canvas = document.getElementById('my-canvas');
+    const gl = getWebGLContext(canvas);
+    initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)
+    gl.clearColor(0, 0, 0, 1);
     gl.enable(gl.DEPTH_TEST);
-    gl.frontFace(gl.CCW);
-    gl.cullFace(gl.BACK);
-
-
-
-    var u_worldViewProjection = gl.getUniformLocation(gl.program, 'u_worldViewProjection');
-
+    const n = initVertexBuffers(gl);
+    let u_viewMatrix = gl.getUniformLocation(gl.program, 'u_viewMatrix')
+    let u_LightDirectional = gl.getUniformLocation(gl.program, 'u_LightDirectional')
+    let u_LightDirection = gl.getUniformLocation(gl.program, 'u_LightDirection')
+    let u_LightPoint = gl.getUniformLocation(gl.program, 'u_LightPoint')
+    let u_LightPosition = gl.getUniformLocation(gl.program, 'u_LightPosition')
+    let u_Matrix = gl.getUniformLocation(gl.program, 'u_Matrix')
+    let u_MatrixInverseTransposee = gl.getUniformLocation(gl.program, 'u_MatrixInverseTransposee')
+
+    //positionne light
+    let Light1Pos = [0.0, 2.0, 0.0];
+    let Light2Pos = [0.0, 2.0, 0.0];
+    gl.uniform3f(u_LightDirectional, 0.0, 0.0, 0.0);
+    let lightDirection = new Vector3(Light2Pos);
+    gl.uniform3fv(u_LightDirection, lightDirection.normalize().elements);
+    gl.uniform3f(u_LightPoint, 1.0, 1.0, 1.0);
+    gl.uniform3fv(u_LightPosition, Light1Pos);
+
+    var viewProjMat = new Matrix4();
+    viewProjMat.setPerspective(30.0, canvas.width / canvas.height, 1.0, 10.0);
+    viewProjMat.lookAt(3.0, 3.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //pos, pt vis, Dir
+
+    var viewMat = new Matrix4(); // Model view projection matrix
     var mat = new Matrix4();
+    var matInverseTransposee = new Matrix4();
 
-
-    var viewProjMatrix = new Matrix4();
-    var aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
-
-
-    viewProjMatrix.setPerspective(1000.0, aspect, 1.0, 2000.0);
-    const cameraMatrix = new Matrix4();
-    viewProjMatrix.lookAt(X, Y, Z, 0, 0, 0, 0, 1, 100);
-
-    const viewMatrix = new Matrix4();
-
-
-
-    // Make a view matrix from the camera matrix.
-
-    // Compute a view projection matrix
-    var viewProjectionMatrix = new Matrix4(viewProjMatrix).multiply(viewMatrix);
-
-
-    const worldMatrix = new Matrix4();
-
-    const worldViewProjectionMatrix = new Matrix4(viewProjectionMatrix).multiply(worldMatrix);
-    const worldInverseMatrix = new Matrix4(worldMatrix).invert();
-    const worldInverseTransposeMatrix = new Matrix4(worldInverseMatrix).transpose();;
-    // Set the matrices
-    console.log("------------------------------------------------------------");
-    console.log(worldViewProjectionMatrix);
-    console.log("------------------------------------------------------------");
-    gl.uniformMatrix4fv(worldViewProjectionLocation, false, worldViewProjectionMatrix.elements);
-    gl.uniformMatrix4fv(worldInverseTransposeLocation, false, worldInverseTransposeMatrix.elements);
-
-    // set the light direction.
-    //gl.uniform3fv(reverseLightDirectionLocation, m4.normalize([0.5, 0.7, 1]));
-
-
-    var vals = [0.0, 0.0];
-    ObjectManager(vals);
-
-
-
-    gl.uniform3fv(reverseLightDirectionLocation, new Vector3([lightWorldPositionX, lightWorldPositionY, lightWorldPositionZ]).normalize().elements);
-
+    var keysMove = [0.0, 0.0];
+    actionsManager(document, gl, keysMove, u_LightPoint, u_LightDirectional, Light1Pos, Light2Pos);
+    var render = function() {
+        gl.uniform3fv(u_LightPosition, Light1Pos);
+        //Directional light direction
+        lightDirection = new Vector3(Light2Pos);
+        gl.uniform3fv(u_LightDirection, lightDirection.normalize().elements);
 
 
-    var display = function() {
-        cameraMatrix.set(viewProjMatrix);
-        cameraMatrix.rotate(vals[0], 1.0, 0.0, 0.0);
-        cameraMatrix.rotate(vals[1], 0.0, 1.0, 0.0);
-        gl.uniformMatrix4fv(u_worldViewProjection, false, cameraMatrix.elements);
+        mat.setRotate(keysMove[0], 1.0, 0.0, 0.0);
+        mat.rotate(keysMove[1], 0.0, 1.0, 0.0);
+        viewMat.set(viewProjMat).multiply(mat);
+        gl.uniformMatrix4fv(u_viewMatrix, false, viewMat.elements);
+        gl.uniformMatrix4fv(u_Matrix, false, mat.elements);
 
+        matInverseTransposee.setInverseOf(mat).transpose()
+        gl.uniformMatrix4fv(u_MatrixInverseTransposee, false, matInverseTransposee.elements);
 
         gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
 
-        gl.drawArrays(gl.TRIANGLES, 0, len);
+        gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
 
+        mat.translate(0, 0.80, 0);
+        mat.rotate(180, 1.0, 0.0, 0.0);
+        viewMat.set(viewProjMat).multiply(mat)
+        gl.uniformMatrix4fv(u_viewMatrix, false, viewMat.elements);
+        gl.uniformMatrix4fv(u_Matrix, false, mat.elements);
 
-        cameraMatrix.translate(0, 3.0, -4)
-        cameraMatrix.rotate(180, 1.0, 0.0, 0.0);
-        gl.uniformMatrix4fv(u_worldViewProjection, false, cameraMatrix.elements);
+        matInverseTransposee.setInverseOf(mat).transpose()
+        gl.uniformMatrix4fv(u_MatrixInverseTransposee, false, matInverseTransposee.elements);
 
+        gl.drawElements(gl.TRIANGLES, n - 6, gl.UNSIGNED_BYTE, 0);
 
-        gl.drawArrays(gl.TRIANGLES, 0, len);
-
-
-        requestAnimationFrame(display);
+        requestAnimationFrame(render);
     };
-    display();
-}
-let i = 0;
-
-function normalizedCrossWith3Points(a0, a1, a2, b0, b1, b2, c0, c1, c2) {
-    const u = [b0 - a0, b1 - a1, b2 - a2];
-    const v = [c0 - a0, c1 - a1, c2 - a2];
-    const rawnormal = [
-        u[1] * v[2] - u[2] * v[1],
-        u[2] * v[0] - u[0] * v[2],
-        u[0] * v[1] - u[1] * v[0]
-    ];
-    const norm = Math.hypot(...rawnormal);
-    return rawnormal.map((n) => n / norm);
+    render();
 }
 
 
 
-function ObjectManager(values) {
-    document.onkeydown = (event) => {
-        v = 1;
+let on = true;
+
+function actionsManager(document, gl, keysMove, u_LightPoint, u_LightDirectional, Light1Pos, Light2Pos) {
+    switchLight = true;
+
+    document.onkeydown = function(event) {
         switch (event.code) {
-            case "KeyA":
-                angle += 0.1;
-                onOff = true;
+            case "KeyJ":
+                if (on) {
+                    {
+                        console.log("1");
+                        gl.uniform3f(u_LightPoint, 0.0, 0.0, 0.0);
+                        gl.uniform3f(u_LightDirectional, 1.0, 1.0, 1.0);
+                        switchLight = false;
+                        on = false;
+                    }
+
+                } else {
+
+                    console.log("2");
+                    gl.uniform3f(u_LightPoint, 1.0, 1.0, 1.0);
+                    gl.uniform3f(u_LightDirectional, 0.0, 0.0, 0.0);
+                    switchLight = true;
+                    on = true;
+                }
                 break;
-            case "KeyD":
-                angle -= 0.1;
-                onOff = true;
+            case "KeyE":
+                if (switchLight) {
+                    Light1Pos[0] += 0.1;
+                } else {
+                    Light2Pos[0] += 0.1;
+                }
                 break;
-            case "KeyW":
-                Y -= 0.1;
-                X -= 0.1;
-                onOff = true;
+            case "KeyQ":
+                if (switchLight) {
+                    Light1Pos[0] -= 0.1;
+                } else {
+                    Light2Pos[0] -= 0.1;
+                }
                 break;
             case "KeyS":
-                Y += 0.1;
-                X += 0.1;
-                onOff = true;
-                break;
-            case "KeyC":
-                i += 0.1;
-                if (i % 2 == 0) {
-                    onOff = true;
-                    console.log(onOff);
+                if (switchLight) {
+                    Light1Pos[1] += 0.1;
                 } else {
-                    onOff = false;
-                    console.log(onOff);
+                    Light2Pos[1] += 0.1;
                 }
                 break;
-
-            case "KeyJ":
-                console.log("on");
-                lightWorldPositionX -= 0.1;
-                angleLight += 0.1;
-                onOff = true;
-                break;
-            case "KeyL":
-                lightWorldPositionX += 0.1;
-                angleLight -= 0.1;
-                onOff = true;
+            case "KeyW":
+                if (switchLight) {
+                    Light1Pos[1] -= 0.1;
+                } else {
+                    Light2Pos[1] -= 0.1;
+                }
                 break;
-            case "KeyI":
-                lightWorldPositionY += 0.1;
-                onOff = true;
+            case "KeyA":
+                if (switchLight) {
+                    Light1Pos[2] -= 0.1;
+                } else {
+                    Light2Pos[2] -= 0.1;
+                }
                 break;
-            case "KeyK":
-                lightWorldPositionY -= 0.1;
-                onOff = true;
+            case "KeyD":
+                if (switchLight) {
+                    Light1Pos[2] += 0.1;
+                } else {
+                    Light2Pos[2] += 0.1;
+                }
                 break;
-            case 'ArrowDown':
-                values[0] += v;
-                onOff = false;
+            case "KeyF":
+                keysMove[1] += 1;
                 break;
-            case 'ArrowUp':
-                onOff = false;
-                values[0] -= v;
+            case "KeyH":
+                keysMove[1] -= 1;
                 break;
-            case 'ArrowRight':
-                onOff = false;
-                values[1] += v;
+            case "KeyT":
+                keysMove[0] += 1;
                 break;
-            case 'ArrowLeft':
-                onOff = false;
-                values[1] -= v;
+            case "KeyG":
+                keysMove[0] -= 1;
                 break;
         }
-        if (onOff) {
-
-            requestAnimationFrame(main);
-            event.preventDefault();
-        }
-
-
+        document.getElementById("pLX").innerHTML = "x: " + Math.round(Light1Pos[0] * 10);
+        document.getElementById("pLY").innerHTML = "y: " + Math.round(Light1Pos[1] * 10);
+        document.getElementById("pLZ").innerHTML = "z: " + Math.round(Light1Pos[2] * 10);
+        document.getElementById("dLX").innerHTML = "x: " + Math.round(Light2Pos[0] * 10);
+        document.getElementById("dLY").innerHTML = "y: " + Math.round(Light2Pos[1] * 10);
+        document.getElementById("dLZ").innerHTML = "z: " + Math.round(Light2Pos[2] * 10);
     }
-};
-
-
-
-function initVertexBuffers(gl) {
-
-    let vertices = new Float32Array([
-
-        // Front
-        // Front
-        -2, -1.5, 0, 0, 1, 0, -1, 1.5, -1, 0, 1, 0,
-        0, -1.5, 0, 0, 1, 0,
-
-        -1, 1.5, -1, 0, 1, 0,
-        0, -1.5, 0, 0, 1, 0,
-        1, 1.5, -1, 0, 1, 0,
-
-        0, -1.5, 0, 0, 1, 0,
-        1, 1.5, -1, 0, 1, 0,
-        2, -1.5, 0, 0, 1, 0,
-
-        // Back
-        -2, -1.5, -4, 0, 1, 0, -1, 1.5, -3, 0, 1, 0,
-        0, -1.5, -4, 0, 1, 0,
-
-        -1, 1.5, -3, 0, 1, 0,
-        0, -1.5, -4, 0, 1, 0,
-        1, 1.5, -3, 0, 1, 0,
-
-        0, -1.5, -4, 0, 1, 0,
-        1, 1.5, -3, 0, 1, 0,
-        2, -1.5, -4, 0, 1, 0,
-
-        // Left
-        -2, -1.5, -4, 0, 1, 0, -1, 1.5, -3, 0, 1, 0, -2, -1.5, -2, 0, 1, 0,
-
-        -1, 1.5, -3, 0, 1, 0, -2, -1.5, -2, 0, 1, 0, -1, 1.5, -1, 0, 1, 0,
-
-        -2, -1.5, -2, 0, 1, 0, -1, 1.5, -1, 0, 1, 0, -2, -1.5, 0, 0, 1, 0,
-
-        // Right
-        2, -1.5, -4, 0, 1, 0,
-        1, 1.5, -3, 0, 1, 0,
-        2, -1.5, -2, 0, 1, 0,
-
-        1, 1.5, -3, 0, 1, 0,
-        2, -1.5, -2, 0, 1, 0,
-        1, 1.5, -1, 0, 1, 0,
-
-        2, -1.5, -2, 0, 1, 0,
-        1, 1.5, -1, 0, 1, 0,
-        2, -1.5, -0, 0, 1, 0,
-
-        // top
-        -1, 1.5, -1, 0, 1, 0, -1, 1.5, -3, 0, 1, 0,
-        0, 1.5, -1, 0, 1, 0,
-
-        -1, 1.5, -3, 0, 1, 0,
-        0, 1.5, -1, 0, 1, 0,
-        1, 1.5, -3, 0, 1, 0,
-
-        0, 1.5, -1, 0, 1, 0,
-        1, 1.5, -3, 0, 1, 0,
-        1, 1.5, -1, 0, 1, 0,
-
-        // ground
-        -2, -1.5, 0, 0, 1, 0, -2, -1.5, -4, 0, 1, 0,
-        0, -1.5, 0, 0, 1, 0,
-
-        -2, -1.5, -4, 0, 1, 0,
-        0, -1.5, 0, 0, 1, 0,
-        2, -1.5, -4, 0, 1, 0,
-
-        0, -1.5, 0, 0, 1, 0,
-        2, -1.5, -4, 0, 1, 0,
-        2, -1.5, 0, 0, 1, 0
-
-    ]);
-
-    const len = vertices.length / 6;
-    return [len, vertices];
-}
-
-
-const normal_f = normalizedCrossWith3Points(-1, 1.5, -1,
-    0, -1.5, 0,
-    1, 1.5, -1,
-
-);
-const normal_b = normalizedCrossWith3Points(-1, 1.5, -3,
-    0, -1.5, -4,
-    1, 1.5, -3,
-);
-const normal_t = normalizedCrossWith3Points(-1, 1.5, -3,
-    0, 1.5, -1,
-    1, 1.5, -3,
-);
-const normal_g = normalizedCrossWith3Points(-2, -1.5, -4,
-    0, -1.5, 0,
-    2, -1.5, -4,
-);
-const normal_r = normalizedCrossWith3Points(
-    1, 1.5, -3,
-    2, -1.5, -2,
-    1, 1.5, -1,
-);
-
-const normal_l = normalizedCrossWith3Points(-1, 1.5, -3, -2, -1.5, -2, -1, 1.5, -1);
-
-// const surfacenormal = normalizedCrossWith3Points(-2.5, -0.501, -2.5,
-//     2.5, -0.501, -2.5,
-//     2.5, -0.501, 2.5
-// );
-
-
-function Createnormals(gl) {
-    var normales = new Float32Array(
-        [ //front
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-
-
-            // back
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-            normal_b[0], normal_b[1], normal_b[2],
-
-
-            // left
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            normal_f[0], normal_f[1], normal_f[2],
-            // right
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-            normal_r[0], normal_r[1], normal_r[2],
-
-            // top
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-            normal_t[0], normal_t[1], normal_t[2],
-
-            // ground
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2],
-            normal_g[0], normal_g[1], normal_g[2]
-        ]);
-    gl.bufferData(gl.ARRAY_BUFFER, normales, gl.STATIC_DRAW);
-
-}
\ No newline at end of file
+};
\ No newline at end of file
diff --git a/lab3Bis/README.md b/lab3Bis/README.md
deleted file mode 100644
index 073809a6c19bc9fcd95b3207f7de74ad0bb24279..0000000000000000000000000000000000000000
--- a/lab3Bis/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Lab2 IHM
-
-* **docs**: contains the lab's statement
-* **libs**: contains WebGL libraries and utilities
-* **src**: contains the source code of the lab2 that you should complete (`main()` function in **lab2.js** file)
-* **DO NOT CHANGE** the name of the file `lab2.html`, however, you are free to change its content.
diff --git a/lab3Bis/docs/Cours 3D Labo 3.pdf b/lab3Bis/docs/Cours 3D Labo 3.pdf
deleted file mode 100644
index 95be1783746c753299fd5ae3d412b90a2c39ad9d..0000000000000000000000000000000000000000
Binary files a/lab3Bis/docs/Cours 3D Labo 3.pdf and /dev/null differ
diff --git a/lab3Bis/lib/cuon-matrix.js b/lab3Bis/lib/cuon-matrix.js
deleted file mode 100644
index b67a5dd1b998eba54f585cf3849b8c17052d2a35..0000000000000000000000000000000000000000
--- a/lab3Bis/lib/cuon-matrix.js
+++ /dev/null
@@ -1,741 +0,0 @@
-// cuon-matrix.js (c) 2012 kanda and matsuda
-/** 
- * This is a class treating 4x4 matrix.
- * This class contains the function that is equivalent to OpenGL matrix stack.
- * The matrix after conversion is calculated by multiplying a conversion matrix from the right.
- * The matrix is replaced by the calculated result.
- */
-
-/**
- * Constructor of Matrix4
- * If opt_src is specified, new matrix is initialized by opt_src.
- * Otherwise, new matrix is initialized by identity matrix.
- * @param opt_src source matrix(option)
- */
-var Matrix4 = function(opt_src) {
-  var i, s, d;
-  if (opt_src && typeof opt_src === 'object' && opt_src.hasOwnProperty('elements')) {
-    s = opt_src.elements;
-    d = new Float32Array(16);
-    for (i = 0; i < 16; ++i) {
-      d[i] = s[i];
-    }
-    this.elements = d;
-  } else {
-    this.elements = new Float32Array([1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]);
-  }
-};
-
-/**
- * Set the identity matrix.
- * @return this
- */
-Matrix4.prototype.setIdentity = function() {
-  var e = this.elements;
-  e[0] = 1;   e[4] = 0;   e[8]  = 0;   e[12] = 0;
-  e[1] = 0;   e[5] = 1;   e[9]  = 0;   e[13] = 0;
-  e[2] = 0;   e[6] = 0;   e[10] = 1;   e[14] = 0;
-  e[3] = 0;   e[7] = 0;   e[11] = 0;   e[15] = 1;
-  return this;
-};
-
-/**
- * Copy matrix.
- * @param src source matrix
- * @return this
- */
-Matrix4.prototype.set = function(src) {
-  var i, s, d;
-
-  s = src.elements;
-  d = this.elements;
-
-  if (s === d) {
-    return;
-  }
-    
-  for (i = 0; i < 16; ++i) {
-    d[i] = s[i];
-  }
-
-  return this;
-};
-
-/**
- * Multiply the matrix from the right.
- * @param other The multiply matrix
- * @return this
- */
-Matrix4.prototype.concat = function(other) {
-  var i, e, a, b, ai0, ai1, ai2, ai3;
-  
-  // Calculate e = a * b
-  e = this.elements;
-  a = this.elements;
-  b = other.elements;
-  
-  // If e equals b, copy b to temporary matrix.
-  if (e === b) {
-    b = new Float32Array(16);
-    for (i = 0; i < 16; ++i) {
-      b[i] = e[i];
-    }
-  }
-  
-  for (i = 0; i < 4; i++) {
-    ai0=a[i];  ai1=a[i+4];  ai2=a[i+8];  ai3=a[i+12];
-    e[i]    = ai0 * b[0]  + ai1 * b[1]  + ai2 * b[2]  + ai3 * b[3];
-    e[i+4]  = ai0 * b[4]  + ai1 * b[5]  + ai2 * b[6]  + ai3 * b[7];
-    e[i+8]  = ai0 * b[8]  + ai1 * b[9]  + ai2 * b[10] + ai3 * b[11];
-    e[i+12] = ai0 * b[12] + ai1 * b[13] + ai2 * b[14] + ai3 * b[15];
-  }
-  
-  return this;
-};
-Matrix4.prototype.multiply = Matrix4.prototype.concat;
-
-/**
- * Multiply the three-dimensional vector.
- * @param pos  The multiply vector
- * @return The result of multiplication(Float32Array)
- */
-Matrix4.prototype.multiplyVector3 = function(pos) {
-  var e = this.elements;
-  var p = pos.elements;
-  var v = new Vector3();
-  var result = v.elements;
-
-  result[0] = p[0] * e[0] + p[1] * e[4] + p[2] * e[ 8] + e[12];
-  result[1] = p[0] * e[1] + p[1] * e[5] + p[2] * e[ 9] + e[13];
-  result[2] = p[0] * e[2] + p[1] * e[6] + p[2] * e[10] + e[14];
-
-  return v;
-};
-
-/**
- * Multiply the four-dimensional vector.
- * @param pos  The multiply vector
- * @return The result of multiplication(Float32Array)
- */
-Matrix4.prototype.multiplyVector4 = function(pos) {
-  var e = this.elements;
-  var p = pos.elements;
-  var v = new Vector4();
-  var result = v.elements;
-
-  result[0] = p[0] * e[0] + p[1] * e[4] + p[2] * e[ 8] + p[3] * e[12];
-  result[1] = p[0] * e[1] + p[1] * e[5] + p[2] * e[ 9] + p[3] * e[13];
-  result[2] = p[0] * e[2] + p[1] * e[6] + p[2] * e[10] + p[3] * e[14];
-  result[3] = p[0] * e[3] + p[1] * e[7] + p[2] * e[11] + p[3] * e[15];
-
-  return v;
-};
-
-/**
- * Transpose the matrix.
- * @return this
- */
-Matrix4.prototype.transpose = function() {
-  var e, t;
-
-  e = this.elements;
-
-  t = e[ 1];  e[ 1] = e[ 4];  e[ 4] = t;
-  t = e[ 2];  e[ 2] = e[ 8];  e[ 8] = t;
-  t = e[ 3];  e[ 3] = e[12];  e[12] = t;
-  t = e[ 6];  e[ 6] = e[ 9];  e[ 9] = t;
-  t = e[ 7];  e[ 7] = e[13];  e[13] = t;
-  t = e[11];  e[11] = e[14];  e[14] = t;
-
-  return this;
-};
-
-/**
- * Calculate the inverse matrix of specified matrix, and set to this.
- * @param other The source matrix
- * @return this
- */
-Matrix4.prototype.setInverseOf = function(other) {
-  var i, s, d, inv, det;
-
-  s = other.elements;
-  d = this.elements;
-  inv = new Float32Array(16);
-
-  inv[0]  =   s[5]*s[10]*s[15] - s[5] *s[11]*s[14] - s[9] *s[6]*s[15]
-            + s[9]*s[7] *s[14] + s[13]*s[6] *s[11] - s[13]*s[7]*s[10];
-  inv[4]  = - s[4]*s[10]*s[15] + s[4] *s[11]*s[14] + s[8] *s[6]*s[15]
-            - s[8]*s[7] *s[14] - s[12]*s[6] *s[11] + s[12]*s[7]*s[10];
-  inv[8]  =   s[4]*s[9] *s[15] - s[4] *s[11]*s[13] - s[8] *s[5]*s[15]
-            + s[8]*s[7] *s[13] + s[12]*s[5] *s[11] - s[12]*s[7]*s[9];
-  inv[12] = - s[4]*s[9] *s[14] + s[4] *s[10]*s[13] + s[8] *s[5]*s[14]
-            - s[8]*s[6] *s[13] - s[12]*s[5] *s[10] + s[12]*s[6]*s[9];
-
-  inv[1]  = - s[1]*s[10]*s[15] + s[1] *s[11]*s[14] + s[9] *s[2]*s[15]
-            - s[9]*s[3] *s[14] - s[13]*s[2] *s[11] + s[13]*s[3]*s[10];
-  inv[5]  =   s[0]*s[10]*s[15] - s[0] *s[11]*s[14] - s[8] *s[2]*s[15]
-            + s[8]*s[3] *s[14] + s[12]*s[2] *s[11] - s[12]*s[3]*s[10];
-  inv[9]  = - s[0]*s[9] *s[15] + s[0] *s[11]*s[13] + s[8] *s[1]*s[15]
-            - s[8]*s[3] *s[13] - s[12]*s[1] *s[11] + s[12]*s[3]*s[9];
-  inv[13] =   s[0]*s[9] *s[14] - s[0] *s[10]*s[13] - s[8] *s[1]*s[14]
-            + s[8]*s[2] *s[13] + s[12]*s[1] *s[10] - s[12]*s[2]*s[9];
-
-  inv[2]  =   s[1]*s[6]*s[15] - s[1] *s[7]*s[14] - s[5] *s[2]*s[15]
-            + s[5]*s[3]*s[14] + s[13]*s[2]*s[7]  - s[13]*s[3]*s[6];
-  inv[6]  = - s[0]*s[6]*s[15] + s[0] *s[7]*s[14] + s[4] *s[2]*s[15]
-            - s[4]*s[3]*s[14] - s[12]*s[2]*s[7]  + s[12]*s[3]*s[6];
-  inv[10] =   s[0]*s[5]*s[15] - s[0] *s[7]*s[13] - s[4] *s[1]*s[15]
-            + s[4]*s[3]*s[13] + s[12]*s[1]*s[7]  - s[12]*s[3]*s[5];
-  inv[14] = - s[0]*s[5]*s[14] + s[0] *s[6]*s[13] + s[4] *s[1]*s[14]
-            - s[4]*s[2]*s[13] - s[12]*s[1]*s[6]  + s[12]*s[2]*s[5];
-
-  inv[3]  = - s[1]*s[6]*s[11] + s[1]*s[7]*s[10] + s[5]*s[2]*s[11]
-            - s[5]*s[3]*s[10] - s[9]*s[2]*s[7]  + s[9]*s[3]*s[6];
-  inv[7]  =   s[0]*s[6]*s[11] - s[0]*s[7]*s[10] - s[4]*s[2]*s[11]
-            + s[4]*s[3]*s[10] + s[8]*s[2]*s[7]  - s[8]*s[3]*s[6];
-  inv[11] = - s[0]*s[5]*s[11] + s[0]*s[7]*s[9]  + s[4]*s[1]*s[11]
-            - s[4]*s[3]*s[9]  - s[8]*s[1]*s[7]  + s[8]*s[3]*s[5];
-  inv[15] =   s[0]*s[5]*s[10] - s[0]*s[6]*s[9]  - s[4]*s[1]*s[10]
-            + s[4]*s[2]*s[9]  + s[8]*s[1]*s[6]  - s[8]*s[2]*s[5];
-
-  det = s[0]*inv[0] + s[1]*inv[4] + s[2]*inv[8] + s[3]*inv[12];
-  if (det === 0) {
-    return this;
-  }
-
-  det = 1 / det;
-  for (i = 0; i < 16; i++) {
-    d[i] = inv[i] * det;
-  }
-
-  return this;
-};
-
-/**
- * Calculate the inverse matrix of this, and set to this.
- * @return this
- */
-Matrix4.prototype.invert = function() {
-  return this.setInverseOf(this);
-};
-
-/**
- * Set the orthographic projection matrix.
- * @param left The coordinate of the left of clipping plane.
- * @param right The coordinate of the right of clipping plane.
- * @param bottom The coordinate of the bottom of clipping plane.
- * @param top The coordinate of the top top clipping plane.
- * @param near The distances to the nearer depth clipping plane. This value is minus if the plane is to be behind the viewer.
- * @param far The distances to the farther depth clipping plane. This value is minus if the plane is to be behind the viewer.
- * @return this
- */
-Matrix4.prototype.setOrtho = function(left, right, bottom, top, near, far) {
-  var e, rw, rh, rd;
-
-  if (left === right || bottom === top || near === far) {
-    throw 'null frustum';
-  }
-
-  rw = 1 / (right - left);
-  rh = 1 / (top - bottom);
-  rd = 1 / (far - near);
-
-  e = this.elements;
-
-  e[0]  = 2 * rw;
-  e[1]  = 0;
-  e[2]  = 0;
-  e[3]  = 0;
-
-  e[4]  = 0;
-  e[5]  = 2 * rh;
-  e[6]  = 0;
-  e[7]  = 0;
-
-  e[8]  = 0;
-  e[9]  = 0;
-  e[10] = -2 * rd;
-  e[11] = 0;
-
-  e[12] = -(right + left) * rw;
-  e[13] = -(top + bottom) * rh;
-  e[14] = -(far + near) * rd;
-  e[15] = 1;
-
-  return this;
-};
-
-/**
- * Multiply the orthographic projection matrix from the right.
- * @param left The coordinate of the left of clipping plane.
- * @param right The coordinate of the right of clipping plane.
- * @param bottom The coordinate of the bottom of clipping plane.
- * @param top The coordinate of the top top clipping plane.
- * @param near The distances to the nearer depth clipping plane. This value is minus if the plane is to be behind the viewer.
- * @param far The distances to the farther depth clipping plane. This value is minus if the plane is to be behind the viewer.
- * @return this
- */
-Matrix4.prototype.ortho = function(left, right, bottom, top, near, far) {
-  return this.concat(new Matrix4().setOrtho(left, right, bottom, top, near, far));
-};
-
-/**
- * Set the perspective projection matrix.
- * @param left The coordinate of the left of clipping plane.
- * @param right The coordinate of the right of clipping plane.
- * @param bottom The coordinate of the bottom of clipping plane.
- * @param top The coordinate of the top top clipping plane.
- * @param near The distances to the nearer depth clipping plane. This value must be plus value.
- * @param far The distances to the farther depth clipping plane. This value must be plus value.
- * @return this
- */
-Matrix4.prototype.setFrustum = function(left, right, bottom, top, near, far) {
-  var e, rw, rh, rd;
-
-  if (left === right || top === bottom || near === far) {
-    throw 'null frustum';
-  }
-  if (near <= 0) {
-    throw 'near <= 0';
-  }
-  if (far <= 0) {
-    throw 'far <= 0';
-  }
-
-  rw = 1 / (right - left);
-  rh = 1 / (top - bottom);
-  rd = 1 / (far - near);
-
-  e = this.elements;
-
-  e[ 0] = 2 * near * rw;
-  e[ 1] = 0;
-  e[ 2] = 0;
-  e[ 3] = 0;
-
-  e[ 4] = 0;
-  e[ 5] = 2 * near * rh;
-  e[ 6] = 0;
-  e[ 7] = 0;
-
-  e[ 8] = (right + left) * rw;
-  e[ 9] = (top + bottom) * rh;
-  e[10] = -(far + near) * rd;
-  e[11] = -1;
-
-  e[12] = 0;
-  e[13] = 0;
-  e[14] = -2 * near * far * rd;
-  e[15] = 0;
-
-  return this;
-};
-
-/**
- * Multiply the perspective projection matrix from the right.
- * @param left The coordinate of the left of clipping plane.
- * @param right The coordinate of the right of clipping plane.
- * @param bottom The coordinate of the bottom of clipping plane.
- * @param top The coordinate of the top top clipping plane.
- * @param near The distances to the nearer depth clipping plane. This value must be plus value.
- * @param far The distances to the farther depth clipping plane. This value must be plus value.
- * @return this
- */
-Matrix4.prototype.frustum = function(left, right, bottom, top, near, far) {
-  return this.concat(new Matrix4().setFrustum(left, right, bottom, top, near, far));
-};
-
-/**
- * Set the perspective projection matrix by fovy and aspect.
- * @param fovy The angle between the upper and lower sides of the frustum.
- * @param aspect The aspect ratio of the frustum. (width/height)
- * @param near The distances to the nearer depth clipping plane. This value must be plus value.
- * @param far The distances to the farther depth clipping plane. This value must be plus value.
- * @return this
- */
-Matrix4.prototype.setPerspective = function(fovy, aspect, near, far) {
-  var e, rd, s, ct;
-
-  if (near === far || aspect === 0) {
-    throw 'null frustum';
-  }
-  if (near <= 0) {
-    throw 'near <= 0';
-  }
-  if (far <= 0) {
-    throw 'far <= 0';
-  }
-
-  fovy = Math.PI * fovy / 180 / 2;
-  s = Math.sin(fovy);
-  if (s === 0) {
-    throw 'null frustum';
-  }
-
-  rd = 1 / (far - near);
-  ct = Math.cos(fovy) / s;
-
-  e = this.elements;
-
-  e[0]  = ct / aspect;
-  e[1]  = 0;
-  e[2]  = 0;
-  e[3]  = 0;
-
-  e[4]  = 0;
-  e[5]  = ct;
-  e[6]  = 0;
-  e[7]  = 0;
-
-  e[8]  = 0;
-  e[9]  = 0;
-  e[10] = -(far + near) * rd;
-  e[11] = -1;
-
-  e[12] = 0;
-  e[13] = 0;
-  e[14] = -2 * near * far * rd;
-  e[15] = 0;
-
-  return this;
-};
-
-/**
- * Multiply the perspective projection matrix from the right.
- * @param fovy The angle between the upper and lower sides of the frustum.
- * @param aspect The aspect ratio of the frustum. (width/height)
- * @param near The distances to the nearer depth clipping plane. This value must be plus value.
- * @param far The distances to the farther depth clipping plane. This value must be plus value.
- * @return this
- */
-Matrix4.prototype.perspective = function(fovy, aspect, near, far) {
-  return this.concat(new Matrix4().setPerspective(fovy, aspect, near, far));
-};
-
-/**
- * Set the matrix for scaling.
- * @param x The scale factor along the X axis
- * @param y The scale factor along the Y axis
- * @param z The scale factor along the Z axis
- * @return this
- */
-Matrix4.prototype.setScale = function(x, y, z) {
-  var e = this.elements;
-  e[0] = x;  e[4] = 0;  e[8]  = 0;  e[12] = 0;
-  e[1] = 0;  e[5] = y;  e[9]  = 0;  e[13] = 0;
-  e[2] = 0;  e[6] = 0;  e[10] = z;  e[14] = 0;
-  e[3] = 0;  e[7] = 0;  e[11] = 0;  e[15] = 1;
-  return this;
-};
-
-/**
- * Multiply the matrix for scaling from the right.
- * @param x The scale factor along the X axis
- * @param y The scale factor along the Y axis
- * @param z The scale factor along the Z axis
- * @return this
- */
-Matrix4.prototype.scale = function(x, y, z) {
-  var e = this.elements;
-  e[0] *= x;  e[4] *= y;  e[8]  *= z;
-  e[1] *= x;  e[5] *= y;  e[9]  *= z;
-  e[2] *= x;  e[6] *= y;  e[10] *= z;
-  e[3] *= x;  e[7] *= y;  e[11] *= z;
-  return this;
-};
-
-/**
- * Set the matrix for translation.
- * @param x The X value of a translation.
- * @param y The Y value of a translation.
- * @param z The Z value of a translation.
- * @return this
- */
-Matrix4.prototype.setTranslate = function(x, y, z) {
-  var e = this.elements;
-  e[0] = 1;  e[4] = 0;  e[8]  = 0;  e[12] = x;
-  e[1] = 0;  e[5] = 1;  e[9]  = 0;  e[13] = y;
-  e[2] = 0;  e[6] = 0;  e[10] = 1;  e[14] = z;
-  e[3] = 0;  e[7] = 0;  e[11] = 0;  e[15] = 1;
-  return this;
-};
-
-/**
- * Multiply the matrix for translation from the right.
- * @param x The X value of a translation.
- * @param y The Y value of a translation.
- * @param z The Z value of a translation.
- * @return this
- */
-Matrix4.prototype.translate = function(x, y, z) {
-  var e = this.elements;
-  e[12] += e[0] * x + e[4] * y + e[8]  * z;
-  e[13] += e[1] * x + e[5] * y + e[9]  * z;
-  e[14] += e[2] * x + e[6] * y + e[10] * z;
-  e[15] += e[3] * x + e[7] * y + e[11] * z;
-  return this;
-};
-
-/**
- * Set the matrix for rotation.
- * The vector of rotation axis may not be normalized.
- * @param angle The angle of rotation (degrees)
- * @param x The X coordinate of vector of rotation axis.
- * @param y The Y coordinate of vector of rotation axis.
- * @param z The Z coordinate of vector of rotation axis.
- * @return this
- */
-Matrix4.prototype.setRotate = function(angle, x, y, z) {
-  var e, s, c, len, rlen, nc, xy, yz, zx, xs, ys, zs;
-
-  angle = Math.PI * angle / 180;
-  e = this.elements;
-
-  s = Math.sin(angle);
-  c = Math.cos(angle);
-
-  if (0 !== x && 0 === y && 0 === z) {
-    // Rotation around X axis
-    if (x < 0) {
-      s = -s;
-    }
-    e[0] = 1;  e[4] = 0;  e[ 8] = 0;  e[12] = 0;
-    e[1] = 0;  e[5] = c;  e[ 9] =-s;  e[13] = 0;
-    e[2] = 0;  e[6] = s;  e[10] = c;  e[14] = 0;
-    e[3] = 0;  e[7] = 0;  e[11] = 0;  e[15] = 1;
-  } else if (0 === x && 0 !== y && 0 === z) {
-    // Rotation around Y axis
-    if (y < 0) {
-      s = -s;
-    }
-    e[0] = c;  e[4] = 0;  e[ 8] = s;  e[12] = 0;
-    e[1] = 0;  e[5] = 1;  e[ 9] = 0;  e[13] = 0;
-    e[2] =-s;  e[6] = 0;  e[10] = c;  e[14] = 0;
-    e[3] = 0;  e[7] = 0;  e[11] = 0;  e[15] = 1;
-  } else if (0 === x && 0 === y && 0 !== z) {
-    // Rotation around Z axis
-    if (z < 0) {
-      s = -s;
-    }
-    e[0] = c;  e[4] =-s;  e[ 8] = 0;  e[12] = 0;
-    e[1] = s;  e[5] = c;  e[ 9] = 0;  e[13] = 0;
-    e[2] = 0;  e[6] = 0;  e[10] = 1;  e[14] = 0;
-    e[3] = 0;  e[7] = 0;  e[11] = 0;  e[15] = 1;
-  } else {
-    // Rotation around another axis
-    len = Math.sqrt(x*x + y*y + z*z);
-    if (len !== 1) {
-      rlen = 1 / len;
-      x *= rlen;
-      y *= rlen;
-      z *= rlen;
-    }
-    nc = 1 - c;
-    xy = x * y;
-    yz = y * z;
-    zx = z * x;
-    xs = x * s;
-    ys = y * s;
-    zs = z * s;
-
-    e[ 0] = x*x*nc +  c;
-    e[ 1] = xy *nc + zs;
-    e[ 2] = zx *nc - ys;
-    e[ 3] = 0;
-
-    e[ 4] = xy *nc - zs;
-    e[ 5] = y*y*nc +  c;
-    e[ 6] = yz *nc + xs;
-    e[ 7] = 0;
-
-    e[ 8] = zx *nc + ys;
-    e[ 9] = yz *nc - xs;
-    e[10] = z*z*nc +  c;
-    e[11] = 0;
-
-    e[12] = 0;
-    e[13] = 0;
-    e[14] = 0;
-    e[15] = 1;
-  }
-
-  return this;
-};
-
-/**
- * Multiply the matrix for rotation from the right.
- * The vector of rotation axis may not be normalized.
- * @param angle The angle of rotation (degrees)
- * @param x The X coordinate of vector of rotation axis.
- * @param y The Y coordinate of vector of rotation axis.
- * @param z The Z coordinate of vector of rotation axis.
- * @return this
- */
-Matrix4.prototype.rotate = function(angle, x, y, z) {
-  return this.concat(new Matrix4().setRotate(angle, x, y, z));
-};
-
-/**
- * Set the viewing matrix.
- * @param eyeX, eyeY, eyeZ The position of the eye point.
- * @param centerX, centerY, centerZ The position of the reference point.
- * @param upX, upY, upZ The direction of the up vector.
- * @return this
- */
-Matrix4.prototype.setLookAt = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) {
-  var e, fx, fy, fz, rlf, sx, sy, sz, rls, ux, uy, uz;
-
-  fx = centerX - eyeX;
-  fy = centerY - eyeY;
-  fz = centerZ - eyeZ;
-
-  // Normalize f.
-  rlf = 1 / Math.sqrt(fx*fx + fy*fy + fz*fz);
-  fx *= rlf;
-  fy *= rlf;
-  fz *= rlf;
-
-  // Calculate cross product of f and up.
-  sx = fy * upZ - fz * upY;
-  sy = fz * upX - fx * upZ;
-  sz = fx * upY - fy * upX;
-
-  // Normalize s.
-  rls = 1 / Math.sqrt(sx*sx + sy*sy + sz*sz);
-  sx *= rls;
-  sy *= rls;
-  sz *= rls;
-
-  // Calculate cross product of s and f.
-  ux = sy * fz - sz * fy;
-  uy = sz * fx - sx * fz;
-  uz = sx * fy - sy * fx;
-
-  // Set to this.
-  e = this.elements;
-  e[0] = sx;
-  e[1] = ux;
-  e[2] = -fx;
-  e[3] = 0;
-
-  e[4] = sy;
-  e[5] = uy;
-  e[6] = -fy;
-  e[7] = 0;
-
-  e[8] = sz;
-  e[9] = uz;
-  e[10] = -fz;
-  e[11] = 0;
-
-  e[12] = 0;
-  e[13] = 0;
-  e[14] = 0;
-  e[15] = 1;
-
-  // Translate.
-  return this.translate(-eyeX, -eyeY, -eyeZ);
-};
-
-/**
- * Multiply the viewing matrix from the right.
- * @param eyeX, eyeY, eyeZ The position of the eye point.
- * @param centerX, centerY, centerZ The position of the reference point.
- * @param upX, upY, upZ The direction of the up vector.
- * @return this
- */
-Matrix4.prototype.lookAt = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) {
-  return this.concat(new Matrix4().setLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ));
-};
-
-/**
- * Multiply the matrix for project vertex to plane from the right.
- * @param plane The array[A, B, C, D] of the equation of plane "Ax + By + Cz + D = 0".
- * @param light The array which stored coordinates of the light. if light[3]=0, treated as parallel light.
- * @return this
- */
-Matrix4.prototype.dropShadow = function(plane, light) {
-  var mat = new Matrix4();
-  var e = mat.elements;
-
-  var dot = plane[0] * light[0] + plane[1] * light[1] + plane[2] * light[2] + plane[3] * light[3];
-
-  e[ 0] = dot - light[0] * plane[0];
-  e[ 1] =     - light[1] * plane[0];
-  e[ 2] =     - light[2] * plane[0];
-  e[ 3] =     - light[3] * plane[0];
-
-  e[ 4] =     - light[0] * plane[1];
-  e[ 5] = dot - light[1] * plane[1];
-  e[ 6] =     - light[2] * plane[1];
-  e[ 7] =     - light[3] * plane[1];
-
-  e[ 8] =     - light[0] * plane[2];
-  e[ 9] =     - light[1] * plane[2];
-  e[10] = dot - light[2] * plane[2];
-  e[11] =     - light[3] * plane[2];
-
-  e[12] =     - light[0] * plane[3];
-  e[13] =     - light[1] * plane[3];
-  e[14] =     - light[2] * plane[3];
-  e[15] = dot - light[3] * plane[3];
-
-  return this.concat(mat);
-}
-
-/**
- * Multiply the matrix for project vertex to plane from the right.(Projected by parallel light.)
- * @param normX, normY, normZ The normal vector of the plane.(Not necessary to be normalized.)
- * @param planeX, planeY, planeZ The coordinate of arbitrary points on a plane.
- * @param lightX, lightY, lightZ The vector of the direction of light.(Not necessary to be normalized.)
- * @return this
- */
-Matrix4.prototype.dropShadowDirectionally = function(normX, normY, normZ, planeX, planeY, planeZ, lightX, lightY, lightZ) {
-  var a = planeX * normX + planeY * normY + planeZ * normZ;
-  return this.dropShadow([normX, normY, normZ, -a], [lightX, lightY, lightZ, 0]);
-};
-
-/**
- * Constructor of Vector3
- * If opt_src is specified, new vector is initialized by opt_src.
- * @param opt_src source vector(option)
- */
-var Vector3 = function(opt_src) {
-  var v = new Float32Array(3);
-  if (opt_src && typeof opt_src === 'object') {
-    v[0] = opt_src[0]; v[1] = opt_src[1]; v[2] = opt_src[2];
-  } 
-  this.elements = v;
-}
-
-/**
-  * Normalize.
-  * @return this
-  */
-Vector3.prototype.normalize = function() {
-  var v = this.elements;
-  var c = v[0], d = v[1], e = v[2], g = Math.sqrt(c*c+d*d+e*e);
-  if(g){
-    if(g == 1)
-        return this;
-   } else {
-     v[0] = 0; v[1] = 0; v[2] = 0;
-     return this;
-   }
-   g = 1/g;
-   v[0] = c*g; v[1] = d*g; v[2] = e*g;
-   return this;
-};
-
-/**
- * Constructor of Vector4
- * If opt_src is specified, new vector is initialized by opt_src.
- * @param opt_src source vector(option)
- */
-var Vector4 = function(opt_src) {
-  var v = new Float32Array(4);
-  if (opt_src && typeof opt_src === 'object') {
-    v[0] = opt_src[0]; v[1] = opt_src[1]; v[2] = opt_src[2]; v[3] = opt_src[3];
-  } 
-  this.elements = v;
-}
diff --git a/lab3Bis/lib/cuon-utils.js b/lab3Bis/lib/cuon-utils.js
deleted file mode 100644
index dc08b2ef1ee96304e68dafa7caed57f7e80894bb..0000000000000000000000000000000000000000
--- a/lab3Bis/lib/cuon-utils.js
+++ /dev/null
@@ -1,113 +0,0 @@
-// cuon-utils.js (c) 2012 kanda and matsuda
-/**
- * Create a program object and make current
- * @param gl GL context
- * @param vshader a vertex shader program (string)
- * @param fshader a fragment shader program (string)
- * @return true, if the program object was created and successfully made current 
- */
-function initShaders(gl, vshader, fshader) {
-  var program = createProgram(gl, vshader, fshader);
-  if (!program) {
-    console.log('Failed to create program');
-    return false;
-  }
-
-  gl.useProgram(program);
-  gl.program = program;
-
-  return true;
-}
-
-/**
- * Create the linked program object
- * @param gl GL context
- * @param vshader a vertex shader program (string)
- * @param fshader a fragment shader program (string)
- * @return created program object, or null if the creation has failed
- */
-function createProgram(gl, vshader, fshader) {
-  // Create shader object
-  var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
-  var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
-  if (!vertexShader || !fragmentShader) {
-    return null;
-  }
-
-  // Create a program object
-  var program = gl.createProgram();
-  if (!program) {
-    return null;
-  }
-
-  // Attach the shader objects
-  gl.attachShader(program, vertexShader);
-  gl.attachShader(program, fragmentShader);
-
-  // Link the program object
-  gl.linkProgram(program);
-
-  // Check the result of linking
-  var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
-  if (!linked) {
-    var error = gl.getProgramInfoLog(program);
-    console.log('Failed to link program: ' + error);
-    gl.deleteProgram(program);
-    gl.deleteShader(fragmentShader);
-    gl.deleteShader(vertexShader);
-    return null;
-  }
-  return program;
-}
-
-/**
- * Create a shader object
- * @param gl GL context
- * @param type the type of the shader object to be created
- * @param source shader program (string)
- * @return created shader object, or null if the creation has failed.
- */
-function loadShader(gl, type, source) {
-  // Create shader object
-  var shader = gl.createShader(type);
-  if (shader == null) {
-    console.log('unable to create shader');
-    return null;
-  }
-
-  // Set the shader program
-  gl.shaderSource(shader, source);
-
-  // Compile the shader
-  gl.compileShader(shader);
-
-  // Check the result of compilation
-  var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
-  if (!compiled) {
-    var error = gl.getShaderInfoLog(shader);
-    console.log('Failed to compile shader: ' + error);
-    gl.deleteShader(shader);
-    return null;
-  }
-
-  return shader;
-}
-
-/** 
- * Initialize and get the rendering for WebglInstance
- * @param canvas <cavnas> element
- * @param opt_debug flag to initialize the context for debugging
- * @return the rendering context for WebglInstance
- */
-function getWebGLContext(canvas, opt_debug) {
-  // Get the rendering context for WebglInstance
-  var gl = WebGLUtils.setupWebGL(canvas);
-  if (!gl) return null;
-
-  // if opt_debug is explicitly false, create the context for debugging
-  if (arguments.length < 2 || opt_debug) {
-    gl = WebGLDebugUtils.makeDebugContext(gl);
-  }
-
-  return gl;
-}
diff --git a/lab3Bis/lib/webgl-debug.js b/lab3Bis/lib/webgl-debug.js
deleted file mode 100644
index 685868dc61347ea10c0376520f1e20ed57a765c7..0000000000000000000000000000000000000000
--- a/lab3Bis/lib/webgl-debug.js
+++ /dev/null
@@ -1,677 +0,0 @@
-//Copyright (c) 2009 The Chromium Authors. All rights reserved.
-//Use of this source code is governed by a BSD-style license that can be
-//found in the LICENSE file.
-
-// Various functions for helping debug WebglInstance apps.
-
-WebGLDebugUtils = function() {
-
-/**
- * Wrapped logging function.
- * @param {string} msg Message to log.
- */
-var log = function(msg) {
-  if (window.console && window.console.log) {
-    window.console.log(msg);
-  }
-};
-
-/**
- * Which arguements are enums.
- * @type {!Object.<number, string>}
- */
-var glValidEnumContexts = {
-
-  // Generic setters and getters
-
-  'enable': { 0:true },
-  'disable': { 0:true },
-  'getParameter': { 0:true },
-
-  // Rendering
-
-  'drawArrays': { 0:true },
-  'drawElements': { 0:true, 2:true },
-
-  // Shaders
-
-  'createShader': { 0:true },
-  'getShaderParameter': { 1:true },
-  'getProgramParameter': { 1:true },
-
-  // Vertex attributes
-
-  'getVertexAttrib': { 1:true },
-  'vertexAttribPointer': { 2:true },
-
-  // Textures
-
-  'bindTexture': { 0:true },
-  'activeTexture': { 0:true },
-  'getTexParameter': { 0:true, 1:true },
-  'texParameterf': { 0:true, 1:true },
-  'texParameteri': { 0:true, 1:true, 2:true },
-  'texImage2D': { 0:true, 2:true, 6:true, 7:true },
-  'texSubImage2D': { 0:true, 6:true, 7:true },
-  'copyTexImage2D': { 0:true, 2:true },
-  'copyTexSubImage2D': { 0:true },
-  'generateMipmap': { 0:true },
-
-  // Buffer objects
-
-  'bindBuffer': { 0:true },
-  'bufferData': { 0:true, 2:true },
-  'bufferSubData': { 0:true },
-  'getBufferParameter': { 0:true, 1:true },
-
-  // Renderbuffers and framebuffers
-
-  'pixelStorei': { 0:true, 1:true },
-  'readPixels': { 4:true, 5:true },
-  'bindRenderbuffer': { 0:true },
-  'bindFramebuffer': { 0:true },
-  'checkFramebufferStatus': { 0:true },
-  'framebufferRenderbuffer': { 0:true, 1:true, 2:true },
-  'framebufferTexture2D': { 0:true, 1:true, 2:true },
-  'getFramebufferAttachmentParameter': { 0:true, 1:true, 2:true },
-  'getRenderbufferParameter': { 0:true, 1:true },
-  'renderbufferStorage': { 0:true, 1:true },
-
-  // Frame buffer operations (clear, blend, depth test, stencil)
-
-  'clear': { 0:true },
-  'depthFunc': { 0:true },
-  'blendFunc': { 0:true, 1:true },
-  'blendFuncSeparate': { 0:true, 1:true, 2:true, 3:true },
-  'blendEquation': { 0:true },
-  'blendEquationSeparate': { 0:true, 1:true },
-  'stencilFunc': { 0:true },
-  'stencilFuncSeparate': { 0:true, 1:true },
-  'stencilMaskSeparate': { 0:true },
-  'stencilOp': { 0:true, 1:true, 2:true },
-  'stencilOpSeparate': { 0:true, 1:true, 2:true, 3:true },
-
-  // Culling
-
-  'cullFace': { 0:true },
-  'frontFace': { 0:true },
-};
-
-/**
- * Map of numbers to names.
- * @type {Object}
- */
-var glEnums = null;
-
-/**
- * Initializes this module. Safe to call more than once.
- * @param {!WebGLRenderingContext} ctx A WebglInstance context. If
- *    you have more than one context it doesn't matter which one
- *    you pass in, it is only used to pull out constants.
- */
-function init(ctx) {
-  if (glEnums == null) {
-    glEnums = { };
-    for (var propertyName in ctx) {
-      if (typeof ctx[propertyName] == 'number') {
-        glEnums[ctx[propertyName]] = propertyName;
-      }
-    }
-  }
-}
-
-/**
- * Checks the utils have been initialized.
- */
-function checkInit() {
-  if (glEnums == null) {
-    throw 'WebGLDebugUtils.init(ctx) not called';
-  }
-}
-
-/**
- * Returns true or false if value matches any WebglInstance enum
- * @param {*} value Value to check if it might be an enum.
- * @return {boolean} True if value matches one of the WebglInstance defined enums
- */
-function mightBeEnum(value) {
-  checkInit();
-  return (glEnums[value] !== undefined);
-}
-
-/**
- * Gets an string version of an WebglInstance enum.
- *
- * Example:
- *   var str = WebGLDebugUtil.glEnumToString(ctx.getError());
- *
- * @param {number} value Value to return an enum for
- * @return {string} The string version of the enum.
- */
-function glEnumToString(value) {
-  checkInit();
-  var name = glEnums[value];
-  return (name !== undefined) ? name :
-      ("*UNKNOWN WebglInstance ENUM (0x" + value.toString(16) + ")");
-}
-
-/**
- * Returns the string version of a WebglInstance argument.
- * Attempts to convert enum arguments to strings.
- * @param {string} functionName the name of the WebglInstance function.
- * @param {number} argumentIndx the index of the argument.
- * @param {*} value The value of the argument.
- * @return {string} The value as a string.
- */
-function glFunctionArgToString(functionName, argumentIndex, value) {
-  var funcInfo = glValidEnumContexts[functionName];
-  if (funcInfo !== undefined) {
-    if (funcInfo[argumentIndex]) {
-      return glEnumToString(value);
-    }
-  }
-  return value.toString();
-}
-
-/**
- * Given a WebglInstance context returns a wrapped context that calls
- * gl.getError after every command and calls a function if the
- * result is not gl.NO_ERROR.
- *
- * @param {!WebGLRenderingContext} ctx The webgl context to
- *        wrap.
- * @param {!function(err, funcName, args): void} opt_onErrorFunc
- *        The function to call when gl.getError returns an
- *        error. If not specified the default function calls
- *        console.log with a message.
- */
-function makeDebugContext(ctx, opt_onErrorFunc) {
-  init(ctx);
-  opt_onErrorFunc = opt_onErrorFunc || function(err, functionName, args) {
-        // apparently we can't do args.join(",");
-        var argStr = "";
-        for (var ii = 0; ii < args.length; ++ii) {
-          argStr += ((ii == 0) ? '' : ', ') +
-              glFunctionArgToString(functionName, ii, args[ii]);
-        }
-        log("WebglInstance error "+ glEnumToString(err) + " in "+ functionName +
-            "(" + argStr + ")");
-      };
-
-  // Holds booleans for each GL error so after we get the error ourselves
-  // we can still return it to the client app.
-  var glErrorShadow = { };
-
-  // Makes a function that calls a WebglInstance function and then calls getError.
-  function makeErrorWrapper(ctx, functionName) {
-    return function() {
-      var result = ctx[functionName].apply(ctx, arguments);
-      var err = ctx.getError();
-      if (err != 0) {
-        glErrorShadow[err] = true;
-        opt_onErrorFunc(err, functionName, arguments);
-      }
-      return result;
-    };
-  }
-
-  // Make a an object that has a copy of every property of the WebglInstance context
-  // but wraps all functions.
-  var wrapper = {};
-  for (var propertyName in ctx) {
-    if (typeof ctx[propertyName] == 'function') {
-       wrapper[propertyName] = makeErrorWrapper(ctx, propertyName);
-     } else {
-       wrapper[propertyName] = ctx[propertyName];
-     }
-  }
-
-  // Override the getError function with one that returns our saved results.
-  wrapper.getError = function() {
-    for (var err in glErrorShadow) {
-      if (glErrorShadow[err]) {
-        glErrorShadow[err] = false;
-        return err;
-      }
-    }
-    return ctx.NO_ERROR;
-  };
-
-  return wrapper;
-}
-
-function resetToInitialState(ctx) {
-  var numAttribs = ctx.getParameter(ctx.MAX_VERTEX_ATTRIBS);
-  var tmp = ctx.createBuffer();
-  ctx.bindBuffer(ctx.ARRAY_BUFFER, tmp);
-  for (var ii = 0; ii < numAttribs; ++ii) {
-    ctx.disableVertexAttribArray(ii);
-    ctx.vertexAttribPointer(ii, 4, ctx.FLOAT, false, 0, 0);
-    ctx.vertexAttrib1f(ii, 0);
-  }
-  ctx.deleteBuffer(tmp);
-
-  var numTextureUnits = ctx.getParameter(ctx.MAX_TEXTURE_IMAGE_UNITS);
-  for (var ii = 0; ii < numTextureUnits; ++ii) {
-    ctx.activeTexture(ctx.TEXTURE0 + ii);
-    ctx.bindTexture(ctx.TEXTURE_CUBE_MAP, null);
-    ctx.bindTexture(ctx.TEXTURE_2D, null);
-  }
-
-  ctx.activeTexture(ctx.TEXTURE0);
-  ctx.useProgram(null);
-  ctx.bindBuffer(ctx.ARRAY_BUFFER, null);
-  ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null);
-  ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
-  ctx.bindRenderbuffer(ctx.RENDERBUFFER, null);
-  ctx.disable(ctx.BLEND);
-  ctx.disable(ctx.CULL_FACE);
-  ctx.disable(ctx.DEPTH_TEST);
-  ctx.disable(ctx.DITHER);
-  ctx.disable(ctx.SCISSOR_TEST);
-  ctx.blendColor(0, 0, 0, 0);
-  ctx.blendEquation(ctx.FUNC_ADD);
-  ctx.blendFunc(ctx.ONE, ctx.ZERO);
-  ctx.clearColor(0, 0, 0, 0);
-  ctx.clearDepth(1);
-  ctx.clearStencil(-1);
-  ctx.colorMask(true, true, true, true);
-  ctx.cullFace(ctx.BACK);
-  ctx.depthFunc(ctx.LESS);
-  ctx.depthMask(true);
-  ctx.depthRange(0, 1);
-  ctx.frontFace(ctx.CCW);
-  ctx.hint(ctx.GENERATE_MIPMAP_HINT, ctx.DONT_CARE);
-  ctx.lineWidth(1);
-  ctx.pixelStorei(ctx.PACK_ALIGNMENT, 4);
-  ctx.pixelStorei(ctx.UNPACK_ALIGNMENT, 4);
-  ctx.pixelStorei(ctx.UNPACK_FLIP_Y_WEBGL, false);
-  ctx.pixelStorei(ctx.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
-  // TODO: Delete this IF.
-  if (ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL) {
-    ctx.pixelStorei(ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL, ctx.BROWSER_DEFAULT_WEBGL);
-  }
-  ctx.polygonOffset(0, 0);
-  ctx.sampleCoverage(1, false);
-  ctx.scissor(0, 0, ctx.canvas.width, ctx.canvas.height);
-  ctx.stencilFunc(ctx.ALWAYS, 0, 0xFFFFFFFF);
-  ctx.stencilMask(0xFFFFFFFF);
-  ctx.stencilOp(ctx.KEEP, ctx.KEEP, ctx.KEEP);
-  ctx.viewport(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
-  ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT);
-
-  // TODO: This should NOT be needed but Firefox fails with 'hint'
-  while(ctx.getError());
-}
-
-function makeLostContextSimulatingContext(ctx) {
-  var wrapper_ = {};
-  var contextId_ = 1;
-  var contextLost_ = false;
-  var resourceId_ = 0;
-  var resourceDb_ = [];
-  var onLost_ = undefined;
-  var onRestored_ = undefined;
-  var nextOnRestored_ = undefined;
-
-  // Holds booleans for each GL error so can simulate errors.
-  var glErrorShadow_ = { };
-
-  function isWebGLObject(obj) {
-    //return false;
-    return (obj instanceof WebGLBuffer ||
-            obj instanceof WebGLFramebuffer ||
-            obj instanceof WebGLProgram ||
-            obj instanceof WebGLRenderbuffer ||
-            obj instanceof WebGLShader ||
-            obj instanceof WebGLTexture);
-  }
-
-  function checkResources(args) {
-    for (var ii = 0; ii < args.length; ++ii) {
-      var arg = args[ii];
-      if (isWebGLObject(arg)) {
-        return arg.__webglDebugContextLostId__ == contextId_;
-      }
-    }
-    return true;
-  }
-
-  function clearErrors() {
-    var k = Object.keys(glErrorShadow_);
-    for (var ii = 0; ii < k.length; ++ii) {
-      delete glErrorShdow_[k];
-    }
-  }
-
-  // Makes a function that simulates WebglInstance when out of context.
-  function makeLostContextWrapper(ctx, functionName) {
-    var f = ctx[functionName];
-    return function() {
-      // Only call the functions if the context is not lost.
-      if (!contextLost_) {
-        if (!checkResources(arguments)) {
-          glErrorShadow_[ctx.INVALID_OPERATION] = true;
-          return;
-        }
-        var result = f.apply(ctx, arguments);
-        return result;
-      }
-    };
-  }
-
-  for (var propertyName in ctx) {
-    if (typeof ctx[propertyName] == 'function') {
-       wrapper_[propertyName] = makeLostContextWrapper(ctx, propertyName);
-     } else {
-       wrapper_[propertyName] = ctx[propertyName];
-     }
-  }
-
-  function makeWebGLContextEvent(statusMessage) {
-    return {statusMessage: statusMessage};
-  }
-
-  function freeResources() {
-    for (var ii = 0; ii < resourceDb_.length; ++ii) {
-      var resource = resourceDb_[ii];
-      if (resource instanceof WebGLBuffer) {
-        ctx.deleteBuffer(resource);
-      } else if (resource instanceof WebctxFramebuffer) {
-        ctx.deleteFramebuffer(resource);
-      } else if (resource instanceof WebctxProgram) {
-        ctx.deleteProgram(resource);
-      } else if (resource instanceof WebctxRenderbuffer) {
-        ctx.deleteRenderbuffer(resource);
-      } else if (resource instanceof WebctxShader) {
-        ctx.deleteShader(resource);
-      } else if (resource instanceof WebctxTexture) {
-        ctx.deleteTexture(resource);
-      }
-    }
-  }
-
-  wrapper_.loseContext = function() {
-    if (!contextLost_) {
-      contextLost_ = true;
-      ++contextId_;
-      while (ctx.getError());
-      clearErrors();
-      glErrorShadow_[ctx.CONTEXT_LOST_WEBGL] = true;
-      setTimeout(function() {
-          if (onLost_) {
-            onLost_(makeWebGLContextEvent("context lost"));
-          }
-        }, 0);
-    }
-  };
-
-  wrapper_.restoreContext = function() {
-    if (contextLost_) {
-      if (onRestored_) {
-        setTimeout(function() {
-            freeResources();
-            resetToInitialState(ctx);
-            contextLost_ = false;
-            if (onRestored_) {
-              var callback = onRestored_;
-              onRestored_ = nextOnRestored_;
-              nextOnRestored_ = undefined;
-              callback(makeWebGLContextEvent("context restored"));
-            }
-          }, 0);
-      } else {
-        throw "You can not restore the context without a listener"
-      }
-    }
-  };
-
-  // Wrap a few functions specially.
-  wrapper_.getError = function() {
-    if (!contextLost_) {
-      var err;
-      while (err = ctx.getError()) {
-        glErrorShadow_[err] = true;
-      }
-    }
-    for (var err in glErrorShadow_) {
-      if (glErrorShadow_[err]) {
-        delete glErrorShadow_[err];
-        return err;
-      }
-    }
-    return ctx.NO_ERROR;
-  };
-
-  var creationFunctions = [
-    "createBuffer",
-    "createFramebuffer",
-    "createProgram",
-    "createRenderbuffer",
-    "createShader",
-    "createTexture"
-  ];
-  for (var ii = 0; ii < creationFunctions.length; ++ii) {
-    var functionName = creationFunctions[ii];
-    wrapper_[functionName] = function(f) {
-      return function() {
-        if (contextLost_) {
-          return null;
-        }
-        var obj = f.apply(ctx, arguments);
-        obj.__webglDebugContextLostId__ = contextId_;
-        resourceDb_.push(obj);
-        return obj;
-      };
-    }(ctx[functionName]);
-  }
-
-  var functionsThatShouldReturnNull = [
-    "getActiveAttrib",
-    "getActiveUniform",
-    "getBufferParameter",
-    "getContextAttributes",
-    "getAttachedShaders",
-    "getFramebufferAttachmentParameter",
-    "getParameter",
-    "getProgramParameter",
-    "getProgramInfoLog",
-    "getRenderbufferParameter",
-    "getShaderParameter",
-    "getShaderInfoLog",
-    "getShaderSource",
-    "getTexParameter",
-    "getUniform",
-    "getUniformLocation",
-    "getVertexAttrib"
-  ];
-  for (var ii = 0; ii < functionsThatShouldReturnNull.length; ++ii) {
-    var functionName = functionsThatShouldReturnNull[ii];
-    wrapper_[functionName] = function(f) {
-      return function() {
-        if (contextLost_) {
-          return null;
-        }
-        return f.apply(ctx, arguments);
-      }
-    }(wrapper_[functionName]);
-  }
-
-  var isFunctions = [
-    "isBuffer",
-    "isEnabled",
-    "isFramebuffer",
-    "isProgram",
-    "isRenderbuffer",
-    "isShader",
-    "isTexture"
-  ];
-  for (var ii = 0; ii < isFunctions.length; ++ii) {
-    var functionName = isFunctions[ii];
-    wrapper_[functionName] = function(f) {
-      return function() {
-        if (contextLost_) {
-          return false;
-        }
-        return f.apply(ctx, arguments);
-      }
-    }(wrapper_[functionName]);
-  }
-
-  wrapper_.checkFramebufferStatus = function(f) {
-    return function() {
-      if (contextLost_) {
-        return ctx.FRAMEBUFFER_UNSUPPORTED;
-      }
-      return f.apply(ctx, arguments);
-    };
-  }(wrapper_.checkFramebufferStatus);
-
-  wrapper_.getAttribLocation = function(f) {
-    return function() {
-      if (contextLost_) {
-        return -1;
-      }
-      return f.apply(ctx, arguments);
-    };
-  }(wrapper_.getAttribLocation);
-
-  wrapper_.getVertexAttribOffset = function(f) {
-    return function() {
-      if (contextLost_) {
-        return 0;
-      }
-      return f.apply(ctx, arguments);
-    };
-  }(wrapper_.getVertexAttribOffset);
-
-  wrapper_.isContextLost = function() {
-    return contextLost_;
-  };
-
-  function wrapEvent(listener) {
-    if (typeof(listener) == "function") {
-      return listener;
-    } else {
-      return function(info) {
-        listener.handleEvent(info);
-      }
-    }
-  }
-
-  wrapper_.registerOnContextLostListener = function(listener) {
-    onLost_ = wrapEvent(listener);
-  };
-
-  wrapper_.registerOnContextRestoredListener = function(listener) {
-    if (contextLost_) {
-      nextOnRestored_ = wrapEvent(listener);
-    } else {
-      onRestored_ = wrapEvent(listener);
-    }
-  }
-
-  return wrapper_;
-}
-
-return {
-  /**
-   * Initializes this module. Safe to call more than once.
-   * @param {!WebGLRenderingContext} ctx A WebglInstance context. If
-   *    you have more than one context it doesn't matter which one
-   *    you pass in, it is only used to pull out constants.
-   */
-  'init': init,
-
-  /**
-   * Returns true or false if value matches any WebglInstance enum
-   * @param {*} value Value to check if it might be an enum.
-   * @return {boolean} True if value matches one of the WebglInstance defined enums
-   */
-  'mightBeEnum': mightBeEnum,
-
-  /**
-   * Gets an string version of an WebglInstance enum.
-   *
-   * Example:
-   *   WebGLDebugUtil.init(ctx);
-   *   var str = WebGLDebugUtil.glEnumToString(ctx.getError());
-   *
-   * @param {number} value Value to return an enum for
-   * @return {string} The string version of the enum.
-   */
-  'glEnumToString': glEnumToString,
-
-  /**
-   * Converts the argument of a WebglInstance function to a string.
-   * Attempts to convert enum arguments to strings.
-   *
-   * Example:
-   *   WebGLDebugUtil.init(ctx);
-   *   var str = WebGLDebugUtil.glFunctionArgToString('bindTexture', 0, gl.TEXTURE_2D);
-   *
-   * would return 'TEXTURE_2D'
-   *
-   * @param {string} functionName the name of the WebglInstance function.
-   * @param {number} argumentIndx the index of the argument.
-   * @param {*} value The value of the argument.
-   * @return {string} The value as a string.
-   */
-  'glFunctionArgToString': glFunctionArgToString,
-
-  /**
-   * Given a WebglInstance context returns a wrapped context that calls
-   * gl.getError after every command and calls a function if the
-   * result is not NO_ERROR.
-   *
-   * You can supply your own function if you want. For example, if you'd like
-   * an exception thrown on any GL error you could do this
-   *
-   *    function throwOnGLError(err, funcName, args) {
-   *      throw WebGLDebugUtils.glEnumToString(err) + " was caused by call to" +
-   *            funcName;
-   *    };
-   *
-   *    ctx = WebGLDebugUtils.makeDebugContext(
-   *        canvas.getContext("webgl"), throwOnGLError);
-   *
-   * @param {!WebGLRenderingContext} ctx The webgl context to wrap.
-   * @param {!function(err, funcName, args): void} opt_onErrorFunc The function
-   *     to call when gl.getError returns an error. If not specified the default
-   *     function calls console.log with a message.
-   */
-  'makeDebugContext': makeDebugContext,
-
-  /**
-   * Given a WebglInstance context returns a wrapped context that adds 4
-   * functions.
-   *
-   * ctx.loseContext:
-   *   simulates a lost context event.
-   *
-   * ctx.restoreContext:
-   *   simulates the context being restored.
-   *
-   * ctx.registerOnContextLostListener(listener):
-   *   lets you register a listener for context lost. Use instead
-   *   of addEventListener('webglcontextlostevent', listener);
-   *
-   * ctx.registerOnContextRestoredListener(listener):
-   *   lets you register a listener for context restored. Use
-   *   instead of addEventListener('webglcontextrestored',
-   *   listener);
-   *
-   * @param {!WebGLRenderingContext} ctx The webgl context to wrap.
-   */
-  'makeLostContextSimulatingContext': makeLostContextSimulatingContext,
-
-  /**
-   * Resets a context to the initial state.
-   * @param {!WebGLRenderingContext} ctx The webgl context to
-   *     reset.
-   */
-  'resetToInitialState': resetToInitialState
-};
-
-}();
-
diff --git a/lab3Bis/lib/webgl-utils.js b/lab3Bis/lib/webgl-utils.js
deleted file mode 100644
index 26ed37e0d6adf469edabfa17b0c9e3d00199e744..0000000000000000000000000000000000000000
--- a/lab3Bis/lib/webgl-utils.js
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 2010, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains functions every webgl program will need
- * a version of one way or another.
- *
- * Instead of setting up a context manually it is recommended to
- * use. This will check for success or failure. On failure it
- * will attempt to present an approriate message to the user.
- *
- *       gl = WebGLUtils.setupWebGL(canvas);
- *
- * For animated WebglInstance apps use of setTimeout or setInterval are
- * discouraged. It is recommended you structure your rendering
- * loop like this.
- *
- *       function render() {
- *         window.requestAnimationFrame(render, canvas);
- *
- *         // do rendering
- *         ...
- *       }
- *       render();
- *
- * This will call your rendering function up to the refresh rate
- * of your display but will stop rendering if your app is not
- * visible.
- */
-
-WebGLUtils = function() {
-
-/**
- * Creates the HTLM for a failure message
- * @param {string} canvasContainerId id of container of th
- *        canvas.
- * @return {string} The html.
- */
-var makeFailHTML = function(msg) {
-  return '' +
-        '<div style="margin: auto; width:500px;z-index:10000;margin-top:20em;text-align:center;">' + msg + '</div>';
-  return '' +
-    '<table style="background-color: #8CE; width: 100%; height: 100%;"><tr>' +
-    '<td align="center">' +
-    '<div style="display: table-cell; vertical-align: middle;">' +
-    '<div style="">' + msg + '</div>' +
-    '</div>' +
-    '</td></tr></table>';
-};
-
-/**
- * Mesasge for getting a webgl browser
- * @type {string}
- */
-var GET_A_WEBGL_BROWSER = '' +
-  'This page requires a browser that supports WebglInstance.<br/>' +
-  '<a href="http://get.webgl.org">Click here to upgrade your browser.</a>';
-
-/**
- * Mesasge for need better hardware
- * @type {string}
- */
-var OTHER_PROBLEM = '' +
-  "It doesn't appear your computer can support WebglInstance.<br/>" +
-  '<a href="http://get.webgl.org">Click here for more information.</a>';
-
-/**
- * Creates a webgl context. If creation fails it will
- * change the contents of the container of the <canvas>
- * tag to an error message with the correct links for WebglInstance.
- * @param {Element} canvas. The canvas element to create a
- *     context from.
- * @param {WebGLContextCreationAttirbutes} opt_attribs Any
- *     creation attributes you want to pass in.
- * @param {function:(msg)} opt_onError An function to call
- *     if there is an error during creation.
- * @return {WebGLRenderingContext} The created context.
- */
-var setupWebGL = function(canvas, opt_attribs, opt_onError) {
-  function handleCreationError(msg) {
-      var container = document.getElementsByTagName("body")[0];
-    //var container = canvas.parentNode;
-    if (container) {
-      var str = window.WebGLRenderingContext ?
-           OTHER_PROBLEM :
-           GET_A_WEBGL_BROWSER;
-      if (msg) {
-        str += "<br/><br/>Status: " + msg;
-      }
-      container.innerHTML = makeFailHTML(str);
-    }
-  };
-
-  opt_onError = opt_onError || handleCreationError;
-
-  if (canvas.addEventListener) {
-    canvas.addEventListener("webglcontextcreationerror", function(event) {
-          opt_onError(event.statusMessage);
-        }, false);
-  }
-  var context = create3DContext(canvas, opt_attribs);
-  if (!context) {
-    if (!window.WebGLRenderingContext) {
-      opt_onError("");
-    } else {
-      opt_onError("");
-    }
-  }
-
-  return context;
-};
-
-/**
- * Creates a webgl context.
- * @param {!Canvas} canvas The canvas tag to get context
- *     from. If one is not passed in one will be created.
- * @return {!WebGLContext} The created context.
- */
-var create3DContext = function(canvas, opt_attribs) {
-  var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
-  var context = null;
-  for (var ii = 0; ii < names.length; ++ii) {
-    try {
-      context = canvas.getContext(names[ii], opt_attribs);
-    } catch(e) {}
-    if (context) {
-      break;
-    }
-  }
-  return context;
-}
-
-return {
-  create3DContext: create3DContext,
-  setupWebGL: setupWebGL
-};
-}();
-
-/**
- * Provides requestAnimationFrame in a cross browser
- * way.
- */
-if (!window.requestAnimationFrame) {
-  window.requestAnimationFrame = (function() {
-    return window.requestAnimationFrame ||
-           window.webkitRequestAnimationFrame ||
-           window.mozRequestAnimationFrame ||
-           window.oRequestAnimationFrame ||
-           window.msRequestAnimationFrame ||
-           function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
-             window.setTimeout(callback, 1000/60);
-           };
-  })();
-}
-
-/** * ERRATA: 'cancelRequestAnimationFrame' renamed to 'cancelAnimationFrame' to reflect an update to the W3C Animation-Timing Spec. 
- * 
- * Cancels an animation frame request. 
- * Checks for cross-browser support, falls back to clearTimeout. 
- * @param {number}  Animation frame request. */
-if (!window.cancelAnimationFrame) {
-  window.cancelAnimationFrame = (window.cancelRequestAnimationFrame ||
-                                 window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame ||
-                                 window.mozCancelAnimationFrame || window.mozCancelRequestAnimationFrame ||
-                                 window.msCancelAnimationFrame || window.msCancelRequestAnimationFrame ||
-                                 window.oCancelAnimationFrame || window.oCancelRequestAnimationFrame ||
-                                 window.clearTimeout);
-}
\ No newline at end of file
diff --git a/lab3Bis/src/lab3.html b/lab3Bis/src/lab3.html
deleted file mode 100644
index 6acac41e3031de43f5500ec4ba996da025b74bff..0000000000000000000000000000000000000000
--- a/lab3Bis/src/lab3.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-
-<head>
-    <meta charset="UTF-8">
-    <title>point light</title>
-</head>
-
-<body onload="main()">
-    <canvas width="500" height="500" id="my-canvas">
-Please use a browser that supports "canvas"
-</canvas>
-    <script src="../lib/webgl-utils.js"></script>
-    <script src="../lib/webgl-debug.js"></script>
-    <script src="../lib/cuon-utils.js"></script>
-    <script src="../lib/cuon-matrix.js"></script>
-    <script src="lab3.js"></script>
-</body>
-
-</html>
\ No newline at end of file
diff --git a/lab3Bis/src/lab3.js b/lab3Bis/src/lab3.js
deleted file mode 100644
index 5b2bf83f630d61971f49ca96fad99b0440bd718b..0000000000000000000000000000000000000000
--- a/lab3Bis/src/lab3.js
+++ /dev/null
@@ -1,458 +0,0 @@
-//author : QUentin Berthet
-const VSHADER_SOURCE =
-    'attribute vec4 a_position;\n' +
-    'attribute vec4 a_Color;\n' +
-    'attribute vec3 a_normal;\n' +
-
-
-    'uniform vec3 u_lightWorldPosition;\n' +
-    'uniform vec3 u_viewWorldPosition;\n' +
-
-
-    'uniform mat4 u_world;\n' +
-    'uniform mat4 u_worldViewProjection;\n' +
-    'uniform mat4 u_worldInverseTranspose;\n' +
-
-    'varying vec3 v_normal;\n' +
-
-    'varying vec3 v_surfaceToLight;\n' +
-    'varying vec3 v_surfaceToView;\n' +
-
-    'void main() {\n' +
-    '  gl_Position = u_worldViewProjection * a_position ;\n' +
-    '  v_normal = mat3(u_worldInverseTranspose) * a_normal;\n' +
-    '  vec3 surfaceWorldPosition = (u_world * a_position).xyz;\n' +
-    '  v_surfaceToLight = u_lightWorldPosition - surfaceWorldPosition;\n' +
-    '  v_surfaceToView = u_viewWorldPosition - surfaceWorldPosition;\n' +
-    '}\n';
-
-
-const FSHADER_SOURCE =
-    'precision mediump float;\n' +
-    'varying vec3 v_normal;\n' +
-    'varying vec3 v_surfaceToLight;\n' +
-    'varying vec3 v_surfaceToView;\n' +
-    'uniform vec4 u_color;\n' +
-    'uniform float u_shininess;\n' +
-
-    'void main() {\n' +
-    '  vec3 normal = normalize(v_normal);\n' +
-    '  vec3 surfaceToLightDirection = normalize(v_surfaceToLight);\n' +
-    '  vec3 surfaceToViewDirection = normalize(v_surfaceToView);\n' +
-    '  vec3 halfVector = normalize(surfaceToLightDirection + surfaceToViewDirection);\n' +
-    '  float light = dot(normal, surfaceToLightDirection);\n' +
-    '  float specular = 0.0;\n' +
-    '  if (light > 0.0) {specular = pow(dot(normal, halfVector), u_shininess);}\n' +
-    '  gl_FragColor = u_color;\n' +
-    '  gl_FragColor.rgb *= light;\n' +
-    '  gl_FragColor.rgb += specular;\n' +
-    '}\n';
-
-
-
-function main() {
-
-    const canvas = document.getElementById('my-canvas');
-
-
-    const gl = getWebGLContext(canvas);
-    if (!gl) {
-        console.log('Failed to get the displaying context for WebGL');
-        return;
-    }
-
-
-    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
-        console.log('Failed to intialize shaders.');
-        return;
-    }
-
-    // look up where the vertex data needs to go.
-    var positionLocation = gl.getAttribLocation(gl.program, "a_position");
-    var normalLocation = gl.getAttribLocation(gl.program, "a_normal");
-
-    // lookup uniforms
-    var worldViewProjectionLocation = gl.getUniformLocation(gl.program, "u_worldViewProjection");
-    var worldInverseTransposeLocation = gl.getUniformLocation(gl.program, "u_worldInverseTranspose");
-    var colorLocation = gl.getUniformLocation(gl.program, "u_color");
-    var shininessLocation = gl.getUniformLocation(gl.program, "u_shininess");
-    var lightWorldPositionLocation =
-        gl.getUniformLocation(gl.program, "u_lightWorldPosition");
-    var viewWorldPositionLocation =
-        gl.getUniformLocation(gl.program, "u_viewWorldPosition");
-    var worldLocation =
-        gl.getUniformLocation(gl.program, "u_world");
-
-
-
-    // Create a buffer to put positions in    
-    var positionBuffer = gl.createBuffer();
-    // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
-    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
-    // Put geometry data into buffer    
-
-    const len = initVertexBuffers(gl);
-
-    if (len < 0) {
-        console.log('Failed to set the positions of the vertices');
-        return;
-    }
-
-    // Create a buffer to put normals in
-    var normalBuffer = gl.createBuffer();
-    // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = normalBuffer)
-    gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
-    // Put normals data into buffer
-
-
-    CreateNormals(gl);
-    var shininess = 150;
-
-    function updateShininess(event, ui) {
-        shininess = ui.value;
-        drawScene();
-    }
-
-
-
-
-    function drawScene() {
-
-        gl.clearColor(0.75, 0.85, 0.8, 1.0);
-        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-        gl.enable(gl.DEPTH_TEST);
-        gl.frontFace(gl.CCW);
-        gl.cullFace(gl.BACK);
-        // Turn on the position attribute
-
-        const projMatrix = new Matrix4();
-        projMatrix.setPerspective(45, gl.canvas.clientWidth / gl.canvas.clientHeight, 1, 100);
-
-        const cameraMatrix = new Matrix4();
-        let angle = 1;
-        let X = 5 * Math.cos(angle);
-        let Y = 0;
-        let Z = 5 * Math.sin(angle);
-
-        cameraMatrix.setLookAt(X, Y, Z, 0, 0, 0, 0, 1, 0);
-        const viewMatrix = new Matrix4(cameraMatrix);
-
-        const viewProjectionMatrix = new Matrix4(projMatrix).multiply(new Matrix4(viewMatrix));
-
-        const worldMatrix = new Matrix4();
-
-
-        const worldViewProjectionMatrix = new Matrix4(viewProjectionMatrix).multiply(worldMatrix);
-        const worldInverseMatrix = new Matrix4(worldMatrix).invert();
-        const worldInverseTransposeMatrix = new Matrix4(worldInverseMatrix).transpose();
-
-
-
-        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
-        gl.enableVertexAttribArray(positionLocation);
-        var size = 3; // 3 components per iteration
-        var type = gl.FLOAT; // the data is 32bit floats
-        var normalize = false; // don't normalize the data
-        var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
-        var offset = 0; // start at the beginning of the buffer
-        gl.vertexAttribPointer(positionLocation, size, type, normalize, stride, offset);
-
-
-
-
-
-        // Turn on the normal attribute
-        gl.enableVertexAttribArray(normalLocation);
-        // Bind the normal buffer.
-        gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
-        // Tell the attribute how to get data out of normalBuffer (ARRAY_BUFFER)
-        var size = 3; // 3 components per iteration
-        var type = gl.FLOAT; // the data is 32bit floating point values
-        var normalize = false; // normalize the data (convert from 0-255 to 0-1)
-        var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
-        var offset = 0; // start at the beginning of the buffer
-        gl.vertexAttribPointer(
-            normalLocation, size, type, normalize, stride, offset);
-
-
-        //Set the matrices
-        gl.uniformMatrix4fv(worldViewProjectionLocation, false, worldViewProjectionMatrix);
-        gl.uniformMatrix4fv(worldInverseTransposeLocation, false, worldInverseTransposeMatrix);
-        gl.uniformMatrix4fv(worldLocation, false, worldMatrix);
-        // Set the color to use
-        gl.uniform4fv(colorLocation, [0.2, 1, 0.2, 1]); // green
-        // set the light position
-        gl.uniform3fv(lightWorldPositionLocation, [20, 30, 60]);
-        // set the camera/view position
-        gl.uniform3fv(viewWorldPositionLocation, camera);
-        // set the shininess
-        gl.uniform1f(shininessLocation, shininess);
-
-
-
-
-
-
-        var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
-        if (a_Color < 0) {
-            console.log('Failed to get the storage location of a_Color');
-            return -1;
-        }
-
-        gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 24, 12);
-        gl.enableVertexAttribArray(a_Color);
-        gl.bindBuffer(gl.ARRAY_BUFFER, null);
-
-
-
-
-        var viewProjMatrix = new Matrix4();
-        viewProjMatrix.setPerspective(100.0, 1.0, 1.0, 1000.0);
-        viewProjMatrix.lookAt(1.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
-
-        var vals = [0.0, 0.0];
-        ObjectManager(vals);
-
-        var display = function() {
-            let count = 42;
-            // Don't render the upper surface because we duplicate frustum + surface
-            if (i === 1) {
-                count -= 6;
-            }
-            cameraMatrix.set(viewProjMatrix);
-            cameraMatrix.rotate(vals[0], 1.0, 0.0, 0.0);
-            cameraMatrix.rotate(vals[1], 0.0, 1.0, 0.0);
-            gl.uniformMatrix4fv(u_worldViewProjection, false, cameraMatrix.elements);
-
-
-            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-
-            gl.drawElements(gl.TRIANGLES, count, gl.UNSIGNED_SHORT, 0);
-
-            cameraMatrix.translate(0, 3.0, -4)
-            cameraMatrix.rotate(180, 1.0, 0.0, 0.0);
-            gl.uniformMatrix4fv(u_worldViewProjection, false, cameraMatrix.elements);
-
-            gl.drawElements(gl.TRIANGLES, count, gl.UNSIGNED_SHORT, 0);
-
-
-            requestAnimationFrame(display);
-        };
-        display();
-    }
-
-}
-
-function ObjectManager(values) {
-    document.onkeydown = (ev) => {
-        v = 10;
-        switch (ev.key) {
-            case 'ArrowDown':
-                values[0] += v;
-                break;
-            case 'ArrowUp':
-                values[0] -= v;
-                break;
-            case 'ArrowRight':
-                values[1] += v;
-                break;
-            case 'ArrowLeft':
-                values[1] -= v;
-                break;
-        }
-    };
-}
-
-
-
-function initVertexBuffers(gl) {
-
-    let vertices = new Float32Array([
-
-        // Front
-        -2, -1.5, 0, -1, 1.5, -1,
-        0, -1.5, 0,
-
-        -1, 1.5, -1,
-        0, -1.5, 0,
-        1, 1.5, -1,
-
-        0, -1.5, 0,
-        1, 1.5, -1,
-        2, -1.5, 0,
-
-        // Back
-        -2, -1.5, -4, -1, 1.5, -3,
-        0, -1.5, -4,
-
-        -1, 1.5, -3,
-        0, -1.5, -4,
-        1, 1.5, -3,
-
-        0, -1.5, -4,
-        1, 1.5, -3,
-        2, -1.5, -4,
-
-        // Left
-        -2, -1.5, -4, -1, 1.5, -3, -2, -1.5, -2,
-
-        -1, 1.5, -3, -2, -1.5, -2, -1, 1.5, -1,
-
-        -2, -1.5, -2, -1, 1.5, -1, -2, -1.5, 0,
-
-        // Right
-        2, -1.5, -4,
-        1, 1.5, -3,
-        2, -1.5, -2,
-
-        1, 1.5, -3,
-        2, -1.5, -2,
-        1, 1.5, -1,
-
-        2, -1.5, -2,
-        1, 1.5, -1,
-        2, -1.5, -0,
-
-        // top
-        -1, 1.5, -1, -1, 1.5, -3,
-        0, 1.5, -1,
-
-        -1, 1.5, -3,
-        0, 1.5, -1,
-        1, 1.5, -3,
-
-        0, 1.5, -1,
-        1, 1.5, -3,
-        1, 1.5, -1,
-
-        // ground
-        -2, -1.5, 0, -2, -1.5, -4,
-        0, -1.5, 0,
-
-        -2, -1.5, -4,
-        0, -1.5, 0,
-        2, -1.5, -4,
-
-        0, -1.5, 0,
-        2, -1.5, -4,
-        2, -1.5, 0,
-
-
-    ]);
-
-    const len = vertices.length / 6;
-    const vertexBuffer = gl.createBuffer();
-    if (!vertexBuffer) {
-        console.log('Failed to create the buffer object');
-        return -1;
-    }
-
-    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
-    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
-
-    return len;
-}
-
-function normalizedCrossWith3Points(a0, a1, a2, b0, b1, b2, c0, c1, c2) {
-    const u = [b0 - a0, b1 - a1, b2 - a2];
-    const v = [c0 - a0, c1 - a1, c2 - a2];
-    const rawNormal = [
-        u[1] * v[2] - u[2] * v[1],
-        u[2] * v[0] - u[0] * v[2],
-        u[0] * v[1] - u[1] * v[0]
-    ];
-    const norm = Math.hypot(...rawNormal);
-    return rawNormal.map((n) => n / norm);
-}
-
-const Normal_f = normalizedCrossWith3Points(-1, 1.5, -1,
-    0, -1.5, 0,
-    1, 1.5, -1
-
-);
-const Normal_b = normalizedCrossWith3Points(-1, 1.5, -3,
-    0, -1.5, -4,
-    1, 1.5, -3
-);
-const Normal_t = normalizedCrossWith3Points(-1, 1.5, -3,
-    0, 1.5, -1,
-    1, 1.5, -3
-);
-const Normal_g = normalizedCrossWith3Points(-2, -1.5, -4,
-    0, -1.5, 0,
-    2, -1.5, -4
-);
-const Normal_r = normalizedCrossWith3Points(
-    1, 1.5, -3,
-    2, -1.5, -2,
-    1, 1.5, -1
-);
-
-const leftNormal = normalizedCrossWith3Points(-1, 1.5, -3, -2, -1.5, -2, -1, 1.5, -1);
-
-
-
-function CreateNormals(gl, bottomNormal) {
-    var vertexNormals = new Float32Array(
-        [ //front
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-
-            // back
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-            0, 0, -1,
-
-
-            // left
-            -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0,
-
-            // right
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-
-            // top
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-
-            // ground
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-            0, -1, 0,
-
-        ]);
-    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW);
-}
\ No newline at end of file
diff --git a/lab4/README.md b/lab4/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ec24bbc47e6fb90dff16892e6da9e36d3cedc96f
--- /dev/null
+++ b/lab4/README.md
@@ -0,0 +1,6 @@
+# Lab4 IHM
+
+* **docs**: contains the lab's statement
+* **libs**: contains WebGL libraries and utilities
+* **src**: contains the source code of the lab4 that you should complete (`main()` function in **lab4.js** file)
+* **DO NOT CHANGE** the name of the file `lab4.html`, however, you are free to change its content.
diff --git a/lab4/docs/Cours 3D Labo 4.pdf b/lab4/docs/Cours 3D Labo 4.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..e639f4bfba3ee962e43ab8c26c7d1e2e56830580
Binary files /dev/null and b/lab4/docs/Cours 3D Labo 4.pdf differ
diff --git a/lab3.0/lib/cuon-utils.js b/lab4/lib/cuon-utils.js
similarity index 100%
rename from lab3.0/lib/cuon-utils.js
rename to lab4/lib/cuon-utils.js
diff --git a/lab3.0/lib/webgl-debug.js b/lab4/lib/webgl-debug.js
similarity index 100%
rename from lab3.0/lib/webgl-debug.js
rename to lab4/lib/webgl-debug.js
diff --git a/lab3.0/lib/webgl-utils.js b/lab4/lib/webgl-utils.js
similarity index 100%
rename from lab3.0/lib/webgl-utils.js
rename to lab4/lib/webgl-utils.js
diff --git a/lab4/src/lab4.html b/lab4/src/lab4.html
new file mode 100644
index 0000000000000000000000000000000000000000..2bb37bcbd21a70f6bb9acddb83953d93aa5bf516
--- /dev/null
+++ b/lab4/src/lab4.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>Lab 4</title>
+</head>
+<body onload="main()">
+<canvas width="400" height="600" id="my-canvas">
+  Please use a browser that supports "canvas"
+</canvas>
+<script src="../lib/webgl-utils.js"></script>
+<script src="../lib/webgl-debug.js"></script>
+<script src="../lib/cuon-utils.js"></script>
+<script src="lab4.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/lab4/src/lab4.js b/lab4/src/lab4.js
new file mode 100644
index 0000000000000000000000000000000000000000..105a227db9e7e4d4abde40b5002e7c75eb860fb4
--- /dev/null
+++ b/lab4/src/lab4.js
@@ -0,0 +1,18 @@
+// Vertex shader program
+const VSHADER_SOURCE =
+  '\n' +
+  // TODO: Implement your vertex shader code here
+  '\n';
+
+// Fragment shader program
+const FSHADER_SOURCE =
+  '\n' +
+  // TODO: Implement your fragment shader code here
+  '\n';
+
+function main() {
+  // Retrieve <canvas> element
+  const canvas = document.getElementById('my-canvas');
+
+  // TODO: Complete with your code here
+}
\ No newline at end of file