<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>examples/gles/assets/basemap.png</filename>
    </added>
    <added>
      <filename>examples/gles/assets/lightmap.png</filename>
    </added>
    <added>
      <filename>examples/gles/ch10-multitexture.js</filename>
    </added>
    <added>
      <filename>examples/gles/common.js</filename>
    </added>
    <added>
      <filename>examples/gles/shaders/ch10-fshader.sl</filename>
    </added>
    <added>
      <filename>examples/gles/shaders/ch10-vshader.sl</filename>
    </added>
    <added>
      <filename>examples/gles/shaders/m3d-fshader.sl</filename>
    </added>
    <added>
      <filename>examples/gles/shaders/m3d-vshader.sl</filename>
    </added>
    <added>
      <filename>examples/gles/shaderutil.js</filename>
    </added>
    <added>
      <filename>imageloader.cpp</filename>
    </added>
    <added>
      <filename>imageloader.h</filename>
    </added>
    <added>
      <filename>utils.cpp</filename>
    </added>
    <added>
      <filename>utils.h</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -5,7 +5,7 @@ CC = g++
 CFLAGS := $(CFLAGS) -m32 -Wall -Iv8/include 
 PROG = v8-gl 
 
-SRCS = main.cpp v8-gl.cpp glbindings/glbind.cpp glesbindings/glesbind.cpp glubindings/glubind.cpp glutbindings/glutbind.cpp
+SRCS = main.cpp imageloader.cpp utils.cpp v8-gl.cpp glbindings/glbind.cpp glesbindings/glesbind.cpp glubindings/glubind.cpp glutbindings/glutbind.cpp
 
 all: $(PROG)
 </diff>
      <filename>Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,468 +1,5 @@
-//adding matrix 4x4 library
-/*
- * Copyright (c) 2009, Mozilla Corp
- * 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 the &lt;organization&gt; 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 &lt;copyright holder&gt; ''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 &lt;copyright holder&gt; 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.
- */
-
-/*
- * Based on sample code from the OpenGL(R) ES 2.0 Programming Guide, which carriers
- * the following header:
- *
- * Book:      OpenGL(R) ES 2.0 Programming Guide
- * Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
- * ISBN-10:   0321502795
- * ISBN-13:   9780321502797
- * Publisher: Addison-Wesley Professional
- * URLs:      http://safari.informit.com/9780321563835
- *            http://www.opengles-book.com
- */
-
-//
-// A simple 4x4 Matrix utility class
-//
-
-function Matrix4x4() {
-  this.elements = Array(16);
-  this.loadIdentity();
-}
-
-Matrix4x4.prototype = {
-  scale: function (sx, sy, sz) {
-    this.elements[0*4+0] *= sx;
-    this.elements[0*4+1] *= sx;
-    this.elements[0*4+2] *= sx;
-    this.elements[0*4+3] *= sx;
-
-    this.elements[1*4+0] *= sy;
-    this.elements[1*4+1] *= sy;
-    this.elements[1*4+2] *= sy;
-    this.elements[1*4+3] *= sy;
-
-    this.elements[2*4+0] *= sz;
-    this.elements[2*4+1] *= sz;
-    this.elements[2*4+2] *= sz;
-    this.elements[2*4+3] *= sz;
-
-    return this;
-  },
-
-  translate: function (tx, ty, tz) {
-    this.elements[3*4+0] += this.elements[0*4+0] * tx + this.elements[1*4+0] * ty + this.elements[2*4+0] * tz;
-    this.elements[3*4+1] += this.elements[0*4+1] * tx + this.elements[1*4+1] * ty + this.elements[2*4+1] * tz;
-    this.elements[3*4+2] += this.elements[0*4+2] * tx + this.elements[1*4+2] * ty + this.elements[2*4+2] * tz;
-    this.elements[3*4+3] += this.elements[0*4+3] * tx + this.elements[1*4+3] * ty + this.elements[2*4+3] * tz;
-
-    return this;
-  },
-
-  rotate: function (angle, x, y, z) {
-    var mag = Math.sqrt(x*x + y*y + z*z);
-    var sinAngle = Math.sin(angle * Math.PI / 180.0);
-    var cosAngle = Math.cos(angle * Math.PI / 180.0);
-
-    if (mag &gt; 0) {
-      var xx, yy, zz, xy, yz, zx, xs, ys, zs;
-      var oneMinusCos;
-      var rotMat;
-
-      x /= mag;
-      y /= mag;
-      z /= mag;
-
-      xx = x * x;
-      yy = y * y;
-      zz = z * z;
-      xy = x * y;
-      yz = y * z;
-      zx = z * x;
-      xs = x * sinAngle;
-      ys = y * sinAngle;
-      zs = z * sinAngle;
-      oneMinusCos = 1.0 - cosAngle;
-
-      rotMat = new Matrix4x4();
-
-      rotMat.elements[0*4+0] = (oneMinusCos * xx) + cosAngle;
-      rotMat.elements[0*4+1] = (oneMinusCos * xy) - zs;
-      rotMat.elements[0*4+2] = (oneMinusCos * zx) + ys;
-      rotMat.elements[0*4+3] = 0.0;
-
-      rotMat.elements[1*4+0] = (oneMinusCos * xy) + zs;
-      rotMat.elements[1*4+1] = (oneMinusCos * yy) + cosAngle;
-      rotMat.elements[1*4+2] = (oneMinusCos * yz) - xs;
-      rotMat.elements[1*4+3] = 0.0;
-
-      rotMat.elements[2*4+0] = (oneMinusCos * zx) - ys;
-      rotMat.elements[2*4+1] = (oneMinusCos * yz) + xs;
-      rotMat.elements[2*4+2] = (oneMinusCos * zz) + cosAngle;
-      rotMat.elements[2*4+3] = 0.0;
-
-      rotMat.elements[3*4+0] = 0.0;
-      rotMat.elements[3*4+1] = 0.0;
-      rotMat.elements[3*4+2] = 0.0;
-      rotMat.elements[3*4+3] = 1.0;
-
-      rotMat = rotMat.multiply(this);
-      this.elements = rotMat.elements;
-    }
-
-    return this;
-  },
-
-  frustum: function (left, right, bottom, top, nearZ, farZ) {
-    var deltaX = right - left;
-    var deltaY = top - bottom;
-    var deltaZ = farZ - nearZ;
-    var frust;
-
-    if ( (nearZ &lt;= 0.0) || (farZ &lt;= 0.0) ||
-         (deltaX &lt;= 0.0) || (deltaY &lt;= 0.0) || (deltaZ &lt;= 0.0) )
-         return this;
-
-    frust = new Matrix4x4();
-
-    frust.elements[0*4+0] = 2.0 * nearZ / deltaX;
-    frust.elements[0*4+1] = frust.elements[0*4+2] = frust.elements[0*4+3] = 0.0;
-
-    frust.elements[1*4+1] = 2.0 * nearZ / deltaY;
-    frust.elements[1*4+0] = frust.elements[1*4+2] = frust.elements[1*4+3] = 0.0;
-
-    frust.elements[2*4+0] = (right + left) / deltaX;
-    frust.elements[2*4+1] = (top + bottom) / deltaY;
-    frust.elements[2*4+2] = -(nearZ + farZ) / deltaZ;
-    frust.elements[2*4+3] = -1.0;
-
-    frust.elements[3*4+2] = -2.0 * nearZ * farZ / deltaZ;
-    frust.elements[3*4+0] = frust.elements[3*4+1] = frust.elements[3*4+3] = 0.0;
-
-    frust = frust.multiply(this);
-    this.elements = frust.elements;
-
-    return this;
-  },
-
-  perspective: function (fovy, aspect, nearZ, farZ) {
-    var frustumH = Math.tan(fovy / 360.0 * Math.PI) * nearZ;
-    var frustumW = frustumH * aspect;
-
-    return this.frustum(-frustumW, frustumW, -frustumH, frustumH, nearZ, farZ);
-  },
-
-  ortho: function (left, right, bottom, top, nearZ, farZ) {
-    var deltaX = right - left;
-    var deltaY = top - bottom;
-    var deltaZ = farZ - nearZ;
-
-    var ortho = new Matrix4x4();
-
-    if ( (deltaX == 0.0) || (deltaY == 0.0) || (deltaZ == 0.0) )
-        return this;
-
-    ortho.elements[0*4+0] = 2.0 / deltaX;
-    ortho.elements[3*4+0] = -(right + left) / deltaX;
-    ortho.elements[1*4+1] = 2.0 / deltaY;
-    ortho.elements[3*4+1] = -(top + bottom) / deltaY;
-    ortho.elements[2*4+2] = -2.0 / deltaZ;
-    ortho.elements[3*4+2] = -(nearZ + farZ) / deltaZ;
-
-    ortho = ortho.multiply(this);
-    this.elements = ortho.elements;
-
-    return this;
-  },
-
-  multiply: function (right) {
-    var tmp = new Matrix4x4();
-
-    for (var i = 0; i &lt; 4; i++) {
-      tmp.elements[i*4+0] =
-	(this.elements[i*4+0] * right.elements[0*4+0]) +
-	(this.elements[i*4+1] * right.elements[1*4+0]) +
-	(this.elements[i*4+2] * right.elements[2*4+0]) +
-	(this.elements[i*4+3] * right.elements[3*4+0]) ;
-
-      tmp.elements[i*4+1] =
-	(this.elements[i*4+0] * right.elements[0*4+1]) +
-	(this.elements[i*4+1] * right.elements[1*4+1]) +
-	(this.elements[i*4+2] * right.elements[2*4+1]) +
-	(this.elements[i*4+3] * right.elements[3*4+1]) ;
-
-      tmp.elements[i*4+2] =
-	(this.elements[i*4+0] * right.elements[0*4+2]) +
-	(this.elements[i*4+1] * right.elements[1*4+2]) +
-	(this.elements[i*4+2] * right.elements[2*4+2]) +
-	(this.elements[i*4+3] * right.elements[3*4+2]) ;
-
-      tmp.elements[i*4+3] =
-	(this.elements[i*4+0] * right.elements[0*4+3]) +
-	(this.elements[i*4+1] * right.elements[1*4+3]) +
-	(this.elements[i*4+2] * right.elements[2*4+3]) +
-	(this.elements[i*4+3] * right.elements[3*4+3]) ;
-    }
-
-    this.elements = tmp.elements;
-    return this;
-  },
-
-  loadIdentity: function () {
-    for (var i = 0; i &lt; 16; i++)
-      this.elements[i] = 0;
-    this.elements[0*4+0] = 1.0;
-    this.elements[1*4+1] = 1.0;
-    this.elements[2*4+2] = 1.0;
-    this.elements[3*4+3] = 1.0;
-    return this;
-  }
-};
-
-//adding a simple shape library
-/*
- * Copyright (c) 2009, Mozilla Corp
- * 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 the &lt;organization&gt; 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 &lt;copyright holder&gt; ''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 &lt;copyright holder&gt; 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.
- */
-
-/*
- * Based on sample code from the OpenGL(R) ES 2.0 Programming Guide, which carriers
- * the following header:
- *
- * Book:      OpenGL(R) ES 2.0 Programming Guide
- * Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
- * ISBN-10:   0321502795
- * ISBN-13:   9780321502797
- * Publisher: Addison-Wesley Professional
- * URLs:      http://safari.informit.com/9780321563835
- *            http://www.opengles-book.com
- */
-
-//
-// port of esShapes.c
-//
-
-function shallowCloneArray(ar) {
-  var o = Array(ar.length);
-  for (var i = 0; i &lt; ar.length; i++) {
-    o[i] = ar[i];
-  }
-  return o;
-}
-
-function shallowCloneArrayScaled(ar, scale) {
-  var o = Array(ar.length);
-  for (var i = 0; i &lt; ar.length; i++) {
-    o[i] = ar[i] * scale;
-  }
-  return o;
-}
-
-// make these accessible directly in the glboal scope,
-// in case someone wants to use them without copying
-var esCubeVertices = [
-  -0.5, -0.5, -0.5,
-  -0.5, -0.5,  0.5,
-   0.5, -0.5,  0.5,
-   0.5, -0.5, -0.5,
-  -0.5,  0.5, -0.5,
-  -0.5,  0.5,  0.5,
-   0.5,  0.5,  0.5,
-   0.5,  0.5, -0.5,
-  -0.5, -0.5, -0.5,
-  -0.5,  0.5, -0.5,
-   0.5,  0.5, -0.5,
-   0.5, -0.5, -0.5,
-  -0.5, -0.5, 0.5,
-  -0.5,  0.5, 0.5,
-   0.5,  0.5, 0.5,
-   0.5, -0.5, 0.5,
-  -0.5, -0.5, -0.5,
-  -0.5, -0.5,  0.5,
-  -0.5,  0.5,  0.5,
-  -0.5,  0.5, -0.5,
-   0.5, -0.5, -0.5,
-   0.5, -0.5,  0.5,
-   0.5,  0.5,  0.5,
-   0.5,  0.5, -0.5
-];
-
-var esCubeNormals = [
-   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, 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, 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
-];
-
-var esCubeTexCoords = [
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  1.0, 0.0,
-  1.0, 1.0,
-  0.0, 1.0,
-  0.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0
-];
-
-var esCubeIndices = [
-  0, 2, 1,
-  0, 3, 2,
-  4, 5, 6,
-  4, 6, 7,
-  8, 9, 10,
-  8, 10, 11,
-  12, 15, 14,
-  12, 14, 13,
-  16, 17, 18,
-  16, 18, 19,
-  20, 23, 22,
-  20, 22, 21
-];
-
-// will return an object that has vertices, normals, texCoords, and indices members
-function esGenCube (scale) {
-  return {
-    vertices: shallowCloneArrayScaled(esCubeVertices, scale),
-    texCoords: shallowCloneArray(esCubeTexCoords),
-    indices: shallowCloneArray(esCubeIndices),
-    normals: shallowCloneArray(esCubeNormals)
-  };
-}
-
-//
-// generates coordinate information for a sphere
-//
-
-function esGenSphere (numSlices, radius) {
-  var i, j;
-  var numParallels = numSlices;
-  var numVertices = (numParallels + 1) * (numSlices + 1);
-  var numIndices = numParallels * numSlices * 6;
-  var angleStep = (2 * Math.PI) / numSlices;
-
-  var vertices = Array(3*numVertices);
-  var normals = Array(3*numVertices);
-  var texCoords = Array(2*numVertices);
-  var indices = Array(numIndices);
-
-  for (i = 0; i &lt; numParallels+1; i++) {
-    for (j = 0; j &lt; numSlices+1; j++) {
-      var vertex = (i * (numSlices+1) + j) * 3;
-
-      vertices[vertex+0] = radius * Math.sin(angleStep * i) * Math.sin(angleStep * j);
-      vertices[vertex+1] = radius * Math.cos(angleStep * i);
-      vertices[vertex+2] = radius * Math.sin(angleStep * i) * Math.cos(angleStep * j);
-
-      normals[vertex+0] = vertices[vertex+0] / radius;
-      normals[vertex+1] = vertices[vertex+1] / radius;
-      normals[vertex+2] = vertices[vertex+2] / radius;
-
-      var texIndex = (i * (numSlices+1) + j) * 2;
-
-      texCoords[texIndex+0] = j / numSlices;
-      texCoords[texIndex+1] = (1 - i) / (numParallels - 1);
-    }
-  }
-
-  var k = 0;
-  for (i = 0; i &lt; numParallels; i++) {
-    for (j = 0; j &lt; numSlices; j++) {
-      indices[k++] = i * (numSlices + 1) + j;
-      indices[k++] = (i + 1) * (numSlices + 1) + j;
-      indices[k++] = (i + 1) * (numSlices + 1) + (j + 1);
-
-      indices[k++] = i * (numSlices + 1) + j;
-      indices[k++] = (i + 1) * (numSlices + 1) + (j + 1);
-      indices[k++] = i * (numSlices + 1) + (j + 1);
-    }
-  }
-
-  return {
-    vertices: vertices,
-    normals: normals,
-    texCoords: texCoords,
-    indices: indices
-  };
-}
-//end library code.
-
+//load common code.
+load(&quot;common.js&quot;);
 
 //start custom code.
 var angle = 0;</diff>
      <filename>examples/gles/ch8-simple-vertexshader.js</filename>
    </modified>
    <modified>
      <diff>@@ -1,561 +1,5 @@
