Search code examples
javascriptopengl-estextureswebgl

How to use multiple textures on a cube in WebGL?


This is my source code. It still doesnt work. I want to put 6 different pictures on the 6 sides of a cube, which is animated. Please help :)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
<title>WebGL</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">


<script type="text/javascript" src="glMatrix-0.9.5.min.js"></script>

<script type="text/javascript" src="webgl-utils.js"></script>

<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;

varying vec2 vTextureCoord;

uniform sampler2D uSampler;

void main(void) {
    gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
}
</script>

<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;

varying vec2 vTextureCoord;


void main(void) {
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    vTextureCoord = aTextureCoord;
}
</script>


<script type="text/javascript">

var gl;

function initGL(canvas) {
    try {
        gl = canvas.getContext("experimental-webgl");
        gl.viewportWidth = canvas.width;
        gl.viewportHeight = canvas.height;
    } catch (e) {
    }
    if (!gl) {
        alert("Could not initialise WebGL, sorry :-(");
    }
}


function getShader(gl, id) {
    var shaderScript = document.getElementById(id);
    if (!shaderScript) {
        return null;
    }

    var str = "";
    var k = shaderScript.firstChild;
    while (k) {
        if (k.nodeType == 3) {
            str += k.textContent;
        }
        k = k.nextSibling;
    }

    var shader;
    if (shaderScript.type == "x-shader/x-fragment") {
        shader = gl.createShader(gl.FRAGMENT_SHADER);
    } else if (shaderScript.type == "x-shader/x-vertex") {
        shader = gl.createShader(gl.VERTEX_SHADER);
    } else {
        return null;
    }

    gl.shaderSource(shader, str);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(shader));
        return null;
    }

    return shader;
}


var shaderProgram;

function initShaders() {
    var fragmentShader = getShader(gl, "shader-fs");
    var vertexShader = getShader(gl, "shader-vs");

    shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);

    if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
        alert("Could not initialise shaders");
    }

    gl.useProgram(shaderProgram);

    shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
    gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

    shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
    gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);

    shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
    shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
    shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
}


var texturen = new Array();
function initTexture(sFilename,texturen)  
{
  var anz = texturen.length;
  texturen[anz] = gl.createTexture();
  texturen[anz].image = new Image();
  texturen[anz].image.onload = function()    
  {
  gl.bindTexture(gl.TEXTURE_2D, texturen[anz]);
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
  gl.texImage2D
  (gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texturen[anz].image);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  gl.bindTexture(gl.TEXTURE_2D, null);
  }
  texturen[anz].image.src = sFilename;
} 


var mvMatrix = mat4.create();
var mvMatrixStack = [];
var pMatrix = mat4.create();

function mvPushMatrix() {
    var copy = mat4.create();
    mat4.set(mvMatrix, copy);
    mvMatrixStack.push(copy);
}

function mvPopMatrix() {
    if (mvMatrixStack.length == 0) {
        throw "Invalid popMatrix!";
    }
    mvMatrix = mvMatrixStack.pop();
}


function setMatrixUniforms() {
    gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
    gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
}


function degToRad(degrees) {
    return degrees * Math.PI / 180;
}

