Diego Cantor avatar Diego Cantor committed 4e2bc4e Merge

Merge branch 'master' of bitbucket.org:dcantor/webgl-beginners-guide-code

Comments (0)

Files changed (91)

1727_10/PickerFinal.js

-function Picker(canvas){
-    this.plist = [];
-	this.canvas = canvas;
-	this.texture = null;
-	this.framebuffer = null;
-	this.renderbuffer = null;
-	this.configure();
-};
-
-Picker.prototype.configure = function(){
-
-	var width = 512*4;
-	var height = 512*2;
-	
-	//1. Init Picking Texture
-	this.texture = gl.createTexture();
-	gl.bindTexture(gl.TEXTURE_2D, this.texture);
-	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
-	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
-    gl.generateMipmap(gl.TEXTURE_2D);
-    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
-	
-	//2. Init Render Buffer
-	this.renderbuffer = gl.createRenderbuffer();
-    gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderbuffer);
-    gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
-	
-    
-    //3. Init Frame Buffer
-    this.framebuffer = gl.createFramebuffer();
-	gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
-	gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);
-    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderbuffer);
-	
-
-	//4. Clean up
-	gl.bindTexture(gl.TEXTURE_2D, null);
-    gl.bindRenderbuffer(gl.RENDERBUFFER, null);
-    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-};
-
-Picker.prototype._compare = function(readout, color){
-    //console.info('comparing object '+object.alias+' diffuse ('+Math.round(color[0]*255)+','+Math.round(color[1]*255)+','+Math.round(color[2]*255)+') == readout ('+ readout[0]+','+ readout[1]+','+ readout[2]+')');
-    return (Math.abs(Math.round(color[0]*255)-readout[0]) <= 1 &&
-			Math.abs(Math.round(color[1]*255)- readout[1]) <= 1 && 
-			Math.abs(Math.round(color[2]*255)-readout[2]) <= 1);
-}
-
-Picker.prototype.find = function(coords){
-	
-	//read one pixel
-	var readout = new Uint8Array(1 * 1 * 4);
-	gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
-	gl.readPixels(coords.x,coords.y,1,1,gl.RGBA,gl.UNSIGNED_BYTE,readout);
-	gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-
-    var found = false;
-
-    for(var i = 0, max = Scene.objects.length; i < max; i+=1){
-        var ob = Scene.objects[i];
-        if (ob.alias == 'floor') continue;
-        
-        var color = ob.diffuse;
-        if (ob.pcolor) {color = ob.pcolor;}
-    
-        if (this._compare(readout, color)){
-            if (ob.picked){
-                //deselect
-                ob.picked = false;
-                ob.diffuse = ob.previous.slice(0);
-                this.plist.splice(this.plist.indexOf(ob),1);
-            }
-            else {
-                ob.picked = true;
-                ob.previous = ob.diffuse.slice(0);
-                if (ob.pcolor){
-                    ob.diffuse = ob.pcolor.slice(0);
-                }
-                else {
-                    ob.diffuse[3] = 0.5;
-                }
-                this.plist.push(ob);
-            }
-            found = true;
-            break;
-        }
-        
-    }
-    draw();
-    return found;
-};
-
-var notifica_balls = false;
-Picker.prototype.stop = function(){
-    for(var i = 0, max = this.plist.length; i < max; i+=1){
-        var ob = this.plist[i];
-        ob.diffuse = ob.previous;
-        Scene.removeObject(ob.alias);
-        
-        ob.picked = false;
-    }
-    this.plist = [];
-}
-
-Picker.prototype.getHits = function(){
-    return this.plist;
-}
-
-Picker.prototype.move = function(dx,dy,camera,depth){
-    
-    if (this.plist.length == 0) return;
-    
-    for (var i = 0, max = this.plist.length; i < max; i+=1){
-        var ob = this.plist[i];
-        var pos = vec3.create([ob.position[0], ob.position[1], ob.position[2]]);
-        
-        var scaleY = vec3.create();
-        var scaleX = vec3.create();
-        
-        var factor = Math.max(Math.max(camera.position[0], camera.position[1]), camera.position[2])/1000;
-       
-        if (!depth){
-            vec3.scale(camera.up,   -dy * factor, scaleY);
-            vec3.scale(camera.right, dx * factor, scaleX);
-        }
-        else{
-            vec3.scale(camera.normal, dy * factor, scaleY);
-        }
-
-        vec3.add(pos, scaleY);
-        vec3.add(pos, scaleX);
-        
-        ob.position[0] = pos[0];
-        ob.position[1] = pos[1];
-        ob.position[2] = pos[2];
-    }
-    render();
-}

1727_10/PickerFinal2.js

-function Picker(canvas){
-    this.plist = [];
-	this.canvas = canvas;
-	this.texture = null;
-	this.framebuffer = null;
-	this.renderbuffer = null;
-	this.configure();
-};
-
-Picker.prototype.configure = function(){
-
-	var width = 512*4;
-	var height = 512*2;
-	
-	//1. Init Picking Texture
-	this.texture = gl.createTexture();
-	gl.bindTexture(gl.TEXTURE_2D, this.texture);
-	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
-	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
-    gl.generateMipmap(gl.TEXTURE_2D);
-    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
-	
-	//2. Init Render Buffer
-	this.renderbuffer = gl.createRenderbuffer();
-    gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderbuffer);
-    gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
-	
-    
-    //3. Init Frame Buffer
-    this.framebuffer = gl.createFramebuffer();
-	gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
-	gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);
-    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderbuffer);
-	
-
-	//4. Clean up
-	gl.bindTexture(gl.TEXTURE_2D, null);
-    gl.bindRenderbuffer(gl.RENDERBUFFER, null);
-    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-};
-
-Picker.prototype._compare = function(readout, color){
-    //console.info('comparing object '+object.alias+' diffuse ('+Math.round(color[0]*255)+','+Math.round(color[1]*255)+','+Math.round(color[2]*255)+') == readout ('+ readout[0]+','+ readout[1]+','+ readout[2]+')');
-    return (Math.abs(Math.round(color[0]*255)-readout[0]) <= 1 &&
-			Math.abs(Math.round(color[1]*255)- readout[1]) <= 1 && 
-			Math.abs(Math.round(color[2]*255)-readout[2]) <= 1);
-}
-
-Picker.prototype.find = function(coords){
-	
-	//read one pixel
-	var readout = new Uint8Array(1 * 1 * 4);
-	gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
-	gl.readPixels(coords.x,coords.y,1,1,gl.RGBA,gl.UNSIGNED_BYTE,readout);
-	gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-
-    var found = false;
-
-    for(var i = 0, max = Scene.objects.length; i < max; i+=1){
-        var ob = Scene.objects[i];
-        if (ob.alias == 'floor') continue;
-        
-        var color = ob.diffuse;
-        if (ob.pcolor) {color = ob.pcolor;}
-    
-        if (this._compare(readout, color)){
-            if (ob.picked){
-                //deselect
-                ob.picked = false;
-                ob.diffuse = ob.previous.slice(0);
-                this.plist.splice(this.plist.indexOf(ob),1);
-            }
-            else {
-                ob.picked = true;
-                ob.previous = ob.diffuse.slice(0);
-                if (ob.pcolor){
-                    ob.diffuse = ob.pcolor.slice(0);
-                }
-                else {
-                    ob.diffuse[3] = 0.5;
-                }
-                this.plist.push(ob);
-            }
-            found = true;
-            break;
-        }
-        
-    }
-    draw();
-    return found;
-};
-
-var notifica_balls = false;
-Picker.prototype.stop = function(){
-    for(var i = 0, max = this.plist.length; i < max; i+=1){
-        var ob = this.plist[i];
-        ob.diffuse = ob.previous;
-        Scene.removeObject(ob.alias);
-        
-        ob.picked = false;
-    }
-    this.plist = [];
-    if(!notifica_balls){
-        var balls = 0;
-        for(var i = 0, max = Scene.objects.length; i < max; i +=1){
-            var ob = Scene.objects[i];
-            if (ob.alias.indexOf('ball_') == 0) {balls++};
-            
-        }
-        if (balls == 0) {alert('You have removed all the balls from the scene'); notifica_balls = true;}
-    }
-}
-
-Picker.prototype.getHits = function(){
-    return this.plist;
-}
-
-Picker.prototype.move = function(dx,dy,camera,depth){
-    
-    if (this.plist.length == 0) return;
-    
-    for (var i = 0, max = this.plist.length; i < max; i+=1){
-        var ob = this.plist[i];
-        var pos = vec3.create([ob.position[0], ob.position[1], ob.position[2]]);
-        
-        var scaleY = vec3.create();
-        var scaleX = vec3.create();
-        
-        var factor = Math.max(Math.max(camera.position[0], camera.position[1]), camera.position[2])/1000;
-       
-        if (!depth){
-            vec3.scale(camera.up,   -dy * factor, scaleY);
-            vec3.scale(camera.right, dx * factor, scaleX);
-        }
-        else{
-            vec3.scale(camera.normal, dy * factor, scaleY);
-        }
-
-        vec3.add(pos, scaleY);
-        vec3.add(pos, scaleX);
-        
-        ob.position[0] = pos[0];
-        ob.position[1] = pos[1];
-        ob.position[2] = pos[2];
-    }
-    render();
-}