-//adding matrix 4x4 library
-/*
- * Copyright (c) 2009, Mozilla Corp
- * 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 the &lt;organization&gt; 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 &lt;copyright holder&gt; ''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 &lt;copyright holder&gt; 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.
- */
-
-/*
- * Based on sample code from the OpenGL(R) ES 2.0 Programming Guide, which carriers
- * the following header:
- *
- * Book:      OpenGL(R) ES 2.0 Programming Guide
- * Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
- * ISBN-10:   0321502795
- * ISBN-13:   9780321502797
- * Publisher: Addison-Wesley Professional
- * URLs:      http://safari.informit.com/9780321563835
- *            http://www.opengles-book.com
- */
-
-//
-// A simple 4x4 Matrix utility class
-//
-
-function Matrix4x4() {
-  this.elements = Array(16);
-  this.loadIdentity();
-}
-
-Matrix4x4.prototype = {
-  scale: function (sx, sy, sz) {
-    this.elements[0*4+0] *= sx;
-    this.elements[0*4+1] *= sx;
-    this.elements[0*4+2] *= sx;
-    this.elements[0*4+3] *= sx;
-
-    this.elements[1*4+0] *= sy;
-    this.elements[1*4+1] *= sy;
-    this.elements[1*4+2] *= sy;
-    this.elements[1*4+3] *= sy;
-
-    this.elements[2*4+0] *= sz;
-    this.elements[2*4+1] *= sz;
-    this.elements[2*4+2] *= sz;
-    this.elements[2*4+3] *= sz;
-
-    return this;
-  },
-
-  translate: function (tx, ty, tz) {
-    this.elements[3*4+0] += this.elements[0*4+0] * tx + this.elements[1*4+0] * ty + this.elements[2*4+0] * tz;
-    this.elements[3*4+1] += this.elements[0*4+1] * tx + this.elements[1*4+1] * ty + this.elements[2*4+1] * tz;
-    this.elements[3*4+2] += this.elements[0*4+2] * tx + this.elements[1*4+2] * ty + this.elements[2*4+2] * tz;
-    this.elements[3*4+3] += this.elements[0*4+3] * tx + this.elements[1*4+3] * ty + this.elements[2*4+3] * tz;
-
-    return this;
-  },
-
-  rotate: function (angle, x, y, z) {
-    var mag = Math.sqrt(x*x + y*y + z*z);
-    var sinAngle = Math.sin(angle * Math.PI / 180.0);
-    var cosAngle = Math.cos(angle * Math.PI / 180.0);
-
-    if (mag &gt; 0) {
-      var xx, yy, zz, xy, yz, zx, xs, ys, zs;
-      var oneMinusCos;
-      var rotMat;
-
-      x /= mag;
-      y /= mag;
-      z /= mag;
-
-      xx = x * x;
-      yy = y * y;
-      zz = z * z;
-      xy = x * y;
-      yz = y * z;
-      zx = z * x;
-      xs = x * sinAngle;
-      ys = y * sinAngle;
-      zs = z * sinAngle;
-      oneMinusCos = 1.0 - cosAngle;
-
-      rotMat = new Matrix4x4();
-
-      rotMat.elements[0*4+0] = (oneMinusCos * xx) + cosAngle;
-      rotMat.elements[0*4+1] = (oneMinusCos * xy) - zs;
-      rotMat.elements[0*4+2] = (oneMinusCos * zx) + ys;
-      rotMat.elements[0*4+3] = 0.0;
-
-      rotMat.elements[1*4+0] = (oneMinusCos * xy) + zs;
-      rotMat.elements[1*4+1] = (oneMinusCos * yy) + cosAngle;
-      rotMat.elements[1*4+2] = (oneMinusCos * yz) - xs;
-      rotMat.elements[1*4+3] = 0.0;
-
-      rotMat.elements[2*4+0] = (oneMinusCos * zx) - ys;
-      rotMat.elements[2*4+1] = (oneMinusCos * yz) + xs;
-      rotMat.elements[2*4+2] = (oneMinusCos * zz) + cosAngle;
-      rotMat.elements[2*4+3] = 0.0;
-
-      rotMat.elements[3*4+0] = 0.0;
-      rotMat.elements[3*4+1] = 0.0;
-      rotMat.elements[3*4+2] = 0.0;
-      rotMat.elements[3*4+3] = 1.0;
-
-      rotMat = rotMat.multiply(this);
-      this.elements = rotMat.elements;
-    }
-
-    return this;
-  },
-
-  frustum: function (left, right, bottom, top, nearZ, farZ) {
-    var deltaX = right - left;
-    var deltaY = top - bottom;
-    var deltaZ = farZ - nearZ;
-    var frust;
-
-    if ( (nearZ &lt;= 0.0) || (farZ &lt;= 0.0) ||
-         (deltaX &lt;= 0.0) || (deltaY &lt;= 0.0) || (deltaZ &lt;= 0.0) )
-         return this;
-
-    frust = new Matrix4x4();
-
-    frust.elements[0*4+0] = 2.0 * nearZ / deltaX;
-    frust.elements[0*4+1] = frust.elements[0*4+2] = frust.elements[0*4+3] = 0.0;
-
-    frust.elements[1*4+1] = 2.0 * nearZ / deltaY;
-    frust.elements[1*4+0] = frust.elements[1*4+2] = frust.elements[1*4+3] = 0.0;
-
-    frust.elements[2*4+0] = (right + left) / deltaX;
-    frust.elements[2*4+1] = (top + bottom) / deltaY;
-    frust.elements[2*4+2] = -(nearZ + farZ) / deltaZ;
-    frust.elements[2*4+3] = -1.0;
-
-    frust.elements[3*4+2] = -2.0 * nearZ * farZ / deltaZ;
-    frust.elements[3*4+0] = frust.elements[3*4+1] = frust.elements[3*4+3] = 0.0;
-
-    frust = frust.multiply(this);
-    this.elements = frust.elements;
-
-    return this;
-  },
-
-  perspective: function (fovy, aspect, nearZ, farZ) {
-    var frustumH = Math.tan(fovy / 360.0 * Math.PI) * nearZ;
-    var frustumW = frustumH * aspect;
-
-    return this.frustum(-frustumW, frustumW, -frustumH, frustumH, nearZ, farZ);
-  },
-
-  ortho: function (left, right, bottom, top, nearZ, farZ) {
-    var deltaX = right - left;
-    var deltaY = top - bottom;
-    var deltaZ = farZ - nearZ;
-
-    var ortho = new Matrix4x4();
-
-    if ( (deltaX == 0.0) || (deltaY == 0.0) || (deltaZ == 0.0) )
-        return this;
-
-    ortho.elements[0*4+0] = 2.0 / deltaX;
-    ortho.elements[3*4+0] = -(right + left) / deltaX;
-    ortho.elements[1*4+1] = 2.0 / deltaY;
-    ortho.elements[3*4+1] = -(top + bottom) / deltaY;
-    ortho.elements[2*4+2] = -2.0 / deltaZ;
-    ortho.elements[3*4+2] = -(nearZ + farZ) / deltaZ;
-
-    ortho = ortho.multiply(this);
-    this.elements = ortho.elements;
-
-    return this;
-  },
-
-  multiply: function (right) {
-    var tmp = new Matrix4x4();
-
-    for (var i = 0; i &lt; 4; i++) {
-      tmp.elements[i*4+0] =
-	(this.elements[i*4+0] * right.elements[0*4+0]) +
-	(this.elements[i*4+1] * right.elements[1*4+0]) +
-	(this.elements[i*4+2] * right.elements[2*4+0]) +
-	(this.elements[i*4+3] * right.elements[3*4+0]) ;
-
-      tmp.elements[i*4+1] =
-	(this.elements[i*4+0] * right.elements[0*4+1]) +
-	(this.elements[i*4+1] * right.elements[1*4+1]) +
-	(this.elements[i*4+2] * right.elements[2*4+1]) +
-	(this.elements[i*4+3] * right.elements[3*4+1]) ;
-
-      tmp.elements[i*4+2] =
-	(this.elements[i*4+0] * right.elements[0*4+2]) +
-	(this.elements[i*4+1] * right.elements[1*4+2]) +
-	(this.elements[i*4+2] * right.elements[2*4+2]) +
-	(this.elements[i*4+3] * right.elements[3*4+2]) ;
-
-      tmp.elements[i*4+3] =
-	(this.elements[i*4+0] * right.elements[0*4+3]) +
-	(this.elements[i*4+1] * right.elements[1*4+3]) +
-	(this.elements[i*4+2] * right.elements[2*4+3]) +
-	(this.elements[i*4+3] * right.elements[3*4+3]) ;
-    }
-
-    this.elements = tmp.elements;
-    return this;
-  },
-
-  loadIdentity: function () {
-    for (var i = 0; i &lt; 16; i++)
-      this.elements[i] = 0;
-    this.elements[0*4+0] = 1.0;
-    this.elements[1*4+1] = 1.0;
-    this.elements[2*4+2] = 1.0;
-    this.elements[3*4+3] = 1.0;
-    return this;
-  }
-};
-
-//adding a simple shape library
-/*
- * Copyright (c) 2009, Mozilla Corp
- * 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 the &lt;organization&gt; 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 &lt;copyright holder&gt; ''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 &lt;copyright holder&gt; 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.
- */
-
-/*
- * Based on sample code from the OpenGL(R) ES 2.0 Programming Guide, which carriers
- * the following header:
- *
- * Book:      OpenGL(R) ES 2.0 Programming Guide
- * Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
- * ISBN-10:   0321502795
- * ISBN-13:   9780321502797
- * Publisher: Addison-Wesley Professional
- * URLs:      http://safari.informit.com/9780321563835
- *            http://www.opengles-book.com
- */
-
-//
-// port of esShapes.c
-//
-
-function shallowCloneArray(ar) {
-  var o = Array(ar.length);
-  for (var i = 0; i &lt; ar.length; i++) {
-    o[i] = ar[i];
-  }
-  return o;
-}
-
-function shallowCloneArrayScaled(ar, scale) {
-  var o = Array(ar.length);
-  for (var i = 0; i &lt; ar.length; i++) {
-    o[i] = ar[i] * scale;
-  }
-  return o;
-}
-
-// make these accessible directly in the glboal scope,
-// in case someone wants to use them without copying
-var esCubeVertices = [
-  -0.5, -0.5, -0.5,
-  -0.5, -0.5,  0.5,
-   0.5, -0.5,  0.5,
-   0.5, -0.5, -0.5,
-  -0.5,  0.5, -0.5,
-  -0.5,  0.5,  0.5,
-   0.5,  0.5,  0.5,
-   0.5,  0.5, -0.5,
-  -0.5, -0.5, -0.5,
-  -0.5,  0.5, -0.5,
-   0.5,  0.5, -0.5,
-   0.5, -0.5, -0.5,
-  -0.5, -0.5, 0.5,
-  -0.5,  0.5, 0.5,
-   0.5,  0.5, 0.5,
-   0.5, -0.5, 0.5,
-  -0.5, -0.5, -0.5,
-  -0.5, -0.5,  0.5,
-  -0.5,  0.5,  0.5,
-  -0.5,  0.5, -0.5,
-   0.5, -0.5, -0.5,
-   0.5, -0.5,  0.5,
-   0.5,  0.5,  0.5,
-   0.5,  0.5, -0.5
-];
-
-var esCubeNormals = [
-   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, 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, 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
-];
-
-var esCubeTexCoords = [
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  1.0, 0.0,
-  1.0, 1.0,
-  0.0, 1.0,
-  0.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0
-];
-
-var esCubeIndices = [
-  0, 2, 1,
-  0, 3, 2,
-  4, 5, 6,
-  4, 6, 7,
-  8, 9, 10,
-  8, 10, 11,
-  12, 15, 14,
-  12, 14, 13,
-  16, 17, 18,
-  16, 18, 19,
-  20, 23, 22,
-  20, 22, 21
-];
-
-// will return an object that has vertices, normals, texCoords, and indices members
-function esGenCube (scale) {
-  return {
-    vertices: shallowCloneArrayScaled(esCubeVertices, scale),
-    texCoords: shallowCloneArray(esCubeTexCoords),
-    indices: shallowCloneArray(esCubeIndices),
-    normals: shallowCloneArray(esCubeNormals)
-  };
-}
-
-//
-// generates coordinate information for a sphere
-//
-
-function esGenSphere (numSlices, radius) {
-  var i, j;
-  var numParallels = numSlices;
-  var numVertices = (numParallels + 1) * (numSlices + 1);
-  var numIndices = numParallels * numSlices * 6;
-  var angleStep = (2 * Math.PI) / numSlices;
-
-  var vertices = Array(3*numVertices);
-  var normals = Array(3*numVertices);
-  var texCoords = Array(2*numVertices);
-  var indices = Array(numIndices);
-
-  for (i = 0; i &lt; numParallels+1; i++) {
-    for (j = 0; j &lt; numSlices+1; j++) {
-      var vertex = (i * (numSlices+1) + j) * 3;
-
-      vertices[vertex+0] = radius * Math.sin(angleStep * i) * Math.sin(angleStep * j);
-      vertices[vertex+1] = radius * Math.cos(angleStep * i);
-      vertices[vertex+2] = radius * Math.sin(angleStep * i) * Math.cos(angleStep * j);
-
-      normals[vertex+0] = vertices[vertex+0] / radius;
-      normals[vertex+1] = vertices[vertex+1] / radius;
-      normals[vertex+2] = vertices[vertex+2] / radius;
-
-      var texIndex = (i * (numSlices+1) + j) * 2;
-
-      texCoords[texIndex+0] = j / numSlices;
-      texCoords[texIndex+1] = (1 - i) / (numParallels - 1);
-    }
-  }
-
-  var k = 0;
-  for (i = 0; i &lt; numParallels; i++) {
-    for (j = 0; j &lt; numSlices; j++) {
-      indices[k++] = i * (numSlices + 1) + j;
-      indices[k++] = (i + 1) * (numSlices + 1) + j;
-      indices[k++] = (i + 1) * (numSlices + 1) + (j + 1);
-
-      indices[k++] = i * (numSlices + 1) + j;
-      indices[k++] = (i + 1) * (numSlices + 1) + (j + 1);
-      indices[k++] = i * (numSlices + 1) + (j + 1);
-    }
-  }
-
-  return {
-    vertices: vertices,
-    normals: normals,
-    texCoords: texCoords,
-    indices: indices
-  };
-}
-
-/*
- * Copyright (c) 2009, Mozilla Corp
- * 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 the &lt;organization&gt; 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 &lt;copyright holder&gt; ''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 &lt;copyright holder&gt; 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.
- */
-
-// convenience function to create a shader from a filepath
-function getShader(filepath, type)
-{
-    var shaderScriptType = type;
-    var shaderPath = filepath;
-
-    if (!shaderPath || shaderPath.length == 0)
-        return 0;
-
-    var shader = Gles.CreateShader(type);
-    
-    if (shader == 0) return 0;
-
-    //added method
-    Gles.ShaderSourceFile(shader, filepath);
-    Gles.CompileShader(shader);
-
-    if (Gles.GetShaderiv(shader, Gles.COMPILE_STATUS) != 1) {
-    	var error = Gles.GetShaderInfoLog(shader);
-    	log(&quot;Error while compiling &quot; + id + &quot;:&quot;);
-    	log(shader);
-
-    	Gles.DeleteShader(shader);
-        return 0;
-    }
-
-    return shader;
-}
-
-// Convenience function to create a program from all the passed-in
-// shader filepaths and types.
-function getProgram() {
-    var shaders = [];
-
-    // first load and compile all the passed-in shaders.
-    for (var i = 0; i &lt; arguments.length; i+=2) {
-    	var shader = getShader(arguments[i], arguments[i+1]);
-    	if (shader == 0)
-    		return 0;
-    	shaders.push(shader);
-    }
-
-    // then do the program object creation
-    var program = Gles.CreateProgram();
-    if (program == 0)
-	return 0;
-
-    // attach all the shaders
-    for (var i = 0; i &lt; shaders.length; i++) {
-    	Gles.AttachShader(program, shaders[i]);
-    }
-
-    // link, and check for errors
-    Gles.LinkProgram(program);
-
-    var linked = Gles.GetProgramiv(program, Gles.LINK_STATUS);
-    if (!linked) {
-    	var error = Gles.GetProgramInfoLog(program);
-    	log(&quot;Error while linking: &quot; + error);
-    	return 0;
-    }
-
-    return program;
-}
-
-//end library code.
-
+//load libraries
+load(&quot;common.js&quot;, &quot;shaderutil.js&quot;);
 
 // an object we'll use to store shaders, textures, etc. on as we create them
 var userData = { };</diff>
      <filename>examples/gles/ch9-simple-texture-cubemap.js</filename>
    </modified>
    <modified>
      <diff>@@ -1,561 +1,5 @@