function initBuffers() {
    var vertBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
    var vertices = [
        // Front face
        -1.0, -1.0,  1.0,
         1.0, -1.0,  1.0,
         1.0,  1.0,  1.0,
        -1.0,  1.0,  1.0,

        // Back face
        -1.0, -1.0, -1.0,
        -1.0,  1.0, -1.0,
         1.0,  1.0, -1.0,
         1.0, -1.0, -1.0,

        // Top face
        -1.0,  1.0, -1.0,
        -1.0,  1.0,  1.0,
         1.0,  1.0,  1.0,
         1.0,  1.0, -1.0,

       // Bottom face
        -1.0, -1.0, -1.0,
         1.0, -1.0, -1.0,
         1.0, -1.0,  1.0,
        -1.0, -1.0,  1.0,

        // Right face
         1.0, -1.0, -1.0,
         1.0,  1.0, -1.0,
         1.0,  1.0,  1.0,
         1.0, -1.0,  1.0,

        // Left face
        -1.0, -1.0, -1.0,
        -1.0, -1.0,  1.0,
        -1.0,  1.0,  1.0,
        -1.0,  1.0, -1.0,
    ];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    vertBuffer.itemSize = 3;
    vertBuffer.numItems = 24;


    CoordBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER,CoordBuffer);
    var textureCoords = [
      // Front face
      0.0, 0.0,
      1.0, 0.0,
      1.0, 1.0,
      0.0, 1.0,

      // Back face
      1.0, 0.0,
      1.0, 1.0,
      0.0, 1.0,
      0.0, 0.0,

      // Top face
      0.0, 1.0,
      0.0, 0.0,
      1.0, 0.0,
      1.0, 1.0,

   // Bottom face
      1.0, 1.0,
      0.0, 1.0,
      0.0, 0.0,
      1.0, 0.0,

      // Right face
      1.0, 0.0,
      1.0, 1.0,
      0.0, 1.0,
      0.0, 0.0,

      // Left face
      0.0, 0.0,
      1.0, 0.0,
      1.0, 1.0,
      0.0, 1.0,
    ];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);
    CoordBuffer.itemSize = 2;
    CoordBuffer.numItems = 24;

var IndexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, IndexBuffer);
    var Indices = [
        0, 1, 2,      0, 2, 3,    // Front face
        4, 5, 6,      4, 6, 7,    // Back face
        8, 9, 10,     8, 10, 11,  // Top face
        12, 13, 14,   12, 14, 15, // Bottom face
        16, 17, 18,   16, 18, 19, // Right face
        20, 21, 22,   20, 22, 23  // Left face
    ];
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices), gl.STATIC_DRAW);
    IndexBuffer.itemSize = 1;
    IndexBuffer.numItems = 36;



}


var xRot = 0;
var yRot = 0;
var zRot = 0;

function drawScene() {
    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);

    mat4.identity(mvMatrix);

    mat4.translate(mvMatrix, [0.0, 0.0, -5.0]);

    mat4.rotate(mvMatrix, degToRad(xRot), [1, 0, 0]);
    mat4.rotate(mvMatrix, degToRad(yRot), [0, 1, 0]);
    mat4.rotate(mvMatrix, degToRad(zRot), [0, 0, 0]);
    setMatrixUniforms();



gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, IndexBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,vertBuffer.itemSize, 
  gl.FLOAT, false, 0, 0);

// Draw face 0
gl.bindTexture(gl.TEXTURE_2D, texturen[0]);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);

// Draw face 1
gl.bindTexture(gl.TEXTURE_2D, texturen[1]);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 12);

// Draw face 2
gl.bindTexture(gl.TEXTURE_2D, texturen[2]);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 24);

// Draw face 3
gl.bindTexture(gl.TEXTURE_2D, texturen[3]);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 36);

// Draw face 4
gl.bindTexture(gl.TEXTURE_2D, texturen[4]);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 48);

// Draw face 5
gl.bindTexture(gl.TEXTURE_2D, texturen[5]);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 60);
}


var lastTime = 0;

function animate() {
    var timeNow = new Date().getTime();
    if (lastTime != 0) {
        var elapsed = timeNow - lastTime;

        xRot += (90 * elapsed) / 1000.0;
        yRot += (90 * elapsed) / 1000.0;
        zRot += (90 * elapsed) / 1000.0;
    }
    lastTime = timeNow;
}


function tick() {
    requestAnimFrame(tick);
    drawScene();
    animate();
}


function webGLStart() {
    var canvas = document.getElementById("lesson05-canvas");
    initGL(canvas);
    initShaders();
    initBuffers();
    initTexture("Logo.png",texturen);
    initTexture("le.png",texturen);
initTexture("Logo.png",texturen);
    initTexture("le.png",texturen);
initTexture("Logo.png",texturen);
    initTexture("le.png",texturen);

gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.enable(gl.DEPTH_TEST);

    tick();
}


</script>


</head>
<body onload="webGLStart();">
<canvas id="lesson05-canvas" style="border: none;" width="500" height="500">    </canvas>    <canvas id="lesson05-canvas" style="border: none;" width="500" height="500">    </canvas>
</body></html>

