Example of using WebGL Code

This website's homepage uses WebGL animation.  The HTML 5 source code can be
viewed by selecting the browser's source, and it is seen that there are 5
included JavaScript files, 2 included non-JavaScript text files containing
shader code used to program the computer's graphics card, and a few lines
of the JavaScript function loadShaders() in the head tag.  Note that
although the JavaScript library file gl-Matrix-1.3.7 works locally with
Apache, it was found that it does not work on the remote server hosting this
website, so the older file glMatrix-0.9.5.min.js is used here.  It is
planned to fix this problem in due course.  On page load the functions
loadShaders() and hideEmail() are invoked, see below for details of the
former, and click here for more details of the latter.  The files
ajax-load.js, shader-fs.txt and shader-vs.txt are listed here together with
cube-animation.js from the link at the bottom.

In many WebGL applications the shader files are put in-line in the HTML
file, but here we want to keep the shader code separate from the HTML file,
as is the case with JavaScript.  Unfortunately, doing anything like the
equivalent of <script src=...> will not work, so the shader files have to
be loaded with the function loadShaders(), which is invoked on page load.
This first calls loadXMLDoc() in ajax-load.js and writes the contents of
shader-fs.txt in the script tag with id='shader-fs', then loadXMLDoc() is
called a second time and writes the contents of shader-vs.txt in the script
tag with id='shader-vs'.  The JavaScript and the two shader files are as

// ----- ajax-load.js -----
// Note that xmlhttp.open() must be called with "false", as this is not for
// asynchronous operation because the shader files have to be fully loaded
// before the execution starts.

function loadXMLDoc(filename, id) {
  var xmlhttp;
  if (window.XMLHttpRequest) xmlhttp = new XMLHttpRequest();// Other browsers
  else xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");    // IE6, IE5
  xmlhttp.open("GET", filename, false);
  document.getElementById(id).innerHTML = xmlhttp.responseText;

// ----- shader-fs.txt -----

precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
uniform sampler2D uSampler;

void main(void) {
  vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s,
  gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);

// ----- shader-vs.txt -----

attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;

uniform vec3 uAmbientColor;

uniform vec3 uLightingDirection;
uniform vec3 uDirectionalColor;

uniform bool uUseLighting;

varying vec2 vTextureCoord;
varying vec3 vLightWeighting;

void main(void) {
  gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
  vTextureCoord = aTextureCoord;

  if (!uUseLighting) {
  vLightWeighting = vec3(1.0, 1.0, 1.0);
  } else {
    vec3 transformedNormal = uNMatrix * aVertexNormal;
    float directionalLightWeighting = max(dot(transformedNormal,
      uLightingDirection), 0.0);
    vLightWeighting = uAmbientColor + uDirectionalColor *
Before returning, loadShaders() then calls webGLStart() in cube-animation.js,
where it passes the image that will be pasted onto the cube, initializes the
graphics and starts the animation.

Click here to return to the main selection page.