1727_10/ch10_NormalMap.html

+<html>
+
+<head>
+<title>WebGL Beginner's Guide - Chapter 10 - Normal Mapping</title>
+<meta http-equiv='content-type' content='text/html; charset=ISO-8859-1'>
+
+<!-- CSS Styles //-->
+<link href='css/styles.css'   type='text/css' rel='stylesheet'>
+<link href='css/prettify_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' />
+<!-- GUI Libraries //-->
+<script type='text/javascript' src='js/gui/jquery-1.5.1.min.js'></script>
+<script type='text/javascript' src='js/gui/jquery-ui-1.8.13.custom.min.js'></script> 
+<script type='text/javascript' src='js/gui/colorpicker.js'></script>
+<script type='text/javascript' src='js/gui/prettify.js'></script>
+<script type='text/javascript' src='js/gui/codeview.js'></script>
+<!-- MATH Libraries //-->
+<script type='text/javascript' src='js/math/glMatrix-0.9.5.min.js'></script>
+<!-- WEBGL Libraries //-->
+<script type='text/javascript' src='js/webgl/Globals.js'></script>
+<script type='text/javascript' src='js/webgl/Utils.js'></script>
+<script type='text/javascript' src='js/webgl/Program.js'></script>
+<script type='text/javascript' src='js/webgl/Scene.js'></script>
+<script type='text/javascript' src='js/webgl/Axis.js'></script>
+<script type='text/javascript' src='js/webgl/Floor.js'></script>
+<script type='text/javascript' src='js/webgl/Camera.js'></script>
+<script type='text/javascript' src='js/webgl/CameraInteractor.js'></script>
+<script type='text/javascript' src='js/webgl/SceneTransforms.js'></script>
+<script type='text/javascript' src='js/webgl/Texture.js'></script>
+<script type='text/javascript' src='js/webgl/WebGLApp.js'></script>
+
+<script id="shader-vs" type="x-shader/x-vertex">
+//geometry
+attribute vec3 aVertexPosition;
+attribute vec3 aVertexNormal;
+attribute vec3 aVertexTangent;
+attribute vec4 aVertexColor;
+attribute vec2 aVertexTextureCoords;
+
+//matrices
+uniform mat4 uMVMatrix;
+uniform mat4 uPMatrix;
+uniform mat4 uNMatrix;
+
+//lights
+uniform vec3 uLightPosition;
+
+//varyings
+varying vec2 vTextureCoord;
+varying vec3 vTangentLightDir;
+varying vec3 vTangentEyeDir;
+
+void main(void) {
+    //Transformed vertex position
+    vec4 vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
+
+    //Transformed normal position
+    vec3 normal = vec3(uNMatrix * vec4(aVertexNormal, 1.0));
+    vec3 tangent = vec3(uNMatrix * vec4(aVertexTangent, 1.0));
+    vec3 bitangent = cross(normal, tangent);
+
+    mat3 tbnMatrix = mat3(
+        tangent.x, bitangent.x, normal.x,
+        tangent.y, bitangent.y, normal.y,
+        tangent.z, bitangent.z, normal.z
+    );
+
+    //light direction, from light position to vertex
+    vec3 lightDirection = uLightPosition - vertex.xyz;
+
+    //eye direction, from camera position to vertex
+    vec3 eyeDirection = -vertex.xyz;
+ 
+    //Final vertex position
+    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
+    vTextureCoord = aVertexTextureCoords;
+    vTangentLightDir = lightDirection * tbnMatrix;
+    vTangentEyeDir = eyeDirection * tbnMatrix;
+}
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision highp float;
+#endif
+
+//geometry
+uniform vec4 uMaterialDiffuse;
+uniform vec4 uMaterialAmbient;
+
+uniform vec4 uLightAmbient;
+uniform vec4 uLightDiffuse;
+
+//samplers
+uniform sampler2D uSampler;
+uniform sampler2D uNormalSampler;
+
+//varying
+varying vec4 vColor;
+varying vec2 vTextureCoord;
+varying vec3 vTangentLightDir;
+varying vec3 vTangentEyeDir;
+
+void main(void)
+{   
+    // Unpack tangent-space normal from texture
+    vec3 normal = normalize(2.0 * (texture2D(uNormalSampler, vTextureCoord).rgb - 0.5));
+
+    // Normalize the light direction and determine how much light is hitting this point
+    vec3 lightDirection = normalize(vTangentLightDir);
+    float lambertTerm = max(dot(normal,lightDirection),0.20);
+
+    // Calculate Specular level
+    vec3 eyeDirection = normalize(vTangentEyeDir);
+    vec3 reflectDir = reflect(-lightDirection, normal);
+    float Is = pow(clamp(dot(reflectDir, eyeDirection), 0.0, 1.0), 8.0);
+
+    // Combine lighting and material colors
+    vec4 Ia = uLightAmbient * uMaterialAmbient;
+    vec4 Id = uLightDiffuse * uMaterialDiffuse * texture2D(uSampler, vTextureCoord) * lambertTerm;
+    
+    gl_FragColor = Ia + Id + Is;
+}
+</script>
+
+<script id='code-js' type="text/javascript">
+
+var camera = null;
+var interactor = null;
+var transforms = null;
+var useVertexColors = false;
+var texture = null;
+var texture2 = null;
+
+function configure(){
+    gl.clearColor(0.3,0.3,0.3, 1.0);
+    gl.clearDepth(100.0);
+    gl.enable(gl.DEPTH_TEST);
+    gl.depthFunc(gl.LESS);
+    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+    
+
+    //Creates and sets up the camera location
+    camera = new Camera(CAMERA_ORBITING_TYPE);
+    camera.goHome([0,0,4]);
+    camera.setFocus([0.0,0.0,0.0]);
+    camera.setAzimuth(45);
+    camera.setElevation(-30);
+    camera.hookRenderer = draw;
+    
+    //Creates and sets up the mouse and keyboard interactor
+    interactor = new CameraInteractor(camera, document.getElementById('canvas-element-id'));
+    
+    //Scene Transforms
+    transforms = new SceneTransforms(camera);
+   
+    //init transforms
+    transforms.init();
+    
+    //Program
+    attributeList = ["aVertexPosition",
+                    "aVertexNormal",
+                    "aVertexTangent",
+                    "aVertexColor",
+                    "aVertexTextureCoords"];
+
+    uniformList = [ "uPMatrix", 
+                    "uMVMatrix", 
+                    "uNMatrix",
+                    "uMaterialDiffuse",
+                    "uMaterialAmbient",
+                    "uLightAmbient",
+                    "uLightDiffuse",
+                    "uLightPosition",
+                    "uWireframe",
+                    "uAlpha",
+                    "uUseVertexColor",
+                    "uUseLambert",
+                    "uSampler",
+                    "uNormalSampler"
+                    ];
+    
+    
+    Program.load(attributeList, uniformList);
+    
+    gl.uniform3fv(Program.uLightPosition,   [0,5,20]);
+    gl.uniform4fv(Program.uLightAmbient,    [1.0,1.0,1.0,1.0]);
+    gl.uniform4fv(Program.uLightDiffuse,    [1.0,1.0,1.0,1.0]);
+    gl.uniform1f(Program.uAlpha, 1.0);
+    gl.uniform1i(Program.uUseVertexColor, useVertexColors);
+    gl.uniform1i(Program.uUseLambert, true);
+    
+    //Init textures
+    texture = new Texture('textures/fieldstone.jpg');
+    texture2 = new Texture('textures/fieldstone-normal.jpg');
+}
+
+/**
+* Loads the scene
+*/
+function load(){
+    Scene.loadObject('models/geometry/complexCube.json','cube2');
+}
+
+/**
+* invoked on every rendering cycle
+*/
+function draw() {
+    gl.viewport(0, 0, c_width, c_height);
+    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+    transforms.updatePerspective();
+
+    try{
+        for (var i = 0; i < Scene.objects.length; i++){
+            
+            var object = Scene.objects[i];
+            
+            if (object.hidden == true) continue;
+            
+            transforms.calculateModelView();
+            transforms.push();
+            transforms.setMatrixUniforms();
+            transforms.pop();
+   
+            //Setting uniforms
+            gl.uniform4fv(Program.uMaterialDiffuse, object.diffuse);
+            gl.uniform4fv(Program.uMaterialAmbient, object.ambient);
+
+            //Setting attributes
+            gl.enableVertexAttribArray(Program.aVertexPosition);
+            gl.disableVertexAttribArray(Program.aVertexNormal);
+            gl.disableVertexAttribArray(Program.aVertexTangent);
+            
+            gl.bindBuffer(gl.ARRAY_BUFFER, object.vbo);
+            gl.vertexAttribPointer(Program.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
+            gl.enableVertexAttribArray(Program.aVertexPosition);
+            
+            if (object.texture_coords){
+                gl.enableVertexAttribArray(Program.aVertexTextureCoords);
+                gl.bindBuffer(gl.ARRAY_BUFFER, object.tbo);
+                gl.vertexAttribPointer(Program.aVertexTextureCoords, 2, gl.FLOAT, false, 0, 0);
+                gl.activeTexture(gl.TEXTURE0);
+                gl.bindTexture(gl.TEXTURE_2D, texture.tex);
+                gl.uniform1i(Program.uSampler, 0);
+                
+                gl.activeTexture(gl.TEXTURE1);
+                gl.bindTexture(gl.TEXTURE_2D, texture2.tex);
+                gl.uniform1i(Program.uNormalSampler, 1);
+            }
+            
+            if(!object.wireframe){
+                gl.bindBuffer(gl.ARRAY_BUFFER, object.nbo);
+                gl.vertexAttribPointer(Program.aVertexNormal, 3, gl.FLOAT, false, 0, 0);
+                gl.enableVertexAttribArray(Program.aVertexNormal);
+
+                gl.bindBuffer(gl.ARRAY_BUFFER, object.tanbo);
+                gl.vertexAttribPointer(Program.aVertexTangent, 3, gl.FLOAT, false, 0, 0);
+                gl.enableVertexAttribArray(Program.aVertexTangent);
+            }
+            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, object.ibo);
+            
+            if (object.wireframe){
+                gl.drawElements(gl.LINES, object.indices.length, gl.UNSIGNED_SHORT,0);
+            }
+            else{
+                gl.drawElements(gl.TRIANGLES, object.indices.length, gl.UNSIGNED_SHORT,0);
+            }
+            
+            gl.bindBuffer(gl.ARRAY_BUFFER, null);
+            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+            
+        }
+    }
+    catch(err){
+        alert(err);
+        console.error(err.description);
+    }
+}
+
+
+/**
+* Entry point. This function is invoked when the page is loaded
+*/
+var app = null;
+function runWebGLApp() {
+    app = new WebGLApp("canvas-element-id")
+    app.configureGLHook = configure;
+    app.loadSceneHook   = load;
+    app.drawSceneHook   = draw;
+    app.run();
+}
+</script>
+</head>
+
+<body onLoad='runWebGLApp()'>
+<div id='top'>
+<h1>WebGL Beginner's Guide - Chapter 10</h1>
+<h2>Normal Mapping</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'>
+
+</div>
+
+<script>cview.run(cview.MODE_VIEW,false,470);</script>
+</body>
+</html>