I hope the fact that these are just 2 different pictures doesn't matter.


Solution

  • Did you even try to debug this? The code you pasted above does not run and gets JavaScript errors. in Chrome open the JavaScript console (Wrench->Tools->JavaScript Console). In Firefox (Firefox->Web Developer->Web Console)

    Things that were wrong

    • Lots of globals used but are not actually global.

      Declared vertBuffer and IndexBuffer and CoordBuffer as local variables in initBuffers but then used them in drawScene.

    That made it at least not get JavaScript errors.

    • Didn't setup the texture coords.

      The code made a CoordBuffer but never uses it in an attribute. This caused GL errors ("attribs not setup correctly" in Chrome)

    Fixing this made it stop getting GL errors. At that point I set the background color to green and I saw a spinning black cube which suggested the next problem was textures.

    • Not setting the textures up to handle no mips and non-power-of-2 textures.

      If your textures are not power of 2 in each dimension you need to set the texture wrap to clamp.

      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

    Here's a working version using randomly colored canvases instead of images.

    var gl;
    
    function initGL(canvas) {
        try {
            gl = canvas.getContext("experimental-webgl");
            gl.viewportWidth = canvas.width;
            gl.viewportHeight = canvas.height;
        } catch (e) {
        }
        if (!gl) {
            alert("Could not initialise WebGL, sorry :-(");
        }
    }
    
    
    function getShader(gl, id) {
        var shaderScript = document.getElementById(id);
        if (!shaderScript) {
            return null;
        }
    
        str = shaderScript.text;
    
        var shader;
        if (shaderScript.type == "x-shader/x-fragment") {
            shader = gl.createShader(gl.FRAGMENT_SHADER);
        } else if (shaderScript.type == "x-shader/x-vertex") {
            shader = gl.createShader(gl.VERTEX_SHADER);
        } else {
            return null;
        }
    
        gl.shaderSource(shader, str);
        gl.compileShader(shader);
    
        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            alert(gl.getShaderInfoLog(shader));
            return null;
        }
    
        return shader;
    }
    
    
    var shaderProgram;
    
    function initShaders() {
        var fragmentShader = getShader(gl, "shader-fs");
        var vertexShader = getShader(gl, "shader-vs");
    
        shaderProgram = gl.createProgram();
        gl.attachShader(shaderProgram, vertexShader);
        gl.attachShader(shaderProgram, fragmentShader);
        gl.linkProgram(shaderProgram);
    
        if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
            alert("Could not initialise shaders");
        }
    
        gl.useProgram(shaderProgram);
    
        // This is a bad code.
        // If the context is lsot shaderProgram will be null
        // and trying to assign a vertexPositionAttribute to null
        // will throw an exception.
        // better would be 
        // shaderProgram = {};
        // shaderProgram.program = gl.createProgram();
        // shaderProgram.vertexPositionAtrribute = ...
        shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
        gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
    
        shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
        gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
    
        shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
        shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
        shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
    }
    
    
    var texturen = new Array();
    function initTexture(sFilename,texturen)  
    {
      var anz = texturen.length;
      texturen[anz] = gl.createTexture();
      // this is a bad code. on context lost gl.createTexture() will return null and
      // an exception will be thrown when you try to attach .image to null
      // Better would be
      // texturen[anz] = {};
      // texturen[anz].texture = gl.createTexture();
      // texturen[anz].image = new Image();
      texturen[anz].image = new Image();
      texturen[anz].image.onload = function() 
      {
        gl.bindTexture(gl.TEXTURE_2D, texturen[anz]);
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
        //gl.texImage2D  (gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texturen[anz].image);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.bindTexture(gl.TEXTURE_2D, null);
      }
      //texturen[anz].image.src = sFilename;
      // Since I can't load cross domain I'll use a canvas to make textures
      function rnd() { return Math.floor(Math.random() * 256); }
      var c = document.createElement("canvas");
      c.width = 64;
      c.height = 64;
      var ctx = c.getContext("2d");
      ctx.fillStyle = "rgb(" + rnd() + "," + rnd() + "," + rnd() + ")";
      ctx.fillRect(0, 0, 64, 64);
      ctx.fillStyle = "rgb(" + rnd() + "," + rnd() + "," + rnd() + ")";
      ctx.beginPath();
      ctx.arc(32, 32, 30, 0, Math.PI * 2, false);
      ctx.fill();
      gl.bindTexture(gl.TEXTURE_2D, texturen[anz]);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    } 
    
    var mvMatrix = mat4.create();
    var mvMatrixStack = [];
    var pMatrix = mat4.create();
    
    function mvPushMatrix() {
        var copy = mat4.create();
        mat4.copy(copy, mvMatrix);
        mvMatrixStack.push(copy);
    }
    
    function mvPopMatrix() {
        if (mvMatrixStack.length == 0) {
            throw "Invalid popMatrix!";
        }
        mvMatrix = mvMatrixStack.pop();
    }
    
    
    function setMatrixUniforms() {
        gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
        gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
    }
    
    function degToRad(degrees) {
        return degrees * Math.PI / 180;
    }
    
    function initBuffers() {
        vertBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
        var vertices = [
            // Front face
            -1.0, -1.0,  1.0,
             1.0, -1.0,  1.0,
             1.0,  1.0,  1.0,
            -1.0,  1.0,  1.0,
    
            // Back face
            -1.0, -1.0, -1.0,
            -1.0,  1.0, -1.0,
             1.0,  1.0, -1.0,
             1.0, -1.0, -1.0,
    
            // Top face
            -1.0,  1.0, -1.0,
            -1.0,  1.0,  1.0,
             1.0,  1.0,  1.0,
             1.0,  1.0, -1.0,
    
           // Bottom face
            -1.0, -1.0, -1.0,
             1.0, -1.0, -1.0,
             1.0, -1.0,  1.0,
            -1.0, -1.0,  1.0,
    
            // Right face
             1.0, -1.0, -1.0,
             1.0,  1.0, -1.0,
             1.0,  1.0,  1.0,
             1.0, -1.0,  1.0,
    
            // Left face
            -1.0, -1.0, -1.0,
            -1.0, -1.0,  1.0,
            -1.0,  1.0,  1.0,
            -1.0,  1.0, -1.0,
        ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
        
        // This is bad code. See the above examples of bad code.
        // vertBuffer will be null on context lost and this code
        // will throw an exception.
        vertBuffer.itemSize = 3;
        vertBuffer.numItems = 24;
    
        CoordBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER,CoordBuffer);
        var textureCoords = [
          // Front face
          0.0, 0.0,
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,
    
          // Back face
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,
          0.0, 0.0,
    
          // Top face
          0.0, 1.0,
          0.0, 0.0,
          1.0, 0.0,
          1.0, 1.0,
    
       // Bottom face
          1.0, 1.0,
          0.0, 1.0,
          0.0, 0.0,
          1.0, 0.0,
    
          // Right face
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,
          0.0, 0.0,
    
          // Left face
          0.0, 0.0,
          1.0, 0.0,
          1.0, 1.0,
          0.0, 1.0,
        ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);
        CoordBuffer.itemSize = 2;
        CoordBuffer.numItems = 24;
    
        IndexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, IndexBuffer);
        var Indices = [
            0, 1, 2,      0, 2, 3,    // Front face
            4, 5, 6,      4, 6, 7,    // Back face
            8, 9, 10,     8, 10, 11,  // Top face
            12, 13, 14,   12, 14, 15, // Bottom face
            16, 17, 18,   16, 18, 19, // Right face
            20, 21, 22,   20, 22, 23  // Left face
        ];
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices), gl.STATIC_DRAW);
        IndexBuffer.itemSize = 1;
        IndexBuffer.numItems = 36;
    }
    
    
    var xRot = 0;
    var yRot = 0;
    var zRot = 0;
    
    function drawScene() {
        gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    
        mat4.perspective(pMatrix, 45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);
    
        mat4.identity(mvMatrix);
    
        mat4.translate(mvMatrix, mvMatrix, [0.0, 0.0, -5.0]);
    
        mat4.rotate(mvMatrix, mvMatrix, degToRad(xRot), [1, 0, 0]);
        mat4.rotate(mvMatrix, mvMatrix, degToRad(yRot), [0, 1, 0]);
        mat4.rotate(mvMatrix, mvMatrix, degToRad(zRot), [0, 0, 0]);
        setMatrixUniforms();
    
    
        gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
        gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,vertBuffer.itemSize, 
           gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ARRAY_BUFFER, CoordBuffer);
        gl.vertexAttribPointer(shaderProgram.textureCoordAttribute,CoordBuffer.itemSize, 
           gl.FLOAT, false, 0, 0);
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, IndexBuffer);
    
    // Draw face 0
    gl.bindTexture(gl.TEXTURE_2D, texturen[0]);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
    
    // Draw face 1
    gl.bindTexture(gl.TEXTURE_2D, texturen[1]);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 12);
    
    // Draw face 2
    gl.bindTexture(gl.TEXTURE_2D, texturen[2]);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 24);
    
    // Draw face 3
    gl.bindTexture(gl.TEXTURE_2D, texturen[3]);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 36);
    
    // Draw face 4
    gl.bindTexture(gl.TEXTURE_2D, texturen[4]);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 48);
    
    // Draw face 5
    gl.bindTexture(gl.TEXTURE_2D, texturen[5]);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 60);
    }
    
    
    var lastTime = 0;
    
    function animate() {
        var timeNow = new Date().getTime();
        if (lastTime != 0) {
            var elapsed = timeNow - lastTime;
    
            xRot += (90 * elapsed) / 1000.0;
            yRot += (90 * elapsed) / 1000.0;
            zRot += (90 * elapsed) / 1000.0;
        }
        lastTime = timeNow;
    }
    
    
    function tick() {
        requestAnimationFrame(tick);
        drawScene();
        animate();
    }
    
    
    function webGLStart() {
        var canvas = document.getElementById("lesson05-canvas");
        initGL(canvas);
        initShaders();
        initBuffers();
        initTexture("Logo.png",texturen);
        initTexture("le.png",texturen);
        initTexture("Logo.png",texturen);
        initTexture("le.png",texturen);
        initTexture("Logo.png",texturen);
        initTexture("le.png",texturen);
    
        gl.clearColor(0.0, 1.0, 0.0, 1.0);
        gl.enable(gl.DEPTH_TEST);
        tick();
    }
    
    
    webGLStart();
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.3.2/gl-matrix-min.js"></script>
    
    <script id="shader-fs" type="x-shader/x-fragment">
    precision mediump float;
    
    varying vec2 vTextureCoord;
    
    uniform sampler2D uSampler;
    
    void main(void) {
        gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
    }
    </script>
    
    <script id="shader-vs" type="x-shader/x-vertex">
    attribute vec3 aVertexPosition;
    attribute vec2 aTextureCoord;
    
    uniform mat4 uMVMatrix;
    uniform mat4 uPMatrix;
    
    varying vec2 vTextureCoord;
    
    
    void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        vTextureCoord = aTextureCoord;
    }
    </script>
    
    <canvas id="lesson05-canvas" style="border: none;" width="500" height="500">    </canvas>

    Other problems: There's several places in the code where properties are assigned to WebGL objects. Examples

    shaderProgram = gl.createProgram();
    shaderProgram.textureCoordAttribute = 
        gl.getAttribLocation(shaderProgram, "aTextureCoord");
    

    ...

    texturen[anz] = gl.createTexture();
    texturen[anz].image = new Image();
    texturen[anz].image.onload = function() 
    

    ...

    vertBuffer = gl.createBuffer();
    vertBuffer.itemSize = 3;
    

    All of these will have to be refactored if you ever decide to handle context lost events since the gl.create??? functions will return null and attaching a property to null will cause an exception.

    Better to do something more like this

    shaderProgram = {};
    shaderProgram.program = gl.createProgram();
    shaderProgram.textureCoordAttribute = 
        gl.getAttribLocation(shaderProgram, "aTextureCoord");
    

    ...

    texturen[anz] = {};
    texturen[anz].texture = gl.createTexture();
    texturen[anz].image = new Image();
    texturen[anz].image.onload = function() 
    

    ...

    vertBuffer = {};
    vertBuffer.buffer = gl.createBuffer();
    vertBuffer.itemSize = 3;