-//adding matrix 4x4 library
-/*
- * Copyright (c) 2009, Mozilla Corp
- * 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 the &lt;organization&gt; 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 &lt;copyright holder&gt; ''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 &lt;copyright holder&gt; 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.
- */
-
-/*
- * Based on sample code from the OpenGL(R) ES 2.0 Programming Guide, which carriers
- * the following header:
- *
- * Book:      OpenGL(R) ES 2.0 Programming Guide
- * Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
- * ISBN-10:   0321502795
- * ISBN-13:   9780321502797
- * Publisher: Addison-Wesley Professional
- * URLs:      http://safari.informit.com/9780321563835
- *            http://www.opengles-book.com
- */
-
-//
-// A simple 4x4 Matrix utility class
-//
-
-function Matrix4x4() {
-  this.elements = Array(16);
-  this.loadIdentity();
-}
-
-Matrix4x4.prototype = {
-  scale: function (sx, sy, sz) {
-    this.elements[0*4+0] *= sx;
-    this.elements[0*4+1] *= sx;
-    this.elements[0*4+2] *= sx;
-    this.elements[0*4+3] *= sx;
-
-    this.elements[1*4+0] *= sy;
-    this.elements[1*4+1] *= sy;
-    this.elements[1*4+2] *= sy;
-    this.elements[1*4+3] *= sy;
-
-    this.elements[2*4+0] *= sz;
-    this.elements[2*4+1] *= sz;
-    this.elements[2*4+2] *= sz;
-    this.elements[2*4+3] *= sz;
-
-    return this;
-  },
-
-  translate: function (tx, ty, tz) {
-    this.elements[3*4+0] += this.elements[0*4+0] * tx + this.elements[1*4+0] * ty + this.elements[2*4+0] * tz;
-    this.elements[3*4+1] += this.elements[0*4+1] * tx + this.elements[1*4+1] * ty + this.elements[2*4+1] * tz;
-    this.elements[3*4+2] += this.elements[0*4+2] * tx + this.elements[1*4+2] * ty + this.elements[2*4+2] * tz;
-    this.elements[3*4+3] += this.elements[0*4+3] * tx + this.elements[1*4+3] * ty + this.elements[2*4+3] * tz;
-
-    return this;
-  },
-
-  rotate: function (angle, x, y, z) {
-    var mag = Math.sqrt(x*x + y*y + z*z);
-    var sinAngle = Math.sin(angle * Math.PI / 180.0);
-    var cosAngle = Math.cos(angle * Math.PI / 180.0);
-
-    if (mag &gt; 0) {
-      var xx, yy, zz, xy, yz, zx, xs, ys, zs;
-      var oneMinusCos;
-      var rotMat;
-
-      x /= mag;
-      y /= mag;
-      z /= mag;
-
-      xx = x * x;
-      yy = y * y;
-      zz = z * z;
-      xy = x * y;
-      yz = y * z;
-      zx = z * x;
-      xs = x * sinAngle;
-      ys = y * sinAngle;
-      zs = z * sinAngle;
-      oneMinusCos = 1.0 - cosAngle;
-
-      rotMat = new Matrix4x4();
-
-      rotMat.elements[0*4+0] = (oneMinusCos * xx) + cosAngle;
-      rotMat.elements[0*4+1] = (oneMinusCos * xy) - zs;
-      rotMat.elements[0*4+2] = (oneMinusCos * zx) + ys;
-      rotMat.elements[0*4+3] = 0.0;
-
-      rotMat.elements[1*4+0] = (oneMinusCos * xy) + zs;
-      rotMat.elements[1*4+1] = (oneMinusCos * yy) + cosAngle;
-      rotMat.elements[1*4+2] = (oneMinusCos * yz) - xs;
-      rotMat.elements[1*4+3] = 0.0;
-
-      rotMat.elements[2*4+0] = (oneMinusCos * zx) - ys;
-      rotMat.elements[2*4+1] = (oneMinusCos * yz) + xs;
-      rotMat.elements[2*4+2] = (oneMinusCos * zz) + cosAngle;
-      rotMat.elements[2*4+3] = 0.0;
-
-      rotMat.elements[3*4+0] = 0.0;
-      rotMat.elements[3*4+1] = 0.0;
-      rotMat.elements[3*4+2] = 0.0;
-      rotMat.elements[3*4+3] = 1.0;
-
-      rotMat = rotMat.multiply(this);
-      this.elements = rotMat.elements;
-    }
-
-    return this;
-  },
-
-  frustum: function (left, right, bottom, top, nearZ, farZ) {
-    var deltaX = right - left;
-    var deltaY = top - bottom;
-    var deltaZ = farZ - nearZ;
-    var frust;
-
-    if ( (nearZ &lt;= 0.0) || (farZ &lt;= 0.0) ||
-         (deltaX &lt;= 0.0) || (deltaY &lt;= 0.0) || (deltaZ &lt;= 0.0) )
-         return this;
-
-    frust = new Matrix4x4();
-
-    frust.elements[0*4+0] = 2.0 * nearZ / deltaX;
-    frust.elements[0*4+1] = frust.elements[0*4+2] = frust.elements[0*4+3] = 0.0;
-
-    frust.elements[1*4+1] = 2.0 * nearZ / deltaY;
-    frust.elements[1*4+0] = frust.elements[1*4+2] = frust.elements[1*4+3] = 0.0;
-
-    frust.elements[2*4+0] = (right + left) / deltaX;
-    frust.elements[2*4+1] = (top + bottom) / deltaY;
-    frust.elements[2*4+2] = -(nearZ + farZ) / deltaZ;
-    frust.elements[2*4+3] = -1.0;
-
-    frust.elements[3*4+2] = -2.0 * nearZ * farZ / deltaZ;
-    frust.elements[3*4+0] = frust.elements[3*4+1] = frust.elements[3*4+3] = 0.0;
-
-    frust = frust.multiply(this);
-    this.elements = frust.elements;
-
-    return this;
-  },
-
-  perspective: function (fovy, aspect, nearZ, farZ) {
-    var frustumH = Math.tan(fovy / 360.0 * Math.PI) * nearZ;
-    var frustumW = frustumH * aspect;
-
-    return this.frustum(-frustumW, frustumW, -frustumH, frustumH, nearZ, farZ);
-  },
-
-  ortho: function (left, right, bottom, top, nearZ, farZ) {
-    var deltaX = right - left;
-    var deltaY = top - bottom;
-    var deltaZ = farZ - nearZ;
-
-    var ortho = new Matrix4x4();
-
-    if ( (deltaX == 0.0) || (deltaY == 0.0) || (deltaZ == 0.0) )
-        return this;
-
-    ortho.elements[0*4+0] = 2.0 / deltaX;
-    ortho.elements[3*4+0] = -(right + left) / deltaX;
-    ortho.elements[1*4+1] = 2.0 / deltaY;
-    ortho.elements[3*4+1] = -(top + bottom) / deltaY;
-    ortho.elements[2*4+2] = -2.0 / deltaZ;
-    ortho.elements[3*4+2] = -(nearZ + farZ) / deltaZ;
-
-    ortho = ortho.multiply(this);
-    this.elements = ortho.elements;
-
-    return this;
-  },
-
-  multiply: function (right) {
-    var tmp = new Matrix4x4();
-
-    for (var i = 0; i &lt; 4; i++) {
-      tmp.elements[i*4+0] =
-	(this.elements[i*4+0] * right.elements[0*4+0]) +
-	(this.elements[i*4+1] * right.elements[1*4+0]) +
-	(this.elements[i*4+2] * right.elements[2*4+0]) +
-	(this.elements[i*4+3] * right.elements[3*4+0]) ;
-
-      tmp.elements[i*4+1] =
-	(this.elements[i*4+0] * right.elements[0*4+1]) +
-	(this.elements[i*4+1] * right.elements[1*4+1]) +
-	(this.elements[i*4+2] * right.elements[2*4+1]) +
-	(this.elements[i*4+3] * right.elements[3*4+1]) ;
-
-      tmp.elements[i*4+2] =
-	(this.elements[i*4+0] * right.elements[0*4+2]) +
-	(this.elements[i*4+1] * right.elements[1*4+2]) +
-	(this.elements[i*4+2] * right.elements[2*4+2]) +
-	(this.elements[i*4+3] * right.elements[3*4+2]) ;
-
-      tmp.elements[i*4+3] =
-	(this.elements[i*4+0] * right.elements[0*4+3]) +
-	(this.elements[i*4+1] * right.elements[1*4+3]) +
-	(this.elements[i*4+2] * right.elements[2*4+3]) +
-	(this.elements[i*4+3] * right.elements[3*4+3]) ;
-    }
-
-    this.elements = tmp.elements;
-    return this;
-  },
-
-  loadIdentity: function () {
-    for (var i = 0; i &lt; 16; i++)
-      this.elements[i] = 0;
-    this.elements[0*4+0] = 1.0;
-    this.elements[1*4+1] = 1.0;
-    this.elements[2*4+2] = 1.0;
-    this.elements[3*4+3] = 1.0;
-    return this;
-  }
-};
-
-//adding a simple shape library
-/*
- * Copyright (c) 2009, Mozilla Corp
- * 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 the &lt;organization&gt; 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 &lt;copyright holder&gt; ''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 &lt;copyright holder&gt; 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.
- */
-
-/*
- * Based on sample code from the OpenGL(R) ES 2.0 Programming Guide, which carriers
- * the following header:
- *
- * Book:      OpenGL(R) ES 2.0 Programming Guide
- * Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
- * ISBN-10:   0321502795
- * ISBN-13:   9780321502797
- * Publisher: Addison-Wesley Professional
- * URLs:      http://safari.informit.com/9780321563835
- *            http://www.opengles-book.com
- */
-
-//
-// port of esShapes.c
-//
-
-function shallowCloneArray(ar) {
-  var o = Array(ar.length);
-  for (var i = 0; i &lt; ar.length; i++) {
-    o[i] = ar[i];
-  }
-  return o;
-}
-
-function shallowCloneArrayScaled(ar, scale) {
-  var o = Array(ar.length);
-  for (var i = 0; i &lt; ar.length; i++) {
-    o[i] = ar[i] * scale;
-  }
-  return o;
-}
-
-// make these accessible directly in the glboal scope,
-// in case someone wants to use them without copying
-var esCubeVertices = [
-  -0.5, -0.5, -0.5,
-  -0.5, -0.5,  0.5,
-   0.5, -0.5,  0.5,
-   0.5, -0.5, -0.5,
-  -0.5,  0.5, -0.5,
-  -0.5,  0.5,  0.5,
-   0.5,  0.5,  0.5,
-   0.5,  0.5, -0.5,
-  -0.5, -0.5, -0.5,
-  -0.5,  0.5, -0.5,
-   0.5,  0.5, -0.5,
-   0.5, -0.5, -0.5,
-  -0.5, -0.5, 0.5,
-  -0.5,  0.5, 0.5,
-   0.5,  0.5, 0.5,
-   0.5, -0.5, 0.5,
-  -0.5, -0.5, -0.5,
-  -0.5, -0.5,  0.5,
-  -0.5,  0.5,  0.5,
-  -0.5,  0.5, -0.5,
-   0.5, -0.5, -0.5,
-   0.5, -0.5,  0.5,
-   0.5,  0.5,  0.5,
-   0.5,  0.5, -0.5
-];
-
-var esCubeNormals = [
-   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, 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, 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
-];
-
-var esCubeTexCoords = [
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  1.0, 0.0,
-  1.0, 1.0,
-  0.0, 1.0,
-  0.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0,
-  0.0, 0.0,
-  0.0, 1.0,
-  1.0, 1.0,
-  1.0, 0.0
-];
-
-var esCubeIndices = [
-  0, 2, 1,
-  0, 3, 2,
-  4, 5, 6,
-  4, 6, 7,
-  8, 9, 10,
-  8, 10, 11,
-  12, 15, 14,
-  12, 14, 13,
-  16, 17, 18,
-  16, 18, 19,
-  20, 23, 22,
-  20, 22, 21
-];
-
-// will return an object that has vertices, normals, texCoords, and indices members
-function esGenCube (scale) {
-  return {
-    vertices: shallowCloneArrayScaled(esCubeVertices, scale),
-    texCoords: shallowCloneArray(esCubeTexCoords),
-    indices: shallowCloneArray(esCubeIndices),
-    normals: shallowCloneArray(esCubeNormals)
-  };
-}
-
-//
-// generates coordinate information for a sphere
-//
-
-function esGenSphere (numSlices, radius) {
-  var i, j;
-  var numParallels = numSlices;
-  var numVertices = (numParallels + 1) * (numSlices + 1);
-  var numIndices = numParallels * numSlices * 6;
-  var angleStep = (2 * Math.PI) / numSlices;
-
-  var vertices = Array(3*numVertices);
-  var normals = Array(3*numVertices);
-  var texCoords = Array(2*numVertices);
-  var indices = Array(numIndices);
-
-  for (i = 0; i &lt; numParallels+1; i++) {
-    for (j = 0; j &lt; numSlices+1; j++) {
-      var vertex = (i * (numSlices+1) + j) * 3;
-
-      vertices[vertex+0] = radius * Math.sin(angleStep * i) * Math.sin(angleStep * j);
-      vertices[vertex+1] = radius * Math.cos(angleStep * i);
-      vertices[vertex+2] = radius * Math.sin(angleStep * i) * Math.cos(angleStep * j);
-
-      normals[vertex+0] = vertices[vertex+0] / radius;
-      normals[vertex+1] = vertices[vertex+1] / radius;
-      normals[vertex+2] = vertices[vertex+2] / radius;
-
-      var texIndex = (i * (numSlices+1) + j) * 2;
-
-      texCoords[texIndex+0] = j / numSlices;
-      texCoords[texIndex+1] = (1 - i) / (numParallels - 1);
-    }
-  }
-
-  var k = 0;
-  for (i = 0; i &lt; numParallels; i++) {
-    for (j = 0; j &lt; numSlices; j++) {
-      indices[k++] = i * (numSlices + 1) + j;
-      indices[k++] = (i + 1) * (numSlices + 1) + j;
-      indices[k++] = (i + 1) * (numSlices + 1) + (j + 1);
-
-      indices[k++] = i * (numSlices + 1) + j;
-      indices[k++] = (i + 1) * (numSlices + 1) + (j + 1);
-      indices[k++] = i * (numSlices + 1) + (j + 1);
-    }
-  }
-
-  return {
-    vertices: vertices,
-    normals: normals,
-    texCoords: texCoords,
-    indices: indices
-  };
-}
-
-/*
- * Copyright (c) 2009, Mozilla Corp
- * 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 the &lt;organization&gt; 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 &lt;copyright holder&gt; ''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 &lt;copyright holder&gt; 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.
- */
-
-// convenience function to create a shader from a filepath
-function getShader(filepath, type)
-{
-    var shaderScriptType = type;
-    var shaderPath = filepath;
-
-    if (!shaderPath || shaderPath.length == 0)
-        return 0;
-
-    var shader = Gles.CreateShader(type);
-    
-    if (shader == 0) return 0;
-
-    //added method
-    Gles.ShaderSourceFile(shader, filepath);
-    Gles.CompileShader(shader);
-
-    if (Gles.GetShaderiv(shader, Gles.COMPILE_STATUS) != 1) {
-    	var error = Gles.GetShaderInfoLog(shader);
-    	log(&quot;Error while compiling &quot; + id + &quot;:&quot;);
-    	log(shader);
-
-    	Gles.DeleteShader(shader);
-        return 0;
-    }
-
-    return shader;
-}
-
-// Convenience function to create a program from all the passed-in
-// shader filepaths and types.
-function getProgram() {
-    var shaders = [];
-
-    // first load and compile all the passed-in shaders.
-    for (var i = 0; i &lt; arguments.length; i+=2) {
-    	var shader = getShader(arguments[i], arguments[i+1]);
-    	if (shader == 0)
-    		return 0;
-    	shaders.push(shader);
-    }
-
-    // then do the program object creation
-    var program = Gles.CreateProgram();
-    if (program == 0)
-	return 0;
-
-    // attach all the shaders
-    for (var i = 0; i &lt; shaders.length; i++) {
-    	Gles.AttachShader(program, shaders[i]);
-    }
-
-    // link, and check for errors
-    Gles.LinkProgram(program);
-
-    var linked = Gles.GetProgramiv(program, Gles.LINK_STATUS);
-    if (!linked) {
-    	var error = Gles.GetProgramInfoLog(program);
-    	log(&quot;Error while linking: &quot; + error);
-    	return 0;
-    }
-
-    return program;
-}
-
-//end library code.
-
+//load common code.
+load(&quot;common.js&quot;, &quot;shaderutil.js&quot;);
 
 // an object we'll use to store shaders, textures, etc. on as we create them
 var userData = { };</diff>
      <filename>examples/gles/ch9-simple-texture2d.js</filename>
    </modified>
    <modified>
      <diff>@@ -1,21 +1,8 @@
 // This is a hacked up version of vlad's port of FRequency's metatunnel.
 //   http://people.mozilla.com/~vladimir/misc/metatunnel-3d.html