1727_10/ch10_PointSprites.html

+<html>
+
+<head>
+<title>WebGL Beginner's Guide - Chapter 10 - Point Sprites</title>
+<meta http-equiv='content-type' content='text/html; charset=ISO-8859-1'>
+
+<!-- CSS Styles //-->
+<link href='css/styles.css'   type='text/css' rel='stylesheet'>
+<link href='css/prettify_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' />
+<!-- GUI Libraries //-->
+<script type='text/javascript' src='js/gui/jquery-1.5.1.min.js'></script>
+<script type='text/javascript' src='js/gui/jquery-ui-1.8.13.custom.min.js'></script> 
+<script type='text/javascript' src='js/gui/colorpicker.js'></script>
+<script type='text/javascript' src='js/gui/prettify.js'></script>
+<script type='text/javascript' src='js/gui/codeview.js'></script>
+<!-- MATH Libraries //-->
+<script type='text/javascript' src='js/math/glMatrix-0.9.5.min.js'></script>
+<!-- WEBGL Libraries //-->
+<script type='text/javascript' src='js/webgl/Globals.js'></script>
+<script type='text/javascript' src='js/webgl/Utils.js'></script>
+<script type='text/javascript' src='js/webgl/Program.js'></script>
+<script type='text/javascript' src='js/webgl/Scene.js'></script>
+<script type='text/javascript' src='js/webgl/Axis.js'></script>
+<script type='text/javascript' src='js/webgl/Floor.js'></script>
+<script type='text/javascript' src='js/webgl/Camera.js'></script>
+<script type='text/javascript' src='js/webgl/CameraInteractor.js'></script>
+<script type='text/javascript' src='js/webgl/SceneTransforms.js'></script>
+<script type='text/javascript' src='js/webgl/Texture.js'></script>
+<script type='text/javascript' src='js/webgl/WebGLApp.js'></script>
+
+<script id="shader-vs" type="x-shader/x-vertex">
+attribute vec4 aParticle;
+
+uniform mat4 uMVMatrix;
+uniform mat4 uPMatrix;
+uniform float uPointSize;
+
+varying float vLifespan;
+
+void main(void) {
+    gl_Position = uPMatrix * uMVMatrix * vec4(aParticle.xyz, 1.0);
+    vLifespan = aParticle.w;
+    gl_PointSize = uPointSize * vLifespan;
+}
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision highp float;
+#endif
+
+uniform sampler2D uSampler;
+
+varying float vLifespan;
+
+void main(void) {
+    vec4 texColor = texture2D(uSampler, gl_PointCoord);
+    //if (texColor.a == 0.) discard;
+    gl_FragColor = vec4(texColor.rgb, texColor.a * vLifespan);
+}
+</script>
+
+<script id='code-js' type="text/javascript">
+
+var camera      = null;
+var interactor  = null;
+var transforms  = null;
+var spriteTexture = null;
+var particles = [];
+var particleArray = null;
+var particleBuffer = null;
+
+var particleSize = 14.0;
+var particleLifespan = 3.0;
+
+var lastFrameTime = 0.0;
+
+function configure(){
+    gl.clearColor(0.3,0.3,0.3, 1.0);
+    gl.clearDepth(100.0);
+    gl.disable(gl.DEPTH_TEST);
+    gl.depthFunc(gl.LESS);
+    gl.blendFunc(gl.SRC_ALPHA,gl.ONE);
+    
+    //Creates and sets up the camera location
+    camera = new Camera(CAMERA_ORBITING_TYPE);
+    camera.goHome([0,0,40]);
+    camera.setFocus([0.0,0.0,0.0]);
+    camera.setElevation(-40);
+    camera.setAzimuth(-30);
+    camera.hookRenderer = render;
+    
+    var canvas  = document.getElementById('canvas-element-id');
+
+    // Texture to use for the point sprite
+    spriteTexture = new Texture();
+    spriteTexture.setImage("textures/spark.png");
+    
+    //Creates and sets up the mouse and keyboard interactor
+    interactor = new CameraInteractor(camera, canvas);
+        
+    //Scene Transforms
+    transforms = new SceneTransforms(camera);
+   
+    //init transforms
+    transforms.init();
+    
+    //Program
+    attributeList = ["aParticle"];
+
+    uniformList = [ "uPMatrix", 
+                    "uMVMatrix", 
+                    "uPointSize",
+                    "uSampler",
+                    ];
+    
+    Program.load(attributeList, uniformList);
+
+    configureParticles(1024);
+}
+
+function resetParticle(p) {
+    p.pos = [0.0, 0.0, 0.0];
+
+    p.vel = [
+        (Math.random() * 20.0) - 10.0,
+        (Math.random() * 20.0),
+        (Math.random() * 20.0) - 10.0,
+    ];
+
+    p.lifespan = (Math.random() * particleLifespan);
+    p.remainingLife = p.lifespan;
+}
+
+function configureParticles(count) {
+    var i, p;
+
+    particleArray = new Float32Array(count * 4);
+
+    for(i = 0; i < count; ++i) {
+        p = {};
+        resetParticle(p);
+        particles.push(p);
+
+        particleArray[(i*4) + 0] = p.pos[0];
+        particleArray[(i*4) + 1] = p.pos[1];
+        particleArray[(i*4) + 2] = p.pos[2];
+        particleArray[(i*4) + 3] = p.remainingLife / p.lifespan;
+    }
+
+    particleBuffer = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, particleBuffer);
+    gl.bufferData(gl.ARRAY_BUFFER, particleArray, gl.STATIC_DRAW);
+    gl.bindBuffer(gl.ARRAY_BUFFER, null);
+}
+
+function updateParticles(elapsed) {
+    var i, p, count = particles.length;
+
+    // Loop through all the particles in the array
+    for(i = 0; i < count; ++i) {
+        p = particles[i];
+
+        // Track the particles lifespan
+        p.remainingLife -= elapsed;
+        if(p.remainingLife <= 0) {
+            resetParticle(p); // Once the particle expires, reset it to the origin with a new velocity
+        }
+
+        // Update the particle position
+        p.pos[0] += p.vel[0] * elapsed;
+        p.pos[1] += p.vel[1] * elapsed;
+        p.pos[2] += p.vel[2] * elapsed;
+        
+        // Apply gravity to the velocity
+        p.vel[1] -= 9.8 * elapsed;
+        if(p.pos[1] < 0) {
+            p.vel[1] *= -0.75; // Allow particles to bounce off the floor
+            p.pos[1] = 0;
+        }
+
+        // Update the corresponding values in the array
+        particleArray[(i*4) + 0] = p.pos[0];
+        particleArray[(i*4) + 1] = p.pos[1];
+        particleArray[(i*4) + 2] = p.pos[2];
+        particleArray[(i*4) + 3] = p.remainingLife / p.lifespan;
+    }
+
+    // Once we are done looping through all the particles, update the buffer once
+    gl.bindBuffer(gl.ARRAY_BUFFER, particleBuffer);
+    gl.bufferData(gl.ARRAY_BUFFER, particleArray, gl.STATIC_DRAW);
+    gl.bindBuffer(gl.ARRAY_BUFFER, null);
+}
+
+/**
+* Loads the scene
+*/
+function load(){
+    Floor.build(80,2);
+    Scene.addObject(Floor);
+
+    lastFrameTime = Date.now();
+}
+
+function render(){
+    var time = Date.now();
+
+    // Update the particle positions
+    updateParticles((time - lastFrameTime) / 1000.0);
+
+    lastFrameTime = time;
+
+    // Render scene
+    draw();
+}
+
+/**
+* invoked on every rendering cycle
+*/
+function draw() {
+    gl.viewport(0, 0, c_width, c_height);
+    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+    transforms.updatePerspective();
+    try{
+        gl.enable(gl.BLEND);
+        gl.useProgram(prg);
+
+        transforms.calculateModelView();
+        transforms.setMatrixUniforms();
+
+        gl.uniform1f(Program.uPointSize, particleSize);
+
+        gl.bindBuffer(gl.ARRAY_BUFFER, particleBuffer);
+        gl.vertexAttribPointer(Program.aParticle, 4, gl.FLOAT, false, 0, 0);
+        gl.enableVertexAttribArray(Program.aParticle);
+
+        gl.activeTexture(gl.TEXTURE0);
+        gl.bindTexture(gl.TEXTURE_2D, spriteTexture.tex);
+        gl.uniform1i(Program.uSampler, 0);
+
+        gl.drawArrays(gl.POINTS, 0, particles.length);
+        gl.bindBuffer(gl.ARRAY_BUFFER, null);
+    }
+    catch(err){
+        alert(err);
+        console.error(err.description);
+    }
+}
+
+
+/**
+* Entry point. This function is invoked when the page is loaded
+*/
+var app = null;
+function runWebGLApp() {
+    app = new WebGLApp("canvas-element-id");
+    app.configureGLHook = configure;
+    app.loadSceneHook   = load;
+    app.drawSceneHook   = render;
+    app.run();
+}
+</script>
+</head>
+
+<body onLoad='runWebGLApp()'>
+<div id='top'>
+<h1>WebGL Beginner's Guide - Chapter 10</h1>
+<h2 id='title-id'>Point Sprites</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 style='vertical-align:center;'>
+        <table>
+        <tr>
+            <td>Size:</td><td id='slider-particle-size-label'>14</td><td width='150px'><div id='slider-particle-size'/></td>
+        </tr>
+        <tr>
+            <td>Lifespan:</td><td id='slider-particle-lifespan-label'>3.0</td><td width='150px'><div id='slider-particle-lifespan'/></td>
+        </tr>
+        </table>
+    </td>
+</tr>
+</div>
+<script> 
+$('#slider-particle-size').slider({value:14.0, min: 4.0, max:32.0, step:1.0, slide:function(){
+    particleSize = $('#slider-particle-size').slider("value");
+    $('#slider-particle-size-label').html(particleSize);
+}});
+
+$('#slider-particle-lifespan').slider({value:3.0, min:0.1, max:10.0, step:0.1, slide:function(){
+    particleLifespan = $('#slider-particle-lifespan').slider("value");
+    $('#slider-particle-lifespan-label').html(particleLifespan);
+}});
+</script>
+<script>cview.run(cview.MODE_VIEW,false,470);</script>
+</body>
+</html>

