Positional Matrices

A transformation can be achieved by multiplying the positional vectors of the vertices with a 4*4 matrix in the vertex shader.

In this section, we will develop a JavaScript object called Matrix4 that contains many useful methods for transformations, viewing, and projection.

The matrix object defined is passed to the vertex shader as a uniform variable.

Here three functions are added to webgl-library.js, allowing the coder to construct a Matrix4, set it to I, and multiply a matrix to it. This example does not perform any transformation but it teaches how to use Matrix4 at the basic level. It will serve as a template for other examples in this section.
RESETRUNFULL
// /shared/webgl-library.js
function Matrix4(s){
   var i;
   this.entries = new Array();
   if (s && (typeof s)==='object' && s.length &&
        s.length==16){
      for (i=0; i<16; i++) this.entries.push(s[i]);
   } else {
      this.entries=[1,0,0,0,  0,1,0,0,  0,0,1,0,  0,0,0,1];
   }
}

Matrix4.prototype.setIdentity = function(){
   var e = this.entries;
   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;
}

Matrix4.prototype.multiply_matrix = function(other){
  var i, e, a, b, ai0, ai1, ai2, ai3;
  e = this.entries;
  a = this.entries;
  b = other;
  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;
}

<!DOCTYPE html><html>
<head>
<script src="/shared/webgl-library.js"></script>
<script>
function draw_colored_triangle(){
   var points=new Array();
   var vc= new Float32Array([ 0.0,-0.5,  1.0, 0.0, 0.0,
                             -0.5, 0.5,  0.0, 1.0, 0.0,
                              0.5, 0.5,  0.0, 0.0, 1.0]);
   var ESIZE=vc.BYTES_PER_ELEMENT;
   var b=gl.createBuffer();
   gl.bindBuffer(gl.ARRAY_BUFFER,b);
   gl.bufferData(gl.ARRAY_BUFFER,vc,gl.STATIC_DRAW);
   pL=gl.getAttribLocation(gl.program,'p');
   gl.vertexAttribPointer(pL,2,gl.FLOAT,false,ESIZE*5,0);
   gl.enableVertexAttribArray(pL);
   cL=gl.getAttribLocation(gl.program,'c');
   gl.vertexAttribPointer(cL,3,gl.FLOAT,false,ESIZE*5,ESIZE*2);
   gl.enableVertexAttribArray(cL);
   gl.clearColor(0.0,0.0,0.0,1.0);
   gl.clear(gl.COLOR_BUFFER_BIT);
   gl.drawArrays(gl.TRIANGLES,0,3);
}

var VS_SOURCE=`
   uniform mat4 I;
   attribute vec4 p;
   attribute vec4 c;
   varying vec4 c2;
   void main(){
      c2=c;\
      gl_Position = I*p;
   }`;

var FS_SOURCE=`
   precision mediump float;
   varying vec4 c2;
   void main(){
      gl_FragColor=c2;
   }`;

var gl,m,mL;

function start(){
   var canvas = document.getElementById("myCanvas");
   gl = canvas.getContext("webgl");
   initShaders(gl,VS_SOURCE,FS_SOURCE);
   m = new Matrix4();
   mL = gl.getUniformLocation(gl.program, 'I');
   gl.uniformMatrix4fv(mL,false,m.entries);
   draw_colored_triangle();
}
</script>
</head>
<body onload="start()">
   <canvas id="myCanvas" width="500" height="500"></canvas>
</body>
</html>