+load(&quot;shaderutil.js&quot;);
 
-var gl = Gles;
-
-gl.getShaderParameter = gl.GetShaderiv;
-gl.getProgramParameter = gl.GetProgramiv;
-
-// Bind Gles.BlahBlah to Gles.blahBlah.
-for (name in Gles) {
-  var x = Gles[name];
-  if (typeof x === 'function') {
-    var lc = name[0].toLowerCase() + name.substr(1);
-    Gles[lc] = x;
-  }
-}
-
-w = 740; h = 480;
+var w = 740, h = 480;
 
 //Initialize Glut
 Glut.Init();
@@ -25,102 +12,43 @@ Glut.InitWindowSize(w, h);
 //Create the window
 Glut.CreateWindow(&quot;OpenGL on V8 baby!&quot;);
 
- var fragment_shader_source = &quot;\n&quot;
-+       &quot;uniform vec4 in_color;\n&quot;
-+	&quot;vec2 v=(gl_FragCoord.xy-vec2(400,300))/vec2(400,300);\n&quot;
-+	&quot;float w=dot(in_color.xyz,vec3(1.0,256.0,65536.0))*.25;\n&quot;
-+	&quot;const float s=0.4;\n&quot;
-
-+	&quot;float obj(vec3 pos){\n&quot;
-+		&quot;float final=1.0;\n&quot;
-+		&quot;final*=distance(pos,vec3(cos(w)+sin(w*0.2),0.3,2.0+cos(w*0.5)*0.5));\n&quot;
-+		&quot;final*=distance(pos,vec3(-cos(w*0.7),0.3,2.0+sin(w*0.5)));\n&quot;
-+		&quot;final*=distance(pos,vec3(-sin(w*0.2)*0.5,sin(w),2.0));\n&quot;
-+		&quot;final *=cos(pos.y)*cos(pos.x)-0.1-cos(pos.z*7.+w*7.)*cos(pos.x*3.)*cos(pos.y*4.)*0.1;\n&quot;
-+		&quot;return final;\n&quot;
-+	&quot;}\n&quot;
-
-+	&quot;void main(){vec3 o=vec3(v.x,v.y*1.25,0.0);\n&quot;
-+		&quot;vec3 d=vec3(v.x+cos(w)*.3,v.y,1.0)/64.0;\n&quot;
-+		&quot;vec4 color=vec4(0.0);\n&quot;
-+		&quot;float t=0.0;\n&quot;
-+		&quot;for(int i=0;i&lt;75;i++) {\n&quot;
-+			&quot;if(obj(o+d*t)&lt;s){\n&quot;
-+				&quot;t-=5.0;\n&quot;
-+				&quot;for(int j=0;j&lt;5;j++){\n&quot;
-+					&quot;if(obj(o+d*t)&lt;s){\n&quot;
-+						&quot;break;\n&quot;
-+					&quot;}\n&quot;
-+					&quot;t+=1.0;\n&quot;
-+				&quot;}\n&quot;
-+				&quot;vec3 e=vec3(0.01,.0,.0);\n&quot;
-+				&quot;vec3 n=vec3(0.0);\n&quot;
-+				&quot;n.x=obj(o+d*t)-obj(vec3(o+d*t+e.xyy));\n&quot;
-+				&quot;n.y=obj(o+d*t)-obj(vec3(o+d*t+e.yxy));\n&quot;
-+				&quot;n.z=obj(o+d*t)-obj(vec3(o+d*t+e.yyx));\n&quot;
-+				&quot;n=normalize(n);\n&quot;
-+				&quot;color+=max(dot(vec3(0.0,0.0,-0.5),n),0.0)+max(dot(vec3(0.0,-0.5,0.5),n),0.0)*0.5;break;\n&quot;
-+			&quot;}\n&quot;
-+			&quot;t+=5.0;\n&quot;
-+		&quot;}\n&quot;
-+		&quot;gl_FragColor=color+vec4(0.1,0.2,0.5,1.0)*(t*0.025);\n&quot;
-+	&quot;}&quot;;
+//Make a program with the following shaders
+var p = getProgram(&quot;shaders/m3d-vshader.sl&quot;, 
+                  Gles.VERTEX_SHADER, 
+                  &quot;shaders/m3d-fshader.sl&quot;, 
+                  Gles.FRAGMENT_SHADER);
 