1727_10/ch10_PostProcessing.html

+<html>
+
+<head>
+<title>WebGL Beginner's Guide - Chapter 10 - Post Process Effects</title>
+<meta http-equiv='content-type' content='text/html; charset=ISO-8859-1'>
+
+<!-- CSS Styles //-->
+<link href='css/styles.css'   type='text/css' rel='stylesheet'>
+<link href='css/prettify_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' />
+<!-- GUI Libraries //-->
+<script type='text/javascript' src='js/gui/jquery-1.5.1.min.js'></script>
+<script type='text/javascript' src='js/gui/jquery-ui-1.8.13.custom.min.js'></script> 
+<script type='text/javascript' src='js/gui/colorpicker.js'></script>
+<script type='text/javascript' src='js/gui/prettify.js'></script>
+<script type='text/javascript' src='js/gui/codeview.js'></script>
+<!-- MATH Libraries //-->
+<script type='text/javascript' src='js/math/glMatrix-0.9.5.min.js'></script>
+<!-- WEBGL Libraries //-->
+<script type='text/javascript' src='js/webgl/Globals.js'></script>
+<script type='text/javascript' src='js/webgl/Utils.js'></script>
+<script type='text/javascript' src='js/webgl/Program.js'></script>
+<script type='text/javascript' src='js/webgl/Scene.js'></script>
+<script type='text/javascript' src='js/webgl/Axis.js'></script>
+<script type='text/javascript' src='js/webgl/Floor.js'></script>
+<script type='text/javascript' src='js/webgl/Camera.js'></script>
+<script type='text/javascript' src='js/webgl/CameraInteractor.js'></script>
+<script type='text/javascript' src='js/webgl/SceneTransforms.js'></script>
+<script type='text/javascript' src='js/webgl/Texture.js'></script>
+<script type='text/javascript' src='js/webgl/WebGLApp.js'></script>
+<script type='text/javascript' src='js/webgl/PostProcess.js'></script>
+
+<script id="shader-vs" type="x-shader/x-vertex">
+
+attribute vec3 aVertexPosition;
+attribute vec3 aVertexNormal;
+attribute vec4 aVertexColor;
+attribute vec2 aVertexTextureCoords;
+
+uniform mat4 uMVMatrix;
+uniform mat4 uPMatrix;
+uniform mat4 uNMatrix;
+uniform vec3 uLightPosition;
+uniform vec4 uMaterialDiffuse;
+uniform bool uWireframe;
+uniform bool uUseVertexColor;
+uniform bool uUseTextures;
+
+varying vec3 vNormal;
+varying vec3 vLightRay;
+varying vec3 vEyeVec;
+varying vec4 vFinalColor;
+varying vec2 vTextureCoord;
+
+void main(void) {
+    
+ vFinalColor = uMaterialDiffuse;
+ vTextureCoord = vec2(0.0);
+
+ if (uUseVertexColor){
+    vFinalColor = aVertexColor;
+ }
+ 
+ if (uUseTextures){
+    vTextureCoord = aVertexTextureCoords;
+ }
+
+ 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 * uMVMatrix * vec4(aVertexPosition, 1.0);
+ 
+}	
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision highp float;
+#endif
+
+uniform bool uWireframe;
+uniform bool uUseTextures; 
+
+uniform vec4 uLightAmbient;
+uniform vec4 uLightDiffuse;
+uniform vec4 uMaterialAmbient;
+uniform vec4 uMaterialDiffuse;
+uniform bool uOffscreen;  
+
+uniform sampler2D uSampler;  
+
+varying vec3 vNormal; 
+varying vec3 vLightRay;
+varying vec3 vEyeVec;
+varying vec4 vFinalColor;
+varying vec2 vTextureCoord;
+
+void main(void)
+{
+    if(uOffscreen){
+        gl_FragColor = uMaterialDiffuse;
+        return;
+    }
+    
+    if(uWireframe){
+        gl_FragColor = vFinalColor;
+    }
+    else{
+        //ambient term
+        vec4 Ia = uLightAmbient * uMaterialAmbient;
+        
+        //diffuse term
+        vec3 L = normalize(vLightRay);
+        vec3 N = normalize(vNormal);
+        float lambertTerm = max(dot(N,-L),0.33);
+        vec4 Id = uLightDiffuse * uMaterialDiffuse * lambertTerm; 
+        
+        //specular term
+        vec3 E = normalize(vEyeVec);
+        vec3 R = reflect(L, N);
+        float specular = pow( max(dot(R, E), 0.5), 50.0);
+        vec4 Is = vec4(0.5) * specular;
+
+        //result
+        vec4 finalColor = Ia + Id + Is;
+        
+        if (uMaterialDiffuse.a != 1.0) {   
+            finalColor.a = uMaterialDiffuse.a; 
+        }
+        else {
+            finalColor.a = 1.0;
+        }
+       
+        if (uUseTextures){
+            gl_FragColor =  finalColor * texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
+        }
+        else{
+            gl_FragColor = finalColor;
+        }
+    }
+
+}
+</script>
+
+<script id="post-common-vs" type="x-shader/x-vertex">
+attribute vec3 aVertexPosition;
+attribute vec2 aVertexTextureCoords;
+
+varying vec2 vTextureCoord;
+
+void main(void) {
+    vTextureCoord = aVertexTextureCoords;
+    gl_Position = vec4(aVertexPosition, 1.0);
+}
+</script>
+
+<script id="post-greyscale" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision highp float;
+#endif
+
+uniform sampler2D uSampler;
+
+varying vec2 vTextureCoord;
+
+void main(void)
+{
+    vec4 frameColor = texture2D(uSampler, vTextureCoord);
+    float brightness = (frameColor.r + frameColor.g + frameColor.b)/3.0;
+    gl_FragColor = vec4(brightness, brightness, brightness, frameColor.a);
+}
+</script>
+
+<script id="post-invert" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision highp float;
+#endif
+
+uniform sampler2D uSampler;
+
+varying vec2 vTextureCoord;
+
+void main(void)
+{
+    vec4 frameColor = texture2D(uSampler, vTextureCoord);
+    gl_FragColor = vec4(1.0-frameColor.r, 1.0-frameColor.g, 1.0-frameColor.b, frameColor.a);
+}
+</script>
+
+<script id="post-blur" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision highp float;
+#endif
+
+uniform sampler2D uSampler;
+uniform vec2 uInverseTextureSize;
+
+varying vec2 vTextureCoord;
+
+vec4 offsetLookup(float xOff, float yOff) {
+    return texture2D(uSampler, vec2(vTextureCoord.x + xOff*uInverseTextureSize.x, vTextureCoord.y + yOff*uInverseTextureSize.y));
+}
+
+void main(void)
+{
+    vec4 frameColor;
+
+    frameColor += offsetLookup(-4.0, 0.0) * 0.05;
+    frameColor += offsetLookup(-3.0, 0.0) * 0.09;
+    frameColor += offsetLookup(-2.0, 0.0) * 0.12;
+    frameColor += offsetLookup(-1.0, 0.0) * 0.15;
+    frameColor += offsetLookup(0.0, 0.0) * 0.16;
+    frameColor += offsetLookup(1.0, 0.0) * 0.15;
+    frameColor += offsetLookup(2.0, 0.0) * 0.12;
+    frameColor += offsetLookup(3.0, 0.0) * 0.09;
+    frameColor += offsetLookup(4.0, 0.0) * 0.05;
+
+    gl_FragColor = frameColor;
+}
+</script>
+
+<script id="post-wavy" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision highp float;
+#endif
+
+uniform sampler2D uSampler;
+uniform float uTime;
+
+varying vec2 vTextureCoord;
+
+void main(void)
+{
+    float speed = 15.0;
+    float magnitude = 0.015;
+    vec2 wavyCoord;
+    wavyCoord.s = vTextureCoord.s + (sin(uTime+vTextureCoord.t*speed) * magnitude);
+    wavyCoord.t = vTextureCoord.t + (cos(uTime+vTextureCoord.s*speed) * magnitude);
+    vec4 frameColor = texture2D(uSampler, wavyCoord);
+    gl_FragColor = frameColor;
+}
+</script>
+
+<script id="post-filmgrain" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision highp float;
+#endif
+
+uniform sampler2D uSampler;
+uniform sampler2D uNoiseSampler;
+uniform vec2 uInverseTextureSize;
+uniform float uTime;
+
+varying vec2 vTextureCoord;
+
+void main(void)
+{
+    float grainIntensity = 0.1;
+    vec4 frameColor = texture2D(uSampler, vTextureCoord);
+    vec4 grain = texture2D(uNoiseSampler, vTextureCoord * 2.0 + uTime * 4082.0 * uInverseTextureSize);
+    gl_FragColor = frameColor - (grain * grainIntensity);
+}
+</script>
+
+<script id='code-js' type="text/javascript">
+
+var camera 		= null;
+var interactor 	= null;
+var post 		= null;
+var transforms	= null;
+var showPickingImage 	= false;
+var noiseTexture = null;
+
+
+function configure(){
+    gl.clearColor(0.3,0.3,0.3, 1.0);
+    gl.clearDepth(100.0);
+    gl.enable(gl.DEPTH_TEST);
+    gl.depthFunc(gl.LESS);
+	gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);
+    
+    //Creates and sets up the camera location
+    camera = new Camera(CAMERA_ORBITING_TYPE);
+    camera.goHome([0,0,40]);
+    camera.setFocus([0.0,0.0,0.0]);
+    camera.setElevation(-40);
+    camera.setAzimuth(-30);
+    camera.hookRenderer = render;
+    
+    
+    var canvas  = document.getElementById('canvas-element-id');
+    
+    //Post Process
+    post = new PostProcess(canvas, "post-greyscale");
+
+    // Noise texture, for use in the "film grain" post process effect
+    noiseTexture = new Texture();
+    noiseTexture.setImage("textures/noise.png");
+    
+    //Creates and sets up the mouse and keyboard interactor
+    interactor = new CameraInteractor(camera, canvas);
+        
+    //Scene Transforms
+    transforms = new SceneTransforms(camera);
+   
+    //init transforms
+    transforms.init();
+    
+    //Program
+    attributeList = ["aVertexPosition",
+                    "aVertexNormal",
+                    "aVertexColor",
+                    "aVertexTextureCoords"];
+
+    uniformList = [	"uPMatrix", 
+                    "uMVMatrix", 
+                    "uNMatrix",
+                    "uMaterialDiffuse",
+                    "uMaterialAmbient",
+                    "uLightAmbient",
+                    "uLightDiffuse",
+                    "uLightPosition",
+                    "uWireframe",
+                    "uAlpha",
+                    "uUseVertexColor",
+                    "uOffscreen",
+                    "uSampler",
+                    "uUseTextures"
+                    ];
+    
+    
+    Program.load(attributeList, uniformList);
+    
+    gl.uniform3fv(Program.uLightPosition,   [0,5,20]);
+    gl.uniform4fv(Program.uLightAmbient,    [1.0,1.0,1.0,1.0]);
+    gl.uniform4fv(Program.uLightDiffuse,    [1.0,1.0,1.0,1.0]);
+    gl.uniform1f(Program.uAlpha, 1.0);
+}
+
+/**
+* Loads the scene
+*/
+function load(){
+    Floor.build(80,2);
+    Scene.addObject(Floor);
+    Scene.loadObject('models/geometry/ball.json',   'ball', {position:[  0, 0, -4],    scale:[3,3,3]});
+    Scene.loadObject('models/geometry/ball.json',   'disk',{position:[  -10, 0, -10], scale:[3,0.5,3],  diffuse:[0.3,0.1,0.9,0.5]});
+    Scene.loadObject('models/geometry/flag.json',   'flag', {position:[-10, 0 ,0],     scale:[1,1,1]});
+    Scene.loadObject('models/geometry/cone.json',   'cone', {position:[ 10, 0, 5],     scale:[1,1,1]});
+    Scene.loadObject('models/geometry/cone.json',   'cone2',{position:[ -7, 0, 2],     scale:[0.5,1,0.5], diffuse:[0.3,0.3,0.6,1.0]});
+    Scene.loadObject('models/geometry/texCube.json','cube', {position:[1,2,7],         scale:[4,4,4],     ambient:[0.4,0.4,0.4,1.0]});
+}
+
+function render(){
+    // Checks to see if the framebuffer needs to be resized to match the canvas
+    post.validateSize();
+
+    //Render scene to framebuffer
+    gl.bindFramebuffer(gl.FRAMEBUFFER, post.framebuffer);
+    draw();
+
+    // Set up the post-process effect for rendering
+    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+    post.bind();
+
+    // Do any additional post-process shader uniform setup here
+    if(post.uniform.uNoiseSampler) {
+        gl.activeTexture(gl.TEXTURE1);
+        gl.bindTexture(gl.TEXTURE_2D, noiseTexture.tex);
+        gl.uniform1i(post.uniform.uNoiseSampler, 1);
+    }
+
+    //Re-render scene from framebuffer with post process effect
+    post.draw();
+}
+
+/**
+* invoked on every rendering cycle
+*/
+function draw() {
+    gl.viewport(0, 0, c_width, c_height);
+    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+    transforms.updatePerspective();
+    try{
+        gl.useProgram(prg);
+        var offscreen  = Program.getUniform(Program.uOffscreen);
+        
+        for (var i = 0; i < Scene.objects.length; i++){
+                
+            var object = Scene.objects[i];
+            
+            if(object.diffuse[3] < 1.0 && !offscreen) {
+				gl.disable(gl.DEPTH_TEST);
+				gl.enable(gl.BLEND);
+			} else {
+				gl.enable(gl.DEPTH_TEST);
+				gl.disable(gl.BLEND);
+			}
+
+            transforms.calculateModelView();           
+            transforms.push();
+            if (object.alias != 'floor'){
+                mat4.translate(transforms.mvMatrix, object.position);
+                mat4.scale(transforms.mvMatrix, object.scale);
+            }
+            transforms.setMatrixUniforms();
+            transforms.pop();
+
+            //Setting uniforms
+            gl.uniform4fv(Program.uMaterialDiffuse, object.diffuse);
+            gl.uniform4fv(Program.uMaterialAmbient, object.ambient);
+            gl.uniform1i(Program.uWireframe,object.wireframe);
+            gl.uniform1i(Program.uUseVertexColor, false);
+            gl.uniform1i(Program.uUseTextures, false);
+            
+            //Setting attributes
+            gl.enableVertexAttribArray(Program.aVertexPosition);
+            gl.disableVertexAttribArray(Program.aVertexNormal);
+            gl.disableVertexAttribArray(Program.aVertexColor);
+            gl.disableVertexAttribArray(Program.aVertexTextureCoords);
+            
+            //Bind Array Buffer
+            gl.bindBuffer(gl.ARRAY_BUFFER, object.vbo);
+            gl.vertexAttribPointer(Program.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
+            gl.enableVertexAttribArray(Program.aVertexPosition);
+
+            //render scalars
+            if (object.scalars != null){
+                gl.enableVertexAttribArray(Program.aVertexColor);
+                gl.uniform1i(Program.uUseVertexColor, true);
+                gl.bindBuffer(gl.ARRAY_BUFFER, object.cbo);
+                gl.vertexAttribPointer(Program.aVertexColor, 4, gl.FLOAT, false, 0, 0);
+                
+            }
+            
+            //render textures
+            if (object.texture_coords){
+                gl.enableVertexAttribArray(Program.aVertexTextureCoords);
+                gl.uniform1i(Program.uUseTextures, true);
+                gl.bindBuffer(gl.ARRAY_BUFFER, object.tbo);
+                gl.vertexAttribPointer(Program.aVertexTextureCoords, 2, gl.FLOAT, false, 0, 0);
+                gl.activeTexture(gl.TEXTURE0);
+                gl.bindTexture(gl.TEXTURE_2D, object.texture.tex);
+                gl.uniform1i(Program.uSampler, 0);
+            }
+            
+            if(!object.wireframe){
+                gl.bindBuffer(gl.ARRAY_BUFFER, object.nbo);
+                gl.vertexAttribPointer(Program.aVertexNormal, 3, gl.FLOAT, false, 0, 0);
+                gl.enableVertexAttribArray(Program.aVertexNormal);
+            }
+            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, object.ibo);
+            
+            if (object.wireframe){
+                gl.drawElements(gl.LINES, object.indices.length, gl.UNSIGNED_SHORT,0);
+            }
+            else{
+                gl.drawElements(gl.TRIANGLES, object.indices.length, gl.UNSIGNED_SHORT,0);
+            }
+            
+            gl.bindBuffer(gl.ARRAY_BUFFER, null);
+            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+        }
+    }
+    catch(err){
+        alert(err);
+        console.error(err.description);
+    }
+}
+
+
+/**
+* Entry point. This function is invoked when the page is loaded
+*/
+var app = null;
+function runWebGLApp() {
+    app = new WebGLApp("canvas-element-id");
+    app.configureGLHook = configure;
+    app.loadSceneHook   = load;
+    app.drawSceneHook   = render;
+    app.run();
+}
+</script>
+</head>
+
+<body onLoad='runWebGLApp()'>
+<div id='top'>
+<h1>WebGL Beginner's Guide - Chapter 10</h1>
+<h2 id='title-id'>Post Process Effects</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> 
+    <table cellspacing=4px style='vertical-align:top'>
+        <tr>
+            <td>Filter:</td>
+            <td>
+            <div id='opt-filter' align='center'>
+                <input type='radio' id='filter-greyscale' name='filter' checked='checked'/><label for='filter-greyscale'>Greyscale</label>
+                <input type='radio' id='filter-invert' name='filter' /><label for='filter-invert'>Invert</label>
+                <input type='radio' id='filter-wavy' name='filter' /><label for='filter-wavy'>Wavy</label>
+                <input type='radio' id='filter-blur' name='filter' /><label for='filter-blur'>Blur</label>
+                <input type='radio' id='filter-filmgrain' name='filter' /><label for='filter-filmgrain'>Film-Grain</label>
+            </div>
+            </td>
+        </tr>
+    </table>
+    </td>
+</table>
+</div>
+<script> 
+
+$('#opt-filter').buttonset();
+
+$('#filter-greyscale').click(function(){
+    post.configureShader("post-greyscale");
+});
+
+$('#filter-invert').click(function(){
+    post.configureShader("post-invert");
+});
+
+$('#filter-wavy').click(function(){
+    post.configureShader("post-wavy");
+});
+
+$('#filter-blur').click(function(){
+    post.configureShader("post-blur");
+});
+
+$('#filter-filmgrain').click(function(){
+    post.configureShader("post-filmgrain");
+});
+
+</script>
+<script>cview.run(cview.MODE_VIEW,false,470);</script>
+</body>
+</html>

