Commits

Diego Cantor committed afc8184

Revisions for chapters 1-5 implemented

Comments (0)

Files changed (33)

1727_03/ch3_Ambient_Test.html

+<html>
+
+<head>
+<title>WebGL Beginner's Guide - Chapter 3 - Ambient Test</title>
+<meta http-equiv='content-type' content='text/html; charset=ISO-8859-1'>
+
+<!-- CSS Styles //-->
+<link href='css/style.css' 		type='text/css' rel='stylesheet'>
+<link href='css/desert.css' 	type='text/css' rel='stylesheet'/>
+<link href='css/colorpicker.css' 	type='text/css' rel='stylesheet'/>
+<link href='css/smoothness/jquery-ui-1.8.13.custom.css' type='text/css' rel='stylesheet' />
+
+<!-- JavaScript Libraries //-->
+<script type='text/javascript' src='js/glMatrix-0.9.5.min.js'></script>
+<script type='text/javascript' src='js/jquery-1.5.1.min.js'></script>
+<script type='text/javascript' src='js/jquery-ui-1.8.13.custom.min.js'></script> 
+<script type='text/javascript' src='js/prettify.js'></script>
+<script type='text/javascript' src='js/utils.js'></script>
+<script type='text/javascript' src='js/colorpicker.js'></script>
+<script type='text/javascript' src='js/codeview.js'></script>
+
+
+<script id="shader-vs" type="x-shader/x-vertex">
+attribute vec3 aVertexPosition;
+attribute vec3 aVertexNormal;
+
+uniform mat4 uMVMatrix; 
+uniform mat4 uPMatrix; 
+uniform mat4 uNMatrix;
+ 
+uniform float uShininess;		 //shininness
+uniform vec3 uLightDirection;	 //light direction
+
+uniform vec4 uLightAmbient;      //light ambient property
+uniform vec4 uLightDiffuse;      //light diffuse property 
+uniform vec4 uLightSpecular;     //light specular property
+
+uniform vec4 uMaterialAmbient;	 //object ambient property
+uniform vec4 uMaterialDiffuse;   //object diffuse property
+uniform vec4 uMaterialSpecular;  //object specular property
+
+varying vec4 vFinalColor;
+
+void main(void) {
+
+	//Transformed vertex position
+	vec4 vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
+	
+	//Transformed normal position
+    vec3 N = vec3(uNMatrix * vec4(aVertexNormal, 1.0));
+	
+	//Invert and normalize light to calculate lambertTerm
+    vec3 L = normalize(uLightDirection); 
+	
+	//Lambert's cosine law
+	float lambertTerm = clamp(dot(N,-L),0.0,1.0);
+	
+	//Ambient Term
+    vec4 Ia = uLightAmbient * uMaterialAmbient;
+	
+	//Diffuse Term
+	vec4 Id = vec4(0.0,0.0,0.0,1.0);
+	
+	//Specular Term
+	vec4 Is = vec4(0.0,0.0,0.0,1.0);
+    
+	
+    Id = uLightDiffuse* uMaterialDiffuse * lambertTerm; //add diffuse term
+    
+    vec3 eyeVec = -vec3(vertex.xyz);
+    vec3 E = normalize(eyeVec);
+    vec3 R = reflect(L, N);
+    float specular = pow(max(dot(R, E), 0.0), uShininess );
+    
+    Is = uLightSpecular * uMaterialSpecular * specular;	//add specular term
+
+	
+	//Final color
+	vFinalColor = Ia + Id + Is;
+	vFinalColor.a = 1.0;
+
+	//Transformed vertex position
+	gl_Position = uPMatrix * vertex;
+}
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision highp float;
+#endif
+
+varying vec4 vFinalColor;
+
+void main(void)
+{
+	gl_FragColor = vFinalColor;
+}
+</script>
+
+
+<script id='code-js' type="text/javascript">
+
+var gl = null; // WebGL context
+var prg = null; // The program (shaders)
+var c_width = 0; // Variable to store the width of the canvas
+var c_height = 0; // Variable to store the height of the canvas
+var clearColor = [0.3,0.3,0.3,1.0];
+
+var mvMatrix = mat4.create(); // The Model-View matrix
+var pMatrix = mat4.create(); // The projection matrix
+
+/*-----------------------------------------------------*/
+var nMatrix =  mat4.create();      // The normal matrix
+/*-----------------------------------------------------*/
+
+var sphereVerticesBuffer;
+var sphereIndicesBuffer;
+
+/*-----------------------------------------------------*/
+var sphereNormalsBuffer;              //VBO for Normals
+/*-----------------------------------------------------*/
+
+
+var vertices;
+var indices;
+/*-----------------------------------------------------*/
+var normals;              //JavaScript Array for Normals
+/*-----------------------------------------------------*/
+
+var angle = 0;
+
+/**
+* The program contains a series of instructions that tell the Graphic Processing Unit (GPU)
+* what to do with every vertex and fragment that we pass it. 
+* The vertex shader and the fragment shader together are called the program.
+*/
+function initProgram() {
+	var fragmentShader        = utils.getShader(gl, "shader-fs");
+    var vertexShader          = utils.getShader(gl, "shader-vs");
+	prg = gl.createProgram();
+	gl.attachShader(prg, vertexShader);
+	gl.attachShader(prg, fragmentShader);
+	gl.linkProgram(prg);
+
+	if (!gl.getProgramParameter(prg, gl.LINK_STATUS)) {
+		alert("Could not initialise shaders");
+	}
+
+	gl.useProgram(prg);
+
+	prg.aVertexPosition    = gl.getAttribLocation(prg, "aVertexPosition");
+	prg.aVertexNormal      = gl.getAttribLocation(prg, "aVertexNormal");
+		
+	prg.uPMatrix   		   = gl.getUniformLocation(prg, "uPMatrix");
+	prg.uMVMatrix  	       = gl.getUniformLocation(prg, "uMVMatrix");
+	prg.uNMatrix           = gl.getUniformLocation(prg, "uNMatrix");
+	
+	prg.uMaterialAmbient	= gl.getUniformLocation(prg, "uMaterialAmbient");	
+	prg.uMaterialDiffuse    = gl.getUniformLocation(prg, "uMaterialDiffuse");
+	prg.uMaterialSpecular	= gl.getUniformLocation(prg, "uMaterialSpecular");
+	
+	prg.uShininess         	= gl.getUniformLocation(prg, "uShininess");
+	
+	prg.uLightAmbient     	= gl.getUniformLocation(prg, "uLightAmbient");
+	prg.uLightDiffuse       = gl.getUniformLocation(prg, "uLightDiffuse");
+	prg.uLightSpecular		= gl.getUniformLocation(prg, "uLightSpecular");
+	
+	prg.uLightDirection    	= gl.getUniformLocation(prg, "uLightDirection");
+
+}
+
+
+function initLights(){
+	gl.uniform3fv(prg.uLightDirection, [-0.25, -0.25, -0.25]);
+	gl.uniform4fv(prg.uLightAmbient,[0.03,0.03,0.03,1.0]);
+	gl.uniform4fv(prg.uLightDiffuse, [1.0,1.0,1.0,1.0]);	
+	gl.uniform4fv(prg.uLightSpecular, [1.0,1.0,1.0,1.0]);
+    
+	gl.uniform4fv(prg.uMaterialAmbient, [1.0,1.0,1.0,1.0]);
+	gl.uniform4fv(prg.uMaterialDiffuse, [46/256,99/256,191/256,1.0]);
+	gl.uniform4fv(prg.uMaterialSpecular, [1.0,1.0,1.0,1.0]);
+    gl.uniform1f(prg.uShininess, 10.0);
+}
+
+/**
+* This function generates SPHERE data and creates the buffers
+*/
+function initBuffers()
+{
+	vertices = [0.0540595,0.0,0.497069,0.0528782,0.0112396,0.497069,0.0,0.0,0.5,0.0493858,0.021988,0.497069,0.0437351,0.0317754,0.497069,0.0361729,0.040174,0.497069,0.0270298,0.0468169,0.497069,0.0167053,0.0514137,0.497069,0.00565076,0.0537634,0.497069,-0.00565076,0.0537634,0.497069,-0.0167053,0.0514136,0.497069,-0.0270298,0.0468169,0.497069,-0.0361729,0.040174,0.497069,-0.0437351,0.0317754,0.497069,-0.0493858,0.021988,0.497069,-0.0528782,0.0112396,0.497069,-0.0540595,-4.72603e-09,0.497069,-0.0528782,-0.0112396,0.497069,-0.0493858,-0.021988,0.497069,-0.0437351,-0.0317754,0.497069,-0.0361729,-0.040174,0.497069,-0.0270297,-0.0468169,0.497069,-0.0167053,-0.0514137,0.497069,-0.00565075,-0.0537634,0.497069,0.00565076,-0.0537634,0.497069,0.0167053,-0.0514136,0.497069,0.0270298,-0.0468169,0.497069,0.0361729,-0.040174,0.497069,0.0437351,-0.0317754,0.497069,0.0493858,-0.021988,0.497069,0.0528782,-0.0112396,0.497069,0.0540595,0.0,-0.497069,0.0,0.0,-0.5,0.0528781,0.0112396,-0.497069,0.0493858,0.021988,-0.497069,0.043735,0.0317754,-0.497069,0.0361728,0.040174,-0.497069,0.0270297,0.0468169,-0.497069,0.0167053,0.0514136,-0.497069,0.00565075,0.0537633,-0.497069,-0.00565076,0.0537633,-0.497069,-0.0167053,0.0514136,-0.497069,-0.0270297,0.0468169,-0.497069,-0.0361728,0.040174,-0.497069,-0.043735,0.0317754,-0.497069,-0.0493858,0.021988,-0.497069,-0.0528781,0.0112396,-0.497069,-0.0540595,-4.72603e-09,-0.497069,-0.0528781,-0.0112396,-0.497069,-0.0493858,-0.021988,-0.497069,-0.043735,-0.0317754,-0.497069,-0.0361728,-0.040174,-0.497069,-0.0270297,-0.0468169,-0.497069,-0.0167053,-0.0514136,-0.497069,-0.00565075,-0.0537633,-0.497069,0.00565076,-0.0537633,-0.497069,0.0167053,-0.0514136,-0.497069,0.0270297,-0.0468169,-0.497069,0.0361729,-0.040174,-0.497069,0.043735,-0.0317754,-0.497069,0.0493858,-0.021988,-0.497069,0.0528781,-0.0112396,-0.497069,0.107485,0.0,0.48831,0.105136,0.0223474,0.48831,0.159651,0.0,0.473827,0.156162,0.0331933,0.473827,0.209945,0.0,0.453788,0.205357,0.0436499,0.453788,0.257777,0.0,0.428429,0.252144,0.0535948,0.428429,0.302587,0.0,0.398047,0.295975,0.0629114,0.398047,0.34385,0.0,0.362998,0.336336,0.0714904,0.362998,0.381081,0.0,0.323693,0.372754,0.0792312,0.323693,0.413844,0.0,0.280594,0.404801,0.0860431,0.280594,0.441756,0.0,0.234204,0.432103,0.0918462,0.234204,0.464488,0.0,0.185069,0.454338,0.0965726,0.185069,0.481775,0.0,0.133764,0.471247,0.100167,0.133764,0.493413,0.0,0.080891,0.482631,0.102586,0.080891,0.499267,0.0,0.0270694,0.488357,0.103803,0.0270694,0.499267,0.0,-0.0270695,0.488357,0.103803,-0.0270695,0.493413,0.0,-0.080891,0.482631,0.102586,-0.080891,0.481775,0.0,-0.133764,0.471247,0.100167,-0.133764,0.464488,0.0,-0.185069,0.454338,0.0965726,-0.185069,0.441756,0.0,-0.234204,0.432103,0.0918462,-0.234204,0.413844,0.0,-0.280594,0.404801,0.0860431,-0.280594,0.381081,0.0,-0.323693,0.372753,0.0792312,-0.323693,0.34385,0.0,-0.362998,0.336336,0.0714904,-0.362998,0.302587,0.0,-0.398047,0.295975,0.0629114,-0.398047,0.257777,0.0,-0.428429,0.252144,0.0535948,-0.428429,0.209945,0.0,-0.453788,0.205357,0.0436499,-0.453788,0.159651,0.0,-0.473827,0.156162,0.0331933,-0.473827,0.107485,0.0,-0.48831,0.105136,0.0223474,-0.48831,0.0981926,0.0437182,0.48831,0.145848,0.0649358,0.473827,0.191794,0.0853921,0.453788,0.235491,0.104847,0.428429,0.276427,0.123073,0.398047,0.314122,0.139856,0.362998,0.348135,0.155,0.323693,0.378066,0.168326,0.280594,0.403564,0.179678,0.234204,0.424331,0.188924,0.185069,0.440123,0.195956,0.133764,0.450755,0.200689,0.080891,0.456103,0.20307,0.0270694,0.456103,0.20307,-0.0270695,0.450755,0.200689,-0.080891,0.440123,0.195956,-0.133764,0.424331,0.188924,-0.185069,0.403564,0.179678,-0.234204,0.378066,0.168326,-0.280594,0.348135,0.155,-0.323693,0.314122,0.139856,-0.362998,0.276427,0.123073,-0.398047,0.235491,0.104847,-0.428429,0.191794,0.0853921,-0.453788,0.145848,0.0649358,-0.473827,0.0981926,0.0437182,-0.48831,0.0869574,0.0631782,0.48831,0.12916,0.0938404,0.473827,0.169849,0.123402,0.453788,0.208546,0.151517,0.428429,0.244798,0.177856,0.398047,0.27818,0.20211,0.362998,0.308301,0.223994,0.323693,0.334807,0.243252,0.280594,0.357388,0.259658,0.234204,0.375779,0.273019,0.185069,0.389764,0.28318,0.133764,0.39918,0.290021,0.080891,0.403915,0.293462,0.0270694,0.403915,0.293462,-0.0270695,0.39918,0.290021,-0.080891,0.389764,0.28318,-0.133764,0.375779,0.273019,-0.185069,0.357388,0.259658,-0.234204,0.334807,0.243252,-0.280594,0.308301,0.223994,-0.323693,0.27818,0.20211,-0.362998,0.244798,0.177856,-0.398047,0.208546,0.151517,-0.428429,0.169849,0.123402,-0.453788,0.12916,0.0938403,-0.473827,0.0869573,0.0631782,-0.48831,0.0719217,0.0798771,0.48831,0.106827,0.118644,0.473827,0.14048,0.156019,0.453788,0.172486,0.191566,0.428429,0.20247,0.224866,0.398047,0.23008,0.25553,0.362998,0.254993,0.283198,0.323693,0.276916,0.307546,0.280594,0.295592,0.328289,0.234204,0.310803,0.345182,0.185069,0.32237,0.358029,0.133764,0.330158,0.366678,0.080891,0.334075,0.371027,0.0270694,0.334075,0.371027,-0.0270695,0.330158,0.366678,-0.080891,0.32237,0.358029,-0.133764,0.310803,0.345182,-0.185069,0.295592,0.328289,-0.234204,0.276916,0.307546,-0.280594,0.254993,0.283198,-0.323693,0.23008,0.25553,-0.362998,0.20247,0.224866,-0.398047,0.172486,0.191566,-0.428429,0.14048,0.156019,-0.453788,0.106827,0.118644,-0.473827,0.0719216,0.0798771,-0.48831,0.0537426,0.0930849,0.48831,0.0798254,0.138262,0.473827,0.104972,0.181817,0.453788,0.128888,0.223241,0.428429,0.151294,0.262048,0.398047,0.171925,0.297783,0.362998,0.190541,0.330026,0.323693,0.206922,0.3584,0.280594,0.220878,0.382572,0.234204,0.232244,0.402259,0.185069,0.240887,0.417229,0.133764,0.246707,0.427308,0.080891,0.249633,0.432378,0.0270694,0.249633,0.432378,-0.0270695,0.246707,0.427308,-0.080891,0.240887,0.417229,-0.133764,0.232244,0.402259,-0.185069,0.220878,0.382572,-0.234204,0.206922,0.3584,-0.280594,0.19054,0.330026,-0.323693,0.171925,0.297783,-0.362998,0.151294,0.262048,-0.398047,0.128888,0.223241,-0.428429,0.104972,0.181817,-0.453788,0.0798254,0.138262,-0.473827,0.0537426,0.0930849,-0.48831,0.0332148,0.102225,0.48831,0.0493348,0.151837,0.473827,0.0648764,0.199669,0.453788,0.0796574,0.24516,0.428429,0.0935045,0.287777,0.398047,0.106255,0.327021,0.362998,0.117761,0.36243,0.323693,0.127885,0.39359,0.280594,0.13651,0.420135,0.234204,0.143535,0.441755,0.185069,0.148877,0.458195,0.133764,0.152473,0.469264,0.080891,0.154282,0.474831,0.0270694,0.154282,0.474831,-0.0270695,0.152473,0.469264,-0.080891,0.148877,0.458195,-0.133764,0.143535,0.441755,-0.185069,0.13651,0.420135,-0.234204,0.127885,0.393589,-0.280594,0.11776,0.36243,-0.323693,0.106255,0.32702,-0.362998,0.0935045,0.287777,-0.398047,0.0796574,0.24516,-0.428429,0.0648764,0.199669,-0.453788,0.0493348,0.151837,-0.473827,0.0332147,0.102224,-0.48831,0.0112353,0.106896,0.48831,0.016688,0.158776,0.473827,0.0219452,0.208794,0.453788,0.026945,0.256365,0.428429,0.031629,0.30093,0.398047,0.0359421,0.341966,0.362998,0.0398338,0.378993,0.323693,0.0432585,0.411577,0.280594,0.0461761,0.439336,0.234204,0.0485522,0.461944,0.185069,0.0503592,0.479136,0.133764,0.0515757,0.49071,0.080891,0.0521876,0.496532,0.0270694,0.0521876,0.496532,-0.0270695,0.0515757,0.49071,-0.080891,0.0503592,0.479136,-0.133764,0.0485522,0.461944,-0.185069,0.0461761,0.439336,-0.234204,0.0432585,0.411577,-0.280594,0.0398338,0.378993,-0.323693,0.0359421,0.341966,-0.362998,0.031629,0.300929,-0.398047,0.026945,0.256365,-0.428429,0.0219452,0.208794,-0.453788,0.016688,0.158776,-0.473827,0.0112353,0.106896,-0.48831,-0.0112353,0.106896,0.48831,-0.0166881,0.158776,0.473827,-0.0219452,0.208794,0.453788,-0.026945,0.256365,0.428429,-0.031629,0.30093,0.398047,-0.0359421,0.341966,0.362998,-0.0398338,0.378993,0.323693,-0.0432585,0.411577,0.280594,-0.0461761,0.439336,0.234204,-0.0485523,0.461944,0.185069,-0.0503592,0.479136,0.133764,-0.0515758,0.49071,0.080891,-0.0521876,0.496532,0.0270694,-0.0521876,0.496532,-0.0270695,-0.0515758,0.49071,-0.080891,-0.0503592,0.479136,-0.133764,-0.0485523,0.461944,-0.185069,-0.0461761,0.439336,-0.234204,-0.0432585,0.411577,-0.280594,-0.0398338,0.378993,-0.323693,-0.0359421,0.341966,-0.362998,-0.031629,0.300929,-0.398047,-0.026945,0.256365,-0.428429,-0.0219452,0.208794,-0.453788,-0.0166881,0.158776,-0.473827,-0.0112353,0.106896,-0.48831,-0.0332148,0.102225,0.48831,-0.0493348,0.151837,0.473827,-0.0648764,0.199669,0.453788,-0.0796575,0.24516,0.428429,-0.0935046,0.287777,0.398047,-0.106255,0.327021,0.362998,-0.117761,0.36243,0.323693,-0.127885,0.393589,0.280594,-0.13651,0.420135,0.234204,-0.143535,0.441755,0.185069,-0.148877,0.458195,0.133764,-0.152473,0.469264,0.080891,-0.154282,0.474831,0.0270694,-0.154282,0.474831,-0.0270695,-0.152473,0.469264,-0.080891,-0.148877,0.458195,-0.133764,-0.143535,0.441755,-0.185069,-0.13651,0.420135,-0.234204,-0.127885,0.393589,-0.280594,-0.117761,0.36243,-0.323693,-0.106255,0.32702,-0.362998,-0.0935046,0.287777,-0.398047,-0.0796575,0.24516,-0.428429,-0.0648764,0.199669,-0.453788,-0.0493348,0.151837,-0.473827,-0.0332148,0.102224,-0.48831,-0.0537426,0.0930849,0.48831,-0.0798254,0.138262,0.473827,-0.104972,0.181817,0.453788,-0.128888,0.223241,0.428429,-0.151294,0.262048,0.398047,-0.171925,0.297783,0.362998,-0.190541,0.330026,0.323693,-0.206922,0.3584,0.280594,-0.220878,0.382572,0.234204,-0.232244,0.402259,0.185069,-0.240888,0.417229,0.133764,-0.246707,0.427308,0.080891,-0.249633,0.432378,0.0270694,-0.249633,0.432378,-0.0270695,-0.246707,0.427308,-0.080891,-0.240888,0.417229,-0.133764,-0.232244,0.402259,-0.185069,-0.220878,0.382572,-0.234204,-0.206922,0.3584,-0.280594,-0.190541,0.330026,-0.323693,-0.171925,0.297783,-0.362998,-0.151294,0.262048,-0.398047,-0.128888,0.223241,-0.428429,-0.104972,0.181817,-0.453788,-0.0798254,0.138262,-0.473827,-0.0537426,0.0930849,-0.48831,-0.0719217,0.0798771,0.48831,-0.106827,0.118644,0.473827,-0.14048,0.156019,0.453788,-0.172486,0.191566,0.428429,-0.20247,0.224866,0.398047,-0.23008,0.25553,0.362998,-0.254993,0.283198,0.323693,-0.276916,0.307546,0.280594,-0.295592,0.328289,0.234204,-0.310803,0.345182,0.185069,-0.32237,0.358029,0.133764,-0.330158,0.366677,0.080891,-0.334075,0.371027,0.0270694,-0.334075,0.371027,-0.0270695,-0.330158,0.366677,-0.080891,-0.32237,0.358029,-0.133764,-0.310803,0.345182,-0.185069,-0.295592,0.328289,-0.234204,-0.276916,0.307546,-0.280594,-0.254993,0.283198,-0.323693,-0.23008,0.25553,-0.362998,-0.20247,0.224866,-0.398047,-0.172486,0.191566,-0.428429,-0.14048,0.156019,-0.453788,-0.106827,0.118644,-0.473827,-0.0719216,0.079877,-0.48831,-0.0869574,0.0631782,0.48831,-0.12916,0.0938404,0.473827,-0.169849,0.123402,0.453788,-0.208546,0.151517,0.428429,-0.244798,0.177856,0.398047,-0.27818,0.20211,0.362998,-0.308301,0.223994,0.323693,-0.334807,0.243252,0.280594,-0.357388,0.259658,0.234204,-0.375779,0.273019,0.185069,-0.389764,0.28318,0.133764,-0.39918,0.290021,0.080891,-0.403915,0.293462,0.0270694,-0.403915,0.293462,-0.0270695,-0.39918,0.290021,-0.080891,-0.389764,0.28318,-0.133764,-0.375779,0.273019,-0.185069,-0.357388,0.259658,-0.234204,-0.334807,0.243252,-0.280594,-0.308301,0.223994,-0.323693,-0.27818,0.20211,-0.362998,-0.244798,0.177856,-0.398047,-0.208546,0.151517,-0.428429,-0.169849,0.123402,-0.453788,-0.12916,0.0938403,-0.473827,-0.0869573,0.0631782,-0.48831,-0.0981926,0.0437182,0.48831,-0.145848,0.0649358,0.473827,-0.191794,0.0853921,0.453788,-0.235491,0.104847,0.428429,-0.276427,0.123073,0.398047,-0.314122,0.139856,0.362998,-0.348135,0.155,0.323693,-0.378066,0.168326,0.280594,-0.403564,0.179678,0.234204,-0.424331,0.188924,0.185069,-0.440123,0.195956,0.133764,-0.450755,0.200689,0.080891,-0.456103,0.20307,0.0270694,-0.456103,0.20307,-0.0270695,-0.450755,0.200689,-0.080891,-0.440123,0.195956,-0.133764,-0.424331,0.188924,-0.185069,-0.403564,0.179678,-0.234204,-0.378066,0.168326,-0.280594,-0.348135,0.155,-0.323693,-0.314122,0.139856,-0.362998,-0.276427,0.123073,-0.398047,-0.235491,0.104847,-0.428429,-0.191794,0.0853921,-0.453788,-0.145848,0.0649358,-0.473827,-0.0981926,0.0437182,-0.48831,-0.105136,0.0223474,0.48831,-0.156162,0.0331932,0.473827,-0.205357,0.0436499,0.453788,-0.252144,0.0535948,0.428429,-0.295975,0.0629114,0.398047,-0.336336,0.0714904,0.362998,-0.372754,0.0792312,0.323693,-0.404801,0.0860431,0.280594,-0.432103,0.0918462,0.234204,-0.454338,0.0965725,0.185069,-0.471247,0.100167,0.133764,-0.482631,0.102586,0.080891,-0.488357,0.103803,0.0270694,-0.488357,0.103803,-0.0270695,-0.482631,0.102586,-0.080891,-0.471247,0.100167,-0.133764,-0.454338,0.0965725,-0.185069,-0.432103,0.0918462,-0.234204,-0.404801,0.0860431,-0.280594,-0.372753,0.0792312,-0.323693,-0.336336,0.0714903,-0.362998,-0.295975,0.0629114,-0.398047,-0.252144,0.0535948,-0.428429,-0.205357,0.0436499,-0.453788,-0.156162,0.0331932,-0.473827,-0.105136,0.0223474,-0.48831,-0.107485,-9.39666e-09,0.48831,-0.159651,-1.39571e-08,0.473827,-0.209945,-1.83539e-08,0.453788,-0.257777,-2.25356e-08,0.428429,-0.302587,-2.6453e-08,0.398047,-0.34385,-3.00603e-08,0.362998,-0.381081,-3.33152e-08,0.323693,-0.413844,-3.61794e-08,0.280594,-0.441756,-3.86195e-08,0.234204,-0.464488,-4.06069e-08,0.185069,-0.481775,-4.21181e-08,0.133764,-0.493413,-4.31356e-08,0.080891,-0.499267,-4.36473e-08,0.0270694,-0.499267,-4.36473e-08,-0.0270695,-0.493413,-4.31356e-08,-0.080891,-0.481775,-4.21181e-08,-0.133764,-0.464488,-4.06069e-08,-0.185069,-0.441756,-3.86195e-08,-0.234204,-0.413844,-3.61794e-08,-0.280594,-0.381081,-3.33152e-08,-0.323693,-0.34385,-3.00603e-08,-0.362998,-0.302587,-2.6453e-08,-0.398047,-0.257777,-2.25356e-08,-0.428429,-0.209945,-1.83539e-08,-0.453788,-0.159651,-1.39571e-08,-0.473827,-0.107485,-9.39665e-09,-0.48831,-0.105136,-0.0223474,0.48831,-0.156162,-0.0331933,0.473827,-0.205357,-0.0436499,0.453788,-0.252144,-0.0535949,0.428429,-0.295975,-0.0629114,0.398047,-0.336336,-0.0714904,0.362998,-0.372754,-0.0792312,0.323693,-0.404801,-0.0860431,0.280594,-0.432103,-0.0918463,0.234204,-0.454338,-0.0965726,0.185069,-0.471247,-0.100167,0.133764,-0.482631,-0.102586,0.080891,-0.488357,-0.103803,0.0270694,-0.488357,-0.103803,-0.0270695,-0.482631,-0.102586,-0.080891,-0.471247,-0.100167,-0.133764,-0.454338,-0.0965726,-0.185069,-0.432103,-0.0918463,-0.234204,-0.404801,-0.0860431,-0.280594,-0.372753,-0.0792312,-0.323693,-0.336336,-0.0714904,-0.362998,-0.295975,-0.0629114,-0.398047,-0.252144,-0.0535949,-0.428429,-0.205357,-0.0436499,-0.453788,-0.156162,-0.0331933,-0.473827,-0.105136,-0.0223474,-0.48831,-0.0981926,-0.0437182,0.48831,-0.145848,-0.0649358,0.473827,-0.191794,-0.0853922,0.453788,-0.235491,-0.104847,0.428429,-0.276427,-0.123073,0.398047,-0.314122,-0.139856,0.362998,-0.348135,-0.155,0.323693,-0.378066,-0.168326,0.280594,-0.403564,-0.179678,0.234204,-0.424331,-0.188924,0.185069,-0.440123,-0.195956,0.133764,-0.450755,-0.200689,0.080891,-0.456103,-0.20307,0.0270694,-0.456103,-0.20307,-0.0270695,-0.450755,-0.200689,-0.080891,-0.440123,-0.195956,-0.133764,-0.424331,-0.188924,-0.185069,-0.403564,-0.179678,-0.234204,-0.378066,-0.168326,-0.280594,-0.348135,-0.155,-0.323693,-0.314122,-0.139856,-0.362998,-0.276427,-0.123073,-0.398047,-0.235491,-0.104847,-0.428429,-0.191794,-0.0853921,-0.453788,-0.145848,-0.0649358,-0.473827,-0.0981926,-0.0437182,-0.48831,-0.0869574,-0.0631782,0.48831,-0.12916,-0.0938404,0.473827,-0.169849,-0.123402,0.453788,-0.208546,-0.151517,0.428429,-0.244798,-0.177856,0.398047,-0.27818,-0.20211,0.362998,-0.308301,-0.223994,0.323693,-0.334807,-0.243252,0.280594,-0.357388,-0.259658,0.234204,-0.375779,-0.273019,0.185069,-0.389764,-0.28318,0.133764,-0.39918,-0.290021,0.080891,-0.403915,-0.293462,0.0270694,-0.403915,-0.293462,-0.0270695,-0.39918,-0.290021,-0.080891,-0.389764,-0.28318,-0.133764,-0.375779,-0.273019,-0.185069,-0.357388,-0.259658,-0.234204,-0.334807,-0.243252,-0.280594,-0.308301,-0.223994,-0.323693,-0.27818,-0.20211,-0.362998,-0.244798,-0.177856,-0.398047,-0.208546,-0.151517,-0.428429,-0.169849,-0.123402,-0.453788,-0.12916,-0.0938404,-0.473827,-0.0869573,-0.0631782,-0.48831,-0.0719216,-0.0798771,0.48831,-0.106827,-0.118644,0.473827,-0.14048,-0.156019,0.453788,-0.172486,-0.191566,0.428429,-0.20247,-0.224866,0.398047,-0.23008,-0.25553,0.362998,-0.254993,-0.283198,0.323693,-0.276916,-0.307546,0.280594,-0.295592,-0.328289,0.234204,-0.310803,-0.345182,0.185069,-0.32237,-0.358029,0.133764,-0.330158,-0.366678,0.080891,-0.334075,-0.371027,0.0270694,-0.334075,-0.371027,-0.0270695,-0.330158,-0.366678,-0.080891,-0.32237,-0.358029,-0.133764,-0.310803,-0.345182,-0.185069,-0.295592,-0.328289,-0.234204,-0.276916,-0.307546,-0.280594,-0.254993,-0.283198,-0.323693,-0.23008,-0.25553,-0.362998,-0.20247,-0.224866,-0.398047,-0.172486,-0.191566,-0.428429,-0.14048,-0.156019,-0.453788,-0.106827,-0.118644,-0.473827,-0.0719216,-0.0798771,-0.48831,-0.0537426,-0.0930849,0.48831,-0.0798254,-0.138262,0.473827,-0.104972,-0.181817,0.453788,-0.128888,-0.223241,0.428429,-0.151294,-0.262048,0.398047,-0.171925,-0.297783,0.362998,-0.19054,-0.330026,0.323693,-0.206922,-0.3584,0.280594,-0.220878,-0.382572,0.234204,-0.232244,-0.402259,0.185069,-0.240887,-0.417229,0.133764,-0.246707,-0.427308,0.080891,-0.249633,-0.432378,0.0270694,-0.249633,-0.432378,-0.0270695,-0.246707,-0.427308,-0.080891,-0.240887,-0.417229,-0.133764,-0.232244,-0.402259,-0.185069,-0.220878,-0.382572,-0.234204,-0.206922,-0.3584,-0.280594,-0.19054,-0.330026,-0.323693,-0.171925,-0.297783,-0.362998,-0.151294,-0.262048,-0.398047,-0.128888,-0.223241,-0.428429,-0.104972,-0.181817,-0.453788,-0.0798253,-0.138262,-0.473827,-0.0537426,-0.0930849,-0.48831,-0.0332147,-0.102225,0.48831,-0.0493348,-0.151837,0.473827,-0.0648764,-0.199669,0.453788,-0.0796574,-0.24516,0.428429,-0.0935045,-0.287777,0.398047,-0.106255,-0.327021,0.362998,-0.11776,-0.36243,0.323693,-0.127885,-0.39359,0.280594,-0.13651,-0.420135,0.234204,-0.143535,-0.441755,0.185069,-0.148877,-0.458195,0.133764,-0.152473,-0.469264,0.080891,-0.154282,-0.474831,0.0270694,-0.154282,-0.474831,-0.0270695,-0.152473,-0.469264,-0.080891,-0.148877,-0.458195,-0.133764,-0.143535,-0.441755,-0.185069,-0.13651,-0.420135,-0.234204,-0.127885,-0.393589,-0.280594,-0.11776,-0.36243,-0.323693,-0.106255,-0.327021,-0.362998,-0.0935045,-0.287777,-0.398047,-0.0796574,-0.24516,-0.428429,-0.0648764,-0.199669,-0.453788,-0.0493348,-0.151837,-0.473827,-0.0332147,-0.102224,-0.48831,-0.0112353,-0.106896,0.48831,-0.016688,-0.158776,0.473827,-0.0219452,-0.208794,0.453788,-0.026945,-0.256365,0.428429,-0.0316289,-0.30093,0.398047,-0.035942,-0.341966,0.362998,-0.0398338,-0.378993,0.323693,-0.0432585,-0.411577,0.280594,-0.046176,-0.439336,0.234204,-0.0485522,-0.461944,0.185069,-0.0503591,-0.479136,0.133764,-0.0515757,-0.49071,0.080891,-0.0521875,-0.496532,0.0270694,-0.0521875,-0.496532,-0.0270695,-0.0515757,-0.49071,-0.080891,-0.0503591,-0.479136,-0.133764,-0.0485522,-0.461944,-0.185069,-0.046176,-0.439336,-0.234204,-0.0432585,-0.411577,-0.280594,-0.0398338,-0.378993,-0.323693,-0.035942,-0.341966,-0.362998,-0.0316289,-0.300929,-0.398047,-0.026945,-0.256365,-0.428429,-0.0219452,-0.208794,-0.453788,-0.016688,-0.158776,-0.473827,-0.0112352,-0.106896,-0.48831,0.0112353,-0.106896,0.48831,0.0166881,-0.158776,0.473827,0.0219452,-0.208794,0.453788,0.0269451,-0.256365,0.428429,0.031629,-0.30093,0.398047,0.0359421,-0.341966,0.362998,0.0398339,-0.378993,0.323693,0.0432586,-0.411577,0.280594,0.0461761,-0.439336,0.234204,0.0485523,-0.461944,0.185069,0.0503593,-0.479136,0.133764,0.0515758,-0.49071,0.080891,0.0521876,-0.496532,0.0270694,0.0521876,-0.496532,-0.0270695,0.0515758,-0.49071,-0.080891,0.0503593,-0.479136,-0.133764,0.0485523,-0.461944,-0.185069,0.0461761,-0.439336,-0.234204,0.0432586,-0.411577,-0.280594,0.0398339,-0.378993,-0.323693,0.0359421,-0.341966,-0.362998,0.031629,-0.300929,-0.398047,0.0269451,-0.256365,-0.428429,0.0219452,-0.208794,-0.453788,0.0166881,-0.158776,-0.473827,0.0112353,-0.106896,-0.48831,0.0332148,-0.102225,0.48831,0.0493348,-0.151837,0.473827,0.0648765,-0.199669,0.453788,0.0796575,-0.24516,0.428429,0.0935046,-0.287777,0.398047,0.106255,-0.327021,0.362998,0.117761,-0.36243,0.323693,0.127885,-0.393589,0.280594,0.13651,-0.420135,0.234204,0.143535,-0.441755,0.185069,0.148877,-0.458195,0.133764,0.152473,-0.469264,0.080891,0.154282,-0.474831,0.0270694,0.154282,-0.474831,-0.0270695,0.152473,-0.469264,-0.080891,0.148877,-0.458195,-0.133764,0.143535,-0.441755,-0.185069,0.13651,-0.420135,-0.234204,0.127885,-0.393589,-0.280594,0.117761,-0.36243,-0.323693,0.106255,-0.32702,-0.362998,0.0935046,-0.287777,-0.398047,0.0796575,-0.24516,-0.428429,0.0648765,-0.199669,-0.453788,0.0493348,-0.151837,-0.473827,0.0332148,-0.102224,-0.48831,0.0537426,-0.0930849,0.48831,0.0798254,-0.138262,0.473827,0.104972,-0.181817,0.453788,0.128889,-0.223241,0.428429,0.151294,-0.262048,0.398047,0.171925,-0.297783,0.362998,0.190541,-0.330026,0.323693,0.206922,-0.3584,0.280594,0.220878,-0.382572,0.234204,0.232244,-0.402259,0.185069,0.240888,-0.417229,0.133764,0.246707,-0.427308,0.080891,0.249633,-0.432378,0.0270694,0.249633,-0.432378,-0.0270695,0.246707,-0.427308,-0.080891,0.240888,-0.417229,-0.133764,0.232244,-0.402259,-0.185069,0.220878,-0.382572,-0.234204,0.206922,-0.3584,-0.280594,0.190541,-0.330026,-0.323693,0.171925,-0.297783,-0.362998,0.151294,-0.262048,-0.398047,0.128888,-0.223241,-0.428429,0.104972,-0.181817,-0.453788,0.0798254,-0.138262,-0.473827,0.0537426,-0.0930849,-0.48831,0.0719217,-0.0798771,0.48831,0.106827,-0.118644,0.473827,0.14048,-0.156019,0.453788,0.172486,-0.191566,0.428429,0.20247,-0.224866,0.398047,0.23008,-0.25553,0.362998,0.254993,-0.283198,0.323693,0.276916,-0.307546,0.280594,0.295593,-0.328289,0.234204,0.310803,-0.345182,0.185069,0.32237,-0.358029,0.133764,0.330158,-0.366677,0.080891,0.334075,-0.371027,0.0270694,0.334075,-0.371027,-0.0270695,0.330158,-0.366677,-0.080891,0.32237,-0.358029,-0.133764,0.310803,-0.345182,-0.185069,0.295593,-0.328289,-0.234204,0.276916,-0.307546,-0.280594,0.254993,-0.283198,-0.323693,0.23008,-0.25553,-0.362998,0.20247,-0.224866,-0.398047,0.172486,-0.191566,-0.428429,0.14048,-0.156019,-0.453788,0.106827,-0.118644,-0.473827,0.0719216,-0.079877,-0.48831,0.0869574,-0.0631782,0.48831,0.12916,-0.0938403,0.473827,0.169849,-0.123402,0.453788,0.208546,-0.151517,0.428429,0.244798,-0.177856,0.398047,0.27818,-0.20211,0.362998,0.308301,-0.223994,0.323693,0.334807,-0.243252,0.280594,0.357388,-0.259658,0.234204,0.375779,-0.273019,0.185069,0.389764,-0.28318,0.133764,0.39918,-0.290021,0.080891,0.403915,-0.293462,0.0270694,0.403915,-0.293462,-0.0270695,0.39918,-0.290021,-0.080891,0.389764,-0.28318,-0.133764,0.375779,-0.273019,-0.185069,0.357388,-0.259658,-0.234204,0.334807,-0.243252,-0.280594,0.308301,-0.223994,-0.323693,0.27818,-0.20211,-0.362998,0.244798,-0.177856,-0.398047,0.208546,-0.151517,-0.428429,0.169849,-0.123402,-0.453788,0.12916,-0.0938403,-0.473827,0.0869574,-0.0631782,-0.48831,0.0981926,-0.0437182,0.48831,0.145848,-0.0649358,0.473827,0.191794,-0.0853921,0.453788,0.235491,-0.104847,0.428429,0.276427,-0.123073,0.398047,0.314122,-0.139856,0.362998,0.348135,-0.155,0.323693,0.378066,-0.168326,0.280594,0.403564,-0.179678,0.234204,0.424331,-0.188924,0.185069,0.440123,-0.195955,0.133764,0.450755,-0.200689,0.080891,0.456103,-0.20307,0.0270694,0.456103,-0.20307,-0.0270695,0.450755,-0.200689,-0.080891,0.440123,-0.195955,-0.133764,0.424331,-0.188924,-0.185069,0.403564,-0.179678,-0.234204,0.378066,-0.168326,-0.280594,0.348135,-0.155,-0.323693,0.314122,-0.139856,-0.362998,0.276427,-0.123073,-0.398047,0.235491,-0.104847,-0.428429,0.191794,-0.0853921,-0.453788,0.145848,-0.0649358,-0.473827,0.0981926,-0.0437181,-0.48831,0.105136,-0.0223474,0.48831,0.156162,-0.0331932,0.473827,0.205357,-0.0436499,0.453788,0.252144,-0.0535948,0.428429,0.295975,-0.0629113,0.398047,0.336336,-0.0714903,0.362998,0.372754,-0.0792311,0.323693,0.404801,-0.086043,0.280594,0.432103,-0.0918462,0.234204,0.454338,-0.0965725,0.185069,0.471247,-0.100167,0.133764,0.482631,-0.102586,0.080891,0.488357,-0.103803,0.0270694,0.488357,-0.103803,-0.0270695,0.482631,-0.102586,-0.080891,0.471247,-0.100167,-0.133764,0.454338,-0.0965725,-0.185069,0.432103,-0.0918462,-0.234204,0.404801,-0.086043,-0.280594,0.372754,-0.0792311,-0.323693,0.336336,-0.0714903,-0.362998,0.295975,-0.0629113,-0.398047,0.252144,-0.0535948,-0.428429,0.205357,-0.0436499,-0.453788,0.156162,-0.0331932,-0.473827,0.105136,-0.0223474,-0.48831];
+	indices = [0,1,2,1,3,2,3,4,2,4,5,2,5,6,2,6,7,2,7,8,2,8,9,2,9,10,2,10,11,2,11,12,2,12,13,2,13,14,2,14,15,2,15,16,2,16,17,2,17,18,2,18,19,2,19,20,2,20,21,2,21,22,2,22,23,2,23,24,2,24,25,2,25,26,2,26,27,2,27,28,2,28,29,2,29,30,2,30,0,2,31,32,33,33,32,34,34,32,35,35,32,36,36,32,37,37,32,38,38,32,39,39,32,40,40,32,41,41,32,42,42,32,43,43,32,44,44,32,45,45,32,46,46,32,47,47,32,48,48,32,49,49,32,50,50,32,51,51,32,52,52,32,53,53,32,54,54,32,55,55,32,56,56,32,57,57,32,58,58,32,59,59,32,60,60,32,61,61,32,31,0,62,63,0,63,1,62,64,65,62,65,63,64,66,67,64,67,65,66,68,69,66,69,67,68,70,71,68,71,69,70,72,73,70,73,71,72,74,75,72,75,73,74,76,77,74,77,75,76,78,79,76,79,77,78,80,81,78,81,79,80,82,83,80,83,81,82,84,85,82,85,83,84,86,87,84,87,85,86,88,89,86,89,87,88,90,91,88,91,89,90,92,93,90,93,91,92,94,95,92,95,93,94,96,97,94,97,95,96,98,99,96,99,97,98,100,101,98,101,99,100,102,103,100,103,101,102,104,105,102,105,103,104,106,107,104,107,105,106,108,109,106,109,107,108,110,111,108,111,109,110,112,113,110,113,111,112,31,33,112,33,113,1,63,114,1,114,3,63,65,115,63,115,114,65,67,116,65,116,115,67,69,117,67,117,116,69,71,118,69,118,117,71,73,119,71,119,118,73,75,120,73,120,119,75,77,121,75,121,120,77,79,122,77,122,121,79,81,123,79,123,122,81,83,124,81,124,123,83,85,125,83,125,124,85,87,126,85,126,125,87,89,127,87,127,126,89,91,128,89,128,127,91,93,129,91,129,128,93,95,130,93,130,129,95,97,131,95,131,130,97,99,132,97,132,131,99,101,133,99,133,132,101,103,134,101,134,133,103,105,135,103,135,134,105,107,136,105,136,135,107,109,137,107,137,136,109,111,138,109,138,137,111,113,139,111,139,138,113,33,34,113,34,139,3,114,140,3,140,4,114,115,141,114,141,140,115,116,142,115,142,141,116,117,143,116,143,142,117,118,144,117,144,143,118,119,145,118,145,144,119,120,146,119,146,145,120,121,147,120,147,146,121,122,148,121,148,147,122,123,149,122,149,148,123,124,150,123,150,149,124,125,151,124,151,150,125,126,152,125,152,151,126,127,153,126,153,152,127,128,154,127,154,153,128,129,155,128,155,154,129,130,156,129,156,155,130,131,157,130,157,156,131,132,158,131,158,157,132,133,159,132,159,158,133,134,160,133,160,159,134,135,161,134,161,160,135,136,162,135,162,161,136,137,163,136,163,162,137,138,164,137,164,163,138,139,165,138,165,164,139,34,35,139,35,165,4,140,166,4,166,5,140,141,167,140,167,166,141,142,168,141,168,167,142,143,169,142,169,168,143,144,170,143,170,169,144,145,171,144,171,170,145,146,172,145,172,171,146,147,173,146,173,172,147,148,174,147,174,173,148,149,175,148,175,174,149,150,176,149,176,175,150,151,177,150,177,176,151,152,178,151,178,177,152,153,179,152,179,178,153,154,180,153,180,179,154,155,181,154,181,180,155,156,182,155,182,181,156,157,183,156,183,182,157,158,184,157,184,183,158,159,185,158,185,184,159,160,186,159,186,185,160,161,187,160,187,186,161,162,188,161,188,187,162,163,189,162,189,188,163,164,190,163,190,189,164,165,191,164,191,190,165,35,36,165,36,191,5,166,192,5,192,6,166,167,193,166,193,192,167,168,194,167,194,193,168,169,195,168,195,194,169,170,196,169,196,195,170,171,197,170,197,196,171,172,198,171,198,197,172,173,199,172,199,198,173,174,200,173,200,199,174,175,201,174,201,200,175,176,202,175,202,201,176,177,203,176,203,202,177,178,204,177,204,203,178,179,205,178,205,204,179,180,206,179,206,205,180,181,207,180,207,206,181,182,208,181,208,207,182,183,209,182,209,208,183,184,210,183,210,209,184,185,211,184,211,210,185,186,212,185,212,211,186,187,213,186,213,212,187,188,214,187,214,213,188,189,215,188,215,214,189,190,216,189,216,215,190,191,217,190,217,216,191,36,37,191,37,217,6,192,218,6,218,7,192,193,219,192,219,218,193,194,220,193,220,219,194,195,221,194,221,220,195,196,222,195,222,221,196,197,223,196,223,222,197,198,224,197,224,223,198,199,225,198,225,224,199,200,226,199,226,225,200,201,227,200,227,226,201,202,228,201,228,227,202,203,229,202,229,228,203,204,230,203,230,229,204,205,231,204,231,230,205,206,232,205,232,231,206,207,233,206,233,232,207,208,234,207,234,233,208,209,235,208,235,234,209,210,236,209,236,235,210,211,237,210,237,236,211,212,238,211,238,237,212,213,239,212,239,238,213,214,240,213,240,239,214,215,241,214,241,240,215,216,242,215,242,241,216,217,243,216,243,242,217,37,38,217,38,243,7,218,244,7,244,8,218,219,245,218,245,244,219,220,246,219,246,245,220,221,247,220,247,246,221,222,248,221,248,247,222,223,249,222,249,248,223,224,250,223,250,249,224,225,251,224,251,250,225,226,252,225,252,251,226,227,253,226,253,252,227,228,254,227,254,253,228,229,255,228,255,254,229,230,256,229,256,255,230,231,257,230,257,256,231,232,258,231,258,257,232,233,259,232,259,258,233,234,260,233,260,259,234,235,261,234,261,260,235,236,262,235,262,261,236,237,263,236,263,262,237,238,264,237,264,263,238,239,265,238,265,264,239,240,266,239,266,265,240,241,267,240,267,266,241,242,268,241,268,267,242,243,269,242,269,268,243,38,39,243,39,269,8,244,270,8,270,9,244,245,271,244,271,270,245,246,272,245,272,271,246,247,273,246,273,272,247,248,274,247,274,273,248,249,275,248,275,274,249,250,276,249,276,275,250,251,277,250,277,276,251,252,278,251,278,277,252,253,279,252,279,278,253,254,280,253,280,279,254,255,281,254,281,280,255,256,282,255,282,281,256,257,283,256,283,282,257,258,284,257,284,283,258,259,285,258,285,284,259,260,286,259,286,285,260,261,287,260,287,286,261,262,288,261,288,287,262,263,289,262,289,288,263,264,290,263,290,289,264,265,291,264,291,290,265,266,292,265,292,291,266,267,293,266,293,292,267,268,294,267,294,293,268,269,295,268,295,294,269,39,40,269,40,295,9,270,296,9,296,10,270,271,297,270,297,296,271,272,298,271,298,297,272,273,299,272,299,298,273,274,300,273,300,299,274,275,301,274,301,300,275,276,302,275,302,301,276,277,303,276,303,302,277,278,304,277,304,303,278,279,305,278,305,304,279,280,306,279,306,305,280,281,307,280,307,306,281,282,308,281,308,307,282,283,309,282,309,308,283,284,310,283,310,309,284,285,311,284,311,310,285,286,312,285,312,311,286,287,313,286,313,312,287,288,314,287,314,313,288,289,315,288,315,314,289,290,316,289,316,315,290,291,317,290,317,316,291,292,318,291,318,317,292,293,319,292,319,318,293,294,320,293,320,319,294,295,321,294,321,320,295,40,41,295,41,321,10,296,322,10,322,11,296,297,323,296,323,322,297,298,324,297,324,323,298,299,325,298,325,324,299,300,326,299,326,325,300,301,327,300,327,326,301,302,328,301,328,327,302,303,329,302,329,328,303,304,330,303,330,329,304,305,331,304,331,330,305,306,332,305,332,331,306,307,333,306,333,332,307,308,334,307,334,333,308,309,335,308,335,334,309,310,336,309,336,335,310,311,337,310,337,336,311,312,338,311,338,337,312,313,339,312,339,338,313,314,340,313,340,339,314,315,341,314,341,340,315,316,342,315,342,341,316,317,343,316,343,342,317,318,344,317,344,343,318,319,345,318,345,344,319,320,346,319,346,345,320,321,347,320,347,346,321,41,42,321,42,347,11,322,348,11,348,12,322,323,349,322,349,348,323,324,350,323,350,349,324,325,351,324,351,350,325,326,352,325,352,351,326,327,353,326,353,352,327,328,354,327,354,353,328,329,355,328,355,354,329,330,356,329,356,355,330,331,357,330,357,356,331,332,358,331,358,357,332,333,359,332,359,358,333,334,360,333,360,359,334,335,361,334,361,360,335,336,362,335,362,361,336,337,363,336,363,362,337,338,364,337,364,363,338,339,365,338,365,364,339,340,366,339,366,365,340,341,367,340,367,366,341,342,368,341,368,367,342,343,369,342,369,368,343,344,370,343,370,369,344,345,371,344,371,370,345,346,372,345,372,371,346,347,373,346,373,372,347,42,43,347,43,373,12,348,374,12,374,13,348,349,375,348,375,374,349,350,376,349,376,375,350,351,377,350,377,376,351,352,378,351,378,377,352,353,379,352,379,378,353,354,380,353,380,379,354,355,381,354,381,380,355,356,382,355,382,381,356,357,383,356,383,382,357,358,384,357,384,383,358,359,385,358,385,384,359,360,386,359,386,385,360,361,387,360,387,386,361,362,388,361,388,387,362,363,389,362,389,388,363,364,390,363,390,389,364,365,391,364,391,390,365,366,392,365,392,391,366,367,393,366,393,392,367,368,394,367,394,393,368,369,395,368,395,394,369,370,396,369,396,395,370,371,397,370,397,396,371,372,398,371,398,397,372,373,399,372,399,398,373,43,44,373,44,399,13,374,400,13,400,14,374,375,401,374,401,400,375,376,402,375,402,401,376,377,403,376,403,402,377,378,404,377,404,403,378,379,405,378,405,404,379,380,406,379,406,405,380,381,407,380,407,406,381,382,408,381,408,407,382,383,409,382,409,408,383,384,410,383,410,409,384,385,411,384,411,410,385,386,412,385,412,411,386,387,413,386,413,412,387,388,414,387,414,413,388,389,415,388,415,414,389,390,416,389,416,415,390,391,417,390,417,416,391,392,418,391,418,417,392,393,419,392,419,418,393,394,420,393,420,419,394,395,421,394,421,420,395,396,422,395,422,421,396,397,423,396,423,422,397,398,424,397,424,423,398,399,425,398,425,424,399,44,45,399,45,425,14,400,426,14,426,15,400,401,427,400,427,426,401,402,428,401,428,427,402,403,429,402,429,428,403,404,430,403,430,429,404,405,431,404,431,430,405,406,432,405,432,431,406,407,433,406,433,432,407,408,434,407,434,433,408,409,435,408,435,434,409,410,436,409,436,435,410,411,437,410,437,436,411,412,438,411,438,437,412,413,439,412,439,438,413,414,440,413,440,439,414,415,441,414,441,440,415,416,442,415,442,441,416,417,443,416,443,442,417,418,444,417,444,443,418,419,445,418,445,444,419,420,446,419,446,445,420,421,447,420,447,446,421,422,448,421,448,447,422,423,449,422,449,448,423,424,450,423,450,449,424,425,451,424,451,450,425,45,46,425,46,451,15,426,452,15,452,16,426,427,453,426,453,452,427,428,454,427,454,453,428,429,455,428,455,454,429,430,456,429,456,455,430,431,457,430,457,456,431,432,458,431,458,457,432,433,459,432,459,458,433,434,460,433,460,459,434,435,461,434,461,460,435,436,462,435,462,461,436,437,463,436,463,462,437,438,464,437,464,463,438,439,465,438,465,464,439,440,466,439,466,465,440,441,467,440,467,466,441,442,468,441,468,467,442,443,469,442,469,468,443,444,470,443,470,469,444,445,471,444,471,470,445,446,472,445,472,471,446,447,473,446,473,472,447,448,474,447,474,473,448,449,475,448,475,474,449,450,476,449,476,475,450,451,477,450,477,476,451,46,47,451,47,477,16,452,478,16,478,17,452,453,479,452,479,478,453,454,480,453,480,479,454,455,481,454,481,480,455,456,482,455,482,481,456,457,483,456,483,482,457,458,484,457,484,483,458,459,485,458,485,484,459,460,486,459,486,485,460,461,487,460,487,486,461,462,488,461,488,487,462,463,489,462,489,488,463,464,490,463,490,489,464,465,491,464,491,490,465,466,492,465,492,491,466,467,493,466,493,492,467,468,494,467,494,493,468,469,495,468,495,494,469,470,496,469,496,495,470,471,497,470,497,496,471,472,498,471,498,497,472,473,499,472,499,498,473,474,500,473,500,499,474,475,501,474,501,500,475,476,502,475,502,501,476,477,503,476,503,502,477,47,48,477,48,503,17,478,504,17,504,18,478,479,505,478,505,504,479,480,506,479,506,505,480,481,507,480,507,506,481,482,508,481,508,507,482,483,509,482,509,508,483,484,510,483,510,509,484,485,511,484,511,510,485,486,512,485,512,511,486,487,513,486,513,512,487,488,514,487,514,513,488,489,515,488,515,514,489,490,516,489,516,515,490,491,517,490,517,516,491,492,518,491,518,517,492,493,519,492,519,518,493,494,520,493,520,519,494,495,521,494,521,520,495,496,522,495,522,521,496,497,523,496,523,522,497,498,524,497,524,523,498,499,525,498,525,524,499,500,526,499,526,525,500,501,527,500,527,526,501,502,528,501,528,527,502,503,529,502,529,528,503,48,49,503,49,529,18,504,530,18,530,19,504,505,531,504,531,530,505,506,532,505,532,531,506,507,533,506,533,532,507,508,534,507,534,533,508,509,535,508,535,534,509,510,536,509,536,535,510,511,537,510,537,536,511,512,538,511,538,537,512,513,539,512,539,538,513,514,540,513,540,539,514,515,541,514,541,540,515,516,542,515,542,541,516,517,543,516,543,542,517,518,544,517,544,543,518,519,545,518,545,544,519,520,546,519,546,545,520,521,547,520,547,546,521,522,548,521,548,547,522,523,549,522,549,548,523,524,550,523,550,549,524,525,551,524,551,550,525,526,552,525,552,551,526,527,553,526,553,552,527,528,554,527,554,553,528,529,555,528,555,554,529,49,50,529,50,555,19,530,556,19,556,20,530,531,557,530,557,556,531,532,558,531,558,557,532,533,559,532,559,558,533,534,560,533,560,559,534,535,561,534,561,560,535,536,562,535,562,561,536,537,563,536,563,562,537,538,564,537,564,563,538,539,565,538,565,564,539,540,566,539,566,565,540,541,567,540,567,566,541,542,568,541,568,567,542,543,569,542,569,568,543,544,570,543,570,569,544,545,571,544,571,570,545,546,572,545,572,571,546,547,573,546,573,572,547,548,574,547,574,573,548,549,575,548,575,574,549,550,576,549,576,575,550,551,577,550,577,576,551,552,578,551,578,577,552,553,579,552,579,578,553,554,580,553,580,579,554,555,581,554,581,580,555,50,51,555,51,581,20,556,582,20,582,21,556,557,583,556,583,582,557,558,584,557,584,583,558,559,585,558,585,584,559,560,586,559,586,585,560,561,587,560,587,586,561,562,588,561,588,587,562,563,589,562,589,588,563,564,590,563,590,589,564,565,591,564,591,590,565,566,592,565,592,591,566,567,593,566,593,592,567,568,594,567,594,593,568,569,595,568,595,594,569,570,596,569,596,595,570,571,597,570,597,596,571,572,598,571,598,597,572,573,599,572,599,598,573,574,600,573,600,599,574,575,601,574,601,600,575,576,602,575,602,601,576,577,603,576,603,602,577,578,604,577,604,603,578,579,605,578,605,604,579,580,606,579,606,605,580,581,607,580,607,606,581,51,52,581,52,607,21,582,608,21,608,22,582,583,609,582,609,608,583,584,610,583,610,609,584,585,611,584,611,610,585,586,612,585,612,611,586,587,613,586,613,612,587,588,614,587,614,613,588,589,615,588,615,614,589,590,616,589,616,615,590,591,617,590,617,616,591,592,618,591,618,617,592,593,619,592,619,618,593,594,620,593,620,619,594,595,621,594,621,620,595,596,622,595,622,621,596,597,623,596,623,622,597,598,624,597,624,623,598,599,625,598,625,624,599,600,626,599,626,625,600,601,627,600,627,626,601,602,628,601,628,627,602,603,629,602,629,628,603,604,630,603,630,629,604,605,631,604,631,630,605,606,632,605,632,631,606,607,633,606,633,632,607,52,53,607,53,633,22,608,634,22,634,23,608,609,635,608,635,634,609,610,636,609,636,635,610,611,637,610,637,636,611,612,638,611,638,637,612,613,639,612,639,638,613,614,640,613,640,639,614,615,641,614,641,640,615,616,642,615,642,641,616,617,643,616,643,642,617,618,644,617,644,643,618,619,645,618,645,644,619,620,646,619,646,645,620,621,647,620,647,646,621,622,648,621,648,647,622,623,649,622,649,648,623,624,650,623,650,649,624,625,651,624,651,650,625,626,652,625,652,651,626,627,653,626,653,652,627,628,654,627,654,653,628,629,655,628,655,654,629,630,656,629,656,655,630,631,657,630,657,656,631,632,658,631,658,657,632,633,659,632,659,658,633,53,54,633,54,659,23,634,660,23,660,24,634,635,661,634,661,660,635,636,662,635,662,661,636,637,663,636,663,662,637,638,664,637,664,663,638,639,665,638,665,664,639,640,666,639,666,665,640,641,667,640,667,666,641,642,668,641,668,667,642,643,669,642,669,668,643,644,670,643,670,669,644,645,671,644,671,670,645,646,672,645,672,671,646,647,673,646,673,672,647,648,674,647,674,673,648,649,675,648,675,674,649,650,676,649,676,675,650,651,677,650,677,676,651,652,678,651,678,677,652,653,679,652,679,678,653,654,680,653,680,679,654,655,681,654,681,680,655,656,682,655,682,681,656,657,683,656,683,682,657,658,684,657,684,683,658,659,685,658,685,684,659,54,55,659,55,685,24,660,686,24,686,25,660,661,687,660,687,686,661,662,688,661,688,687,662,663,689,662,689,688,663,664,690,663,690,689,664,665,691,664,691,690,665,666,692,665,692,691,666,667,693,666,693,692,667,668,694,667,694,693,668,669,695,668,695,694,669,670,696,669,696,695,670,671,697,670,697,696,671,672,698,671,698,697,672,673,699,672,699,698,673,674,700,673,700,699,674,675,701,674,701,700,675,676,702,675,702,701,676,677,703,676,703,702,677,678,704,677,704,703,678,679,705,678,705,704,679,680,706,679,706,705,680,681,707,680,707,706,681,682,708,681,708,707,682,683,709,682,709,708,683,684,710,683,710,709,684,685,711,684,711,710,685,55,56,685,56,711,25,686,712,25,712,26,686,687,713,686,713,712,687,688,714,687,714,713,688,689,715,688,715,714,689,690,716,689,716,715,690,691,717,690,717,716,691,692,718,691,718,717,692,693,719,692,719,718,693,694,720,693,720,719,694,695,721,694,721,720,695,696,722,695,722,721,696,697,723,696,723,722,697,698,724,697,724,723,698,699,725,698,725,724,699,700,726,699,726,725,700,701,727,700,727,726,701,702,728,701,728,727,702,703,729,702,729,728,703,704,730,703,730,729,704,705,731,704,731,730,705,706,732,705,732,731,706,707,733,706,733,732,707,708,734,707,734,733,708,709,735,708,735,734,709,710,736,709,736,735,710,711,737,710,737,736,711,56,57,711,57,737,26,712,738,26,738,27,712,713,739,712,739,738,713,714,740,713,740,739,714,715,741,714,741,740,715,716,742,715,742,741,716,717,743,716,743,742,717,718,744,717,744,743,718,719,745,718,745,744,719,720,746,719,746,745,720,721,747,720,747,746,721,722,748,721,748,747,722,723,749,722,749,748,723,724,750,723,750,749,724,725,751,724,751,750,725,726,752,725,752,751,726,727,753,726,753,752,727,728,754,727,754,753,728,729,755,728,755,754,729,730,756,729,756,755,730,731,757,730,757,756,731,732,758,731,758,757,732,733,759,732,759,758,733,734,760,733,760,759,734,735,761,734,761,760,735,736,762,735,762,761,736,737,763,736,763,762,737,57,58,737,58,763,27,738,764,27,764,28,738,739,765,738,765,764,739,740,766,739,766,765,740,741,767,740,767,766,741,742,768,741,768,767,742,743,769,742,769,768,743,744,770,743,770,769,744,745,771,744,771,770,745,746,772,745,772,771,746,747,773,746,773,772,747,748,774,747,774,773,748,749,775,748,775,774,749,750,776,749,776,775,750,751,777,750,777,776,751,752,778,751,778,777,752,753,779,752,779,778,753,754,780,753,780,779,754,755,781,754,781,780,755,756,782,755,782,781,756,757,783,756,783,782,757,758,784,757,784,783,758,759,785,758,785,784,759,760,786,759,786,785,760,761,787,760,787,786,761,762,788,761,788,787,762,763,789,762,789,788,763,58,59,763,59,789,28,764,790,28,790,29,764,765,791,764,791,790,765,766,792,765,792,791,766,767,793,766,793,792,767,768,794,767,794,793,768,769,795,768,795,794,769,770,796,769,796,795,770,771,797,770,797,796,771,772,798,771,798,797,772,773,799,772,799,798,773,774,800,773,800,799,774,775,801,774,801,800,775,776,802,775,802,801,776,777,803,776,803,802,777,778,804,777,804,803,778,779,805,778,805,804,779,780,806,779,806,805,780,781,807,780,807,806,781,782,808,781,808,807,782,783,809,782,809,808,783,784,810,783,810,809,784,785,811,784,811,810,785,786,812,785,812,811,786,787,813,786,813,812,787,788,814,787,814,813,788,789,815,788,815,814,789,59,60,789,60,815,29,790,816,29,816,30,790,791,817,790,817,816,791,792,818,791,818,817,792,793,819,792,819,818,793,794,820,793,820,819,794,795,821,794,821,820,795,796,822,795,822,821,796,797,823,796,823,822,797,798,824,797,824,823,798,799,825,798,825,824,799,800,826,799,826,825,800,801,827,800,827,826,801,802,828,801,828,827,802,803,829,802,829,828,803,804,830,803,830,829,804,805,831,804,831,830,805,806,832,805,832,831,806,807,833,806,833,832,807,808,834,807,834,833,808,809,835,808,835,834,809,810,836,809,836,835,810,811,837,810,837,836,811,812,838,811,838,837,812,813,839,812,839,838,813,814,840,813,840,839,814,815,841,814,841,840,815,60,61,815,61,841,30,816,62,30,62,0,816,817,64,816,64,62,817,818,66,817,66,64,818,819,68,818,68,66,819,820,70,819,70,68,820,821,72,820,72,70,821,822,74,821,74,72,822,823,76,822,76,74,823,824,78,823,78,76,824,825,80,824,80,78,825,826,82,825,82,80,826,827,84,826,84,82,827,828,86,827,86,84,828,829,88,828,88,86,829,830,90,829,90,88,830,831,92,830,92,90,831,832,94,831,94,92,832,833,96,832,96,94,833,834,98,833,98,96,834,835,100,834,100,98,835,836,102,835,102,100,836,837,104,836,104,102,837,838,106,837,106,104,838,839,108,838,108,106,839,840,110,839,110,108,840,841,112,840,112,110,841,61,31,841,31,112];
+	normals = utils.calculateNormals(vertices, indices);
+	 	
+	sphereVerticesBuffer = gl.createBuffer();
+	gl.bindBuffer(gl.ARRAY_BUFFER, sphereVerticesBuffer);
+	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
+	
+	sphereNormalsBuffer = gl.createBuffer();
+	gl.bindBuffer(gl.ARRAY_BUFFER, sphereNormalsBuffer);
+	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
+	
+	sphereIndicesBuffer = gl.createBuffer();
+	gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereIndicesBuffer);
+	gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
+	
+	gl.bindBuffer(gl.ARRAY_BUFFER, null);
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+	
+}
+
+/**
+* Main rendering function. Called every 500ms according to WebGLStart function (see below)
+*/
+function drawScene() {
+    gl.clearColor(clearColor[0],clearColor[1],clearColor[2],clearColor[3]);
+    gl.clearDepth(100.0);
+	gl.enable(gl.DEPTH_TEST);
+	gl.depthFunc(gl.LEQUAL);
+	gl.viewport(0, 0, c_width, c_height);
+	gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+	mat4.perspective(45, c_width / c_height, 0.1, 10000.0, pMatrix);
+    
+    mat4.identity(mvMatrix);
+    mat4.translate(mvMatrix, [0.0, 0.0, -1.5]); //Sets the camera to a reasonable distance to view the part
+    mat4.rotate(mvMatrix, angle * Math.PI / 180, [0, 1, 0]);	
+    
+    gl.uniformMatrix4fv(prg.uMVMatrix, false, mvMatrix);
+	gl.uniformMatrix4fv(prg.uPMatrix, false, pMatrix);
+	
+    mat4.set(mvMatrix, nMatrix);
+    mat4.inverse(nMatrix);
+    mat4.transpose(nMatrix);
+    
+    gl.uniformMatrix4fv(prg.uNMatrix, false, nMatrix);
+    
+    
+	
+    try{
+    	gl.enableVertexAttribArray(prg.aVertexPosition);
+		gl.enableVertexAttribArray(prg.aVertexNormal);
+				
+		//2. bind buffers 
+		gl.bindBuffer(gl.ARRAY_BUFFER, sphereVerticesBuffer);
+		gl.vertexAttribPointer(prg.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
+		
+		gl.bindBuffer(gl.ARRAY_BUFFER, sphereNormalsBuffer);
+		gl.vertexAttribPointer(prg.aVertexNormal,3,gl.FLOAT, false, 0,0);
+		
+	    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,sphereIndicesBuffer);
+		gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
+		//gl.drawElements(gl.LINES, indices.length, gl.UNSIGNED_SHORT,0);
+		gl.bindBuffer(gl.ARRAY_BUFFER, null);
+		gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+		
+	}
+	catch(err){
+		alert(err);
+		message(err.description);
+	}
+}
+
+
+
+
+var lastTime = 0;
+
+/**
+* Updates the angle of rotation by a little bit each time
+*/
+function animate() {
+    var timeNow = new Date().getTime();
+    if (lastTime != 0) {
+        var elapsed = timeNow - lastTime;
+        angle += (90 * elapsed) / 10000.0;
+    }
+    lastTime = timeNow;
+}
+
+/**
+* Render Loop
+*/
+function renderLoop() {
+    requestAnimFrame(renderLoop);
+    drawScene();
+    animate();
+}
+
+/**
+* Entry point. This function is invoked when the page is loaded
+*/
+function runWebGLApp() {
+	//Obtains a WebGL context
+	gl = utils.getGLContext("canvas-element-id");
+	//Initializes the program (shaders) 
+    initProgram();
+    //Initializes the buffers that we are going to use
+    initBuffers();
+    //Initializes lights
+ 	initLights();
+    //Renders the scene!
+    renderLoop();
+}
+</script>
+</head>
+
+<body onLoad='runWebGLApp()'>
+<div id='top'>
+	<h1>WebGL Beginner's Guide - Chapter 3</h1>
+	<h2>Ambient Test</h2>
+	<div id='logo-packt'><img src='packt.gif'/></div>
+	<p>This test will produce negative Lambert coefficients. This happens when you have vertex normals forming an obtuse angle with the negative light-direction vector. 
+    
+    Set x to 0 and z to 1. You will be locating thie light source behind the sphere. Then, increase the intensity of the ambient light property. As it is explained in Chapter 3, we have modified the ambient light color to show you that when you the object is behind the object and your point of view, you do not account with the diffuse component to see the object.
+</p>
+</div>
+
+<div id='contents'>
+	<div id='canvasContainer'>
+		<canvas id='canvas-element-id' width='480' height='400'>
+			Your browser does not support the HTML5 canvas element.
+		</canvas>
+	</div>
+</div>
+
+<div id='bottom'>
+
+<table style='padding=0px'>
+		<tr>
+			<td align='right'>Light Color (Light Diffuse Term):</td><td colspan='2'><div id='colorSelectorLight' class='colorSelector'><div style='background-color:rgb(256,256,256)'></div></div></td>
+			<td>Sphere Color (Material Diffuse Term):</td><td colspan='2'><div id='colorSelectorSphere' class='colorSelector'><div style='background-color:rgb(46,99,191)'></div></div></td>	
+		</tr>
+		<tr>
+			<td align='right'>Light Ambient Term:</td><td id='slider-la-value'  width='30px'>0.03</td><td><div id='slider-la'/></td>
+			<td>Material Ambient Term:</td><td id='slider-ma-value' width='30px'>1.0</td><td colspan='3'><div id='slider-ma'/></td>
+		</tr>
+		
+		<tr>
+			<td align='right'>Light Specular Term:</td><td id='slider-ls-value'  width='30px'>1.0</td><td><div id='slider-ls'/></td>
+			<td>Material Specular Term:</td><td id='slider-ms-value' width='30px'>1.0</td><td colspan='3'><div id='slider-ms'/></td>
+		</tr>
+		<tr>
+			
+			<td align='right'>X:</td><td id='slider-x-value' width='30px' align='center'>-0.25</td><td width='150px'><div id='slider-x'/></td>
+			
+			<td>Shininess:</td><td id='slider-s-value' width='30px'>10.0</td><td width='150px'><div id='slider-s'/></td>
+		</tr>
+		<tr>
+			<td align='right'>Y:</td><td id='slider-y-value'  width='30px' align='center'>-0.25</td><td width='150px'><div id='slider-y'/></td>
+			<td>Background Color (gl.clearColor):</td><td colspan='2'><div id='colorSelectorBg' class='colorSelector'><div style='background-color:rgb(77,77,77)'></div></div></td>	
+		</tr>
+		<tr>
+			<td align='right'>Z:</td> <td id='slider-z-value'  width='30px' align='center'>-0.25</td><td width='150px'><div id='slider-z'/></td>
+			
+		</tr>
+	</table>
+
+	<br/>
+	
+	<p>This model has three terms:</p>
+	<ul>
+	<li><b>Ia</b>: ambient term</li>
+	<li><b>Id</b>: diffuse term</li>
+	<li><b>Is</b>: specular term</li>
+	</ul>
+	<p>However, the diffusive and specular terms are only taken into account if the Lambert term is larger than zero.</p>
+	<p>In this case: I = <b>Ia</b> + <b>Id</b> + <b>Is</b>,  otherwise (Lambert term <= 0):I = <b>Ia</b></p>
+</div>
+<script>cview.run(cview.MODE_VIEW);</script>
+<script>
+
+function updateShininess(){
+    var v = $('#slider-s').slider("value");
+	
+    gl.uniform1f(prg.uShininess, v);
+    $('#slider-s-value').html(v);
+}
+
+$('#slider-s').slider({value:10.0, min:0, max:40, step:1, slide: updateShininess});
+
+function updateLightAmbientTerm(){
+	var la = $('#slider-la').slider("value");
+	gl.uniform4fv(prg.uLightAmbient,[0.0,la,0.0,1.0]);
+	$('#slider-la-value').html(la);
+}
+
+function updateLightDiffuseTerm(){
+	var ld = $('#slider-ld').slider("value");
+	gl.uniform4fv(prg.uLightDiffuse,[ld,ld,ld,1.0]);
+	$('#slider-ld-value').html(ld);
+}
+
+function updateLightSpecularTerm(){
+	var ls = $('#slider-ls').slider("value");
+	gl.uniform4fv(prg.uLightSpecular,[ls,ls,ls,1.0]);
+	$('#slider-ls-value').html(ls);
+}
+
+
+function updateMaterialAmbientTerm(){
+	var ma = $('#slider-ma').slider("value");
+	gl.uniform4fv(prg.uMaterialAmbient,[ma,ma,ma,1.0]);
+	$('#slider-ma-value').html(ma);
+}
+
+function updateMaterialSpecularTerm(){
+	var ms = $('#slider-ms').slider("value");
+	gl.uniform4fv(prg.uMaterialSpecular,[ms,ms,ms,1.0]);
+	$('#slider-ms-value').html(ms);
+}
+
+$('#slider-la').slider({value:0.03, min:-0.01, max:1.0, step:0.01, slide:updateLightAmbientTerm});
+$('#slider-ld').slider({value:0.35, min:-0.01, max:1.0, step:0.01, slide:updateLightDiffuseTerm});
+$('#slider-ls').slider({value:1.0, min:-0.01, max:1.0, step:0.01, slide:updateLightSpecularTerm});
+
+$('#slider-ma').slider({value:1.0, min:-0.2, max:1.2, step:0.1, slide:updateMaterialAmbientTerm});
+$('#slider-ms').slider({value:1.0, min:-0.01, max:1.2, step:0.1, slide:updateMaterialSpecularTerm});
+
+function updateLightDirection(){
+   var x = $('#slider-x').slider("value");
+   var y = $('#slider-y').slider("value");
+   var z = $('#slider-z').slider("value");
+   gl.uniform3fv(prg.uLightDirection, [x,y,z]);
+   $('#slider-x-value').html(x);
+   $('#slider-y-value').html(y);
+   $('#slider-z-value').html(z);
+}
+
+$('#slider-x').slider({value:-0.25, min:-1.05, max:1.05, step:0.01, slide:updateLightDirection});
+$('#slider-y').slider({value:-0.25, min:-1.05, max:1.05, step:0.01, slide:updateLightDirection});
+$('#slider-z').slider({value:-0.25, min:-1.05, max:1.05, step:0.01, slide:updateLightDirection});
+
+function updateObjectColor(r,g,b){
+    gl.uniform4fv(prg.uMaterialDiffuse,[r,g,b,1.0]);	
+}
+
+function updateLightColor(r,g,b){
+    gl.uniform4fv(prg.uLightDiffuse,[r,g,b,1.0]);	
+}
+
+function updateClearColor(r,g,b){
+    clearColor = [r,g,b,1.0];
+}
+
+
+$('#colorSelectorSphere').ColorPicker({
+    onSubmit: function(hsb, hex, rgb, el) {
+			$(el).val(hex);
+			$(el).ColorPickerHide();
+			
+	},
+	color: '#00ff00',
+    onShow: function (colpkr) {
+        $(colpkr).fadeIn(500);
+        return false;
+    },
+    onHide: function (colpkr) {
+        $(colpkr).fadeOut(500);
+        return false;
+    },
+    onChange: function (hsb, hex, rgb) {
+        $('#colorSelectorSphere div').css('backgroundColor', '#' + hex);
+        updateObjectColor(rgb.r/256,rgb.g/256,rgb.b/256);
+    },
+    
+    onBeforeShow: function (colpkr) {
+			$(this).ColorPickerSetColor('rgb(0.5,0.8,0.1)');
+		}
+	})
+
+	
+$('#colorSelectorLight').ColorPicker({
+    onSubmit: function(hsb, hex, rgb, el) {
+			$(el).val(hex);
+			$(el).ColorPickerHide();
+			
+	},
+	color: '#00ff00',
+    onShow: function (colpkr) {
+        $(colpkr).fadeIn(500);
+        return false;
+    },
+    onHide: function (colpkr) {
+        $(colpkr).fadeOut(500);
+        return false;
+    },
+    onChange: function (hsb, hex, rgb) {
+        $('#colorSelectorLight div').css('backgroundColor', '#' + hex);
+        updateLightColor(rgb.r/256,rgb.g/256,rgb.b/256);
+    },
+    
+    onBeforeShow: function (colpkr) {
+			$(this).ColorPickerSetColor('rgb(0.5,0.8,0.1)');
+		}
+	})	
+	
+$('#colorSelectorBg').ColorPicker({
+    onSubmit: function(hsb, hex, rgb, el) {
+			$(el).val(hex);
+			$(el).ColorPickerHide();
+			
+	},
+	color: '#00ff00',
+    onShow: function (colpkr) {
+        $(colpkr).fadeIn(500);
+        return false;
+    },
+    onHide: function (colpkr) {
+        $(colpkr).fadeOut(500);
+        return false;
+    },
+    onChange: function (hsb, hex, rgb) {
+        $('#colorSelectorBg div').css('backgroundColor', '#' + hex);
+        updateClearColor(rgb.r/256,rgb.g/256,rgb.b/256);
+    },
+    
+    onBeforeShow: function (colpkr) {
+			$(this).ColorPickerSetColor('rgb(0.5,0.8,0.1)');
+		}
+	})	
+	
+</script>
+</body>
+</html>