-  var vertex_shader_source =
-	&quot;attribute vec4 pos; void main() { gl_Position = vec4(pos.x * float(&quot; + w/2 + &quot;), pos.y * float(&quot; + h/2 + &quot;), 0.0, 1.0); }&quot;;
+if (p == 0)
+  return false;
 
-  var buffers = gl.genBuffers(1);
+Gles.UseProgram(p);
 
-  var vs = gl.createShader(gl.VERTEX_SHADER);
-  gl.shaderSource(vs, vertex_shader_source);
-  gl.compileShader(vs);
+// Store our attrib data in a VBO.
+var buffers = Gles.GenBuffers(1);
+Gles.BindBuffer(Gles.ARRAY_BUFFER, buffers[0]);
+Gles.BufferData(Gles.ARRAY_BUFFER, [ -1, 1, 1, 1, -1, -1, 1, -1], Gles.FLOAT, Gles.STATIC_DRAW);
 
-  var fs = gl.createShader(gl.FRAGMENT_SHADER);
-  gl.shaderSource(fs, fragment_shader_source);
-  gl.compileShader(fs);
-  if (gl.getShaderParameter(fs, gl.COMPILE_STATUS) != 1) {
-    var error = gl.getShaderInfoLog(fs);
-    return;
-  }
+Gles.VertexAttribPointer(0, 2, Gles.FLOAT, false, 0, 0);
+Gles.EnableVertexAttribArray(0);
 