1727_10/ch10_Raytracing.html

+<html>
+
+<head>
+<title>WebGL Beginner's Guide - Chapter 10 - Raytracing</title>
+<meta http-equiv='content-type' content='text/html; charset=ISO-8859-1'>
+
+<!-- CSS Styles //-->
+<link href='css/styles.css'   type='text/css' rel='stylesheet'>
+<link href='css/prettify_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' />
+<!-- GUI Libraries //-->
+<script type='text/javascript' src='js/gui/jquery-1.5.1.min.js'></script>
+<script type='text/javascript' src='js/gui/jquery-ui-1.8.13.custom.min.js'></script> 
+<script type='text/javascript' src='js/gui/colorpicker.js'></script>
+<script type='text/javascript' src='js/gui/prettify.js'></script>
+<script type='text/javascript' src='js/gui/codeview.js'></script>
+<!-- MATH Libraries //-->
+<script type='text/javascript' src='js/math/glMatrix-0.9.5.min.js'></script>
+<!-- WEBGL Libraries //-->
+<script type='text/javascript' src='js/webgl/Globals.js'></script>
+<script type='text/javascript' src='js/webgl/Utils.js'></script>
+<script type='text/javascript' src='js/webgl/Program.js'></script>
+<script type='text/javascript' src='js/webgl/Scene.js'></script>
+<script type='text/javascript' src='js/webgl/Axis.js'></script>
+<script type='text/javascript' src='js/webgl/Floor.js'></script>
+<script type='text/javascript' src='js/webgl/Camera.js'></script>
+<script type='text/javascript' src='js/webgl/CameraInteractor.js'></script>
+<script type='text/javascript' src='js/webgl/SceneTransforms.js'></script>
+<script type='text/javascript' src='js/webgl/Texture.js'></script>
+<script type='text/javascript' src='js/webgl/WebGLApp.js'></script>
+<script type='text/javascript' src='js/webgl/PostProcess.js'></script>
+
+<script id="post-common-vs" type="x-shader/x-vertex">
+attribute vec3 aVertexPosition;
+attribute vec2 aVertexTextureCoords;
+
+varying vec2 vTextureCoord;
+
+void main(void) {
+    vTextureCoord = aVertexTextureCoords;
+    gl_Position = vec4(aVertexPosition, 1.0);
+}   
+</script>
+
+<!--http://glsl.heroku.com/e#1686.0-->
+<script id="raytrace-fs" type="x-shader/x-fragment">
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+uniform float uTime;
+uniform vec2 uInverseTextureSize;
+
+vec3 lightDir = normalize( vec3(0.5, 0.5, 0.5) );
+vec3 eyePos = vec3(0.0, 1.0, 4.0);
+vec3 bgColor = vec3(0.2, 0.2, 0.2);
+
+vec3 ambient = vec3(0.05, 0.1, 0.1);
+
+vec4 sphere1 = vec4(0.0, 1.0, 0.0, 1.0);
+vec3 sphere1Color = vec3(0.9, 0.8, 0.6);
+
+float maxDist = 1024.0;
+
+// ro is the ray origin, rd is the ray direction, and s is the sphere
+float sphereInter( vec3 ro, vec3 rd, vec4 s ) {
+    // Transform the ray into object space
+    vec3 oro = ro - s.xyz;
+
+    float a = dot(rd, rd);
+    float b = 2.0 * dot(oro, rd);
+    float c = dot(oro, oro) - s.w * s.w; // w is the sphere radius
+
+    float d = b * b - 4.0 * a * c;
+
+    if(d < 0.0) return d; // No intersection
+    
+    return (-b - sqrt(d)) / 2.0;
+}
+
+vec3 sphereNorm( vec3 pt, vec4 s ) {
+    return ( pt - s.xyz )/ s.w;
+}
+
+float intersect( vec3 ro, vec3 rd, out vec3 norm, out vec3 color ) {
+    float t = maxDist;
+
+    // If we wanted multiple objects in the scene you would loop through them here
+    // and return the normal and color with the closest intersection point (lowest t)
+
+    float ot = sphereInter( ro, rd, sphere1 ); 
+    
+    if ( ot > 0.0 && ot < t ) {
+        t = ot;
+
+        vec3 pt = ro + t * rd; // Point of intersection
+        norm = sphereNorm(pt, sphere1); // Get normal for that point
+        color = sphere1Color; // Get color for the sphere
+    }
+
+    return t;
+}
+
+void main( void ) {
+    // Pixel coordinate of the fragment being rendered
+    vec2 uv = ( gl_FragCoord.xy * uInverseTextureSize );
+    float aspectRatio = uInverseTextureSize.y/uInverseTextureSize.x;
+    
+    // Wiggle the sphere back and forth a bit
+    sphere1.x = 1.5 * sin(uTime);
+    sphere1.z = 0.5 * cos(uTime * 3.0);
+    
+    // Cast a ray out from the eye position into the scene
+    vec3 ro = eyePos;
+    // Ray we cast is tilted slightly downward to give a better view of the scene
+    vec3 rd = normalize(vec3( -0.5 + uv * vec2(aspectRatio, 1.0), -1.0));
+    
+    vec3 rayColor = bgColor; // Default color if we don't intersect with anything
+
+    // See if the ray intesects with any objects. 
+    // Provides the normal of the nearest intersection point and color
+    vec3 objNorm, objColor;
+    float t = intersect(ro, rd, objNorm, objColor);
+    
+    if ( t < maxDist ) {
+        float diffuse = clamp(dot(objNorm, lightDir), 0.0, 1.0); // diffuse factor
+        rayColor = objColor * diffuse + ambient;
+    }
+    
+    gl_FragColor = vec4(rayColor, 1.0);
+}
+</script>
+
+<script id='code-js' type="text/javascript">
+
+var camera 		= null;
+var interactor 	= null;
+var post 		= null;
+var transforms	= null;
+
+function configure(){
+    gl.clearColor(0.3,0.3,0.3, 1.0);
+    gl.clearDepth(100.0);
+    gl.enable(gl.DEPTH_TEST);
+    gl.depthFunc(gl.LESS);
+	gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);
+    
+    //Creates and sets up the camera location
+    camera = new Camera(CAMERA_ORBITING_TYPE);
+    camera.goHome([0,0,40]);
+    camera.setFocus([0.0,0.0,0.0]);
+    camera.setElevation(-40);
+    camera.setAzimuth(-30);
+    camera.hookRenderer = render;
+    
+    
+    var canvas  = document.getElementById('canvas-element-id');
+    
+    //Post Process
+    post = new PostProcess(canvas, "raytrace-fs");
+    
+    //Creates and sets up the mouse and keyboard interactor
+    interactor = new CameraInteractor(camera, canvas);
+        
+    //Scene Transforms
+    transforms = new SceneTransforms(camera);
+   
+    //init transforms
+    transforms.init();
+}
+
+/**
+* Loads the scene
+*/
+function load(){
+
+}
+
+function render(){
+    gl.viewport(0, 0, c_width, c_height);
+    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+    // Checks to see if the framebuffer needs to be resized to match the canvas
+    post.validateSize();
+    post.bind();
+
+    //Render the fullscreen quad
+    post.draw();
+}
+
+/**
+* Entry point. This function is invoked when the page is loaded
+*/
+var app = null;
+function runWebGLApp() {
+    app = new WebGLApp("canvas-element-id");
+    app.configureGLHook = configure;
+    app.loadSceneHook   = load;
+    app.drawSceneHook   = render;
+    app.run();
+}
+</script>
+</head>
+
+<body onLoad='runWebGLApp()'>
+<div id='top'>
+<h1>WebGL Beginner's Guide - Chapter 10</h1>
+<h2 id='title-id'>Raytracing</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'>
+
+</div>
+<script> 
+
+</script>
+<script>cview.run(cview.MODE_VIEW,false,470);</script>
+</body>
+</html>