1727_03/ch3_Nissan.html

+<html>
+
+<head>
+<title>WebGL Beginner's Guide - Chapter 3 - Nissan GTS with Shading</title>
+
+<!-- CSS Styles //-->
+<link href='css/style.css' 		type='text/css' rel='stylesheet'>
+<link href='css/desert.css' 	type='text/css' rel='stylesheet'/>
+<link href='css/colorpicker.css' 	type='text/css' rel='stylesheet'/>
+<link href='css/smoothness/jquery-ui-1.8.13.custom.css' type='text/css' rel='stylesheet' />
+
+<!-- JavaScript Libraries //-->
+<script type='text/javascript' src='js/glMatrix-0.9.5.min.js'></script>
+<script type='text/javascript' src='js/jquery-1.5.1.min.js'></script>
+<script type='text/javascript' src='js/jquery-ui-1.8.13.custom.min.js'></script> 
+<script type='text/javascript' src='js/prettify.js'></script>
+<script type='text/javascript' src='js/utils.js'></script>
+<script type='text/javascript' src='js/colorpicker.js'></script>
+<script type='text/javascript' src='js/codeview.js'></script>
+
+
+<script id="shader-vs" type="x-shader/x-vertex">
+attribute vec3 aVertexPosition;
+attribute vec3 aVertexNormal;
+
+uniform mat4 uMVMatrix; 
+uniform mat4 uPMatrix; 
+uniform mat4 uNMatrix; 
+
+uniform vec3 uLightPosition;
+
+varying vec3 vNormal;
+varying vec3 vLightRay;
+varying  vec3 vEyeVec;
+
+void main(void) {
+
+	vec4 vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
+    
+    vNormal = vec3(uNMatrix * vec4(aVertexNormal, 1.0));
+    
+    vec4 light = vec4(uLightPosition,1.0);
+	
+    vLightRay = vertex.xyz - light.xyz;
+	
+    vEyeVec = -vec3(vertex.xyz);
+    
+    gl_Position = uPMatrix * vertex;
+	
+}
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision highp float;
+#endif
+
+uniform float uShininess;       // 
+uniform vec3 uLightAmbient;     //ambient color
+uniform vec3 uMaterialDiffuse;      //diffuse color
+uniform vec3 uMaterialSpecular;       //specular color
+
+varying vec3 vNormal;
+varying  vec3 vLightRay;
+varying  vec3 vEyeVec;
+
+void main(void)
+{
+	vec3 L = normalize(vLightRay);
+	vec3 N = normalize(vNormal);
+	
+	
+	float lambertTerm = dot(N,-L);
+	
+	vec3 finalColor = uLightAmbient;
+	
+	if(lambertTerm > 0.0)
+	{
+		finalColor += uMaterialDiffuse * lambertTerm;	
+		
+		vec3 E = normalize(vEyeVec);
+		vec3 R = reflect(L, N);
+		float specular = pow( max(dot(R, E), 0.0), uShininess);
+		finalColor += uMaterialSpecular * specular;
+	}
+	
+	gl_FragColor = vec4(finalColor, 1.0);
+
+}
+</script>
+
+<script id="code-js" type="text/javascript">
+    
+var gl = null; // WebGL context
+var prg = null; // The program (shaders)
+var c_width = 0; // Variable to store the width of the canvas
+var c_height = 0; // Variable to store the height of the canvas
+
+var clearColor = [0.1,0.1,0.1,1.0];
+var distance = -2000;
+
+var part = [];    //PARTS LOADED
+var vbo = [];
+var ibo = [];
+var nbo = [];
+
+
+var mvMatrix = mat4.create(); // The Model-View matrix
+var pMatrix = mat4.create(); // The projection matrix
+var nMatrix = mat4.create(); // The normal matrix
+
+var animateFlag = false;
+var angle = 0;
+
+    
+/*
+* The program contains a series of instructions that tell the Graphic Processing Unit (GPU)
+* what to do with every vertex and fragment that we pass it. (more about this on chapter 3)
+* The vertex shader and the fragment shader together are called the program.
+*/
+function initProgram() {
+    var fgShader = utils.getShader(gl, "shader-fs");
+    var vxShader = utils.getShader(gl, "shader-vs");
+
+    prg = gl.createProgram();
+    gl.attachShader(prg, vxShader);
+    gl.attachShader(prg, fgShader);
+    gl.linkProgram(prg);
+
+    if (!gl.getProgramParameter(prg, gl.LINK_STATUS)) {
+        alert("Could not initialise shaders");
+    }
+
+    gl.useProgram(prg);
+
+    prg.aVertexPosition     = gl.getAttribLocation(prg, "aVertexPosition");
+    prg.uPMatrix            = gl.getUniformLocation(prg, "uPMatrix");
+    prg.uMVMatrix           = gl.getUniformLocation(prg, "uMVMatrix");
+    prg.aVertexNormal       = gl.getAttribLocation(prg, "aVertexNormal");
+    
+    prg.uNMatrix            = gl.getUniformLocation(prg,"uNMatrix");
+    prg.uLightAmbient       = gl.getUniformLocation(prg,"uLightAmbient");
+    prg.uLightPosition      = gl.getUniformLocation(prg,"uLightPosition");
+    prg.uMaterialSpecular      = gl.getUniformLocation(prg,"uMaterialSpecular");
+    prg.uMaterialDiffuse    = gl.getUniformLocation(prg,"uMaterialDiffuse");
+    
+    prg.uShininess          = gl.getUniformLocation(prg,"uShininess");
+}	
+
+function initLights(){
+    gl.uniform3f(prg.uLightPosition, 31000, 14000, 24000);
+    gl.uniform3f(prg.uLightAmbient,0.1,0.1,0.1);
+	gl.uniform3f(prg.uMaterialSpecular, 0.5,0.5,0.5);	
+	gl.uniform3f(prg.uMaterialDiffuse, 0.8,0.8,0.8);
+    gl.uniform1f(prg.uShininess, 24.0);
+}	
+    
+/**
+* Creates an AJAX request to load a model asynchronously
+*/
+function loadModel(){
+  for(var i = 1; i < 179; i++){
+        var filename = 'models/nissan_gts/pr'+i+'.json';
+        loadPart(filename);
+   }
+ 
+ 
+}
+
+function loadPart(filename){
+    var request = new XMLHttpRequest();
+    console.info('Requesting ' + filename);
+    request.open("GET",filename);
+    
+    request.onreadystatechange = function() {
+      if (request.readyState == 4) {
+        if(request.status == 404) {
+            console.info(filename + ' does not exist');
+         }
+        else {
+            handleLoadedPart(filename,JSON.parse(request.responseText));
+        }
+      }
+    }
+    request.send();
+}
+
+/**
+* Creates the buffers that contain the geometry of the model
+*/
+function handleLoadedPart(filename,payload) {
+    
+    console.info(filename + ' has been retrieved from the server');
+    
+    var vertexBufferObject = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBufferObject);
+    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(payload.vertices), gl.STATIC_DRAW);
+    
+           
+    var normalBufferObject = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, normalBufferObject);
+    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(utils.calculateNormals(payload.vertices, payload.indices)), gl.STATIC_DRAW);
+    
+    var indexBufferObject = gl.createBuffer();
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBufferObject);
+    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(payload.indices), gl.STATIC_DRAW);
+        
+    
+    vbo.push(vertexBufferObject);
+    ibo.push(indexBufferObject);
+    nbo.push(normalBufferObject);
+    
+    
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+    gl.bindBuffer(gl.ARRAY_BUFFER,null);
+    
+    part.push(payload);
+}
+
+/**
+* Draws the scene
+*/
+function drawScene(){
+    
+    gl.clearColor(clearColor[0],clearColor[1],clearColor[2],clearColor[3]);
+    gl.enable(gl.DEPTH_TEST);
+    gl.depthFunc(gl.LEQUAL);
+    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+    gl.viewport(0,0,c_width, c_height);
+    
+    mat4.perspective(45, c_width / c_height, 100, 10000.0, pMatrix);
+    mat4.identity(mvMatrix);
+    mat4.translate(mvMatrix, [0.0, -200.0, distance]); //Sets the camera to a reasonable distance to view the part
+    mat4.rotate(mvMatrix, 17 * Math.PI /180, [1,0,0]);
+    mat4.rotate(mvMatrix, angle * Math.PI / 180, [0, 1, 0]);
+    
+    gl.uniformMatrix4fv(prg.uPMatrix, false, pMatrix);
+    gl.uniformMatrix4fv(prg.uMVMatrix, false, mvMatrix);
+    
+    mat4.set(mvMatrix, nMatrix);
+    mat4.inverse(nMatrix);
+    mat4.transpose(nMatrix);
+    
+    gl.uniformMatrix4fv(prg.uNMatrix, false, nMatrix);
+    
+    
+    
+    
+    for(var i = 0; i < part.length; i++){
+        gl.bindBuffer(gl.ARRAY_BUFFER, vbo[i]);
+        gl.vertexAttribPointer(prg.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
+        gl.enableVertexAttribArray(prg.aVertexPosition);
+        
+        gl.bindBuffer(gl.ARRAY_BUFFER, nbo[i]);
+        gl.vertexAttribPointer(prg.aVertexNormal, 3, gl.FLOAT, false, 0, 0);
+        gl.enableVertexAttribArray(prg.aVertexNormal);
+    
+        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo[i]);
+        gl.drawElements(gl.TRIANGLES, part[i].indices.length, gl.UNSIGNED_SHORT,0);
+    }
+    
+}
+
+
+
+
+var lastTime = 0;
+
+/**
+* Updates the angle of rotation by a little bit each time
+*/
+function animate() {
+    var timeNow = new Date().getTime();
+    if (lastTime != 0) {
+        var elapsed = timeNow - lastTime;
+        if (animateFlag) angle += (90 * elapsed) / 10000.0;
+    }
+    lastTime = timeNow;
+}
+
+/**
+* Render Loop
+*/
+function renderLoop() {
+    utils.requestAnimFrame(renderLoop);
+    drawScene();
+    animate();
+}
+/**
+* Executes the WebGL application
+* This function is invoked on the onLoad event of the webpage. 
+*/
+function runWebGLApp(){
+    //Obtains a WebGL context
+    gl = utils.getGLContext('canvas-element-id');
+    //Initializes the program (shaders). More about this on chapter 3!
+    initProgram();
+    //Init Lights!
+    initLights();
+    //Initializes the buffers that we are going to use to draw the part (vertex buffer and index buffer)
+    loadModel();
+    //Draws the part!
+    renderLoop();
+}
+</script>
+</head>
+
+<body onLoad='runWebGLApp()'>
+<div id='top'>
+<h1>WebGL Beginner's Guide - Chapter 3</h1>
+<h2>Nissan GTS - Phong Lighting Model</h2>
+<div id='logo-packt'><img src='packt.gif'/></div>
+<p></p>
+</div>
+
+<div id='contents'>
+<div id='canvasContainer'>
+<canvas id='canvas-element-id' width='480' height='400'>
+Your browser does not support the HTML5 canvas element.
+</canvas>
+</div>
+</div>
+
+<div id='bottom'>
+<table style='padding=0px'>
+<tr>
+<td>X:</td><td id='slider-x-value' width='30px'>31</td><td width='150px'><div id='slider-x'/></td>
+<td>Shininess:</td><td id='slider-shininess-value'>40</td><td width='150px'><div id='slider-shininess'/></td>
+<td>Car Color (material diffuse property):</td><td><div id='colorSelectorCar' class='colorSelector'><div style='background-color:rgb(204,204,204)'></div></div></td>
+</tr>
+<tr>
+<td>Y:</td><td id='slider-y-value'  width='30px'>99</td><td width='150px'><div id='slider-y'/></td>
+<td>Distance:</td><td id='slider-distance-value'>200</td><td width='150px'><div id='slider-distance'/></td>
+<td>Background Color (gl.clearColor):</td><td colspan='2'><div id='colorSelectorBg' class='colorSelector'><div style='background-color:rgb(28,28,28)'></div></div></td> 
+</tr>
+<tr>
+<td>Z:</td> <td id='slider-z-value'  width='30px'>24</td><td width='150px'><div id='slider-z'/></td>
+<td><label id='lblanimate' for='animate-btn'>Animate</label><input id='animate-btn' type='checkbox'/></td>
+</tr>
+</table>
+</div>
+<script>cview.run(cview.MODE_VIEW);</script>
+<script> 
+
+$('#slider-shininess').slider({value:24, min:1, max:200, step:1, slide:updateShininess});
+$('#slider-distance').slider({value:200, min:40, max:250, step:1, slide:updateDistance});
+$('#slider-x').slider({value:31, min:-200, max:200, step:1, slide:updateLight, change:updateLight});
+$('#slider-y').slider({value:14, min:-200, max:200, step:1, slide:updateLight, change:updateLight});
+$('#slider-z').slider({value:24, min:-200, max:200, step:1, slide:updateLight, change:updateLight});
+
+
+$('#animate-btn').button();
+$('#animate-btn').click(
+function(){
+    if ($('#animate-btn:checked').val()==null){
+        animateFlag = false;
+    }
+    else{
+        animateFlag = true;
+    }
+});
+function updateShininess(){
+    var v = $('#slider-shininess').slider("value");
+    gl.uniform1f(prg.uShininess, v);
+    $('#slider-shininess-value').html(v);
+}
+
+
+
+function updateLight(){
+    var x = $('#slider-x').slider("value");
+    var y = $('#slider-y').slider("value");
+    var z = $('#slider-z').slider("value");
+    gl.uniform3fv(prg.uLightPosition, [x*1000,y*1000,z*1000]);
+    $('#slider-x-value').html(x);
+    $('#slider-y-value').html(y);
+    $('#slider-z-value').html(z);
+}
+
+
+function updateDistance(){
+    var d = $('#slider-distance').slider("value");
+    distance = -d * 10;
+    $('#slider-distance-value').html(d);
+}
+
+function updateClearColor(r,g,b){
+    clearColor = [r,g,b,1.0];
+}
+
+function updateObjectColor(r,g,b){
+    gl.uniform3fv(prg.uMaterialDiffuse,[r,g,b]); 
+}
+
+$('#colorSelectorCar').ColorPicker({
+onSubmit: function(hsb, hex, rgb, el) {
+        $(el).val(hex);
+        $(el).ColorPickerHide();
+
+    },
+color: '#00ff00',
+onShow: function (colpkr) {
+        $(colpkr).fadeIn(500);
+        return false;
+    },
+onHide: function (colpkr) {
+        $(colpkr).fadeOut(500);
+        return false;
+    },
+onChange: function (hsb, hex, rgb) {
+        $('#colorSelectorCar div').css('backgroundColor', '#' + hex);
+        updateObjectColor(rgb.r/256,rgb.g/256,rgb.b/256);
+    },
+    
+onBeforeShow: function (colpkr) {
+        $(this).ColorPickerSetColor('rgb(0.5,0.8,0.1)');
+    }
+})
+
+$('#colorSelectorBg').ColorPicker({
+    onSubmit: function(hsb, hex, rgb, el) {
+   $(el).val(hex);
+   $(el).ColorPickerHide();
+   
+ },
+ color: '#00ff00',
+    onShow: function (colpkr) {
+        $(colpkr).fadeIn(500);
+        return false;
+    },
+    onHide: function (colpkr) {
+        $(colpkr).fadeOut(500);
+        return false;
+    },
+    onChange: function (hsb, hex, rgb) {
+        $('#colorSelectorBg div').css('backgroundColor', '#' + hex);
+        updateClearColor(rgb.r/256,rgb.g/256,rgb.b/256);
+    },
+    
+    onBeforeShow: function (colpkr) {
+   $(this).ColorPickerSetColor('rgb(0.5,0.8,0.1)');
+  }
+ }) 
+</script>
+</body>
+</html>