-  p = gl.createProgram();
-  gl.attachShader(p, vs);
-  gl.attachShader(p, fs);
-  gl.linkProgram(p);
+function draw() {
+  Gles.Viewport(0, 0, w, h);
+  var n = Date.now();
+  var r = n &amp; 0xff;
+  var g = (n&gt;&gt;8) &amp; 0xff;
+  var b = (n&gt;&gt;16) &amp; 0xff;
+  Gles.Uniform4fv(0, 1, [r/255.0, g/255.0, b/255.0, 1.0]);
+  Gles.DrawArrays(Gles.TRIANGLE_STRIP, 0, 4);
 
-  var linked = gl.getProgramParameter(p, gl.LINK_STATUS);
-  if (!linked) {
-    var error = gl.getProgramInfoLog(p);
-    return 0;
-  }
-
-  gl.useProgram(p);
-
-  // Store our attrib data in a VBO.
-  gl.bindBuffer(gl.ARRAY_BUFFER, buffers[0]);
-  gl.bufferData(gl.ARRAY_BUFFER, [ -1, 1, 1, 1, -1, -1, 1, -1], gl.FLOAT, gl.STATIC_DRAW);
-
-  gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
-  gl.enableVertexAttribArray(0);
-  
-  function draw() {
-    gl.viewport(0, 0, w, h);
-    var n = Date.now();
-    r = n &amp; 0xff;
-    g = (n&gt;&gt;8) &amp; 0xff;
-    b = (n&gt;&gt;16) &amp; 0xff;
-    gl.uniform4fv(0, 1, [r/255.0, g/255.0, b/255.0, 1.0]);
-    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
-
-    Glut.SwapBuffers();
-  }
+  Glut.SwapBuffers();
+}
 
-  Glut.DisplayFunc(draw);
+Glut.DisplayFunc(draw);
 