1727_10/css/colorpicker.css

+.colorpicker {
+	width: 356px;
+	height: 176px;
+	overflow: hidden;
+	position: absolute;
+	background: url(colorpickerImages/colorpicker_background.png);
+	font-family: Arial, Helvetica, sans-serif;
+	display: none;
+	z-index: 9999999; /*modification made by Diego*/
+}
+.colorpicker_color {
+	width: 150px;
+	height: 150px;
+	left: 14px;
+	top: 13px;
+	position: absolute;
+	background: #D1D1D1;
+	overflow: hidden;
+	cursor: crosshair;
+}
+.colorpicker_color div {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 150px;
+	height: 150px;
+	background: url(colorpickerImages/colorpicker_overlay.png);
+}
+.colorpicker_color div div {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 11px;
+	height: 11px;
+	overflow: hidden;
+	background: url(colorpickerImages/colorpicker_select.gif);
+	margin: -5px 0 0 -5px;
+}
+.colorpicker_hue {
+	position: absolute;
+	top: 13px;
+	left: 171px;
+	width: 35px;
+	height: 150px;
+	cursor: n-resize;
+}
+.colorpicker_hue div {
+	position: absolute;
+	width: 35px;
+	height: 9px;
+	overflow: hidden;
+	background: url(colorpickerImages/colorpicker_indic.gif) left top;
+	margin: -4px 0 0 0;
+	left: 0px;
+}
+.colorpicker_new_color {
+	position: absolute;
+	width: 60px;
+	height: 30px;
+	left: 213px;
+	top: 13px;
+	background: #f00;
+}
+.colorpicker_current_color {
+	position: absolute;
+	width: 60px;
+	height: 30px;
+	left: 283px;
+	top: 13px;
+	background: #f00;
+}
+.colorpicker input {
+	background-color: transparent;
+	border: 1px solid transparent;
+	position: absolute;
+	font-size: 10px;
+	font-family: Arial, Helvetica, sans-serif;
+	color: #898989;
+	top: 4px;
+	right: 11px;
+	text-align: right;
+	margin: 0;
+	padding: 0;
+	height: 11px;
+}
+.colorpicker_hex {
+	position: absolute;
+	width: 72px;
+	height: 22px;
+	background: url(colorpickerImages/colorpicker_hex.png) top;
+	left: 212px;
+	top: 142px;
+}
+.colorpicker_hex input {
+	right: 6px;
+}
+.colorpicker_field {
+	height: 22px;
+	width: 62px;
+	background-position: top;
+	position: absolute;
+}
+.colorpicker_field span {
+	position: absolute;
+	width: 12px;
+	height: 22px;
+	overflow: hidden;
+	top: 0;
+	right: 0;
+	cursor: n-resize;
+}
+.colorpicker_rgb_r {
+	background-image: url(colorpickerImages/colorpicker_rgb_r.png);
+	top: 52px;
+	left: 212px;
+}
+.colorpicker_rgb_g {
+	background-image: url(colorpickerImages/colorpicker_rgb_g.png);
+	top: 82px;
+	left: 212px;
+}
+.colorpicker_rgb_b {
+	background-image: url(colorpickerImages/colorpicker_rgb_b.png);
+	top: 112px;
+	left: 212px;
+}
+.colorpicker_hsb_h {
+	background-image: url(colorpickerImages/colorpicker_hsb_h.png);
+	top: 52px;
+	left: 282px;
+}
+.colorpicker_hsb_s {
+	background-image: url(colorpickerImages/colorpicker_hsb_s.png);
+	top: 82px;
+	left: 282px;
+}
+.colorpicker_hsb_b {
+	background-image: url(colorpickerImages/colorpicker_hsb_b.png);
+	top: 112px;
+	left: 282px;
+}
+.colorpicker_submit {
+	position: absolute;
+	width: 22px;
+	height: 22px;
+	background: url(colorpickerImages/colorpicker_submit.png) top;
+	left: 322px;
+	top: 142px;
+	overflow: hidden;
+}
+.colorpicker_focus {
+	background-position: center;
+}
+.colorpicker_hex.colorpicker_focus {
+	background-position: bottom;
+}
+.colorpicker_submit.colorpicker_focus {
+	background-position: bottom;
+}
+.colorpicker_slider {
+	background-position: bottom;
+}
+
+.colorSelector {
+    background: url(colorpickerImages/select2.png) scroll 0 0 transparent;
+    height: 36px;
+    left: 0px;
+    position: relative;
+    top: 0px;
+    width: 36px;
+}
+
+.colorSelector div {
+    background: url(colorpickerImages/select2.png) scroll center center transparent;
+    height: 28px;
+    left: 4px;
+    position: absolute;
+    top: 4px;
+    width: 28px;
+}
+
+
Add a comment to this file