1727_03/ch3_Nissan_Diffuse.html

-<html>
-
-<head>
-<title>WebGL Beginner's Guide - Chapter 3 - Nissan GTS with Shading</title>
-
-<!-- CSS Styles //-->
-<link href='css/style.css' 		type='text/css' rel='stylesheet'>
-<link href='css/desert.css' 	type='text/css' rel='stylesheet'/>
-<link href='css/colorpicker.css' 	type='text/css' rel='stylesheet'/>
-<link href='css/smoothness/jquery-ui-1.8.13.custom.css' type='text/css' rel='stylesheet' />
-
-<!-- JavaScript Libraries //-->
-<script type='text/javascript' src='js/glMatrix-0.9.5.min.js'></script>
-<script type='text/javascript' src='js/jquery-1.5.1.min.js'></script>
-<script type='text/javascript' src='js/jquery-ui-1.8.13.custom.min.js'></script> 
-<script type='text/javascript' src='js/prettify.js'></script>
-<script type='text/javascript' src='js/utils.js'></script>
-<script type='text/javascript' src='js/colorpicker.js'></script>
-<script type='text/javascript' src='js/codeview.js'></script>
-
-
-<!-- Fragment Shader //-->
-<script id="shader-fs" type="x-shader/x-fragment">
-    #ifdef GL_ES
-    precision highp float;
-    #endif
-    
-    varying vec3 vColor;
-    
-    void main(void) {
-        gl_FragColor = vec4(vColor, 1.0);
-    }
-</script>
-
-<!-- Vertex Shader //-->
-<script id="shader-vs" type="x-shader/x-vertex">
-    attribute vec3 aVertexPosition;
-    attribute vec3 aVertexNormal;
-
-    uniform mat4 uMVMatrix;
-    uniform mat4 uPMatrix;
-    uniform mat4 uNMatrix;
-    
-    //Uniforms that define lighting model
-    uniform vec3 uLightingDirection;
-    uniform vec3 uAmbientColor;
-    uniform vec3 uDirectionalColor;
-    uniform vec3 uObjectColor;
-    
-    varying vec3 vColor;
-
-    void main(void) {
-        vec4 transformedNormal = uNMatrix * vec4(aVertexNormal, 1.0);
-        float directionalLightWeighting = max(dot(transformedNormal.xyz,uLightingDirection),0.0);
-        vColor = uObjectColor * (uAmbientColor + uDirectionalColor * directionalLightWeighting);
-        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
-    }
-</script>
-
-<script id="code-js" type="text/javascript">
-    
-var gl = null; // WebGL context
-var prg = null; // The program (shaders)
-var c_width = 0; // Variable to store the width of the canvas
-var c_height = 0; // Variable to store the height of the canvas
-
-var part = [];    //PARTS LOADED
-var vbo = [];
-var ibo = [];
-var nbo = [];
-
-
-var mvMatrix = mat4.create(); // The Model-View matrix
-var pMatrix = mat4.create(); // The projection matrix
-var nMatrix = mat4.create(); // The normal matrix
-
-var angle = 0;
-
-    
-/*
-* The program contains a series of instructions that tell the Graphic Processing Unit (GPU)
-* what to do with every vertex and fragment that we pass it. (more about this on chapter 3)
-* The vertex shader and the fragment shader together are called the program.
-*/
-function initProgram() {
-    var fgShader = utils.getShader(gl, "shader-fs");
-    var vxShader = utils.getShader(gl, "shader-vs");
-
-    prg = gl.createProgram();
-    gl.attachShader(prg, vxShader);
-    gl.attachShader(prg, fgShader);
-    gl.linkProgram(prg);
-
-    if (!gl.getProgramParameter(prg, gl.LINK_STATUS)) {
-        alert("Could not initialise shaders");
-    }
-
-    gl.useProgram(prg);
-
-    prg.aVertexPosition     = gl.getAttribLocation(prg, "aVertexPosition");
-    prg.uPMatrix            = gl.getUniformLocation(prg, "uPMatrix");
-    prg.uMVMatrix           = gl.getUniformLocation(prg, "uMVMatrix");
-    
-    //Lighting model
-    prg.aVertexNormal       = gl.getAttribLocation(prg, "aVertexNormal");
-    
-    
-    prg.uNMatrix            = gl.getUniformLocation(prg,"uNMatrix");
-    prg.uAmbientColor       = gl.getUniformLocation(prg,"uAmbientColor");
-    prg.uLightingDirection  = gl.getUniformLocation(prg,"uLightingDirection");
-    prg.uDirectionalColor   = gl.getUniformLocation(prg,"uDirectionalColor");
-    prg.uObjectColor        = gl.getUniformLocation(prg,"uObjectColor");
-}	
-
-function initLights(){
-    /**
-     * try x = 1, y = 0, z = 0 to see a really dramatic light effect 
-     * try x = 0, y = 0, z = -1 this is when the light source is on the other side
-     * 
-     */
-    gl.uniform3f(prg.uLightingDirection, 0.0, 0.0, 1.0);
-    gl.uniform3f(prg.uDirectionalColor,0.6 ,0.6, 0.6);
-    gl.uniform3f(prg.uAmbientColor,0.02,0.02,0.02);
-    gl.uniform3f(prg.uObjectColor,1.0,1.0,1.0);
-}	
-    
-/**
-* Creates an AJAX request to load a model asynchronously
-*/
-function loadModel(){
-  for(var i = 1; i < 179; i++){
-        var filename = 'models/nissan_gts/pr'+i+'.json';
-        loadPart(filename);
-   }
- 
- 
-}
-
-function loadPart(filename){
-    var request = new XMLHttpRequest();
-    console.info('Requesting ' + filename);
-    request.open("GET",filename);
-    
-    request.onreadystatechange = function() {
-      if (request.readyState == 4) {
-        if(request.status == 404) {
-            console.info(filename + ' does not exist');
-         }
-        else {
-            handleLoadedPart(filename,JSON.parse(request.responseText));
-        }
-      }
-    }
-    request.send();
-}
-
-/**
-* Creates the buffers that contain the geometry of the model
-*/
-function handleLoadedPart(filename,payload) {
-    
-    console.info(filename + ' has been retrieved from the server');
-    
-    var vertexBufferObject = gl.createBuffer();
-    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBufferObject);
-    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(payload.vertices), gl.STATIC_DRAW);
-    
-           
-    var normalBufferObject = gl.createBuffer();
-    gl.bindBuffer(gl.ARRAY_BUFFER, normalBufferObject);
-    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(createNormals(payload)), gl.STATIC_DRAW);
-    
-    var indexBufferObject = gl.createBuffer();
-    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBufferObject);
-    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(payload.indices), gl.STATIC_DRAW);
-        
-    
-    vbo.push(vertexBufferObject);
-    ibo.push(indexBufferObject);
-    nbo.push(normalBufferObject);
-    
-    
-    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
-    gl.bindBuffer(gl.ARRAY_BUFFER,null);
-    
-    part.push(payload);
-}
-
-
-function createNormals(payload){
-    //face normal calculation
-    var vs = payload.vertices;
-    var ind = payload.indices;
-    
-    var x=0; 
-    var y=1;
-    var z=2;
-    
-    var ns = [];
-    for(var i=0;i<vs.length;i=i+3){ //for each vertex, initialize normal x, normal y, normal z
-        ns[i+x]=0.0;
-        ns[i+y]=0.0;
-        ns[i+z]=0.0;
-    }
-    
-    for(var i=0;i<ind.length;i=i+3){ //we work on triads of vertices to calculate normals so i = i+3 (i = indices index)
-        var v1 = [];
-        var v2 = [];
-        var normal = [];	
-        //p2 - p1
-        v1[x] = vs[3*ind[i+2]+x] - vs[3*ind[i+1]+x];
-        v1[y] = vs[3*ind[i+2]+y] - vs[3*ind[i+1]+y];
-        v1[z] = vs[3*ind[i+2]+z] - vs[3*ind[i+1]+z];
-        //p0 - p1
-        v2[x] = vs[3*ind[i]+x] - vs[3*ind[i+1]+x];
-        v2[y] = vs[3*ind[i]+y] - vs[3*ind[i+1]+y];
-        v2[z] = vs[3*ind[i]+z] - vs[3*ind[i+1]+z];
-        //cross product
-        normal[x] = v1[y]*v2[z] - v1[z]*v2[y];
-        normal[y] = v1[z]*v2[x] - v1[x]*v2[z];
-        normal[z] = v1[x]*v2[y] - v1[y]*v2[x];
-        for(j=0;j<3;j++){ //update the normals of that triangle
-            ns[3*ind[i+j]+x] =  ns[3*ind[i+j]+x] + normal[x];
-            ns[3*ind[i+j]+y] =  ns[3*ind[i+j]+y] + normal[y];
-            ns[3*ind[i+j]+z] =  ns[3*ind[i+j]+z] + normal[z];
-        }
-    }
-    //normalize the result
-    for(var i=0;i<vs.length;i=i+3){ //the increment here is because each vertex occurs with an offset of 3 in the array (due to x, y, z contiguous values)
-    
-        var nn=[];
-        nn[x] = ns[i+x];
-        nn[y] = ns[i+y];
-        nn[z] = ns[i+z];
-        
-        var len = Math.sqrt((nn[x]*nn[x])+(nn[y]*nn[y])+(nn[z]*nn[z]));
-        if (len == 0) len = 1.0;
-        
-        nn[x] = nn[x]/len;
-        nn[y] = nn[y]/len;
-        nn[z] = nn[z]/len;
-        
-        ns[i+x] = nn[x];
-        ns[i+y] = nn[y];
-        ns[i+z] = nn[z];
-    }
-    
-    return ns;
-}
-    
-/**
-* Draws the scene
-*/
-function drawScene(){
-    
-    gl.clearColor(0.3, 0.3, 0.3, 1.0);
-    gl.enable(gl.DEPTH_TEST);
-    
-    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-    gl.viewport(0,0,c_width, c_height);
-    
-    mat4.perspective(45, c_width / c_height, 10, 10000.0, pMatrix);
-    mat4.identity(mvMatrix);	
-    mat4.translate(mvMatrix, [0.0, -200.0, -2000.0]); //Sets the camera to a reasonable distance to view the part
-    mat4.rotate(mvMatrix, 30 * Math.PI /180, [1,0,0]);
-    mat4.rotate(mvMatrix, angle * Math.PI / 180, [0, 1, 0]);
-    
-    gl.uniformMatrix4fv(prg.uPMatrix, false, pMatrix);
-    gl.uniformMatrix4fv(prg.uMVMatrix, false, mvMatrix);
-    
-    mat4.set(mvMatrix, nMatrix);
-    mat4.inverse(nMatrix);
-    mat4.transpose(nMatrix);
-    
-    gl.uniformMatrix4fv(prg.uNMatrix, false, nMatrix);
-    
-    
-    
-    
-    for(var i = 0; i < part.length; i++){
-        gl.bindBuffer(gl.ARRAY_BUFFER, vbo[i]);
-        gl.vertexAttribPointer(prg.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
-        gl.enableVertexAttribArray(prg.aVertexPosition);
-        
-        gl.bindBuffer(gl.ARRAY_BUFFER, nbo[i]);
-        gl.vertexAttribPointer(prg.aVertexNormal, 3, gl.FLOAT, false, 0, 0);
-        gl.enableVertexAttribArray(prg.aVertexNormal);
-    
-        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo[i]);
-        gl.drawElements(gl.TRIANGLES, part[i].indices.length, gl.UNSIGNED_SHORT,0);
-    }
-    
-}
-
-
-
-
-var lastTime = 0;
-
-/**
-* Updates the angle of rotation by a little bit each time
-*/
-function animate() {
-    var timeNow = new Date().getTime();
-    if (lastTime != 0) {
-        var elapsed = timeNow - lastTime;
-        angle += (90 * elapsed) / 10000.0;
-    }
-    lastTime = timeNow;
-}
-
-/**
-* Render Loop
-*/
-function renderLoop() {
-    utils.requestAnimFrame(renderLoop);
-    drawScene();
-    animate();
-}
-/**
-* Executes the WebGL application
-* This function is invoked on the onLoad event of the webpage. 
-*/
-function runWebGLApp(){
-    //Obtains a WebGL context
-    gl = utils.getGLContext('canvas-element-id');
-    //Initializes the program (shaders). More about this on chapter 3!
-    initProgram();
-    //Init Lights!
-    initLights();
-    //Initializes the buffers that we are going to use to draw the part (vertex buffer and index buffer)
-    loadModel();
-    //Draws the part!
-    renderLoop();
-}
-</script>
-</head>
-
-<body onLoad='runWebGLApp()'>
-<div id='top'>
-    <h1>WebGL Beginner's Guide - Chapter 3</h1>
-    <h2>Nissan GTX - Simple Shading Model</h2>
-    <div id='logo-packt'><img src='packt.gif'/></div>
-    <p>This example shows how to apply a simple lighting model to the Nissan GTX model that we saw at the end of Chapter 2. </p>
-    
-        
-</div>
-
-<div id='contents'>
-    <div id='canvasContainer'>
-        <canvas id='canvas-element-id' width='480' height='400'>
-            Your browser does not support the HTML5 canvas element.
-        </canvas>
-    </div>
-</div>
-
-<div id='bottom' class='t_table'>
-<div class='t_row'>
-    <div class='t_cell'>Shininess:</div>
-    <div id='slider-shininess'></div>
-    <div id='slider-shininess-value' class='t_cell' >200</div>
-    <div class='t_cell' style='width:20px;'></div>
-    <div class='t_cell'>Object Color:</div>
-    <div class='t_cell'><div id='colorSelector'><div style='background-color:rgb(128,204,26)'></div></div></div>
-</div>
-</div>
-<script>cview.run(cview.MODE_VIEW);</script>
-<script> 
-function updateShininess(){
-    var v = $('#slider-shininess').slider("value");
-    gl.uniform1f(prg.uShininess, v);
-    $('#slider-shininess-value').html(v);
-}
-
-function updateObjectColor(r,g,b){
-    gl.uniform3f(prg.uObjectColor, r,g,b);
-}
-
-$('#slider-shininess').slider({value:200, min:1, max:300, step:1, slide:updateShininess});
-
-
-$('#colorSelector').ColorPicker({
-    onSubmit: function(hsb, hex, rgb, el) {
-			$(el).val(hex);
-			$(el).ColorPickerHide();
-			
-	},
-	color: '#00ff00',
-    onShow: function (colpkr) {
-        $(colpkr).fadeIn(500);
-        return false;
-    },
-    onHide: function (colpkr) {
-        $(colpkr).fadeOut(500);
-        return false;
-    },
-    onChange: function (hsb, hex, rgb) {
-        $('#colorSelector div').css('backgroundColor', '#' + hex);
-        updateObjectColor(rgb.r/256,rgb.g/256,rgb.b/256);
-    },
-    
-    onBeforeShow: function (colpkr) {
-			$(this).ColorPickerSetColor('rgb(0.5,0.8,0.1)');
-		}
-	})
-	
-
-</script>
-</html>