-  //Set timeout callback
-  Glut.TimerFunc(25, function() {
-    Glut.PostRedisplay();
-    Glut.TimerFunc(25, arguments.callee, 0);
-  }, 0);
+//Set timeout callback
+Glut.TimerFunc(25, function() {
+  Glut.PostRedisplay();
+  Glut.TimerFunc(25, arguments.callee, 0);
+}, 0);
 
-  Glut.MainLoop();
+Glut.MainLoop();</diff>
      <filename>examples/gles/metatunnel-3d.js</filename>
    </modified>
    <modified>
      <diff>@@ -22,7 +22,6 @@ using namespace v8;
 
 Persistent&lt;Object&gt; GlesFactory::self_;
 Persistent&lt;Context&gt; GlesFactory::gles_persistent_context;
-char* GlesFactory::root_path;
 // glGenBuffers uses an output parameter to return an array of ints.
 Handle&lt;Value&gt; GLESglGenBuffersCallback(const Arguments&amp; args) {
   if (args.Length() != 1)
@@ -1021,6 +1020,8 @@ Handle&lt;Value&gt; GLESglGetVertexAttribCallback(const Arguments&amp; args) {
   return v8::Undefined();
 }
 
+
+
 Handle&lt;Value&gt; GLESglTexImage2DCallback(const Arguments&amp; args) {
 
   if (args.Length() != 9) return v8::Undefined();
@@ -1195,6 +1196,33 @@ Handle&lt;Value&gt; GLESglTexImage2DCallback(const Arguments&amp; args) {
   return v8::Undefined();
 }
 
+Handle&lt;Value&gt; GLESglTexImage2DFileCallback(const Arguments&amp; args) {
+
+  if (args.Length() != 1) return v8::Undefined();
+  //define handle scope
+  HandleScope handle_scope;
+  //get arguments
+  String::Utf8Value value(args[0]);
+  char* filepath_str = *value;
+
+  char* filename = Utils::getRealPath(filepath_str);
+
+  //take care of relative/absolute paths.
+  Image* img = loadPNG(filename);
+
+  glTexImage2D(GL_TEXTURE_2D,  // target
+		  0,		  // level
+		  GL_RGB,	  // interal format
+		  img-&gt;width, img-&gt;height, // width, height
+		  0,		  // border
+		  GL_RGB,	  // format
+		  GL_UNSIGNED_BYTE, // type
+		  (const void*)img-&gt;pixels);
+
+  delete[] filename;
+
+  return v8::Undefined();
+}
 
 
 Handle&lt;Value&gt; GLESglTexSubImage2DCallback(const Arguments&amp; args) {
@@ -1506,17 +1534,7 @@ Handle&lt;Value&gt; GLESglShaderSourceFileCallback(const Arguments&amp; args) {
     return v8::Undefined();
 
   char* filepath_str = *filepath_ascii;
-
-  //read the file source
-  char* filename = NULL;
-  if(filepath_str[0] != '/') {
-	  filename = new char[strlen(GlesFactory::root_path) + strlen(filepath_str) +1];
-	  strcpy(filename, GlesFactory::root_path);
-	  strcat(filename, filepath_str);
-  } else {
-	  filename = new char[strlen(filepath_str) +1];
-	  strcpy(filename, filepath_str);
-  }
+  char* filename = Utils::getRealPath(filepath_str);
 
   std::ifstream in_file(filename);
 
@@ -4612,6 +4630,8 @@ Handle&lt;ObjectTemplate&gt; GlesFactory::createGles(void) {
 
      Gles-&gt;Set(String::NewSymbol(&quot;ShaderSourceFile&quot;), FunctionTemplate::New(GLESglShaderSourceFileCallback));
 
+     Gles-&gt;Set(String::NewSymbol(&quot;TexImage2DFile&quot;), FunctionTemplate::New(GLESglTexImage2DFileCallback));
+
 
       // Again, return the result through the current handle scope.
       return handle_scope.Close(Gles);</diff>
      <filename>glesbindings/glesbind.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -7,14 +7,14 @@
 #define GLESBIND_H_
 
 #include &lt;v8.h&gt;
+#include &quot;../utils.h&quot;
+#include &quot;../imageloader.h&quot;
 
 class GlesFactory {
 public:
 	static v8::Handle&lt;v8::ObjectTemplate&gt; createGles(void);
-
-	static v8::Persistent&lt;v8::Object&gt; self_;
 	static v8::Persistent&lt;v8::Context&gt; gles_persistent_context;
-	static char* root_path;
+	static v8::Persistent&lt;v8::Object&gt; self_;
 };
 
 #endif /* GLESBIND_H_ */</diff>
      <filename>glesbindings/glesbind.h</filename>
    </modified>
    <modified>
      <diff>@@ -83,7 +83,8 @@ accessor_extras = ['glGetParameter',
                    'glGetTexParameter', 
                    'glGetVertexAttrib', 
                    'glGetRenderbufferParameter',
-                   'glShaderSourceFile']
+                   'glShaderSourceFile',
+                   'glTexImage2DFile']
 
 EXCLUDE = re.compile(exclude, re.VERBOSE)
 TEMPLATE = re.compile(template, re.VERBOSE)
@@ -149,7 +150,6 @@ using namespace v8;
 
 Persistent&lt;Object&gt; GlesFactory::self_;
 Persistent&lt;Context&gt; GlesFactory::gles_persistent_context;
-char* GlesFactory::root_path;
 &quot;&quot;&quot; + custom_code  + '\n'.join(text_out) + '\n' + generate_main_function(constants, functions))
 
 </diff>
      <filename>glesbindings/glesbind.py</filename>
    </modified>
    <modified>
      <diff>@@ -996,6 +996,8 @@ Handle&lt;Value&gt; GLESglGetVertexAttribCallback(const Arguments&amp; args) {
   return v8::Undefined();
 }
 
+
+
 Handle&lt;Value&gt; GLESglTexImage2DCallback(const Arguments&amp; args) {
 
   if (args.Length() != 9) return v8::Undefined();
@@ -1170,6 +1172,33 @@ Handle&lt;Value&gt; GLESglTexImage2DCallback(const Arguments&amp; args) {
   return v8::Undefined();
 }
 
+Handle&lt;Value&gt; GLESglTexImage2DFileCallback(const Arguments&amp; args) {
+
+  if (args.Length() != 1) return v8::Undefined();
+  //define handle scope
+  HandleScope handle_scope;
+  //get arguments
+  String::Utf8Value value(args[0]);
+  char* filepath_str = *value;
+
+  char* filename = Utils::getRealPath(filepath_str);
+
+  //take care of relative/absolute paths.
+  Image* img = loadPNG(filename);
+
+  glTexImage2D(GL_TEXTURE_2D,  // target
+		  0,		  // level
+		  GL_RGB,	  // interal format
+		  img-&gt;width, img-&gt;height, // width, height
+		  0,		  // border
+		  GL_RGB,	  // format
+		  GL_UNSIGNED_BYTE, // type
+		  (const void*)img-&gt;pixels);
+
+  delete[] filename;
+
+  return v8::Undefined();
+}
 
 
 Handle&lt;Value&gt; GLESglTexSubImage2DCallback(const Arguments&amp; args) {
@@ -1481,17 +1510,7 @@ Handle&lt;Value&gt; GLESglShaderSourceFileCallback(const Arguments&amp; args) {
     return v8::Undefined();
 
   char* filepath_str = *filepath_ascii;
-
-  //read the file source
-  char* filename = NULL;
-  if(filepath_str[0] != '/') {
-	  filename = new char[strlen(GlesFactory::root_path) + strlen(filepath_str) +1];
-	  strcpy(filename, GlesFactory::root_path);
-	  strcat(filename, filepath_str);
-  } else {
-	  filename = new char[strlen(filepath_str) +1];
-	  strcpy(filename, filepath_str);
-  }
+  char* filename = Utils::getRealPath(filepath_str);
 
   std::ifstream in_file(filename);
 </diff>
      <filename>glesbindings/glescustom.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -20,27 +20,6 @@ void ParseOptions(int argc,
   }
 }
 
-// Reads a file into a v8 string.
-Handle&lt;String&gt; ReadFile(const string&amp; name) {
-  FILE* file = fopen(name.c_str(), &quot;rb&quot;);
-  if (file == NULL) return Handle&lt;String&gt;();
-
-  fseek(file, 0, SEEK_END);
-  int size = ftell(file);
-  rewind(file);
-
-  char* chars = new char[size + 1];
-  chars[size] = '\0';
-  for (int i = 0; i &lt; size;) {
-    int read = fread(&amp;chars[i], 1, size - i, file);
-    i += read;
-  }
-  fclose(file);
-  Handle&lt;String&gt; result = String::New(chars, size);
-  delete[] chars;
-  return result;
-}
-
 int main(int argc, char* argv[]) {
 	  string file;
 	  ParseOptions(argc, argv, &amp;file);
@@ -49,14 +28,8 @@ int main(int argc, char* argv[]) {
 	    return 1;
 	  }
 
-	  HandleScope scope;
-	  Handle&lt;String&gt; source = ReadFile(file);
-	  if (source.IsEmpty()) {
-	    fprintf(stderr, &quot;Error reading '%s'.\n&quot;, file.c_str());
-	    return 1;
-	  }
-	  V8GL v8gl(source);
-	  if(!v8gl.initialize(&amp;argc, argv)) {
+	  V8GL v8gl;
+	  if(!v8gl.initialize(&amp;argc, argv, file)) {
 		    fprintf(stderr, &quot;Error initializing script.\n&quot;);
 		    return 1;
 	  }</diff>
      <filename>main.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -5,53 +5,118 @@
 
 #include &quot;v8-gl.h&quot;
 #include &lt;stdio.h&gt;
+#include &lt;string&gt;
 #include &lt;string.h&gt;
 
-Handle&lt;Value&gt; log(const Arguments&amp; args) {
-  //if less that nbr of formal parameters then do nothing
-  if (args.Length() &lt; 1) return v8::Undefined();
-  //define handle scope
-  HandleScope scope;
-  //get arguments
-  String::Utf8Value value0(args[0]);
-  char* arg0 = *value0;
+Persistent&lt;Context&gt; V8GL::context;
 
-  //make call
-  fprintf(stdout, &quot;%s&quot;, arg0);
-  return v8::Undefined();
-}
+//UTILITY FUNCTIONS
+// Reads a file into a v8 string.
+Handle&lt;String&gt; ReadFile(const string&amp; name) {
+  FILE* file = fopen(name.c_str(), &quot;rb&quot;);
+  if (file == NULL) return Handle&lt;String&gt;();
 
-V8GL::V8GL(Handle&lt;String&gt; script) : script_(script) {};
+  fseek(file, 0, SEEK_END);
+  int size = ftell(file);
+  rewind(file);
 
-bool V8GL::executeScript() {
+  char* chars = new char[size + 1];
+  chars[size] = '\0';
+  for (int i = 0; i &lt; size;) {
+    int read = fread(&amp;chars[i], 1, size - i, file);
+    i += read;
+  }
+  fclose(file);
+  Handle&lt;String&gt; result = String::New(chars, size);
+  delete[] chars;
+  return result;
+}
+
+bool exec(string file) {
   HandleScope handle_scope;
+  Handle&lt;String&gt; source = ReadFile(file);
+
+  if (source.IsEmpty()) {
+	fprintf(stderr, &quot;Error reading '%s'.\n&quot;, file.c_str());
+	return false;
+  }
 
   // We're just about to compile the script; set up an error handler to
   // catch any exceptions the script might throw.
   TryCatch try_catch;
 
   // Compile the script and check for errors.
-  Handle&lt;Script&gt; compiled_script = Script::Compile(script_);
+  Handle&lt;Script&gt; compiled_script = Script::Compile(source);
   if (compiled_script.IsEmpty()) {
-    String::Utf8Value error(try_catch.Exception());
-    printf(&quot;%s \n\n&quot;, *error);
-    // The script failed to compile; bail out.
-    return false;
+	String::Utf8Value error(try_catch.Exception());
+	printf(&quot;%s \n\n&quot;, *error);
+	// The script failed to compile; bail out.
+	return false;
   }
 
   // Run the script!
   Handle&lt;Value&gt; result = compiled_script-&gt;Run();
   if (result.IsEmpty()) {
-    // The TryCatch above is still in effect and will have caught the error.
-    String::Utf8Value error(try_catch.Exception());
-    printf(&quot;%s \n\n&quot;, *error);
-    // Running the script failed; bail out.
-    return false;
+	// The TryCatch above is still in effect and will have caught the error.
+	String::Utf8Value error(try_catch.Exception());
+	printf(&quot;%s \n\n&quot;, *error);
+	// Running the script failed; bail out.
+	return false;
   }
   return true;
 }
 
-bool V8GL::initialize(int* pargc, char** argv) {
+
+//FUNCTIONS IN GLOBAL SCOPE
+
+//prints a string to stdout
+Handle&lt;Value&gt; log(const Arguments&amp; args) {
+  //if less that nbr of formal parameters then do nothing
+  if (args.Length() &lt; 1) return v8::Undefined();
+  //define handle scope
+  HandleScope scope;
+  //get arguments
+  String::Utf8Value value0(args[0]);
+  char* arg0 = *value0;
+
+  //make call
+  fprintf(stdout, &quot;%s&quot;, arg0);
+  return v8::Undefined();
+}
+
+//loads a js file
+Handle&lt;Value&gt; load(const Arguments&amp; args) {
+  //if less that nbr of formal parameters then do nothing
+  int len = args.Length();
+  int i;
+
+  if (len &lt; 1) return v8::Undefined();
+  //define handle scope
+  HandleScope scope;
+
+  // Enter the new context so all the following operations take place
+  // within it.
+  Context::Scope context_scope(V8GL::context);
+
+  for (i = 0; i &lt; len; ++i) {
+	  //get argument
+	  String::Utf8Value value0(args[i]);
+	  char* arg0 = *value0;
+	  string str(Utils::getRealPath(arg0));
+	  if(!exec(str)) {
+		  fprintf(stderr, &quot;Error reading '%s'.\n&quot;, arg0);
+		  return v8::Undefined();
+	  }
+  }
+
+  return v8::Undefined();
+}
+
+bool V8GL::executeScript(string file) {
+	return exec(file);
+}
+
+bool V8GL::initialize(int* pargc, char** argv, string scriptname) {
 	  // Create a handle scope to hold the temporary references.
 	  HandleScope handle_scope;
 
@@ -64,16 +129,20 @@ bool V8GL::initialize(int* pargc, char** argv) {
 	  Handle&lt;ObjectTemplate&gt; Gl = GlFactory::createGl();
 	  Handle&lt;ObjectTemplate&gt; Gles = GlesFactory::createGles();
 
+	  //Set global objects and functions.
 	  global-&gt;Set(String::New(&quot;Gl&quot;), Gl);
 	  global-&gt;Set(String::New(&quot;Gles&quot;), Gles);
 	  global-&gt;Set(String::New(&quot;Glu&quot;), createGlu());
 	  global-&gt;Set(String::New(&quot;Glut&quot;), GlutFactory::createGlut(pargc, argv));
 	  global-&gt;Set(String::New(&quot;log&quot;), FunctionTemplate::New(log));
+	  global-&gt;Set(String::New(&quot;load&quot;), FunctionTemplate::New(load));
 
 	  Handle&lt;Context&gt; context = Context::New(NULL, global);
 
-	  GlutFactory::glut_persistent_context = Persistent&lt;Context&gt;::New(context);
-	  GlesFactory::gles_persistent_context = Persistent&lt;Context&gt;::New(context);
+	  //TODO(nico): should find another way to set the right context when calling a func.
+	  V8GL::context = Persistent&lt;Context&gt;::New(context);
+	  GlutFactory::glut_persistent_context = V8GL::context;
+	  GlesFactory::gles_persistent_context = V8GL::context;
 
 	  // Enter the new context so all the following operations take place
 	  // within it.
@@ -83,32 +152,12 @@ bool V8GL::initialize(int* pargc, char** argv) {
 	  GlFactory::self_ = Persistent&lt;Object&gt;::New(Gl-&gt;NewInstance());
 	  GlesFactory::self_ = Persistent&lt;Object&gt;::New(Gles-&gt;NewInstance());
 
-	  //Set the root_path for opening shader files with
-	  //relative paths
-	  //take path from executable
-	  char* pch = strrchr(argv[0], '/');
-	  int last_index = pch - argv[0] +1;
-	  char* tmp_exec_path = new char[last_index +1];
-	  strncpy(tmp_exec_path, argv[0], last_index);
-	  tmp_exec_path[last_index] = '\0';
-
-	  //take relative path from javascript file
-	  char* p1ch = strrchr(argv[1], '/');
-	  int last_index1 = p1ch - argv[1] +1;
-	  char* tmp_js_path = new char[last_index1 +1];
-	  strncpy(tmp_js_path, argv[1], last_index1);
-	  tmp_js_path[last_index1] = '\0';
-
-	  GlesFactory::root_path = new char[last_index + last_index1 +1];
-	  strcpy(GlesFactory::root_path, tmp_exec_path);
-	  strcat(GlesFactory::root_path, tmp_js_path);
-
-	  delete[] tmp_exec_path;
-	  delete[] tmp_js_path;
+	  //Set (only once) the absolute path for the .js file being executed.
+	  Utils::setRootPath(argv[0], argv[1]);
+
 	  // Compile and run the script
-	  if (!executeScript())
+	  if (!executeScript(scriptname))
 		return false;
 
-
 	  return true;
 }</diff>
      <filename>v8-gl.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -7,6 +7,7 @@
 
 #include &lt;v8-debug.h&gt;
 
+#include &quot;utils.h&quot;
 #include &quot;glbindings/glbind.h&quot;
 #include &quot;glesbindings/glesbind.h&quot;
 #include &quot;glubindings/glubind.h&quot;
@@ -18,14 +19,11 @@ using namespace v8;
 class V8GL {
 
 public:
-	V8GL(Handle&lt;String&gt; script);
-
-	bool initialize(int* pargc, char** argv);
-	bool executeScript();
-
-private:
-	Handle&lt;String&gt; script_;
+	bool initialize(int* pargc, char** argv, string scriptname);
+	bool executeScript(string scriptname);
 
+	//keep a reference to the global context.
+	static Persistent&lt;Context&gt; context;
 };
 
 #endif /* V8GL_H_ */</diff>
      <filename>v8-gl.h</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>f7b0d1a0f084bdd7cac7c1ea247c093e9085deaa</id>
    </parent>
  </parents>
  <author>
    <name>philogb</name>
    <email>philogb@gmail.com</email>
  </author>
  <url>http://github.com/philogb/v8-gl/commit/50431dcb7c4f1079c3ab5ec1c6fb3e1e772358a7</url>
  <id>50431dcb7c4f1079c3ab5ec1c6fb3e1e772358a7</id>
  <committed-date>2009-10-16T13:13:08-07:00</committed-date>
  <authored-date>2009-10-16T13:13:08-07:00</authored-date>
  <message>Added a load function to load js files. Clean up.</message>
  <tree>084310962a8794daaf53d5afe3b009204395394b</tree>
  <committer>
    <name>philogb</name>
    <email>philogb@gmail.com</email>
  </committer>
</commit>