1727_10/css/colorpickerImages/blank.gif

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_background.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_hex.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_hsb_b.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_hsb_h.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_hsb_s.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_indic.gif

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_overlay.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_rgb_b.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_rgb_g.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_rgb_r.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_select.gif

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/colorpicker_submit.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/custom_indic.gif

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/select.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/select2.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/slider.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/trashk/colorpicker_background.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/trashk/colorpicker_hex.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/trashk/colorpicker_hsb_b.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/trashk/colorpicker_hsb_h.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/trashk/colorpicker_hsb_s.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/trashk/colorpicker_rgb_b.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/trashk/colorpicker_rgb_g.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/trashk/colorpicker_rgb_r.png

Added
New image
Add a comment to this file

1727_10/css/colorpickerImages/trashk/colorpicker_submit.png

Added
New image

1727_10/css/prettify_default.css

+.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}

1727_10/css/prettify_desert.css

+/* desert scheme ported from vim to google prettify */
+pre { display: block; background-color: #333 }
+pre .nocode { background-color: none; color: #000 }
+pre .str { color: #ffa0a0 } /* string  - pink */
+pre .kwd { color: #f0e68c; font-weight: bold }
+pre .com { color: #87ceeb } /* comment - skyblue */
+pre .typ { color: #98fb98 } /* type    - lightgreen */
+pre .lit { color: #cd5c5c } /* literal - darkred */
+pre .pun { color: #fff }    /* punctuation */
+pre .pln { color: #fff }    /* plaintext */
+pre .tag { color: #f0e68c; font-weight: bold } /* html/xml tag    - lightyellow */
+pre .atn { color: #bdb76b; font-weight: bold } /* attribute name  - khaki */
+pre .atv { color: #ffa0a0 } /* attribute value - pink */
+pre .dec { color: #98fb98 } /* decimal         - lightgreen */
+
+/* Specify class=linenums on a pre to get line numbering */
+ol.linenums { margin-top: 0; margin-bottom: 0; color: #AEAEAE } /* IE indents via margin-left */
+/*li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none }*/
+
+/*li.L1,li.L3,li.L5,li.L7,li.L9 { list-style-type: none }*/
+/* Alternate shading for lines */
+li.L1,li.L3,li.L5,li.L7,li.L9 { }
+
+
+@media print {
+  pre { background-color: none }
+  pre .str, code .str { color: #060 }
+  pre .kwd, code .kwd { color: #006; font-weight: bold }
+  pre .com, code .com { color: #600; font-style: italic }
+  pre .typ, code .typ { color: #404; font-weight: bold }
+  pre .lit, code .lit { color: #044 }
+  pre .pun, code .pun { color: #440 }
+  pre .pln, code .pln { color: #000 }
+  pre .tag, code .tag { color: #006; font-weight: bold }
+  pre .atn, code .atn { color: #404 }
+  pre .atv, code .atv { color: #060 }
+}
+