1727_03/ch3_Nissan_Phong.html

-<html>
-
-<head>
-<title>WebGL Beginner's Guide - Chapter 3 - Nissan GTS with Shading</title>
-
-<!-- CSS Styles //-->
-<link href='css/style.css' 		type='text/css' rel='stylesheet'>
-<link href='css/desert.css' 	type='text/css' rel='stylesheet'/>
-<link href='css/colorpicker.css' 	type='text/css' rel='stylesheet'/>
-<link href='css/smoothness/jquery-ui-1.8.13.custom.css' type='text/css' rel='stylesheet' />
-
-<!-- JavaScript Libraries //-->
-<script type='text/javascript' src='js/glMatrix-0.9.5.min.js'></script>
-<script type='text/javascript' src='js/jquery-1.5.1.min.js'></script>
-<script type='text/javascript' src='js/jquery-ui-1.8.13.custom.min.js'></script> 
-<script type='text/javascript' src='js/prettify.js'></script>
-<script type='text/javascript' src='js/utils.js'></script>
-<script type='text/javascript' src='js/colorpicker.js'></script>
-<script type='text/javascript' src='js/codeview.js'></script>
-
-
-<script id="shader-vs" type="x-shader/x-vertex">
-attribute vec3 aVertexPosition;
-attribute vec3 aVertexNormal;
-
-uniform mat4 uMVMatrix; 
-uniform mat4 uPMatrix; 
-uniform mat4 uNMatrix; 
-
-uniform vec3 uLightPosition;
-
-varying vec3 vNormal;
-varying vec3 vLightRay;
-varying  vec3 vEyeVec;
-
-void main(void) {
-
-	vec4 vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
-    
-    vNormal = vec3(uNMatrix * vec4(aVertexNormal, 1.0));
-    
-    vec4 light = vec4(uLightPosition,1.0);
-	
-    vLightRay = vertex.xyz - light.xyz;
-	
-    vEyeVec = -vec3(vertex.xyz);
-    
-    gl_Position = uPMatrix * vertex;
-	
-}
-</script>
-
-<script id="shader-fs" type="x-shader/x-fragment">
-#ifdef GL_ES
-precision highp float;
-#endif
-
-uniform float uShininess;       // 
-uniform vec3 uLightAmbient;     //ambient color
-uniform vec3 uMaterialDiffuse;      //diffuse color
-uniform vec3 uMaterialSpecular;       //specular color
-
-varying vec3 vNormal;
-varying  vec3 vLightRay;
-varying  vec3 vEyeVec;
-
-void main(void)
-{
-	vec3 L = normalize(vLightRay);
-	vec3 N = normalize(vNormal);
-	
-	
-	float lambertTerm = dot(N,-L);
-	
-	vec3 finalColor = uLightAmbient;
-	
-	if(lambertTerm > 0.0)
-	{
-		finalColor += uMaterialDiffuse * lambertTerm;	
-		
-		vec3 E = normalize(vEyeVec);
-		vec3 R = reflect(L, N);
-		float specular = pow( max(dot(R, E), 0.0), uShininess);
-		finalColor += uMaterialSpecular * specular;
-	}
-	
-	gl_FragColor = vec4(finalColor, 1.0);
-
-}
-</script>
-
-<script id="code-js" type="text/javascript">
-    
-var gl = null; // WebGL context
-var prg = null; // The program (shaders)
-var c_width = 0; // Variable to store the width of the canvas
-var c_height = 0; // Variable to store the height of the canvas
-
-var clearColor = [0.1,0.1,0.1,1.0];
-var distance = -2000;
-
-var part = [];    //PARTS LOADED
-var vbo = [];
-var ibo = [];
-var nbo = [];
-
-
-var mvMatrix = mat4.create(); // The Model-View matrix
-var pMatrix = mat4.create(); // The projection matrix
-var nMatrix = mat4.create(); // The normal matrix
-
-var animateFlag = false;
-var angle = 0;
-
-    
-/*
-* The program contains a series of instructions that tell the Graphic Processing Unit (GPU)
-* what to do with every vertex and fragment that we pass it. (more about this on chapter 3)
-* The vertex shader and the fragment shader together are called the program.
-*/
-function initProgram() {
-    var fgShader = utils.getShader(gl, "shader-fs");
-    var vxShader = utils.getShader(gl, "shader-vs");
-
-    prg = gl.createProgram();
-    gl.attachShader(prg, vxShader);
-    gl.attachShader(prg, fgShader);
-    gl.linkProgram(prg);
-
-    if (!gl.getProgramParameter(prg, gl.LINK_STATUS)) {
-        alert("Could not initialise shaders");
-    }
-
-    gl.useProgram(prg);
-
-    prg.aVertexPosition     = gl.getAttribLocation(prg, "aVertexPosition");
-    prg.uPMatrix            = gl.getUniformLocation(prg, "uPMatrix");
-    prg.uMVMatrix           = gl.getUniformLocation(prg, "uMVMatrix");
-    prg.aVertexNormal       = gl.getAttribLocation(prg, "aVertexNormal");
-    
-    prg.uNMatrix            = gl.getUniformLocation(prg,"uNMatrix");
-    prg.uLightAmbient       = gl.getUniformLocation(prg,"uLightAmbient");
-    prg.uLightPosition      = gl.getUniformLocation(prg,"uLightPosition");
-    prg.uMaterialSpecular      = gl.getUniformLocation(prg,"uMaterialSpecular");
-    prg.uMaterialDiffuse    = gl.getUniformLocation(prg,"uMaterialDiffuse");
-    
-    prg.uShininess          = gl.getUniformLocation(prg,"uShininess");
-}	
-
-function initLights(){
-    gl.uniform3f(prg.uLightPosition, 31000, 14000, 24000);
-    gl.uniform3f(prg.uLightAmbient,0.1,0.1,0.1);
-	gl.uniform3f(prg.uMaterialSpecular, 0.5,0.5,0.5);	
-	gl.uniform3f(prg.uMaterialDiffuse, 0.8,0.8,0.8);
-    gl.uniform1f(prg.uShininess, 24.0);
-}	
-    
-/**
-* Creates an AJAX request to load a model asynchronously
-*/
-function loadModel(){
-  for(var i = 1; i < 179; i++){
-        var filename = 'models/nissan_gts/pr'+i+'.json';
-        loadPart(filename);
-   }
- 
- 
-}
-
-function loadPart(filename){
-    var request = new XMLHttpRequest();
-    console.info('Requesting ' + filename);
-    request.open("GET",filename);
-    
-    request.onreadystatechange = function() {
-      if (request.readyState == 4) {
-        if(request.status == 404) {
-            console.info(filename + ' does not exist');
-         }
-        else {
-            handleLoadedPart(filename,JSON.parse(request.responseText));
-        }
-      }
-    }
-    request.send();
-}
-
-/**
-* Creates the buffers that contain the geometry of the model
-*/
-function handleLoadedPart(filename,payload) {
-    
-    console.info(filename + ' has been retrieved from the server');
-    
-    var vertexBufferObject = gl.createBuffer();
-    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBufferObject);
-    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(payload.vertices), gl.STATIC_DRAW);
-    
-           
-    var normalBufferObject = gl.createBuffer();
-    gl.bindBuffer(gl.ARRAY_BUFFER, normalBufferObject);
-    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(utils.calculateNormals(payload.vertices, payload.indices)), gl.STATIC_DRAW);
-    
-    var indexBufferObject = gl.createBuffer();
-    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBufferObject);
-    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(payload.indices), gl.STATIC_DRAW);
-        
-    
-    vbo.push(vertexBufferObject);
-    ibo.push(indexBufferObject);
-    nbo.push(normalBufferObject);
-    
-    
-    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
-    gl.bindBuffer(gl.ARRAY_BUFFER,null);
-    
-    part.push(payload);
-}
-
-/**
-* Draws the scene
-*/
-function drawScene(){
-    
-    gl.clearColor(clearColor[0],clearColor[1],clearColor[2],clearColor[3]);
-    gl.enable(gl.DEPTH_TEST);
-    gl.depthFunc(gl.LEQUAL);
-    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-    gl.viewport(0,0,c_width, c_height);
-    
-    mat4.perspective(45, c_width / c_height, 100, 10000.0, pMatrix);
-    mat4.identity(mvMatrix);
-    mat4.translate(mvMatrix, [0.0, -200.0, distance]); //Sets the camera to a reasonable distance to view the part
-    mat4.rotate(mvMatrix, 17 * Math.PI /180, [1,0,0]);
-    mat4.rotate(mvMatrix, angle * Math.PI / 180, [0, 1, 0]);
-    
-    gl.uniformMatrix4fv(prg.uPMatrix, false, pMatrix);
-    gl.uniformMatrix4fv(prg.uMVMatrix, false, mvMatrix);
-    
-    mat4.set(mvMatrix, nMatrix);
-    mat4.inverse(nMatrix);
-    mat4.transpose(nMatrix);
-    
-    gl.uniformMatrix4fv(prg.uNMatrix, false, nMatrix);
-    
-    
-    
-    
-    for(var i = 0; i < part.length; i++){
-        gl.bindBuffer(gl.ARRAY_BUFFER, vbo[i]);
-        gl.vertexAttribPointer(prg.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
-        gl.enableVertexAttribArray(prg.aVertexPosition);
-        
-        gl.bindBuffer(gl.ARRAY_BUFFER, nbo[i]);
-        gl.vertexAttribPointer(prg.aVertexNormal, 3, gl.FLOAT, false, 0, 0);
-        gl.enableVertexAttribArray(prg.aVertexNormal);
-    
-        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo[i]);
-        gl.drawElements(gl.TRIANGLES, part[i].indices.length, gl.UNSIGNED_SHORT,0);
-    }
-    
-}
-
-
-
-
-var lastTime = 0;
-
-/**
-* Updates the angle of rotation by a little bit each time
-*/
-function animate() {
-    var timeNow = new Date().getTime();
-    if (lastTime != 0) {
-        var elapsed = timeNow - lastTime;
-        if (animateFlag) angle += (90 * elapsed) / 10000.0;
-    }
-    lastTime = timeNow;
-}
-
-/**
-* Render Loop
-*/
-function renderLoop() {
-    utils.requestAnimFrame(renderLoop);
-    drawScene();
-    animate();
-}
-/**
-* Executes the WebGL application
-* This function is invoked on the onLoad event of the webpage. 
-*/
-function runWebGLApp(){
-    //Obtains a WebGL context
-    gl = utils.getGLContext('canvas-element-id');
-    //Initializes the program (shaders). More about this on chapter 3!
-    initProgram();
-    //Init Lights!
-    initLights();
-    //Initializes the buffers that we are going to use to draw the part (vertex buffer and index buffer)
-    loadModel();
-    //Draws the part!
-    renderLoop();
-}
-</script>
-</head>
-
-<body onLoad='runWebGLApp()'>
-<div id='top'>
-<h1>WebGL Beginner's Guide - Chapter 3</h1>
-<h2>Nissan GTX - Phong Lighting Model</h2>
-<div id='logo-packt'><img src='packt.gif'/></div>
-<p></p>
-</div>
-
-<div id='contents'>
-<div id='canvasContainer'>
-<canvas id='canvas-element-id' width='480' height='400'>
-Your browser does not support the HTML5 canvas element.
-</canvas>
-</div>
-</div>
-
-<div id='bottom'>
-<table style='padding=0px'>
-<tr>
-<td>X:</td><td id='slider-x-value' width='30px'>31</td><td width='150px'><div id='slider-x'/></td>
-<td>Shininess:</td><td id='slider-shininess-value'>40</td><td width='150px'><div id='slider-shininess'/></td>
-<td>Car Color (material diffuse property):</td><td><div id='colorSelectorCar' class='colorSelector'><div style='background-color:rgb(204,204,204)'></div></div></td>
-</tr>
-<tr>
-<td>Y:</td><td id='slider-y-value'  width='30px'>99</td><td width='150px'><div id='slider-y'/></td>
-<td>Distance:</td><td id='slider-distance-value'>200</td><td width='150px'><div id='slider-distance'/></td>
-<td>Background Color (gl.clearColor):</td><td colspan='2'><div id='colorSelectorBg' class='colorSelector'><div style='background-color:rgb(28,28,28)'></div></div></td> 
-</tr>
-<tr>
-<td>Z:</td> <td id='slider-z-value'  width='30px'>24</td><td width='150px'><div id='slider-z'/></td>
-<td><label id='lblanimate' for='animate-btn'>Animate</label><input id='animate-btn' type='checkbox'/></td>
-</tr>
-</table>
-</div>
-<script>cview.run(cview.MODE_VIEW);</script>
-<script> 
-
-$('#slider-shininess').slider({value:24, min:1, max:200, step:1, slide:updateShininess});
-$('#slider-distance').slider({value:200, min:40, max:250, step:1, slide:updateDistance});
-$('#slider-x').slider({value:31, min:-200, max:200, step:1, slide:updateLight, change:updateLight});
-$('#slider-y').slider({value:14, min:-200, max:200, step:1, slide:updateLight, change:updateLight});
-$('#slider-z').slider({value:24, min:-200, max:200, step:1, slide:updateLight, change:updateLight});
-
-
-$('#animate-btn').button();
-$('#animate-btn').click(
-function(){
-    if ($('#animate-btn:checked').val()==null){
-        animateFlag = false;
-    }
-    else{
-        animateFlag = true;
-    }
-});
-function updateShininess(){
-    var v = $('#slider-shininess').slider("value");
-    gl.uniform1f(prg.uShininess, v);
-    $('#slider-shininess-value').html(v);
-}
-
-
-
-function updateLight(){
-    var x = $('#slider-x').slider("value");
-    var y = $('#slider-y').slider("value");
-    var z = $('#slider-z').slider("value");
-    gl.uniform3fv(prg.uLightPosition, [x*1000,y*1000,z*1000]);
-    $('#slider-x-value').html(x);
-    $('#slider-y-value').html(y);
-    $('#slider-z-value').html(z);
-}
-
-
-function updateDistance(){
-    var d = $('#slider-distance').slider("value");
-    distance = -d * 10;
-    $('#slider-distance-value').html(d);
-}
-
-function updateClearColor(r,g,b){
-    clearColor = [r,g,b,1.0];
-}
-
-function updateObjectColor(r,g,b){
-    gl.uniform3fv(prg.uMaterialDiffuse,[r,g,b]); 
-}
-
-$('#colorSelectorCar').ColorPicker({
-onSubmit: function(hsb, hex, rgb, el) {
-        $(el).val(hex);
-        $(el).ColorPickerHide();
-
-    },
-color: '#00ff00',
-onShow: function (colpkr) {
-        $(colpkr).fadeIn(500);
-        return false;
-    },
-onHide: function (colpkr) {
-        $(colpkr).fadeOut(500);
-        return false;
-    },
-onChange: function (hsb, hex, rgb) {
-        $('#colorSelectorCar div').css('backgroundColor', '#' + hex);
-        updateObjectColor(rgb.r/256,rgb.g/256,rgb.b/256);
-    },
-    
-onBeforeShow: function (colpkr) {
-        $(this).ColorPickerSetColor('rgb(0.5,0.8,0.1)');
-    }
-})
-
-$('#colorSelectorBg').ColorPicker({
-    onSubmit: function(hsb, hex, rgb, el) {
-   $(el).val(hex);
-   $(el).ColorPickerHide();
-   
- },
- color: '#00ff00',
-    onShow: function (colpkr) {
-        $(colpkr).fadeIn(500);
-        return false;
-    },
-    onHide: function (colpkr) {
-        $(colpkr).fadeOut(500);
-        return false;
-    },
-    onChange: function (hsb, hex, rgb) {
-        $('#colorSelectorBg div').css('backgroundColor', '#' + hex);
-        updateClearColor(rgb.r/256,rgb.g/256,rgb.b/256);
-    },
-    
-    onBeforeShow: function (colpkr) {
-   $(this).ColorPickerSetColor('rgb(0.5,0.8,0.1)');
-  }
- }) 
-</script>
-</body>
-</html>

1727_03/ch3_Phong_Scene.html

-<html>
-
-<head>
-<title>WebGL Beginner's Guide - Chapter 3 - Phong Lighting</title>
-<meta http-equiv='content-type' content='text/html; charset=ISO-8859-1'>
-
-<!-- CSS Styles //-->
-<link href='css/style.css'   type='text/css' rel='stylesheet'>
-<link href='css/desert.css'  type='text/css' rel='stylesheet'/>
-<link href='css/colorpicker.css'  type='text/css' rel='stylesheet'/>
-<link href='css/smoothness/jquery-ui-1.8.13.custom.css' type='text/css' rel='stylesheet' />
-
-<!-- JavaScript Libraries //-->
-<script type='text/javascript' src='js/glMatrix-0.9.5.min.js'></script>
-<script type='text/javascript' src='js/jquery-1.5.1.min.js'></script>
-<script type='text/javascript' src='js/jquery-ui-1.8.13.custom.min.js'></script> 
-<script type='text/javascript' src='js/prettify.js'></script>
-<script type='text/javascript' src='js/utils.js'></script>
-<script type='text/javascript' src='js/colorpicker.js'></script>
-<script type='text/javascript' src='js/codeview.js'></script>
-
-<script id="shader-vs" type="x-shader/x-vertex">
-attribute vec3 aVertexPosition;
-attribute vec3 aVertexNormal;
-
-uniform mat4 uMVMatrix; 
-uniform mat4 uPMatrix; 
-uniform mat4 uNMatrix; 
-
-uniform vec3 uLightPosition;
-
-varying vec3 vNormal;
-varying vec3 vLightRay;
-varying vec3 vEyeVec;
-
-void main(void) {
-
- //Transformed vertex position
- vec4 vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
- 
- //Transformed normal position
- vNormal = vec3(uNMatrix * vec4(aVertexNormal, 1.0));
-
- //Transformed light position
- vec4 light = uMVMatrix * vec4(uLightPosition,1.0);
-	
- //Light position
- vLightRay = vertex.xyz-light.xyz;
- 
- //Vector Eye
- vEyeVec = -vec3(vertex.xyz);
- 
- //Final vertex position
- gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
- 
-}
-</script>
-
-<script id="shader-fs" type="x-shader/x-fragment">
-#ifdef GL_ES
-precision highp float;
-#endif
-
-
-uniform vec4 uLightAmbient;
-uniform vec4 uLightDiffuse;
-uniform vec4 uLightSpecular;
-
-uniform vec4 uMaterialAmbient;
-uniform vec4 uMaterialDiffuse;
-uniform vec4 uMaterialSpecular;
-uniform float uShininess;       
-
-varying vec3 vNormal;
-varying vec3 vLightRay;
-varying vec3 vEyeVec;
-
-void main(void)
-{
-
-    vec3 L = normalize(vLightRay);
-    vec3 N = normalize(vNormal);
-
-    //Lambert's cosine law
-    float lambertTerm = dot(N,-L);
-    
-    //Ambient Term  
-    vec4 Ia = uLightAmbient * uMaterialAmbient;
-
-    //Diffuse Term
-    vec4 Id = vec4(0.0,0.0,0.0,1.0);
-
-    //Specular Term
-    vec4 Is = vec4(0.0,0.0,0.0,1.0);
-
-    if(lambertTerm > 0.0)
-    {
-        Id = uLightDiffuse * uMaterialDiffuse * lambertTerm; 
-        vec3 E = normalize(vEyeVec);
-        vec3 R = reflect(L, N);
-        float specular = pow( max(dot(R, E), 0.0), uShininess);
-        Is = uLightSpecular * uMaterialSpecular * specular;
-    }
-
-    //Final color
-    vec4 finalColor = Ia + Id + Is;
-    finalColor.a = 1.0;
-
-    gl_FragColor = finalColor;
-
-}
-</script>
-
-
-
-<script id='code-js' type="text/javascript">
-
-var gl = null; // WebGL context
-var prg = null; // The program (shaders)
-var c_width = 0; // Variable to store the width of the canvas
-var c_height = 0; // Variable to store the height of the canvas
-
-var mvMatrix = mat4.create(); // The Model-View matrix
-var pMatrix = mat4.create(); // The projection matrix
-var nMatrix =  mat4.create();      // The normal matrix
-
-var distance = -40;
-var animateFlag = false;
-
-var objects = [];   
-
-/**
-* The program contains a series of instructions that tell the Graphic Processing Unit (GPU)
-* what to do with every vertex and fragment that we pass it. 
-* The vertex shader and the fragment shader together are called the program.
-*/
-function initProgram() {
-var fragmentShader      = utils.getShader(gl, "shader-fs");
-var vertexShader        = utils.getShader(gl, "shader-vs");
-
-prg = gl.createProgram();
-gl.attachShader(prg, vertexShader);
-gl.attachShader(prg, fragmentShader);
-gl.linkProgram(prg);
-
-if (!gl.getProgramParameter(prg, gl.LINK_STATUS)) {
-alert("Could not initialise shaders");
-}
-
-gl.useProgram(prg);
-
-prg.aVertexPosition     = gl.getAttribLocation(prg, "aVertexPosition");
-prg.aVertexNormal       = gl.getAttribLocation(prg, "aVertexNormal");
-
-prg.uPMatrix            = gl.getUniformLocation(prg, "uPMatrix");
-prg.uMVMatrix           = gl.getUniformLocation(prg, "uMVMatrix");
-prg.uNMatrix            = gl.getUniformLocation(prg, "uNMatrix");
-
-
-prg.uMaterialAmbient    = gl.getUniformLocation(prg, "uMaterialAmbient");
-prg.uMaterialDiffuse    = gl.getUniformLocation(prg, "uMaterialDiffuse");
-prg.uMaterialSpecular   = gl.getUniformLocation(prg, "uMaterialSpecular");
-prg.uShininess          = gl.getUniformLocation(prg, "uShininess");
-
-
-prg.uLightPosition      = gl.getUniformLocation(prg, "uLightPosition");
-prg.uLightAmbient       = gl.getUniformLocation(prg, "uLightAmbient");
-prg.uLightDiffuse       = gl.getUniformLocation(prg, "uLightDiffuse");
-prg.uLightSpecular      = gl.getUniformLocation(prg, "uLightSpecular");
-}
-
-
-function initLights(){
-//Light uniforms
-gl.uniform3fv(prg.uLightPosition,[4.5,3.0,15.0]);        
-gl.uniform4f(prg.uLightAmbient ,1.0,1.0,1.0,1.0);
-gl.uniform4f(prg.uLightDiffuse,1.0,1.0,1.0,1.0);
-gl.uniform4f(prg.uLightSpecular,1.0,1.0,1.0,1.0);
-
-//Object Uniforms
-gl.uniform4f(prg.uMaterialAmbient, 0.1,0.1,0.1,1.0);
-gl.uniform4f(prg.uMaterialDiffuse, 0.5,0.8,0.1,1.0);
-gl.uniform4f(prg.uMaterialSpecular, 0.6,0.6,0.6,1.0);
-gl.uniform1f(prg.uShininess, 200.0);
-
-}
-
-
-/**
-* Creates an AJAX request to load the scene asynchronously
-*/
-function loadScene(){
-loadObject('models/geometry/plane.json');
-loadObject('models/geometry/cone.json','cone');
-loadObject('models/geometry/sphere.json','sphere');
-loadObject('models/geometry/smallsph.json','lightsource');
-}
-
-function getObject(alias){
-for(var i=0; i<objects.length; i++){
-if (alias == objects[i].alias) return objects[i];
-}
-return null;
-}
-
-/**
-* Ajax and JSON in action
-*/ 
-
-function loadObject(filename,alias){
-    var request = new XMLHttpRequest();
-    console.info('Requesting ' + filename);
-    request.open("GET",filename);
-    
-    request.onreadystatechange = function() {
-    if (request.readyState == 4) {
-        if(request.status == 404) {
-            console.info(filename + ' does not exist');
-        }
-        else {
-var o = JSON.parse(request.responseText);
-o.alias = (alias==null)?'none':alias;
-            handleLoadedObject(filename,o);
-        }
-    }
-    }
-    request.send();
-}