├── VERSION ├── .npmignore ├── examples ├── lessons │ ├── 1 │ │ ├── index.html │ │ └── index.js │ ├── 2 │ │ ├── index.html │ │ └── index.js │ ├── 3 │ │ ├── index.html │ │ └── index.js │ ├── 4 │ │ ├── index.html │ │ └── index.js │ ├── 5 │ │ ├── nehe.gif │ │ ├── index.html │ │ └── index.js │ ├── 6 │ │ ├── crate.gif │ │ ├── index.html │ │ └── index.js │ ├── 7 │ │ ├── crate.gif │ │ ├── index.html │ │ └── index.js │ ├── 8 │ │ ├── glass.gif │ │ ├── index.html │ │ └── index.js │ ├── 9 │ │ ├── star.gif │ │ ├── index.html │ │ └── index.js │ ├── 10 │ │ ├── mud.gif │ │ ├── index.html │ │ ├── world.txt │ │ └── index.js │ ├── 11 │ │ ├── moon.gif │ │ ├── index.html │ │ └── index.js │ ├── 12 │ │ ├── moon.gif │ │ ├── crate.gif │ │ ├── index.html │ │ └── index.js │ ├── 13 │ │ ├── moon.gif │ │ ├── crate.gif │ │ ├── index.html │ │ └── index.js │ ├── 14 │ │ ├── earth.jpg │ │ ├── arroway.de_metal+structure+06_d100_flat.jpg │ │ ├── index.html │ │ └── index.js │ ├── 15 │ │ ├── earth.jpg │ │ ├── earth-specular.gif │ │ ├── index.html │ │ └── index.js │ ├── 16 │ │ ├── moon.gif │ │ ├── crate.gif │ │ ├── index.html │ │ ├── index.js │ │ └── WebGLExport.py │ └── lessons.css ├── particles │ ├── copy.fs │ ├── simulation.vs │ ├── surface.fs.glsl │ ├── copy.vs │ ├── surface.fs │ ├── surface.vs │ ├── surface.vs.glsl │ ├── style.css │ ├── index.html │ ├── simulation.fs │ ├── graph-compute.js │ └── explorer.js └── picking │ ├── style.css │ ├── index.html │ └── balls.js ├── package.json ├── bower.json ├── shaders ├── frag-lighting.vs.glsl ├── spec-map.vs.glsl ├── render-tex.vs.glsl ├── fog.fs.glsl ├── default.fs.glsl ├── default.vs.glsl ├── render-tex.fs.glsl ├── spec-map.fs.glsl └── frag-lighting.fs.glsl ├── LICENSE └── README.md /VERSION: -------------------------------------------------------------------------------- 1 | 1.3.0 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | docs 2 | examples 3 | shaders 4 | -------------------------------------------------------------------------------- /examples/lessons/10/mud.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/10/mud.gif -------------------------------------------------------------------------------- /examples/lessons/11/moon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/11/moon.gif -------------------------------------------------------------------------------- /examples/lessons/12/moon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/12/moon.gif -------------------------------------------------------------------------------- /examples/lessons/13/moon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/13/moon.gif -------------------------------------------------------------------------------- /examples/lessons/16/moon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/16/moon.gif -------------------------------------------------------------------------------- /examples/lessons/5/nehe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/5/nehe.gif -------------------------------------------------------------------------------- /examples/lessons/6/crate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/6/crate.gif -------------------------------------------------------------------------------- /examples/lessons/7/crate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/7/crate.gif -------------------------------------------------------------------------------- /examples/lessons/8/glass.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/8/glass.gif -------------------------------------------------------------------------------- /examples/lessons/9/star.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/9/star.gif -------------------------------------------------------------------------------- /examples/lessons/12/crate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/12/crate.gif -------------------------------------------------------------------------------- /examples/lessons/13/crate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/13/crate.gif -------------------------------------------------------------------------------- /examples/lessons/14/earth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/14/earth.jpg -------------------------------------------------------------------------------- /examples/lessons/15/earth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/15/earth.jpg -------------------------------------------------------------------------------- /examples/lessons/16/crate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/16/crate.gif -------------------------------------------------------------------------------- /examples/lessons/15/earth-specular.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/15/earth-specular.gif -------------------------------------------------------------------------------- /examples/lessons/14/arroway.de_metal+structure+06_d100_flat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/philogb/philogl/HEAD/examples/lessons/14/arroway.de_metal+structure+06_d100_flat.jpg -------------------------------------------------------------------------------- /examples/particles/copy.fs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | uniform sampler2D sampler1; 6 | varying vec2 vTexCoord1; 7 | 8 | void main() { 9 | gl_FragColor = texture2D(sampler1, vTexCoord1); 10 | } 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/particles/simulation.vs: -------------------------------------------------------------------------------- 1 | attribute vec3 position; 2 | attribute vec2 texCoord1; 3 | 4 | uniform mat4 worldMatrix; 5 | uniform mat4 projectionMatrix; 6 | 7 | varying vec2 vTexCoord1; 8 | 9 | void main() { 10 | vTexCoord1 = texCoord1; 11 | gl_Position = projectionMatrix * worldMatrix * vec4(position, 1); 12 | } 13 | -------------------------------------------------------------------------------- /examples/particles/surface.fs.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | uniform vec3 pointColor; 6 | 7 | varying vec3 vPosition; 8 | varying float opacity; 9 | 10 | void main() { 11 | 12 | if (opacity <= 0.0) discard; 13 | gl_FragColor = vec4( pointColor + vPosition * 0.005, opacity ); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /examples/particles/copy.vs: -------------------------------------------------------------------------------- 1 | attribute vec3 position; 2 | attribute vec2 texCoord1; 3 | 4 | uniform mat4 worldMatrix; 5 | uniform mat4 projectionMatrix; 6 | 7 | varying vec2 vTexCoord1; 8 | 9 | void main() { 10 | vec4 pos = worldMatrix * vec4(position, 1); 11 | vTexCoord1 = texCoord1; 12 | gl_Position = projectionMatrix * pos; 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/particles/surface.fs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | uniform vec3 pointColor; 6 | 7 | varying vec3 vPosition; 8 | varying float opacity; 9 | 10 | void main() { 11 | /*if (opacity <= 0.0) discard;*/ 12 | /*gl_FragColor = vec4( pointColor + vPosition * 0.005, opacity );*/ 13 | gl_FragColor = vec4(1, 0, 0, 1) * 1. / (sqrt(opacity)); 14 | } 15 | -------------------------------------------------------------------------------- /examples/lessons/lessons.css: -------------------------------------------------------------------------------- 1 | .gist { 2 | position: absolute; 3 | left: 550px; 4 | top: 10px; 5 | width: 550px; 6 | height: 500px; 7 | font-size: 12px; 8 | overflow: auto; 9 | border: 1px solid #ccc; 10 | box-shadow: 0 0 10px #000; 11 | -webkit-box-shadow: 0 0 10px #000; 12 | -moz-box-shadow: 0 0 10px #000; 13 | -o-box-shadow: 0 0 10px #000; 14 | } 15 | 16 | canvas { 17 | box-shadow: 0 0 10px #000; 18 | -webkit-box-shadow: 0 0 10px #000; 19 | -moz-box-shadow: 0 0 10px #000; 20 | -o-box-shadow: 0 0 10px #000; 21 | } 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "philogl", 3 | "version": "1.6.8", 4 | "description": "A WebGL JavaScript visualization library.", 5 | "keywords": [ 6 | "webgl", 7 | "w3c", 8 | "visualization", 9 | "canvas", 10 | "animation", 11 | "3d" 12 | ], 13 | "homepage": "http://philogl.org/", 14 | "author": { 15 | "name": "Nicolas Garcia Belmonte", 16 | "url": "http://philogb.github.io" 17 | }, 18 | "contributors": [], 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/philogb/philogl.git" 22 | }, 23 | "main": "./build/PhiloGL.cls.js", 24 | "license": "MIT" 25 | } 26 | -------------------------------------------------------------------------------- /examples/particles/surface.vs: -------------------------------------------------------------------------------- 1 | attribute vec3 position; 2 | 3 | uniform sampler2D sampler1; 4 | uniform float size; 5 | uniform float pointSize; 6 | 7 | uniform mat4 worldMatrix; 8 | uniform mat4 projectionMatrix; 9 | 10 | varying vec3 vPosition; 11 | varying float opacity; 12 | 13 | void main(void) { 14 | gl_PointSize = pointSize; 15 | 16 | vec2 uv = position.xy; 17 | vec4 data = texture2D(sampler1, uv); 18 | data.x *= 15.; 19 | data.y -= 0.4 - data.z * 4.; 20 | data.z *= 15.; 21 | vPosition = data.xyz; 22 | opacity = data.z * data.y; 23 | 24 | gl_Position = projectionMatrix * worldMatrix * vec4(vPosition, 1.0); 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /examples/particles/surface.vs.glsl: -------------------------------------------------------------------------------- 1 | attribute vec3 position; 2 | 3 | uniform sampler2D map; 4 | uniform float size; 5 | 6 | uniform mat4 worldMatrix; 7 | uniform mat4 projectionMatrix; 8 | uniform mat4 worldInverseTransposeMatrix; 9 | 10 | varying vec2 vUv; 11 | varying vec3 vPosition; 12 | varying float opacity; 13 | 14 | void main() { 15 | 16 | vec2 uv = position.xy + vec2( 0.5 / size, 0.5 / size ); 17 | vec4 data = texture2D(map, uv); 18 | 19 | vPosition = data.xyz; 20 | opacity = data.w; 21 | 22 | gl_PointSize = 1.0; // data.w * 10.0 + 1.0; 23 | gl_Position = projectionMatrix * worldMatrix * vec4( vPosition, 1.0 ); 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PhiloGL", 3 | "version": "1.5.3", 4 | "description": "A WebGL Framework for Data Visualization, Creative Coding and Game Development.", 5 | "keywords": [ 6 | "dom", 7 | "w3c", 8 | "visualization", 9 | "WebGL", 10 | "animation" 11 | ], 12 | "main": "build/PhiloGL.js", 13 | "homepage": "http://senchalabs.org/philogl", 14 | "author": { 15 | "name": "Nicolas Garcia Belmonte", 16 | "url": "http://philogb.github.io/" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/philogb/philogl.git" 21 | }, 22 | "licenses": [ 23 | { 24 | "type": "MIT", 25 | "url": "https://github.com/philogb/philogl/blob/master/LICENSE" 26 | } 27 | ] 28 | } 29 | 30 | -------------------------------------------------------------------------------- /shaders/frag-lighting.vs.glsl: -------------------------------------------------------------------------------- 1 | attribute vec3 position; 2 | attribute vec3 normal; 3 | attribute vec2 texCoord1; 4 | attribute vec2 texCoord2; 5 | attribute vec2 texCoord3; 6 | attribute vec4 color; 7 | 8 | uniform mat4 worldMatrix; 9 | uniform mat4 projectionMatrix; 10 | uniform mat4 worldInverseTransposeMatrix; 11 | 12 | varying vec2 vTexCoord1; 13 | varying vec2 vTexCoord2; 14 | varying vec2 vTexCoord3; 15 | varying vec4 vTransformedNormal; 16 | varying vec4 vPosition; 17 | varying vec4 vColor; 18 | 19 | 20 | void main(void) { 21 | vPosition = worldMatrix * vec4(position, 1.0); 22 | vTransformedNormal = worldInverseTransposeMatrix * vec4(normal, 1.0); 23 | vTexCoord1 = texCoord1; 24 | vTexCoord2 = texCoord2; 25 | vTexCoord3 = texCoord3; 26 | vColor = color; 27 | gl_Position = projectionMatrix * vPosition; 28 | } 29 | -------------------------------------------------------------------------------- /shaders/spec-map.vs.glsl: -------------------------------------------------------------------------------- 1 | attribute vec3 position; 2 | attribute vec3 normal; 3 | attribute vec2 texCoord1; 4 | attribute vec2 texCoord2; 5 | attribute vec2 texCoord3; 6 | attribute vec4 color; 7 | 8 | uniform mat4 worldMatrix; 9 | uniform mat4 projectionMatrix; 10 | uniform mat4 worldInverseTransposeMatrix; 11 | 12 | varying vec2 vTexCoord1; 13 | varying vec2 vTexCoord2; 14 | varying vec2 vTexCoord3; 15 | varying vec4 vTransformedNormal; 16 | varying vec4 vPosition; 17 | varying vec4 vColor; 18 | 19 | 20 | void main(void) { 21 | vPosition = worldMatrix * vec4(position, 1.0); 22 | vTransformedNormal = worldInverseTransposeMatrix * vec4(normal, 1.0); 23 | vTexCoord1 = texCoord1; 24 | vTexCoord2 = texCoord2; 25 | vTexCoord3 = texCoord3; 26 | vColor = color; 27 | gl_Position = projectionMatrix * vPosition; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /shaders/render-tex.vs.glsl: -------------------------------------------------------------------------------- 1 | attribute vec3 position; 2 | attribute vec3 normal; 3 | attribute vec2 texCoord1; 4 | attribute vec2 texCoord2; 5 | attribute vec2 texCoord3; 6 | attribute vec4 color; 7 | 8 | uniform mat4 worldMatrix; 9 | uniform mat4 projectionMatrix; 10 | uniform mat4 worldInverseTransposeMatrix; 11 | 12 | varying vec2 vTexCoord1; 13 | varying vec2 vTexCoord2; 14 | varying vec2 vTexCoord3; 15 | varying vec4 vTransformedNormal; 16 | varying vec4 vPosition; 17 | varying vec4 vColor; 18 | 19 | 20 | void main(void) { 21 | vPosition = worldMatrix * vec4(position, 1.0); 22 | vTransformedNormal = worldInverseTransposeMatrix * vec4(normal, 1.0); 23 | vTexCoord1 = texCoord1; 24 | vTexCoord2 = texCoord2; 25 | vTexCoord3 = texCoord3; 26 | vColor = color; 27 | gl_Position = projectionMatrix * vPosition; 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /shaders/fog.fs.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | varying vec4 vColor; 6 | varying vec2 vTexCoord; 7 | varying vec3 lightWeighting; 8 | 9 | uniform bool hasTexture; 10 | uniform sampler2D sampler; 11 | 12 | uniform bool hasFog; 13 | uniform vec3 fogColor; 14 | 15 | uniform float fogNear; 16 | uniform float fogFar; 17 | 18 | void main(){ 19 | if(!hasTexture) { 20 | gl_FragColor = vec4(vColor.rgb * lightWeighting, vColor.a); 21 | } else { 22 | gl_FragColor = vec4(texture2D(sampler, vec2(vTexCoord.s, vTexCoord.t)).rgb * lightWeighting, 1.0); 23 | } 24 | 25 | /* handle fog */ 26 | if (hasFog) { 27 | float depth = gl_FragCoord.z / gl_FragCoord.w; 28 | float fogFactor = smoothstep(fogNear, fogFar, depth); 29 | gl_FragColor = mix(gl_FragColor, vec4(fogColor, gl_FragColor.w), fogFactor); 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /examples/lessons/10/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 10 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Use the cursor keys or WASD to run around, and Page Up/Page Down to 18 | look up and down. 19 | 20 |
21 |
22 | << Back to Lesson 10 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/lessons/9/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 9 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Twinkle
18 | (Use up/down cursor keys to rotate, and Page Up/Page Down to zoom out/in) 19 | 20 |
21 |
22 | << Back to Lesson 9 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/lessons/16/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 16 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | Laptop model adapted from this 3DS Max model by Xedium
19 | Moon texture courtesy of the Jet Propulsion Laboratory. 20 |
21 |
22 | 23 | << Back to Lesson 16
24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /shaders/default.fs.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | varying vec4 vColor; 6 | varying vec2 vTexCoord; 7 | varying vec3 lightWeighting; 8 | 9 | uniform bool hasTexture1; 10 | uniform sampler2D sampler1; 11 | 12 | uniform bool enablePicking; 13 | uniform vec3 pickColor; 14 | 15 | uniform bool hasFog; 16 | uniform vec3 fogColor; 17 | 18 | uniform float fogNear; 19 | uniform float fogFar; 20 | 21 | void main(){ 22 | 23 | if(!hasTexture1) { 24 | gl_FragColor = vec4(vColor.rgb * lightWeighting, vColor.a); 25 | } else { 26 | gl_FragColor = vec4(texture2D(sampler1, vec2(vTexCoord.s, vTexCoord.t)).rgb * lightWeighting, 1.0); 27 | } 28 | 29 | if(enablePicking) { 30 | gl_FragColor = vec4(pickColor, 1.0); 31 | } 32 | 33 | /* handle fog */ 34 | if (hasFog) { 35 | float depth = gl_FragCoord.z / gl_FragCoord.w; 36 | float fogFactor = smoothstep(fogNear, fogFar, depth); 37 | gl_FragColor = mix(gl_FragColor, vec4(fogColor, gl_FragColor.w), fogFactor); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /examples/lessons/1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 20 | 21 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Sencha Labs - Author: Nicolas Garcia Belmonte (http://philogb.github.com/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /examples/lessons/3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Learning WebGL — lesson 3 4 | 5 | 6 | 7 | 8 | 9 | 10 | 21 | 22 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /examples/lessons/4/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 4 5 | 6 | 7 | 8 | 9 | 10 | 11 | 22 | 23 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /examples/lessons/2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 22 | 23 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /examples/lessons/5/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 5 5 | 6 | 7 | 8 | 9 | 10 | 11 | 24 | 25 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /examples/picking/style.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | text-align: center; 3 | font-family: 'Crimson Text', Verdana; 4 | margin: 0; 5 | padding: 0; 6 | } 7 | 8 | input, select { 9 | font-size: 15px; 10 | font-family: 'Crimson Text', Verdana; 11 | max-width: 80px; 12 | } 13 | 14 | #fxy { 15 | width: 550px; 16 | max-width: 550px; 17 | } 18 | 19 | input.error { 20 | background: #ffdddd; 21 | } 22 | 23 | #container { 24 | width: 900px; 25 | margin: auto; 26 | } 27 | 28 | body.no-webgl #container { 29 | display: none; 30 | } 31 | 32 | div.fallback { 33 | display: none; 34 | } 35 | 36 | body.no-webgl div.fallback { 37 | display: block; 38 | } 39 | 40 | .description { 41 | width: 200px; 42 | font-size: 13px; 43 | position: absolute; 44 | padding: 5px; 45 | text-align: left; 46 | right: 8px; 47 | top: 8px; 48 | border: 1px solid #ccc; 49 | background-color: rgb(255, 241, 168); 50 | } 51 | 52 | #title { 53 | 54 | } 55 | 56 | h1 { 57 | text-shadow: rgba(0, 0, 0, 0.2) 0 0 3px; 58 | margin: 5px; 59 | } 60 | 61 | .controls { 62 | position: relative; 63 | background: #E0ECFF; 64 | padding: 7px; 65 | border: 1px solid #ccc; 66 | margin: 7px 0; 67 | /* text-align: left;*/ 68 | } 69 | 70 | .controls table tr td { 71 | text-align: left; 72 | margin: auto; 73 | font-size: 15px; 74 | } 75 | 76 | #canvas-container { 77 | margin: auto; 78 | } 79 | 80 | canvas { 81 | -webkit-box-shadow: #333 0 0 10px; 82 | -o-box-shadow: #333 0 0 10px; 83 | -moz-box-shadow: #333 0 0 10px; 84 | box-shadow: #333 0 0 10px; 85 | } 86 | 87 | .footer { 88 | margin: 4px; 89 | font-size: 13px; 90 | } 91 | -------------------------------------------------------------------------------- /examples/particles/style.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | text-align: center; 3 | font-family: 'Crimson Text', Verdana; 4 | margin: 0; 5 | padding: 0; 6 | } 7 | 8 | input, select { 9 | font-size: 15px; 10 | font-family: 'Crimson Text', Verdana; 11 | max-width: 80px; 12 | } 13 | 14 | canvas { 15 | background: black; 16 | } 17 | 18 | #fxy { 19 | width: 550px; 20 | max-width: 550px; 21 | } 22 | 23 | input.error { 24 | background: #ffdddd; 25 | } 26 | 27 | #container { 28 | margin: auto 10px; 29 | } 30 | 31 | body.no-webgl #container { 32 | display: none; 33 | } 34 | 35 | div.fallback { 36 | display: none; 37 | } 38 | 39 | body.no-webgl div.fallback { 40 | display: block; 41 | } 42 | 43 | .description { 44 | width: 200px; 45 | font-size: 13px; 46 | position: absolute; 47 | padding: 5px; 48 | text-align: left; 49 | right: 8px; 50 | top: 8px; 51 | border: 1px solid #ccc; 52 | background-color: rgb(255, 241, 168); 53 | } 54 | 55 | #title { 56 | 57 | } 58 | 59 | h1 { 60 | text-shadow: rgba(0, 0, 0, 0.2) 0 0 3px; 61 | margin: 5px; 62 | } 63 | 64 | .controls { 65 | position: relative; 66 | background: #E0ECFF; 67 | padding: 7px; 68 | border: 1px solid #ccc; 69 | margin: 7px 0; 70 | /* text-align: left;*/ 71 | } 72 | 73 | .controls table tr td { 74 | text-align: left; 75 | margin: auto; 76 | font-size: 15px; 77 | } 78 | 79 | #canvas-container { 80 | margin: auto; 81 | } 82 | 83 | canvas { 84 | -webkit-box-shadow: #333 0 0 10px; 85 | -o-box-shadow: #333 0 0 10px; 86 | -moz-box-shadow: #333 0 0 10px; 87 | box-shadow: #333 0 0 10px; 88 | cursor: move; 89 | } 90 | 91 | .footer { 92 | margin: 4px; 93 | font-size: 13px; 94 | } 95 | -------------------------------------------------------------------------------- /shaders/default.vs.glsl: -------------------------------------------------------------------------------- 1 | #define LIGHT_MAX 4 2 | 3 | attribute vec3 position; 4 | attribute vec3 normal; 5 | attribute vec4 color; 6 | attribute vec2 texCoord1; 7 | 8 | uniform mat4 worldMatrix; 9 | uniform mat4 viewMatrix; 10 | uniform mat4 projectionMatrix; 11 | uniform mat4 worldInverseTransposeMatrix; 12 | 13 | uniform bool enableLights; 14 | uniform vec3 ambientColor; 15 | uniform vec3 directionalColor; 16 | uniform vec3 lightingDirection; 17 | 18 | uniform vec3 pointLocation[LIGHT_MAX]; 19 | uniform vec3 pointColor[LIGHT_MAX]; 20 | uniform int numberPoints; 21 | 22 | varying vec4 vColor; 23 | varying vec2 vTexCoord; 24 | varying vec3 lightWeighting; 25 | 26 | void main(void) { 27 | vec4 mvPosition = worldMatrix * vec4(position, 1.0); 28 | 29 | if(!enableLights) { 30 | lightWeighting = vec3(1.0, 1.0, 1.0); 31 | } else { 32 | vec3 plightDirection; 33 | vec3 pointWeight = vec3(0.0, 0.0, 0.0); 34 | vec4 transformedNormal = worldInverseTransposeMatrix * vec4(normal, 1.0); 35 | float directionalLightWeighting = max(dot(transformedNormal.xyz, lightingDirection), 0.0); 36 | for (int i = 0; i < LIGHT_MAX; i++) { 37 | if (i < numberPoints) { 38 | plightDirection = normalize((viewMatrix * vec4(pointLocation[i], 1.0)).xyz - mvPosition.xyz); 39 | pointWeight += max(dot(transformedNormal.xyz, plightDirection), 0.0) * pointColor[i]; 40 | } else { 41 | break; 42 | } 43 | } 44 | 45 | lightWeighting = ambientColor + (directionalColor * directionalLightWeighting) + pointWeight; 46 | } 47 | 48 | vColor = color; 49 | vTexCoord = texCoord1; 50 | gl_Position = projectionMatrix * worldMatrix * vec4(position, 1.0); 51 | } 52 | -------------------------------------------------------------------------------- /examples/lessons/6/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 6 5 | 6 | 7 | 8 | 9 | 10 | 11 | 24 | 25 | 40 | 41 | 42 | 43 | 44 | 45 |

Controls:

46 | 47 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Important 2 | ==================================== 3 | 4 | Work on PhiloGL has been discontinued since Sep 2012. An updated framework with similar notions is being developed [here](https://github.com/uber-common/luma.gl). 5 | 6 | PhiloGL: A JavaScript WebGL Framework 7 | ===================================== 8 | 9 | Author: [Nicolas Garcia Belmonte](http://philogb.github.com/). More information in the [home page of the project](http://senchalabs.github.com/philogl/)! 10 | 11 | Copyright (c) Sencha Labs (http://senchalabs.org/). 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in 21 | all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | THE SOFTWARE. 30 | 31 | -------------------------------------------------------------------------------- /examples/picking/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PhiloGL - Picking Test 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 |

Picking Test

15 |
16 | 17 |
18 | Shapes, picking and fog test. (Because of the configuration, not a lib limitation!) Cones and Spheres are pickable only. 19 |
20 | 21 |
22 | 23 |
24 | 25 | 28 | 29 |
30 | 31 |
32 | 33 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /examples/particles/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PhiloGL - Surface Explorer 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 |

Ripples

15 |
16 | 17 |
18 | Using floating point buffers and vertex shader textures to simulate ripples and waves. 19 |
20 | 21 |
22 | 23 | 24 |
25 | 26 | 29 | 30 |
31 | 32 |
33 | 34 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /examples/particles/simulation.fs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | #define WAVES_LENGTH 2 6 | #define POINTS_LENGTH 12 7 | 8 | /*uniform float opacity;*/ 9 | uniform sampler2D sampler1; 10 | 11 | uniform float timer; 12 | varying vec2 vTexCoord1; 13 | 14 | uniform vec4 waves[WAVES_LENGTH]; 15 | uniform vec4 points[POINTS_LENGTH]; 16 | 17 | float rand(vec2 co){ 18 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 19 | } 20 | 21 | void main(void) { 22 | 23 | vec4 pos = texture2D(sampler1, vTexCoord1); 24 | vec2 p = vTexCoord1; 25 | 26 | float wave = 0.; 27 | vec4 w; 28 | for (int i = 0; i < WAVES_LENGTH; ++i) { 29 | w = waves[i]; 30 | wave += sin(mix(p.s, p.t, w.x) * w.y + timer * w.z) * 0.02; 31 | } 32 | /*pos.y = wave;*/ 33 | 34 | for (int i = 0; i < POINTS_LENGTH; i++) { 35 | vec4 point = points[i]; 36 | float radius = mod(timer * 1.1 + point.z, 50.) / 50.; 37 | float dist = distance(point.xy, p); 38 | if (dist > radius) { 39 | continue; 40 | } 41 | float d = abs(radius - dist); 42 | vec2 diff = (point.xy - p); 43 | wave += sin(dot(diff, diff) * 400. + radius) * 0.2 * pow((1. - radius), 10.) / (d * 10. + 1.); 44 | } 45 | pos.y = wave; 46 | 47 | /*if ( pos.w <= 0.0 ) discard;*/ 48 | 49 | /*float x = pos.x + timer * 5.0;*/ 50 | /*float y = pos.y;*/ 51 | /*float z = pos.z + timer * 4.0;*/ 52 | 53 | /*pos.x += sin( y * 0.033 ) * cos( z * 0.037 ) * 0.4;*/ 54 | /*pos.y += sin( x * 0.035 ) * cos( x * 0.035 ) * 0.4;*/ 55 | /*pos.z += sin( x * 0.037 ) * cos( y * 0.033 ) * 0.4;*/ 56 | /*pos.w -= 0.00001;*/ 57 | 58 | gl_FragColor = pos; 59 | /*gl_FragColor = vec4(vUv, length(vUv), 1);*/ 60 | /*gl_FragColor = vec4(1, 0, 0, 1);*/ 61 | } 62 | -------------------------------------------------------------------------------- /examples/lessons/1/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | PhiloGL('lesson01-canvas', { 3 | program: { 4 | from: 'ids', 5 | vs: 'shader-vs', 6 | fs: 'shader-fs' 7 | }, 8 | onError: function() { 9 | alert("An error ocurred while loading the application"); 10 | }, 11 | onLoad: function(app) { 12 | var gl = app.gl, 13 | canvas = app.canvas, 14 | program = app.program, 15 | camera = app.camera; 16 | 17 | gl.viewport(0, 0, canvas.width, canvas.height); 18 | gl.clearColor(0, 0, 0, 1); 19 | gl.clearDepth(1); 20 | gl.enable(gl.DEPTH_TEST); 21 | gl.depthFunc(gl.LEQUAL); 22 | 23 | program.setBuffers({ 24 | 'triangle': { 25 | attribute: 'aVertexPosition', 26 | value: new Float32Array([0, 1, 0, -1, -1, 0, 1, -1, 0]), 27 | size: 3 28 | }, 29 | 30 | 'square': { 31 | attribute: 'aVertexPosition', 32 | value: new Float32Array([1, 1, 0, -1, 1, 0, 1, -1, 0, -1, -1, 0]), 33 | size: 3 34 | } 35 | }); 36 | 37 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 38 | camera.view.id(); 39 | //Draw Triangle 40 | camera.view.$translate(-1.5, 0, -7); 41 | program.setUniform('uMVMatrix', camera.view); 42 | program.setUniform('uPMatrix', camera.projection); 43 | program.setBuffer('triangle'); 44 | gl.drawArrays(gl.TRIANGLES, 0, 3); 45 | 46 | //Draw Square 47 | camera.view.$translate(3, 0, 0); 48 | program.setUniform('uMVMatrix', camera.view); 49 | program.setUniform('uPMatrix', camera.projection); 50 | program.setBuffer('square'); 51 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); 52 | } 53 | }); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /examples/lessons/7/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 7 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Use lighting
18 | (Use cursor keys to spin the box and Page Up/Page Down to zoom out/in) 19 | 20 |
21 |

Directional light:

22 | 23 | 24 | 25 | 30 | 31 | 36 |
Direction: 26 | X: 27 | Y: 28 | Z: 29 |
Colour: 32 | R: 33 | G: 34 | B: 35 |
37 | 38 |

Ambient light:

39 | 40 | 41 | 46 |
Colour: 42 | R: 43 | G: 44 | B: 45 |
47 | 48 | << Back to Lesson 7 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/lessons/12/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 12 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Use lighting
18 | 19 |
20 |

Point light:

21 | 22 | 23 | 24 | 29 | 30 | 35 |
Location: 25 | X: 26 | Y: 27 | Z: 28 |
Colour: 31 | R: 32 | G: 33 | B: 34 |
36 | 37 |

Ambient light:

38 | 39 | 40 | 45 |
Colour: 41 | R: 42 | G: 43 | B: 44 |
46 | 47 | 48 |
49 | Moon texture courtesy of the Jet Propulsion Laboratory. 50 |
51 |
52 | 53 | << Back to Lesson 12
54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /examples/lessons/11/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 11 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | Use lighting
19 | Spin the moon by dragging it with the mouse. 20 | 21 |
22 |

Directional light:

23 | 24 | 25 | 26 | 31 | 32 | 37 |
Direction: 27 | X: 28 | Y: 29 | Z: 30 |
Colour: 33 | R: 34 | G: 35 | B: 36 |
38 | 39 |

Ambient light:

40 | 41 | 42 | 47 |
Colour: 43 | R: 44 | G: 45 | B: 46 |
48 | 49 | 50 |
51 | Moon texture courtesy of the Jet Propulsion Laboratory. 52 |
53 |
54 | 55 | << Back to Lesson 11
56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /examples/lessons/8/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 8 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | Use blending
18 | Alpha level
19 | 20 |
21 | Use lighting
22 | (Use cursor keys to spin the box and Page Up/Page Down to zoom out/in) 23 | 24 |
25 |

Directional light:

26 | 27 | 28 | 29 | 34 | 35 | 40 |
Direction: 30 | X: 31 | Y: 32 | Z: 33 |
Colour: 36 | R: 37 | G: 38 | B: 39 |
41 | 42 |

Ambient light:

43 | 44 | 45 | 50 |
Colour: 46 | R: 47 | G: 48 | B: 49 |
51 | 52 | << Back to Lesson 7 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /examples/particles/graph-compute.js: -------------------------------------------------------------------------------- 1 | //Unpack Math Functions 2 | var that = this; 3 | ['sin', 'cos', 'tan', 'atan', 'max', 'min', 4 | 'acos', 'asin', 'exp', 'log', 'pow', 'sqrt', 'floor', 'ceil', 5 | 'PI', 'E', 'abs'].forEach(function (f) { that[f] = Math[f]; }); 6 | 7 | function sampler(grid, fn) { 8 | var x = grid.x, 9 | xFrom = x.from, 10 | xTo = x.to, 11 | xStep = x.step, 12 | y = grid.y, 13 | yFrom = y.from, 14 | yTo = y.to, 15 | yStep = y.step, 16 | vertices = [], 17 | normals = [], 18 | z, v1, v2, n, d; 19 | 20 | for (x = xFrom; x < xTo; x += xStep) { 21 | for (y = yFrom; y < yTo; y += yStep) { 22 | //get value from fn 23 | z = fn(x, y); 24 | //add vertex 25 | vertices.push(x, y, z); 26 | //calculate normal 27 | v1 = [xStep, 0, fn(x + xStep, y) - z]; 28 | v2 = [0, yStep, fn(x, y + yStep) - z]; 29 | n = [v1[1] * v2[2] - v1[2] * v2[1], 30 | v1[2] * v2[0] - v1[0] * v2[2], 31 | v1[0] * v2[1] - v1[1] * v2[0]]; 32 | d = sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]); 33 | if (d > 1e-6) { 34 | normals.push(n[0] / d, n[1] / d, n[2] / d); 35 | } else { 36 | normals.push(n[0], n[1], n[2]); 37 | } 38 | } 39 | } 40 | 41 | return { 42 | vertices: vertices, 43 | normals: normals 44 | }; 45 | } 46 | 47 | onmessage = function(e) { 48 | var data = e.data, 49 | grid = data.grid, 50 | t = data.t, 51 | body = data.f, 52 | fn, 53 | memofn = (function() { 54 | var memo = {}; 55 | return function(x, y) { 56 | var key = x + '|' + y; 57 | if (key in memo) return memo[key]; 58 | return (memo[key] = fn(x, y)); 59 | }; 60 | })(); 61 | 62 | try { 63 | fn = new Function('x, y', 'var t = ' + t + '; \n return (' + body + ');'); 64 | //evaluate 65 | fn(0, 0); 66 | } catch(e) { 67 | fn = function() { return 0; }; 68 | } 69 | 70 | postMessage(sampler(grid, fn)); 71 | }; 72 | -------------------------------------------------------------------------------- /examples/lessons/2/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | PhiloGL('lesson02-canvas', { 3 | program: { 4 | from: 'ids', 5 | vs: 'shader-vs', 6 | fs: 'shader-fs' 7 | }, 8 | onError: function() { 9 | alert("An error ocurred while loading the application"); 10 | }, 11 | onLoad: function(app) { 12 | var gl = app.gl, 13 | canvas = app.canvas, 14 | program = app.program, 15 | camera = app.camera; 16 | 17 | gl.viewport(0, 0, canvas.width, canvas.height); 18 | gl.clearColor(0, 0, 0, 1); 19 | gl.clearDepth(1); 20 | gl.enable(gl.DEPTH_TEST); 21 | gl.depthFunc(gl.LEQUAL); 22 | 23 | program.setBuffers({ 24 | 'triangle': { 25 | attribute: 'aVertexPosition', 26 | value: new Float32Array([0, 1, 0, -1, -1, 0, 1, -1, 0]), 27 | size: 3 28 | }, 29 | 30 | 'triangleColors': { 31 | attribute: 'aVertexColor', 32 | value: new Float32Array([1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1]), 33 | size: 4 34 | }, 35 | 36 | 'square': { 37 | attribute: 'aVertexPosition', 38 | value: new Float32Array([1, 1, 0, -1, 1, 0, 1, -1, 0, -1, -1, 0]), 39 | size: 3 40 | }, 41 | 42 | 'squareColors': { 43 | attribute: 'aVertexColor', 44 | value: new Float32Array([0.5, 0.5, 1, 1, 0.5, 0.5, 1, 1, 0.5, 0.5, 1, 1, 0.5, 0.5, 1, 1]), 45 | size: 4 46 | } 47 | }); 48 | 49 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 50 | camera.view.id(); 51 | //Draw Triangle 52 | camera.view.$translate(-1.5, 0, -7); 53 | program.setUniform('uMVMatrix', camera.view); 54 | program.setUniform('uPMatrix', camera.projection); 55 | program.setBuffer('triangle'); 56 | program.setBuffer('triangleColors'); 57 | gl.drawArrays(gl.TRIANGLES, 0, 3); 58 | 59 | //Draw Square 60 | camera.view.$translate(3, 0, 0); 61 | program.setUniform('uMVMatrix', camera.view); 62 | program.setUniform('uPMatrix', camera.projection); 63 | program.setBuffer('square'); 64 | program.setBuffer('squareColors'); 65 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); 66 | } 67 | }); 68 | } 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /examples/lessons/15/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 15 5 | 6 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | Show color map
26 | Show specular map
27 | Use lighting
28 | 29 |

Point light:

30 | 31 | 32 | 37 | 38 | 43 | 44 | 49 |
Location: 33 | X: 34 | Y: 35 | Z: 36 |
Specular colour: 39 | R: 40 | G: 41 | B: 42 |
Diffuse colour: 45 | R: 46 | G: 47 | B: 48 |
50 | 51 |

Ambient light:

52 | 53 | 54 | 59 |
Colour: 55 | R: 56 | G: 57 | B: 58 |
60 | 61 |
62 | Galvanized texture courtesy of Arroway Textures.
63 | Earth texture courtesy of the European Space Agency/Envisat.
64 |
65 | 66 | << Back to Lesson 15
67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /examples/lessons/14/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 14 5 | 6 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | Show specular highlight
26 | Use lighting
27 | Texture: 28 | 33 | 34 |
35 |

Material:

36 | 37 | 38 | 39 | 42 |
Shininess: 40 | 41 |
43 | 44 |

Point light:

45 | 46 | 47 | 48 | 53 | 54 | 59 | 60 | 65 |
Location: 49 | X: 50 | Y: 51 | Z: 52 |
Specular colour: 55 | R: 56 | G: 57 | B: 58 |
Diffuse colour: 61 | R: 62 | G: 63 | B: 64 |
66 | 67 |

Ambient light:

68 | 69 | 70 | 75 |
Colour: 71 | R: 72 | G: 73 | B: 74 |
76 | 77 | 78 |
79 | Galvanized texture courtesy of Arroway Textures.
80 | Earth texture courtesy of the European Space Agency/Envisat.
81 |
82 | 83 | << Back to Lesson 14
84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /shaders/render-tex.fs.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | #define LIGHT_MAX 4 6 | 7 | varying vec2 vTexCoord1; 8 | varying vec2 vTexCoord2; 9 | varying vec2 vTexCoord3; 10 | varying vec4 vColor; 11 | varying vec4 vTransformedNormal; 12 | varying vec4 vPosition; 13 | 14 | uniform float shininess; 15 | uniform bool enableSpecularHighlights; 16 | 17 | uniform vec3 ambientColor; 18 | uniform vec3 directionalColor; 19 | uniform vec3 lightingDirection; 20 | 21 | uniform vec3 pointLocation[LIGHT_MAX]; 22 | uniform vec3 pointColor[LIGHT_MAX]; 23 | uniform vec3 pointSpecularColor[LIGHT_MAX]; 24 | uniform int numberPoints; 25 | 26 | uniform vec3 materialAmbientColor; 27 | uniform vec3 materialDiffuseColor; 28 | uniform vec3 materialSpecularColor; 29 | uniform vec3 materialEmissiveColor; 30 | 31 | uniform bool hasTexture1; 32 | uniform sampler2D sampler1; 33 | 34 | uniform mat4 viewMatrix; 35 | 36 | void main(void) { 37 | vec3 ambientLightWeighting = ambientColor; 38 | 39 | vec3 lightDirection; 40 | float specularLightWeighting = 0.0; 41 | float diffuseLightWeighting = 0.0; 42 | vec3 specularLight = vec3(0.0, 0.0, 0.0); 43 | vec3 diffuseLight = vec3(0.0, 0.0, 0.0); 44 | 45 | vec3 transformedPointLocation; 46 | vec3 normal = vTransformedNormal.xyz; 47 | 48 | vec3 eyeDirection = normalize(-vPosition.xyz); 49 | vec3 reflectionDirection; 50 | 51 | for (int i = 0; i < LIGHT_MAX; i++) { 52 | if (i < numberPoints) { 53 | transformedPointLocation = (viewMatrix * vec4(pointLocation[i], 1.0)).xyz; 54 | lightDirection = normalize(transformedPointLocation - vPosition.xyz); 55 | 56 | if (enableSpecularHighlights) { 57 | reflectionDirection = reflect(-lightDirection, normal); 58 | specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), shininess); 59 | specularLight += specularLightWeighting * pointSpecularColor[i]; 60 | } 61 | 62 | diffuseLightWeighting = max(dot(normal, lightDirection), 0.0); 63 | diffuseLight += diffuseLightWeighting * pointColor[i]; 64 | } else { 65 | break; 66 | } 67 | } 68 | 69 | vec3 matAmbientColor = materialAmbientColor; 70 | vec3 matDiffuseColor = materialDiffuseColor; 71 | vec3 matSpecularColor = materialSpecularColor; 72 | vec3 matEmissiveColor = materialEmissiveColor; 73 | float alpha = 1.0; 74 | if (hasTexture1) { 75 | vec4 textureColor = texture2D(sampler1, vec2(vTexCoord1.s, vTexCoord1.t)); 76 | matAmbientColor = matAmbientColor * textureColor.rgb; 77 | matDiffuseColor = matDiffuseColor * textureColor.rgb; 78 | matEmissiveColor = matEmissiveColor * textureColor.rgb; 79 | alpha = textureColor.a; 80 | } 81 | gl_FragColor = vec4( 82 | matAmbientColor * ambientLightWeighting 83 | + matDiffuseColor * diffuseLightWeighting 84 | + matSpecularColor * specularLightWeighting 85 | + matEmissiveColor, 86 | alpha 87 | ); 88 | } 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /shaders/spec-map.fs.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | #define LIGHT_MAX 4 6 | 7 | varying vec2 vTexCoord1; 8 | varying vec2 vTexCoord2; 9 | varying vec2 vTexCoord3; 10 | varying vec4 vColor; 11 | varying vec4 vTransformedNormal; 12 | varying vec4 vPosition; 13 | 14 | uniform float shininess; 15 | uniform bool enableSpecularMap; 16 | uniform bool enableColorMap; 17 | uniform bool enableLights; 18 | 19 | uniform vec3 ambientColor; 20 | uniform vec3 directionalColor; 21 | uniform vec3 lightingDirection; 22 | 23 | uniform vec3 pointLocation[LIGHT_MAX]; 24 | uniform vec3 pointColor[LIGHT_MAX]; 25 | uniform vec3 pointSpecularColor[LIGHT_MAX]; 26 | uniform float enableSpecular[LIGHT_MAX]; 27 | uniform int numberPoints; 28 | 29 | uniform bool hasTexture1; 30 | uniform sampler2D sampler1; 31 | 32 | uniform bool hasTexture2; 33 | uniform sampler2D sampler2; 34 | 35 | uniform bool hasTexture3; 36 | uniform sampler2D sampler3; 37 | 38 | uniform mat4 viewMatrix; 39 | 40 | void main(void) { 41 | vec3 lightWeighting; 42 | if (!enableLights) { 43 | lightWeighting = vec3(1.0, 1.0, 1.0); 44 | } else { 45 | vec3 lightDirection; 46 | float specularLightWeighting = 0.0; 47 | float diffuseLightWeighting = 0.0; 48 | vec3 specularLight = vec3(0.0, 0.0, 0.0); 49 | vec3 diffuseLight = vec3(0.0, 0.0, 0.0); 50 | 51 | vec3 transformedPointLocation; 52 | vec3 normal = vTransformedNormal.xyz; 53 | 54 | vec3 eyeDirection = normalize(-vPosition.xyz); 55 | vec3 reflectionDirection; 56 | 57 | float shininessVal = shininess; 58 | if (enableSpecularMap) { 59 | shininessVal = texture2D(sampler2, vec2(vTexCoord1.s, vTexCoord1.t)).r * 255.0; 60 | } 61 | 62 | if (shininessVal > 255.0) { 63 | shininessVal = shininess; 64 | } 65 | 66 | for (int i = 0; i < LIGHT_MAX; i++) { 67 | if (i < numberPoints) { 68 | transformedPointLocation = (viewMatrix * vec4(pointLocation[i], 1.0)).xyz; 69 | lightDirection = normalize(transformedPointLocation - vPosition.xyz); 70 | 71 | if (enableSpecular[i] > 0.0) { 72 | reflectionDirection = reflect(-lightDirection, normal); 73 | specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), shininessVal); 74 | specularLight += specularLightWeighting * pointSpecularColor[i]; 75 | } 76 | 77 | diffuseLightWeighting = max(dot(normal, lightDirection), 0.0); 78 | diffuseLight += diffuseLightWeighting * pointColor[i]; 79 | } else { 80 | break; 81 | } 82 | } 83 | 84 | lightWeighting = ambientColor + diffuseLight + specularLight; 85 | } 86 | 87 | vec4 fragmentColor = vec4(0.0, 0.0, 0.0, 0.0); 88 | if (enableColorMap) { 89 | fragmentColor += texture2D(sampler1, vec2(vTexCoord1.s, vTexCoord1.t)); 90 | } else { 91 | fragmentColor = vColor; 92 | } 93 | gl_FragColor = vec4(fragmentColor.rgb * lightWeighting, fragmentColor.a); 94 | } 95 | 96 | -------------------------------------------------------------------------------- /shaders/frag-lighting.fs.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | #define LIGHT_MAX 4 6 | 7 | varying vec2 vTexCoord1; 8 | varying vec2 vTexCoord2; 9 | varying vec2 vTexCoord3; 10 | varying vec4 vColor; 11 | varying vec4 vTransformedNormal; 12 | varying vec4 vPosition; 13 | 14 | uniform float shininess; 15 | uniform bool enableSpecularHighlights; 16 | uniform bool enableLights; 17 | 18 | uniform vec3 ambientColor; 19 | uniform vec3 directionalColor; 20 | uniform vec3 lightingDirection; 21 | 22 | uniform vec3 pointLocation[LIGHT_MAX]; 23 | uniform vec3 pointColor[LIGHT_MAX]; 24 | uniform vec3 pointSpecularColor[LIGHT_MAX]; 25 | uniform float enableSpecular[LIGHT_MAX]; 26 | uniform int numberPoints; 27 | 28 | uniform bool hasTexture1; 29 | uniform sampler2D sampler1; 30 | 31 | uniform bool hasTexture2; 32 | uniform sampler2D sampler2; 33 | 34 | uniform bool hasTexture3; 35 | uniform sampler2D sampler3; 36 | 37 | uniform mat4 viewMatrix; 38 | 39 | void main(void) { 40 | vec3 lightWeighting; 41 | if (!enableLights) { 42 | lightWeighting = vec3(1.0, 1.0, 1.0); 43 | } else { 44 | vec3 lightDirection; 45 | float specularLightWeighting = 0.0; 46 | float diffuseLightWeighting = 0.0; 47 | vec3 specularLight = vec3(0.0, 0.0, 0.0); 48 | vec3 diffuseLight = vec3(0.0, 0.0, 0.0); 49 | 50 | vec3 transformedPointLocation; 51 | vec3 normal = vTransformedNormal.xyz; 52 | 53 | vec3 eyeDirection = normalize(-vPosition.xyz); 54 | vec3 reflectionDirection; 55 | 56 | vec3 pointWeight = vec3(0.0, 0.0, 0.0); 57 | 58 | for (int i = 0; i < LIGHT_MAX; i++) { 59 | if (i < numberPoints) { 60 | transformedPointLocation = (viewMatrix * vec4(pointLocation[i], 1.0)).xyz; 61 | lightDirection = normalize(transformedPointLocation - vPosition.xyz); 62 | 63 | if (enableSpecular[i] > 0.0) { 64 | reflectionDirection = reflect(-lightDirection, normal); 65 | specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), shininess); 66 | specularLight += specularLightWeighting * pointSpecularColor[i]; 67 | } 68 | 69 | diffuseLightWeighting = max(dot(normal, lightDirection), 0.0); 70 | diffuseLight += diffuseLightWeighting * pointColor[i]; 71 | } else { 72 | break; 73 | } 74 | } 75 | 76 | lightWeighting = ambientColor + diffuseLight + specularLight; 77 | } 78 | 79 | vec4 fragmentColor = vec4(0.0, 0.0, 0.0, 0.0); 80 | if (hasTexture1 || hasTexture2 || hasTexture3) { 81 | if (hasTexture1) { 82 | fragmentColor += texture2D(sampler1, vec2(vTexCoord1.s, vTexCoord1.t)); 83 | } 84 | if (hasTexture2) { 85 | fragmentColor += texture2D(sampler2, vec2(vTexCoord2.s, vTexCoord2.t)); 86 | } 87 | if (hasTexture3) { 88 | fragmentColor += texture2D(sampler3, vec2(vTexCoord3.s, vTexCoord3.t)); 89 | } 90 | } else { 91 | fragmentColor = vColor; 92 | } 93 | gl_FragColor = vec4(fragmentColor.rgb * lightWeighting, fragmentColor.a); 94 | } 95 | -------------------------------------------------------------------------------- /examples/lessons/3/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | //Load models 3 | var triangle = new PhiloGL.O3D.Model({ 4 | vertices: [ 0, 1, 0, 5 | -1, -1, 0, 6 | 1, -1, 0], 7 | 8 | colors: [1, 0, 0, 1, 9 | 0, 1, 0, 1, 10 | 0, 0, 1, 1] 11 | }); 12 | 13 | var square = new PhiloGL.O3D.Model({ 14 | vertices: [ 1, 1, 0, 15 | -1, 1, 0, 16 | 1, -1, 0, 17 | -1, -1, 0], 18 | 19 | colors: [0.5, 0.5, 1, 1, 20 | 0.5, 0.5, 1, 1, 21 | 0.5, 0.5, 1, 1, 22 | 0.5, 0.5, 1, 1] 23 | }); 24 | 25 | //Create App 26 | PhiloGL('lesson03-canvas', { 27 | program: { 28 | from: 'ids', 29 | vs: 'shader-vs', 30 | fs: 'shader-fs' 31 | }, 32 | onError: function() { 33 | alert("An error ocurred while loading the application"); 34 | }, 35 | onLoad: function(app) { 36 | var gl = app.gl, 37 | canvas = app.canvas, 38 | program = app.program, 39 | camera = app.camera, 40 | view = new PhiloGL.Mat4, 41 | rTri = 0, rSquare = 0; 42 | 43 | gl.viewport(0, 0, canvas.width, canvas.height); 44 | gl.clearColor(0, 0, 0, 1); 45 | gl.clearDepth(1); 46 | gl.enable(gl.DEPTH_TEST); 47 | gl.depthFunc(gl.LEQUAL); 48 | 49 | camera.view.id(); 50 | 51 | function setupElement(elem) { 52 | //update element matrix 53 | elem.update(); 54 | //get new view matrix out of element and camera matrices 55 | view.mulMat42(camera.view, elem.matrix); 56 | //set buffers with element data 57 | program.setBuffers({ 58 | 'aVertexPosition': { 59 | value: elem.vertices, 60 | size: 3 61 | }, 62 | 63 | 'aVertexColor': { 64 | value: elem.colors, 65 | size: 4 66 | } 67 | }); 68 | //set uniforms 69 | program.setUniform('uMVMatrix', view); 70 | program.setUniform('uPMatrix', camera.projection); 71 | } 72 | 73 | function animate() { 74 | rTri += 0.01; 75 | rSquare += 0.1; 76 | } 77 | 78 | function tick() { 79 | drawScene(); 80 | animate(); 81 | PhiloGL.Fx.requestAnimationFrame(tick); 82 | } 83 | 84 | function drawScene() { 85 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 86 | 87 | //Draw triangle 88 | triangle.position.set(-1.5, 0, -7); 89 | triangle.rotation.set(0, rTri, 0); 90 | setupElement(triangle); 91 | gl.drawArrays(gl.TRIANGLES, 0, 3); 92 | 93 | //Draw Square 94 | square.position.set(1.5, 0, -7); 95 | square.rotation.set(rSquare, 0, 0); 96 | setupElement(square); 97 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); 98 | } 99 | 100 | tick(); 101 | } 102 | }); 103 | 104 | } 105 | 106 | 107 | -------------------------------------------------------------------------------- /examples/lessons/10/world.txt: -------------------------------------------------------------------------------- 1 | 2 | NUMPOLLIES 36 3 | 4 | // Floor 1 5 | -3.0 0.0 -3.0 0.0 6.0 6 | -3.0 0.0 3.0 0.0 0.0 7 | 3.0 0.0 3.0 6.0 0.0 8 | 9 | -3.0 0.0 -3.0 0.0 6.0 10 | 3.0 0.0 -3.0 6.0 6.0 11 | 3.0 0.0 3.0 6.0 0.0 12 | 13 | // Ceiling 1 14 | -3.0 1.0 -3.0 0.0 6.0 15 | -3.0 1.0 3.0 0.0 0.0 16 | 3.0 1.0 3.0 6.0 0.0 17 | -3.0 1.0 -3.0 0.0 6.0 18 | 3.0 1.0 -3.0 6.0 6.0 19 | 3.0 1.0 3.0 6.0 0.0 20 | 21 | // A1 22 | 23 | -2.0 1.0 -2.0 0.0 1.0 24 | -2.0 0.0 -2.0 0.0 0.0 25 | -0.5 0.0 -2.0 1.5 0.0 26 | -2.0 1.0 -2.0 0.0 1.0 27 | -0.5 1.0 -2.0 1.5 1.0 28 | -0.5 0.0 -2.0 1.5 0.0 29 | 30 | // A2 31 | 32 | 2.0 1.0 -2.0 2.0 1.0 33 | 2.0 0.0 -2.0 2.0 0.0 34 | 0.5 0.0 -2.0 0.5 0.0 35 | 2.0 1.0 -2.0 2.0 1.0 36 | 0.5 1.0 -2.0 0.5 1.0 37 | 0.5 0.0 -2.0 0.5 0.0 38 | 39 | // B1 40 | 41 | -2.0 1.0 2.0 2.0 1.0 42 | -2.0 0.0 2.0 2.0 0.0 43 | -0.5 0.0 2.0 0.5 0.0 44 | -2.0 1.0 2.0 2.0 1.0 45 | -0.5 1.0 2.0 0.5 1.0 46 | -0.5 0.0 2.0 0.5 0.0 47 | 48 | // B2 49 | 50 | 2.0 1.0 2.0 2.0 1.0 51 | 2.0 0.0 2.0 2.0 0.0 52 | 0.5 0.0 2.0 0.5 0.0 53 | 2.0 1.0 2.0 2.0 1.0 54 | 0.5 1.0 2.0 0.5 1.0 55 | 0.5 0.0 2.0 0.5 0.0 56 | 57 | // C1 58 | 59 | -2.0 1.0 -2.0 0.0 1.0 60 | -2.0 0.0 -2.0 0.0 0.0 61 | -2.0 0.0 -0.5 1.5 0.0 62 | -2.0 1.0 -2.0 0.0 1.0 63 | -2.0 1.0 -0.5 1.5 1.0 64 | -2.0 0.0 -0.5 1.5 0.0 65 | 66 | // C2 67 | 68 | -2.0 1.0 2.0 2.0 1.0 69 | -2.0 0.0 2.0 2.0 0.0 70 | -2.0 0.0 0.5 0.5 0.0 71 | -2.0 1.0 2.0 2.0 1.0 72 | -2.0 1.0 0.5 0.5 1.0 73 | -2.0 0.0 0.5 0.5 0.0 74 | 75 | // D1 76 | 77 | 2.0 1.0 -2.0 0.0 1.0 78 | 2.0 0.0 -2.0 0.0 0.0 79 | 2.0 0.0 -0.5 1.5 0.0 80 | 2.0 1.0 -2.0 0.0 1.0 81 | 2.0 1.0 -0.5 1.5 1.0 82 | 2.0 0.0 -0.5 1.5 0.0 83 | 84 | // D2 85 | 86 | 2.0 1.0 2.0 2.0 1.0 87 | 2.0 0.0 2.0 2.0 0.0 88 | 2.0 0.0 0.5 0.5 0.0 89 | 2.0 1.0 2.0 2.0 1.0 90 | 2.0 1.0 0.5 0.5 1.0 91 | 2.0 0.0 0.5 0.5 0.0 92 | 93 | // Upper hallway - L 94 | -0.5 1.0 -3.0 0.0 1.0 95 | -0.5 0.0 -3.0 0.0 0.0 96 | -0.5 0.0 -2.0 1.0 0.0 97 | -0.5 1.0 -3.0 0.0 1.0 98 | -0.5 1.0 -2.0 1.0 1.0 99 | -0.5 0.0 -2.0 1.0 0.0 100 | 101 | // Upper hallway - R 102 | 0.5 1.0 -3.0 0.0 1.0 103 | 0.5 0.0 -3.0 0.0 0.0 104 | 0.5 0.0 -2.0 1.0 0.0 105 | 0.5 1.0 -3.0 0.0 1.0 106 | 0.5 1.0 -2.0 1.0 1.0 107 | 0.5 0.0 -2.0 1.0 0.0 108 | 109 | // Lower hallway - L 110 | -0.5 1.0 3.0 0.0 1.0 111 | -0.5 0.0 3.0 0.0 0.0 112 | -0.5 0.0 2.0 1.0 0.0 113 | -0.5 1.0 3.0 0.0 1.0 114 | -0.5 1.0 2.0 1.0 1.0 115 | -0.5 0.0 2.0 1.0 0.0 116 | 117 | // Lower hallway - R 118 | 0.5 1.0 3.0 0.0 1.0 119 | 0.5 0.0 3.0 0.0 0.0 120 | 0.5 0.0 2.0 1.0 0.0 121 | 0.5 1.0 3.0 0.0 1.0 122 | 0.5 1.0 2.0 1.0 1.0 123 | 0.5 0.0 2.0 1.0 0.0 124 | 125 | 126 | // Left hallway - Lw 127 | 128 | -3.0 1.0 0.5 1.0 1.0 129 | -3.0 0.0 0.5 1.0 0.0 130 | -2.0 0.0 0.5 0.0 0.0 131 | -3.0 1.0 0.5 1.0 1.0 132 | -2.0 1.0 0.5 0.0 1.0 133 | -2.0 0.0 0.5 0.0 0.0 134 | 135 | // Left hallway - Hi 136 | 137 | -3.0 1.0 -0.5 1.0 1.0 138 | -3.0 0.0 -0.5 1.0 0.0 139 | -2.0 0.0 -0.5 0.0 0.0 140 | -3.0 1.0 -0.5 1.0 1.0 141 | -2.0 1.0 -0.5 0.0 1.0 142 | -2.0 0.0 -0.5 0.0 0.0 143 | 144 | // Right hallway - Lw 145 | 146 | 3.0 1.0 0.5 1.0 1.0 147 | 3.0 0.0 0.5 1.0 0.0 148 | 2.0 0.0 0.5 0.0 0.0 149 | 3.0 1.0 0.5 1.0 1.0 150 | 2.0 1.0 0.5 0.0 1.0 151 | 2.0 0.0 0.5 0.0 0.0 152 | 153 | // Right hallway - Hi 154 | 155 | 3.0 1.0 -0.5 1.0 1.0 156 | 3.0 0.0 -0.5 1.0 0.0 157 | 2.0 0.0 -0.5 0.0 0.0 158 | 3.0 1.0 -0.5 1.0 1.0 159 | 2.0 1.0 -0.5 0.0 1.0 160 | 2.0 0.0 -0.5 0.0 0.0 -------------------------------------------------------------------------------- /examples/lessons/11/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | var pos, $id = function(d) { return document.getElementById(d); }; 3 | 4 | //Create moon 5 | var moon = new PhiloGL.O3D.Sphere({ 6 | nlat: 30, 7 | nlong: 30, 8 | radius: 2, 9 | textures: 'moon.gif' 10 | }); 11 | 12 | //Create application 13 | PhiloGL('lesson11-canvas', { 14 | camera: { 15 | position: { 16 | x: 0, y: 0, z: -7 17 | } 18 | }, 19 | textures: { 20 | src: ['moon.gif'], 21 | parameters: [{ 22 | name: 'TEXTURE_MAG_FILTER', 23 | value: 'LINEAR' 24 | }, { 25 | name: 'TEXTURE_MIN_FILTER', 26 | value: 'LINEAR_MIPMAP_NEAREST', 27 | generateMipmap: true 28 | }] 29 | }, 30 | events: { 31 | onDragStart: function(e) { 32 | pos = { 33 | x: e.x, 34 | y: e.y 35 | }; 36 | }, 37 | onDragMove: function(e) { 38 | var z = this.camera.position.z, 39 | sign = Math.abs(z) / z; 40 | 41 | moon.rotation.y += -(pos.x - e.x) / 100; 42 | moon.rotation.x += sign * (pos.y - e.y) / 100; 43 | moon.update(); 44 | pos.x = e.x; 45 | pos.y = e.y; 46 | }, 47 | onMouseWheel: function(e) { 48 | e.stop(); 49 | var camera = this.camera; 50 | camera.position.z += e.wheel; 51 | camera.update(); 52 | } 53 | }, 54 | onError: function() { 55 | alert("There was an error creating the app."); 56 | }, 57 | onLoad: function(app) { 58 | //Unpack app properties 59 | var gl = app.gl, 60 | program = app.program, 61 | scene = app.scene, 62 | canvas = app.canvas, 63 | camera = app.camera, 64 | //get light config from forms 65 | lighting = $id('lighting'), 66 | ambient = { 67 | r: $id('ambientR'), 68 | g: $id('ambientG'), 69 | b: $id('ambientB') 70 | }, 71 | direction = { 72 | x: $id('lightDirectionX'), 73 | y: $id('lightDirectionY'), 74 | z: $id('lightDirectionZ'), 75 | 76 | r: $id('directionalR'), 77 | g: $id('directionalG'), 78 | b: $id('directionalB') 79 | }; 80 | 81 | //Basic gl setup 82 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 83 | gl.clearDepth(1.0); 84 | gl.enable(gl.DEPTH_TEST); 85 | gl.depthFunc(gl.LEQUAL); 86 | gl.viewport(0, 0, +canvas.width, +canvas.height); 87 | //Add object to the scene 88 | scene.add(moon); 89 | //Animate 90 | draw(); 91 | 92 | //Draw the scene 93 | function draw() { 94 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 95 | //Setup lighting 96 | var lights = scene.config.lights; 97 | lights.enable = lighting.checked; 98 | lights.ambient = { 99 | r: +ambient.r.value, 100 | g: +ambient.g.value, 101 | b: +ambient.b.value 102 | }; 103 | lights.directional = { 104 | color: { 105 | r: +direction.r.value, 106 | g: +direction.g.value, 107 | b: +direction.b.value 108 | }, 109 | direction: { 110 | x: +direction.x.value, 111 | y: +direction.y.value, 112 | z: +direction.z.value 113 | } 114 | }; 115 | //render moon 116 | scene.render(); 117 | //request new frame 118 | PhiloGL.Fx.requestAnimationFrame(draw); 119 | } 120 | } 121 | }); 122 | } 123 | -------------------------------------------------------------------------------- /examples/lessons/13/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Learning WebGL — lesson 13 5 | 6 | 7 | 8 | 9 | 10 | 11 | 51 | 52 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 | Use lighting
81 | Per-fragment lighting
82 | Use textures
83 | 84 |
85 |

Point light:

86 | 87 | 88 | 89 | 94 | 95 | 100 |
Location: 90 | X: 91 | Y: 92 | Z: 93 |
Colour: 96 | R: 97 | G: 98 | B: 99 |
101 | 102 |

Ambient light:

103 | 104 | 105 | 110 |
Colour: 106 | R: 107 | G: 108 | B: 109 |
111 | 112 | 113 |
114 | Moon texture courtesy of the Jet Propulsion Laboratory. 115 |
116 |
117 | 118 | << Back to Lesson 13
119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /examples/lessons/15/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | var $id = function(d) { return document.getElementById(d); }; 3 | 4 | //Create moon 5 | var earth = new PhiloGL.O3D.Sphere({ 6 | nlat: 30, 7 | nlong: 30, 8 | radius: 2, 9 | uniforms: { 10 | shininess: 32 11 | }, 12 | textures: ['earth.jpg', 'earth-specular.gif'], 13 | colors: [1, 1, 1, 1] 14 | }); 15 | 16 | //Create application 17 | PhiloGL('lesson15-canvas', { 18 | program: { 19 | from: 'uris', 20 | path: '../../../shaders/', 21 | vs: 'spec-map.vs.glsl', 22 | fs: 'spec-map.fs.glsl' 23 | }, 24 | camera: { 25 | position: { 26 | x: 0, y: 0, z: -6 27 | } 28 | }, 29 | textures: { 30 | src: ['earth.jpg', 'earth-specular.gif'], 31 | parameters: [{ 32 | name: 'TEXTURE_MAG_FILTER', 33 | value: 'LINEAR' 34 | }, { 35 | name: 'TEXTURE_MIN_FILTER', 36 | value: 'LINEAR_MIPMAP_NEAREST', 37 | generateMipmap: true 38 | }] 39 | }, 40 | onError: function() { 41 | alert("There was an error creating the app."); 42 | }, 43 | onLoad: function(app) { 44 | //Unpack app properties 45 | var gl = app.gl, 46 | scene = app.scene, 47 | canvas = app.canvas, 48 | //enable specular, color map 49 | specularMap = $id('specular-map'), 50 | colorMap = $id('color-map'), 51 | //get light config from forms 52 | lighting = $id('lighting'), 53 | ambient = { 54 | r: $id('ambientR'), 55 | g: $id('ambientG'), 56 | b: $id('ambientB') 57 | }, 58 | point = { 59 | x: $id('lightPositionX'), 60 | y: $id('lightPositionY'), 61 | z: $id('lightPositionZ'), 62 | 63 | sr: $id('specularR'), 64 | sg: $id('specularG'), 65 | sb: $id('specularB'), 66 | 67 | dr: $id('diffuseR'), 68 | dg: $id('diffuseG'), 69 | db: $id('diffuseB') 70 | }, 71 | //object rotation 72 | theta = 0; 73 | 74 | //onBeforeRender 75 | earth.onBeforeRender = function(program, camera) { 76 | program.setUniform('enableSpecularMap', specularMap.checked); 77 | program.setUniform('enableColorMap', colorMap.checked); 78 | }; 79 | 80 | //Basic gl setup 81 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 82 | gl.clearDepth(1.0); 83 | gl.enable(gl.DEPTH_TEST); 84 | gl.depthFunc(gl.LEQUAL); 85 | gl.viewport(0, 0, +canvas.width, +canvas.height); 86 | //Add objects to the scene 87 | scene.add(earth); 88 | //Animate 89 | draw(); 90 | 91 | //Draw the scene 92 | function draw() { 93 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 94 | //Setup lighting 95 | var lights = scene.config.lights; 96 | lights.enable = lighting.checked; 97 | lights.ambient = { 98 | r: +ambient.r.value, 99 | g: +ambient.g.value, 100 | b: +ambient.b.value 101 | }; 102 | lights.points = { 103 | diffuse: { 104 | r: +point.dr.value, 105 | g: +point.dg.value, 106 | b: +point.db.value 107 | }, 108 | specular: { 109 | r: +point.sr.value, 110 | g: +point.sg.value, 111 | b: +point.sb.value 112 | }, 113 | position: { 114 | x: +point.x.value, 115 | y: +point.y.value, 116 | z: +point.z.value 117 | } 118 | }; 119 | 120 | //Update position 121 | theta += 0.01; 122 | earth.rotation.set(Math.PI, theta, 0.1); 123 | earth.update(); 124 | 125 | //render objects 126 | scene.render(); 127 | 128 | //request new frame 129 | PhiloGL.Fx.requestAnimationFrame(draw); 130 | } 131 | } 132 | }); 133 | } 134 | 135 | 136 | -------------------------------------------------------------------------------- /examples/lessons/12/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | var pos, $id = function(d) { return document.getElementById(d); }; 3 | 4 | //Create moon 5 | var moon = new PhiloGL.O3D.Sphere({ 6 | nlat: 30, 7 | nlong: 30, 8 | radius: 2, 9 | textures: 'moon.gif' 10 | }); 11 | //Create box 12 | var box = new PhiloGL.O3D.Cube({ 13 | textures: 'crate.gif' 14 | }); 15 | box.scale.set(2, 2, 2); 16 | 17 | //Create application 18 | PhiloGL('lesson12-canvas', { 19 | camera: { 20 | position: { 21 | x: 0, y: 0, z: 30 22 | } 23 | }, 24 | scene: { 25 | lights: { 26 | directional: { 27 | color: { 28 | r: 0, g: 0, b: 0 29 | }, 30 | direction: { 31 | x: 0, y: 0, z: 0 32 | } 33 | } 34 | } 35 | }, 36 | textures: { 37 | src: ['moon.gif', 'crate.gif'], 38 | parameters: [{ 39 | name: 'TEXTURE_MAG_FILTER', 40 | value: 'LINEAR' 41 | }, { 42 | name: 'TEXTURE_MIN_FILTER', 43 | value: 'LINEAR_MIPMAP_NEAREST', 44 | generateMipmap: true 45 | }] 46 | }, 47 | events: { 48 | onMouseWheel: function(e, info) { 49 | info.stop(); 50 | var camera = this.camera; 51 | 52 | camera.position.z += info.wheel; 53 | camera.update(); 54 | } 55 | }, 56 | onError: function() { 57 | alert("There was an error creating the app."); 58 | }, 59 | onLoad: function(app) { 60 | //Unpack app properties 61 | var gl = app.gl, 62 | program = app.program, 63 | scene = app.scene, 64 | canvas = app.canvas, 65 | camera = app.camera, 66 | //get light config from forms 67 | lighting = $id('lighting'), 68 | ambient = { 69 | r: $id('ambientR'), 70 | g: $id('ambientG'), 71 | b: $id('ambientB') 72 | }, 73 | point = { 74 | x: $id('lightPositionX'), 75 | y: $id('lightPositionY'), 76 | z: $id('lightPositionZ'), 77 | 78 | r: $id('pointR'), 79 | g: $id('pointG'), 80 | b: $id('pointB') 81 | }, 82 | //objects position 83 | rho = 6, 84 | theta = 0; 85 | 86 | //Basic gl setup 87 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 88 | gl.clearDepth(1.0); 89 | gl.enable(gl.DEPTH_TEST); 90 | gl.depthFunc(gl.LEQUAL); 91 | gl.viewport(0, 0, +canvas.width, +canvas.height); 92 | //Add objects to the scene 93 | scene.add(moon, box); 94 | //Animate 95 | draw(); 96 | 97 | //Draw the scene 98 | function draw() { 99 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 100 | //Setup lighting 101 | var lights = scene.config.lights; 102 | lights.enable = lighting.checked; 103 | lights.ambient = { 104 | r: +ambient.r.value, 105 | g: +ambient.g.value, 106 | b: +ambient.b.value 107 | }; 108 | lights.points = { 109 | color: { 110 | r: +point.r.value, 111 | g: +point.g.value, 112 | b: +point.b.value 113 | }, 114 | position: { 115 | x: +point.x.value, 116 | y: +point.y.value, 117 | z: +point.z.value 118 | } 119 | }; 120 | //Update position 121 | theta += 0.01; 122 | 123 | moon.position = { 124 | x: rho * Math.cos(theta), 125 | y: 0, 126 | z: rho * Math.sin(theta) 127 | }; 128 | moon.update(); 129 | 130 | box.position = { 131 | x: rho * Math.cos(Math.PI + theta), 132 | y: 0, 133 | z: rho * Math.sin(Math.PI + theta) 134 | }; 135 | box.update(); 136 | 137 | //render objects 138 | scene.render(); 139 | 140 | //request frame 141 | PhiloGL.Fx.requestAnimationFrame(draw); 142 | } 143 | } 144 | }); 145 | } 146 | -------------------------------------------------------------------------------- /examples/lessons/5/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | //Create object 3 | var cube = new PhiloGL.O3D.Model({ 4 | texture: 'nehe.gif', 5 | 6 | vertices: [-1, -1, 1, 7 | 1, -1, 1, 8 | 1, 1, 1, 9 | -1, 1, 1, 10 | 11 | -1, -1, -1, 12 | -1, 1, -1, 13 | 1, 1, -1, 14 | 1, -1, -1, 15 | 16 | -1, 1, -1, 17 | -1, 1, 1, 18 | 1, 1, 1, 19 | 1, 1, -1, 20 | 21 | -1, -1, -1, 22 | 1, -1, -1, 23 | 1, -1, 1, 24 | -1, -1, 1, 25 | 26 | 1, -1, -1, 27 | 1, 1, -1, 28 | 1, 1, 1, 29 | 1, -1, 1, 30 | 31 | -1, -1, -1, 32 | -1, -1, 1, 33 | -1, 1, 1, 34 | -1, 1, -1], 35 | 36 | texCoords: [ 37 | // Front face 38 | 0.0, 0.0, 39 | 1.0, 0.0, 40 | 1.0, 1.0, 41 | 0.0, 1.0, 42 | 43 | // Back face 44 | 1.0, 0.0, 45 | 1.0, 1.0, 46 | 0.0, 1.0, 47 | 0.0, 0.0, 48 | 49 | // Top face 50 | 0.0, 1.0, 51 | 0.0, 0.0, 52 | 1.0, 0.0, 53 | 1.0, 1.0, 54 | 55 | // Bottom face 56 | 1.0, 1.0, 57 | 0.0, 1.0, 58 | 0.0, 0.0, 59 | 1.0, 0.0, 60 | 61 | // Right face 62 | 1.0, 0.0, 63 | 1.0, 1.0, 64 | 0.0, 1.0, 65 | 0.0, 0.0, 66 | 67 | // Left face 68 | 0.0, 0.0, 69 | 1.0, 0.0, 70 | 1.0, 1.0, 71 | 0.0, 1.0 72 | ], 73 | 74 | indices: [0, 1, 2, 0, 2, 3, 75 | 4, 5, 6, 4, 6, 7, 76 | 8, 9, 10, 8, 10, 11, 77 | 12, 13, 14, 12, 14, 15, 78 | 16, 17, 18, 16, 18, 19, 79 | 20, 21, 22, 20, 22, 23] 80 | }); 81 | 82 | PhiloGL('lesson05-canvas', { 83 | program: { 84 | from: 'ids', 85 | vs: 'shader-vs', 86 | fs: 'shader-fs' 87 | }, 88 | textures: { 89 | src: ['nehe.gif'] 90 | }, 91 | onError: function() { 92 | alert("An error ocurred while loading the application"); 93 | }, 94 | onLoad: function(app) { 95 | var gl = app.gl, 96 | canvas = app.canvas, 97 | program = app.program, 98 | camera = app.camera, 99 | view = new PhiloGL.Mat4, 100 | rCube = 0; 101 | 102 | gl.viewport(0, 0, canvas.width, canvas.height); 103 | gl.clearColor(0, 0, 0, 1); 104 | gl.clearDepth(1); 105 | gl.enable(gl.DEPTH_TEST); 106 | gl.depthFunc(gl.LEQUAL); 107 | 108 | camera.view.id(); 109 | 110 | //set buffers with cube data 111 | program.setBuffers({ 112 | 'aVertexPosition': { 113 | value: cube.vertices, 114 | size: 3 115 | }, 116 | 'aTextureCoord': { 117 | value: cube.texCoords, 118 | size: 2 119 | }, 120 | 'indices': { 121 | value: cube.indices, 122 | bufferType: gl.ELEMENT_ARRAY_BUFFER, 123 | size: 1 124 | } 125 | }); 126 | 127 | function drawScene() { 128 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 129 | //draw Cube 130 | rCube += 0.01; 131 | cube.position.set(0, 0, -8); 132 | cube.rotation.set(rCube, rCube, rCube); 133 | //update element matrix 134 | cube.update(); 135 | //get new view matrix out of element and camera matrices 136 | view.mulMat42(camera.view, cube.matrix); 137 | //set attributes, indices and textures 138 | program.setBuffer('aVertexPosition') 139 | .setBuffer('aTextureCoord') 140 | .setBuffer('indices') 141 | .setTexture('nehe.gif'); 142 | //set uniforms 143 | program.setUniform('uMVMatrix', view) 144 | .setUniform('uPMatrix', camera.projection) 145 | .setUniform('uSampler', 0); 146 | //draw triangles 147 | gl.drawElements(gl.TRIANGLES, cube.indices.length, gl.UNSIGNED_SHORT, 0); 148 | //request new frame 149 | PhiloGL.Fx.requestAnimationFrame(drawScene); 150 | } 151 | 152 | drawScene(); 153 | 154 | } 155 | 156 | }); 157 | } 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /examples/lessons/10/index.js: -------------------------------------------------------------------------------- 1 | PhiloGL.unpack(); 2 | function webGLStart() { 3 | var pitch = 0, 4 | pitchRate = 0, 5 | yaw = 0, 6 | yawRate = 0, 7 | xPos = 0, 8 | yPos = 0.4, 9 | zPos = 0, 10 | speed = 0, 11 | joggingAngle = 0; 12 | 13 | //Model 14 | var world; 15 | 16 | //load world 17 | new IO.XHR({ 18 | url: 'world.txt', 19 | onSuccess: function(data) { 20 | var lines = data.split("\n"); 21 | var vertexCount = 0; 22 | var vertexPositions = []; 23 | var vertexTextureCoords = []; 24 | for (var i in lines) { 25 | var vals = lines[i].replace(/^\s+/, "").split(/\s+/); 26 | if (vals.length == 5 && vals[0] != "//") { 27 | // It is a line describing a vertex; get X, Y and Z first 28 | vertexPositions.push(parseFloat(vals[0])); 29 | vertexPositions.push(parseFloat(vals[1])); 30 | vertexPositions.push(parseFloat(vals[2])); 31 | 32 | // And then the texture coords 33 | vertexTextureCoords.push(parseFloat(vals[3])); 34 | vertexTextureCoords.push(parseFloat(vals[4])); 35 | 36 | vertexCount += 1; 37 | } 38 | } 39 | 40 | world = new O3D.Model({ 41 | vertices: vertexPositions, 42 | texCoords: vertexTextureCoords, 43 | textures: 'mud.gif' 44 | }); 45 | 46 | startApp(); 47 | }, 48 | onError: function() { 49 | console.log("There was something wrong with loading the world"); 50 | } 51 | }).send(); 52 | 53 | function startApp() { 54 | 55 | //Create App 56 | PhiloGL('lesson10-canvas', { 57 | textures: { 58 | src: ['mud.gif'], 59 | parameters: [{ 60 | name: 'TEXTURE_MAG_FILTER', 61 | value: 'LINEAR' 62 | }, { 63 | name: 'TEXTURE_MIN_FILTER', 64 | value: 'LINEAR_MIPMAP_NEAREST', 65 | generateMipmap: true 66 | }] 67 | }, 68 | events: { 69 | onKeyDown: function(e) { 70 | switch(e.key) { 71 | case 'left': case 'a': 72 | yawRate = 0.001; 73 | break; 74 | case 'right': case 'd': 75 | yawRate = -0.001; 76 | break; 77 | case 'up': case 'w': 78 | speed = 0.001; 79 | break; 80 | case 'down': case 's': 81 | speed = -0.001; 82 | break; 83 | } 84 | if (e.code == 33) { 85 | pichRate = 0.001; 86 | } else if (e.code == 34) { 87 | pichRate = -0.001; 88 | } 89 | }, 90 | onKeyUp: function() { 91 | speed = 0; 92 | pitchRate = 0; 93 | yawRate = 0; 94 | } 95 | }, 96 | onError: function() { 97 | console.log('The app could not be loaded'); 98 | }, 99 | onLoad: function(app) { 100 | var gl = app.gl, 101 | scene = app.scene, 102 | camera = app.camera, 103 | canvas = app.canvas; 104 | 105 | scene.add(world); 106 | 107 | gl.viewport(0, 0, canvas.width, canvas.height); 108 | gl.clearColor(0, 0, 0, 1); 109 | gl.clearDepth(1); 110 | gl.enable(gl.DEPTH_TEST); 111 | gl.depthFunc(gl.LEQUAL); 112 | 113 | function tick() { 114 | drawScene(); 115 | animate(); 116 | Fx.requestAnimationFrame(tick); 117 | } 118 | 119 | var lastTime = 0; 120 | function animate() { 121 | var timeNow = Date.now(); 122 | if (lastTime != 0) { 123 | var elapsed = timeNow - lastTime; 124 | 125 | if (speed != 0) { 126 | xPos -= Math.sin(yaw) * speed * elapsed; 127 | zPos -= Math.cos(yaw) * speed * elapsed; 128 | 129 | joggingAngle += elapsed * 0.01; // 0.6 "fiddle factor" - makes it feel more realistic :-) 130 | yPos = Math.sin(joggingAngle) / 100 + 0.4 131 | } 132 | 133 | yaw += yawRate * elapsed; 134 | pitch += pitchRate * elapsed; 135 | 136 | } 137 | lastTime = timeNow; 138 | } 139 | 140 | function drawScene() { 141 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 142 | 143 | //Update Camera Position 144 | camera.view.id() 145 | .$rotateXYZ(-pitch, -yaw, 0) 146 | .$translate(-xPos, -yPos, -zPos); 147 | 148 | //Render all elements in the Scene 149 | scene.render(); 150 | } 151 | 152 | tick(); 153 | 154 | } 155 | }); 156 | } 157 | } 158 | 159 | -------------------------------------------------------------------------------- /examples/lessons/14/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | var $id = function(d) { return document.getElementById(d); }; 3 | 4 | //Get Model 5 | new PhiloGL.IO.XHR({ 6 | url: 'Teapot.json', 7 | onSuccess: function(text) { 8 | var json = JSON.parse(text); 9 | json.colors = [1, 1, 1, 1]; 10 | json.textures = 'arroway.de_metal+structure+06_d100_flat.jpg'; 11 | var teapot = new PhiloGL.O3D.Model(json); 12 | animateObject(teapot); 13 | } 14 | }).send(); 15 | 16 | function animateObject(teapot) { 17 | //Create application 18 | PhiloGL('lesson14-canvas', { 19 | program: { 20 | from: 'uris', 21 | path: '../../../shaders/', 22 | vs: 'frag-lighting.vs.glsl', 23 | fs: 'frag-lighting.fs.glsl', 24 | noCache: true 25 | }, 26 | camera: { 27 | position: { 28 | x: 0, y: 0, z: -50 29 | } 30 | }, 31 | textures: { 32 | src: ['arroway.de_metal+structure+06_d100_flat.jpg', 'earth.jpg'], 33 | parameters: [{ 34 | name: 'TEXTURE_MAG_FILTER', 35 | value: 'LINEAR' 36 | }, { 37 | name: 'TEXTURE_MIN_FILTER', 38 | value: 'LINEAR_MIPMAP_NEAREST', 39 | generateMipmap: true 40 | }] 41 | }, 42 | onError: function() { 43 | alert("There was an error creating the app."); 44 | }, 45 | onLoad: function(app) { 46 | //Unpack app properties 47 | var gl = app.gl, 48 | scene = app.scene, 49 | canvas = app.canvas, 50 | //shininess 51 | shininess = $id('shininess'), 52 | //specular 53 | specular = $id('specular'), 54 | //get light config from forms 55 | lighting = $id('lighting'), 56 | ambient = { 57 | r: $id('ambientR'), 58 | g: $id('ambientG'), 59 | b: $id('ambientB') 60 | }, 61 | point = { 62 | x: $id('lightPositionX'), 63 | y: $id('lightPositionY'), 64 | z: $id('lightPositionZ'), 65 | 66 | sr: $id('specularR'), 67 | sg: $id('specularG'), 68 | sb: $id('specularB'), 69 | 70 | dr: $id('diffuseR'), 71 | dg: $id('diffuseG'), 72 | db: $id('diffuseB') 73 | }, 74 | texture = $id('texture'), 75 | //object rotation 76 | theta = 0; 77 | 78 | //Basic gl setup 79 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 80 | gl.clearDepth(1.0); 81 | gl.enable(gl.DEPTH_TEST); 82 | gl.depthFunc(gl.LEQUAL); 83 | gl.viewport(0, 0, +canvas.width, +canvas.height); 84 | //Add objects to the scene 85 | scene.add(teapot); 86 | 87 | //Animate 88 | draw(); 89 | 90 | //Draw the scene 91 | function draw() { 92 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 93 | //Setup lighting 94 | var lights = scene.config.lights; 95 | lights.enable = lighting.checked; 96 | lights.ambient = { 97 | r: +ambient.r.value, 98 | g: +ambient.g.value, 99 | b: +ambient.b.value 100 | }; 101 | lights.points = { 102 | diffuse: { 103 | r: +point.dr.value, 104 | g: +point.dg.value, 105 | b: +point.db.value 106 | }, 107 | specular: { 108 | r: +point.sr.value, 109 | g: +point.sg.value, 110 | b: +point.sb.value 111 | }, 112 | position: { 113 | x: +point.x.value, 114 | y: +point.y.value, 115 | z: +point.z.value 116 | } 117 | }; 118 | //Set/Unset specular highlights 119 | if (!specular.checked) { 120 | delete lights.points.specular; 121 | } 122 | //Set shininess 123 | teapot.uniforms.shininess = +shininess.value; 124 | //Set texture 125 | if (texture.value == 'none') { 126 | delete teapot.textures; 127 | } else if (texture.value == 'galvanized') { 128 | teapot.textures = ['arroway.de_metal+structure+06_d100_flat.jpg']; 129 | } else { 130 | teapot.textures = ['earth.jpg']; 131 | } 132 | 133 | //Update position 134 | theta += 0.01; 135 | teapot.rotation.set(theta / 100, theta, 0); 136 | teapot.update(); 137 | 138 | //render objects 139 | scene.render(); 140 | 141 | //request new frame 142 | PhiloGL.Fx.requestAnimationFrame(draw); 143 | } 144 | } 145 | }); 146 | 147 | } 148 | } 149 | 150 | 151 | -------------------------------------------------------------------------------- /examples/picking/balls.js: -------------------------------------------------------------------------------- 1 | PhiloGL.Shaders.Fragment.Ufm = [ 2 | 3 | "#ifdef GL_ES", 4 | "precision highp float;", 5 | "#endif", 6 | 7 | "varying vec4 vColor;", 8 | "varying vec2 vTexCoord;", 9 | "varying vec3 lightWeighting;", 10 | 11 | "uniform bool hasTexture1;", 12 | "uniform sampler2D sampler1;", 13 | 14 | "uniform bool enablePicking;", 15 | "uniform vec3 pickColor;", 16 | 17 | "uniform bool hasFog;", 18 | "uniform vec3 fogColor;", 19 | 20 | "uniform float fogNear;", 21 | "uniform float fogFar;", 22 | 23 | "uniform vec4 colorUfm;", 24 | 25 | "void main(){", 26 | 27 | "if(!hasTexture1) {", 28 | "gl_FragColor = vec4(colorUfm.rgb * lightWeighting, colorUfm.a);", 29 | "} else {", 30 | "gl_FragColor = vec4(texture2D(sampler1, vec2(vTexCoord.s, vTexCoord.t)).rgb * lightWeighting, 1.0);", 31 | "}", 32 | 33 | /* handle fog */ 34 | "if (hasFog && colorUfm.r != 1.0) {", 35 | "float depth = gl_FragCoord.z / gl_FragCoord.w;", 36 | "float fogFactor = smoothstep(fogNear, fogFar, depth);", 37 | "gl_FragColor = mix(gl_FragColor, vec4(fogColor, gl_FragColor.w), fogFactor);", 38 | "}", 39 | 40 | "if(enablePicking) {", 41 | "gl_FragColor = vec4(pickColor, 1.0);", 42 | "}", 43 | "}" 44 | 45 | ].join("\n"); 46 | 47 | (function() { 48 | //Unpack PhiloGL modules 49 | PhiloGL.unpack(); 50 | 51 | //Utility fn to getElementById 52 | function $id(d) { 53 | return document.getElementById(d); 54 | } 55 | 56 | var models = [], i = 50; 57 | while (i--) { 58 | var model = new O3D[["Cylinder", "Cone", "Cube", "Sphere"][i % 4]]({ 59 | pickable: !!(i % 2), 60 | shininess: 2, 61 | radius: Math.random() * 2 + 1, 62 | nvertical: 10, 63 | nradial: 10, 64 | height: 10, 65 | topCap: true, 66 | bottomCap: true, 67 | cap: true, 68 | colors: [0.5, 0.5, 0.5, 1], 69 | uniforms: { 70 | 'colorUfm': [0.5, 0.5, 0.5, 1] 71 | } 72 | }); 73 | var n = 20; 74 | model.position = { 75 | x: -n + Math.random() * 2 * n, 76 | y: -n + Math.random() * 2 * n, 77 | z: -n + Math.random() * 2 * n 78 | }; 79 | model.update(); 80 | models.push(model); 81 | if (i % 2) { 82 | model.texCoords = false; 83 | } 84 | } 85 | 86 | window.init = function() { 87 | //Create App 88 | PhiloGL('surface-explorer-canvas', { 89 | program: { 90 | fs: 'Ufm' 91 | }, 92 | camera: { 93 | //near: 30, 94 | //far: 50, 95 | position: { 96 | x: 0, y: 0, z: -50 97 | }, 98 | //type: 'orthographic' 99 | }, 100 | scene: { 101 | lights: { 102 | enable: true, 103 | ambient: { 104 | r: 0.6, 105 | g: 0.6, 106 | b: 0.6 107 | }, 108 | directional: { 109 | color: { 110 | r: 0.8, g: 0.5, b: 0.2 111 | }, 112 | direction: { 113 | x: -1, y: 1, z: 1 114 | } 115 | } 116 | }, 117 | effects: { 118 | fog: { 119 | color: { 120 | r: 0.1, g: 0.1, b: 0.1 121 | }, 122 | near: 0, 123 | far: 70 124 | } 125 | } 126 | }, 127 | events: { 128 | picking: true, 129 | // lazyPicking: true, 130 | centerOrigin: false, 131 | cachePosition: false, 132 | onMouseEnter: function(e, model) { 133 | model.uniforms.colorUfm = [1, 1, 1, 1]; 134 | }, 135 | onMouseLeave: function(e, model) { 136 | model.uniforms.colorUfm = [0.5, 0.5, 0.5, 1]; 137 | }, 138 | onMouseWheel: function(e) { 139 | e.stop(); 140 | var camera = this.camera; 141 | camera.position.z += e.wheel; 142 | camera.update(); 143 | } 144 | }, 145 | onError: function() { 146 | console.log(arguments); 147 | //alert("There was an error while creating the WebGL application"); 148 | }, 149 | onLoad: function(app) { 150 | var gl = app.gl, 151 | canvas = gl.canvas, 152 | scene = app.scene; 153 | //Basic gl setup 154 | gl.clearDepth(1.0); 155 | gl.clearColor(0, 0, 0, 1.0); 156 | gl.enable(gl.DEPTH_TEST); 157 | gl.depthFunc(gl.LEQUAL); 158 | //Add balls 159 | scene.add.apply(scene, models); 160 | //run loop 161 | render(); 162 | //Render the scene and perform a new loop 163 | function render() { 164 | gl.viewport(0, 0, canvas.width, canvas.height); 165 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 166 | scene.render(); 167 | Fx.requestAnimationFrame(render); 168 | } 169 | } 170 | }); 171 | }; 172 | })(); 173 | -------------------------------------------------------------------------------- /examples/lessons/13/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | var $id = function(d) { return document.getElementById(d); }; 3 | 4 | //Create moon 5 | var moon = new PhiloGL.O3D.Sphere({ 6 | nlat: 30, 7 | nlong: 30, 8 | radius: 2, 9 | textures: 'moon.gif', 10 | program: 'vertex', 11 | colors: [1, 1, 1, 1] 12 | }); 13 | //Create box 14 | var box = new PhiloGL.O3D.Cube({ 15 | textures: 'crate.gif', 16 | program: 'vertex', 17 | colors: [1, 1, 1, 1] 18 | }); 19 | box.scale.set(2, 2, 2); 20 | 21 | //Create application 22 | PhiloGL('lesson13-canvas', { 23 | program: [{ 24 | id: 'vertex', 25 | from: 'defaults' 26 | }, { 27 | id: 'fragment', 28 | from: 'ids', 29 | vs: 'per-fragment-lighting-vs', 30 | fs: 'per-fragment-lighting-fs' 31 | }], 32 | camera: { 33 | position: { 34 | x: 0, y: 0, z: -30 35 | } 36 | }, 37 | scene: { 38 | lights: { 39 | directional: { 40 | color: { 41 | r: 0, g: 0, b: 0 42 | }, 43 | direction: { 44 | x: 0, y: 0, z: 0 45 | } 46 | } 47 | } 48 | }, 49 | textures: { 50 | src: ['moon.gif', 'crate.gif'], 51 | parameters: [{ 52 | name: 'TEXTURE_MAG_FILTER', 53 | value: 'LINEAR' 54 | }, { 55 | name: 'TEXTURE_MIN_FILTER', 56 | value: 'LINEAR_MIPMAP_NEAREST', 57 | generateMipmap: true 58 | }] 59 | }, 60 | events: { 61 | onMouseWheel: function(e, info) { 62 | info.stop(); 63 | var camera = this.camera; 64 | 65 | camera.position.z += info.wheel; 66 | camera.update(); 67 | } 68 | }, 69 | onError: function() { 70 | alert("There was an error creating the app."); 71 | }, 72 | onLoad: function(app) { 73 | //Unpack app properties 74 | var gl = app.gl, 75 | scene = app.scene, 76 | canvas = app.canvas, 77 | camera = app.camera, 78 | //get light config from forms 79 | lighting = $id('lighting'), 80 | ambient = { 81 | r: $id('ambientR'), 82 | g: $id('ambientG'), 83 | b: $id('ambientB') 84 | }, 85 | point = { 86 | x: $id('lightPositionX'), 87 | y: $id('lightPositionY'), 88 | z: $id('lightPositionZ'), 89 | 90 | r: $id('pointR'), 91 | g: $id('pointG'), 92 | b: $id('pointB') 93 | }, 94 | program = $id('per-fragment'), 95 | textures = $id('textures'), 96 | //objects position 97 | rho = 6, 98 | theta = 0; 99 | 100 | //Basic gl setup 101 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 102 | gl.clearDepth(1.0); 103 | gl.enable(gl.DEPTH_TEST); 104 | gl.depthFunc(gl.LEQUAL); 105 | gl.viewport(0, 0, +canvas.width, +canvas.height); 106 | //Add objects to the scene 107 | scene.add(box, moon); 108 | //Animate 109 | draw(); 110 | 111 | //Draw the scene 112 | function draw() { 113 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 114 | //Setup lighting 115 | var lights = scene.config.lights; 116 | lights.enable = lighting.checked; 117 | lights.ambient = { 118 | r: +ambient.r.value, 119 | g: +ambient.g.value, 120 | b: +ambient.b.value 121 | }; 122 | lights.points = { 123 | color: { 124 | r: +point.r.value, 125 | g: +point.g.value, 126 | b: +point.b.value 127 | }, 128 | position: { 129 | x: +point.x.value, 130 | y: +point.y.value, 131 | z: +point.z.value 132 | } 133 | }; 134 | 135 | //Set program 136 | if (program.checked) { 137 | moon.program = 'fragment'; 138 | box.program = 'fragment'; 139 | } else { 140 | moon.program = 'vertex'; 141 | box.program = 'vertex'; 142 | } 143 | 144 | //Set textures 145 | if (textures.checked) { 146 | moon.textures = 'moon.gif'; 147 | box.textures = 'crate.gif'; 148 | } else { 149 | delete moon.textures; 150 | delete box.textures; 151 | } 152 | 153 | //Update position 154 | theta += 0.01; 155 | 156 | moon.position = { 157 | x: rho * Math.cos(theta), 158 | y: 0, 159 | z: rho * Math.sin(theta) 160 | }; 161 | moon.update(); 162 | 163 | box.position = { 164 | x: rho * Math.cos(Math.PI + theta), 165 | y: 0, 166 | z: rho * Math.sin(Math.PI + theta) 167 | }; 168 | box.update(); 169 | 170 | //render objects 171 | scene.render(); 172 | 173 | //request new frame 174 | PhiloGL.Fx.requestAnimationFrame(draw); 175 | } 176 | } 177 | }); 178 | } 179 | 180 | -------------------------------------------------------------------------------- /examples/lessons/4/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | //Load models 3 | var pyramid = new PhiloGL.O3D.Model({ 4 | vertices: [ 0, 1, 0, 5 | -1, -1, 1, 6 | 1, -1, 1, 7 | 0, 1, 0, 8 | 1, -1, 1, 9 | 1, -1, -1, 10 | 0, 1, 0, 11 | 1, -1, -1, 12 | -1, -1, -1, 13 | 0, 1, 0, 14 | -1, -1, -1, 15 | -1, -1, 1], 16 | 17 | colors: [1, 0, 0, 1, 18 | 0, 1, 0, 1, 19 | 0, 0, 1, 1, 20 | 1, 0, 0, 1, 21 | 0, 0, 1, 1, 22 | 0, 1, 0, 1, 23 | 1, 0, 0, 1, 24 | 0, 1, 0, 1, 25 | 0, 0, 1, 1, 26 | 1, 0, 0, 1, 27 | 0, 0, 1, 1, 28 | 0, 1, 0, 1] 29 | }); 30 | 31 | var cube = new PhiloGL.O3D.Model({ 32 | vertices: [-1, -1, 1, 33 | 1, -1, 1, 34 | 1, 1, 1, 35 | -1, 1, 1, 36 | 37 | -1, -1, -1, 38 | -1, 1, -1, 39 | 1, 1, -1, 40 | 1, -1, -1, 41 | 42 | -1, 1, -1, 43 | -1, 1, 1, 44 | 1, 1, 1, 45 | 1, 1, -1, 46 | 47 | -1, -1, -1, 48 | 1, -1, -1, 49 | 1, -1, 1, 50 | -1, -1, 1, 51 | 52 | 1, -1, -1, 53 | 1, 1, -1, 54 | 1, 1, 1, 55 | 1, -1, 1, 56 | 57 | -1, -1, -1, 58 | -1, -1, 1, 59 | -1, 1, 1, 60 | -1, 1, -1], 61 | 62 | colors: [1, 0, 0, 1, 63 | 1, 0, 0, 1, 64 | 1, 0, 0, 1, 65 | 1, 0, 0, 1, 66 | 1, 1, 0, 1, 67 | 1, 1, 0, 1, 68 | 1, 1, 0, 1, 69 | 1, 1, 0, 1, 70 | 0, 1, 0, 1, 71 | 0, 1, 0, 1, 72 | 0, 1, 0, 1, 73 | 0, 1, 0, 1, 74 | 1, 0.5, 0.5, 1, 75 | 1, 0.5, 0.5, 1, 76 | 1, 0.5, 0.5, 1, 77 | 1, 0.5, 0.5, 1, 78 | 1, 0, 1, 1, 79 | 1, 0, 1, 1, 80 | 1, 0, 1, 1, 81 | 1, 0, 1, 1, 82 | 0, 0, 1, 1, 83 | 0, 0, 1, 1, 84 | 0, 0, 1, 1, 85 | 0, 0, 1, 1], 86 | 87 | indices: [0, 1, 2, 0, 2, 3, 88 | 4, 5, 6, 4, 6, 7, 89 | 8, 9, 10, 8, 10, 11, 90 | 12, 13, 14, 12, 14, 15, 91 | 16, 17, 18, 16, 18, 19, 92 | 20, 21, 22, 20, 22, 23] 93 | }); 94 | 95 | PhiloGL('lesson04-canvas', { 96 | program: { 97 | from: 'ids', 98 | vs: 'shader-vs', 99 | fs: 'shader-fs' 100 | }, 101 | onError: function() { 102 | alert("An error ocurred while loading the application"); 103 | }, 104 | onLoad: function(app) { 105 | var gl = app.gl, 106 | canvas = app.canvas, 107 | program = app.program, 108 | camera = app.camera, 109 | view = new PhiloGL.Mat4, 110 | rPyramid = 0, rCube = 0; 111 | 112 | gl.viewport(0, 0, canvas.width, canvas.height); 113 | gl.clearColor(0, 0, 0, 1); 114 | gl.clearDepth(1); 115 | gl.enable(gl.DEPTH_TEST); 116 | gl.depthFunc(gl.LEQUAL); 117 | 118 | camera.view.id(); 119 | 120 | function setupElement(elem) { 121 | //update element matrix 122 | elem.update(); 123 | //get new view matrix out of element and camera matrices 124 | view.mulMat42(camera.view, elem.matrix); 125 | //set buffers with element data 126 | program.setBuffers({ 127 | 'aVertexPosition': { 128 | value: elem.vertices, 129 | size: 3 130 | }, 131 | 'aVertexColor': { 132 | value: elem.colors, 133 | size: 4 134 | } 135 | }); 136 | //set uniforms 137 | program.setUniform('uMVMatrix', view); 138 | program.setUniform('uPMatrix', camera.projection); 139 | } 140 | 141 | function animate() { 142 | rPyramid += 0.01; 143 | rCube += 0.01; 144 | } 145 | 146 | function tick() { 147 | drawScene(); 148 | animate(); 149 | PhiloGL.Fx.requestAnimationFrame(tick); 150 | } 151 | 152 | function drawScene() { 153 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 154 | 155 | //Draw Pyramid 156 | pyramid.position.set(-1.5, 0, -8); 157 | pyramid.rotation.set(0, rPyramid, 0); 158 | setupElement(pyramid); 159 | gl.drawArrays(gl.TRIANGLES, 0, pyramid.vertices.length / 3); 160 | 161 | //Draw Cube 162 | cube.position.set(1.5, 0, -8); 163 | cube.rotation.set(rCube, rCube, rCube); 164 | setupElement(cube); 165 | program.setBuffer('indices', { 166 | value: cube.indices, 167 | bufferType: gl.ELEMENT_ARRAY_BUFFER, 168 | size: 1 169 | }); 170 | gl.drawElements(gl.TRIANGLES, cube.indices.length, gl.UNSIGNED_SHORT, 0); 171 | } 172 | 173 | tick(); 174 | } 175 | }); 176 | 177 | } 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /examples/lessons/9/index.js: -------------------------------------------------------------------------------- 1 | //Add Uniform Color Fragment Shader 2 | PhiloGL.Shaders.Fragment.ColorUniform = [ 3 | 4 | "#ifdef GL_ES", 5 | "precision highp float;", 6 | "#endif", 7 | 8 | "varying vec4 vColor;", 9 | "varying vec2 vTexCoord;", 10 | "varying vec3 lightWeighting;", 11 | 12 | "uniform bool hasTexture1;", 13 | "uniform sampler2D sampler1;", 14 | "uniform vec3 uColor;", 15 | 16 | "void main(){", 17 | 18 | "if (hasTexture1) {", 19 | 20 | "gl_FragColor = vec4(texture2D(sampler1, vec2(vTexCoord.s, vTexCoord.t)).rgb * lightWeighting, 1.0) * vec4(uColor, 1.0);", 21 | 22 | "}", 23 | 24 | "}" 25 | 26 | ].join("\n"); 27 | 28 | 29 | function webGLStart() { 30 | var $id = function(d) { return document.getElementById(d); }, 31 | zoom = -15, 32 | tilt = 90, 33 | spin = 0, 34 | twinkle = $id('twinkle'); 35 | 36 | //Define a Star Class 37 | var Star = function(startingDistance, rotationSpeed) { 38 | PhiloGL.O3D.Model.call(this, { 39 | vertices: [ 40 | -1.0, -1.0, 0.0, 41 | 1.0, -1.0, 0.0, 42 | -1.0, 1.0, 0.0, 43 | 1.0, 1.0, 0.0 44 | ], 45 | 46 | texCoords: [ 47 | 0.0, 0.0, 48 | 1.0, 0.0, 49 | 0.0, 1.0, 50 | 1.0, 1.0 51 | ], 52 | 53 | textures: 'star.gif', 54 | 55 | indices: [0, 1, 3, 3, 2, 0], 56 | 57 | onBeforeRender: function(program, camera) { 58 | var min = Math.min, 59 | isTwinkle = twinkle.checked, 60 | r = isTwinkle? min(1, this.r + this.twinklerR) : this.r, 61 | g = isTwinkle? min(1, this.g + this.twinklerG) : this.g, 62 | b = isTwinkle? min(1, this.b + this.twinklerB) : this.b; 63 | program.setUniform('uColor', [r, g, b]); 64 | } 65 | 66 | }); 67 | 68 | this.angle = 0; 69 | this.dist = startingDistance; 70 | this.rotationSpeed = rotationSpeed; 71 | this.spin = 0; 72 | 73 | this.randomiseColors(); 74 | }; 75 | 76 | Star.prototype = Object.create(PhiloGL.O3D.Model.prototype, { 77 | 78 | randomiseColors: { 79 | value: function() { 80 | var rd = Math.random; 81 | 82 | this.r = rd(); 83 | this.g = rd(); 84 | this.b = rd(); 85 | 86 | this.twinklerR = rd(); 87 | this.twinklerG = rd(); 88 | this.twinklerB = rd(); 89 | } 90 | }, 91 | 92 | animate: { 93 | value: function(elapsedTime, twinkle) { 94 | this.angle += this.rotationSpeed / 10; 95 | 96 | this.dist -= 0.001; 97 | 98 | if (this.dist < 0) { 99 | this.dist += 5; 100 | this.randomiseColors(); 101 | } 102 | 103 | //update position 104 | this.position.set(Math.cos(this.angle) * this.dist, Math.sin(this.angle) * this.dist, 0); 105 | this.rotation.set(0, 0, this.spin); 106 | this.spin += 0.1; 107 | this.update(); 108 | } 109 | } 110 | 111 | }); 112 | 113 | PhiloGL('lesson09-canvas', { 114 | program: { 115 | from: 'defaults', 116 | fs: 'ColorUniform' 117 | }, 118 | textures: { 119 | src: ['star.gif'], 120 | parameters: [{ 121 | name: 'TEXTURE_MAG_FILTER', 122 | value: 'LINEAR' 123 | }, { 124 | name: 'TEXTURE_MIN_FILTER', 125 | value: 'LINEAR_MIPMAP_NEAREST', 126 | generateMipmap: true 127 | }] 128 | }, 129 | events: { 130 | onKeyDown: function(e) { 131 | switch(e.key) { 132 | case 'up': 133 | tilt -= 1.5; 134 | break; 135 | case 'down': 136 | tilt += 1.5; 137 | break; 138 | //handle page up/down 139 | default: 140 | if (e.code == 33) { 141 | zoom -= 0.1; 142 | } else if (e.code == 34) { 143 | zoom += 0.1; 144 | } 145 | } 146 | } 147 | }, 148 | onError: function() { 149 | alert("An error ocurred while loading the application"); 150 | }, 151 | onLoad: function(app) { 152 | var gl = app.gl, 153 | canvas = app.canvas, 154 | program = app.program, 155 | camera = app.camera, 156 | scene = app.scene; 157 | 158 | gl.viewport(0, 0, canvas.width, canvas.height); 159 | gl.clearColor(0, 0, 0, 1); 160 | gl.clearDepth(1); 161 | 162 | gl.blendFunc(gl.SRC_ALPHA, gl.ONE); 163 | gl.enable(gl.BLEND); 164 | 165 | //Load all world objects 166 | var numStars = 50; 167 | for (var i = 0; i < numStars; i++) { 168 | scene.add(new Star(i / numStars * 5.0, i / numStars)); 169 | } 170 | 171 | tick(); 172 | 173 | function tick() { 174 | drawScene(); 175 | animate(); 176 | PhiloGL.Fx.requestAnimationFrame(tick); 177 | } 178 | 179 | function animate() { 180 | scene.models.forEach(function(star) { 181 | star.animate(); 182 | }); 183 | } 184 | 185 | function drawScene() { 186 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 187 | //Update Camera Position 188 | var radTilt = tilt / 180 * Math.PI; 189 | camera.position.set(0, Math.cos(radTilt) * zoom, 190 | Math.sin(radTilt) * zoom); 191 | camera.update(); 192 | //Render all elements in the Scene 193 | scene.render(); 194 | } 195 | } 196 | }); 197 | } 198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /examples/lessons/6/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | var xRot = 0, xSpeed = 0, 3 | yRot = 0, ySpeed = 0, 4 | z = -5.0, 5 | filter = 0, 6 | filters = ['nearest', 'linear', 'mipmap']; 7 | 8 | //Create object 9 | var cube = new PhiloGL.O3D.Model({ 10 | vertices: [-1, -1, 1, 11 | 1, -1, 1, 12 | 1, 1, 1, 13 | -1, 1, 1, 14 | 15 | -1, -1, -1, 16 | -1, 1, -1, 17 | 1, 1, -1, 18 | 1, -1, -1, 19 | 20 | -1, 1, -1, 21 | -1, 1, 1, 22 | 1, 1, 1, 23 | 1, 1, -1, 24 | 25 | -1, -1, -1, 26 | 1, -1, -1, 27 | 1, -1, 1, 28 | -1, -1, 1, 29 | 30 | 1, -1, -1, 31 | 1, 1, -1, 32 | 1, 1, 1, 33 | 1, -1, 1, 34 | 35 | -1, -1, -1, 36 | -1, -1, 1, 37 | -1, 1, 1, 38 | -1, 1, -1], 39 | 40 | texCoords: [ 41 | // Front face 42 | 0.0, 0.0, 43 | 1.0, 0.0, 44 | 1.0, 1.0, 45 | 0.0, 1.0, 46 | 47 | // Back face 48 | 1.0, 0.0, 49 | 1.0, 1.0, 50 | 0.0, 1.0, 51 | 0.0, 0.0, 52 | 53 | // Top face 54 | 0.0, 1.0, 55 | 0.0, 0.0, 56 | 1.0, 0.0, 57 | 1.0, 1.0, 58 | 59 | // Bottom face 60 | 1.0, 1.0, 61 | 0.0, 1.0, 62 | 0.0, 0.0, 63 | 1.0, 0.0, 64 | 65 | // Right face 66 | 1.0, 0.0, 67 | 1.0, 1.0, 68 | 0.0, 1.0, 69 | 0.0, 0.0, 70 | 71 | // Left face 72 | 0.0, 0.0, 73 | 1.0, 0.0, 74 | 1.0, 1.0, 75 | 0.0, 1.0 76 | ], 77 | 78 | indices: [0, 1, 2, 0, 2, 3, 79 | 4, 5, 6, 4, 6, 7, 80 | 8, 9, 10, 8, 10, 11, 81 | 12, 13, 14, 12, 14, 15, 82 | 16, 17, 18, 16, 18, 19, 83 | 20, 21, 22, 20, 22, 23] 84 | }); 85 | 86 | PhiloGL('lesson06-canvas', { 87 | program: { 88 | from: 'ids', 89 | vs: 'shader-vs', 90 | fs: 'shader-fs' 91 | }, 92 | events: { 93 | onKeyDown: function(e) { 94 | switch(e.key) { 95 | case 'f': 96 | filter = (filter + 1) % 3; 97 | break; 98 | case 'up': 99 | xSpeed -= 0.02; 100 | break; 101 | case 'down': 102 | xSpeed += 0.02; 103 | break; 104 | case 'left': 105 | ySpeed -= 0.02; 106 | break; 107 | case 'right': 108 | ySpeed += 0.02; 109 | break; 110 | //handle page up/down 111 | default: 112 | if (e.code == 33) { 113 | z -= 0.05; 114 | } else if (e.code == 34) { 115 | z += 0.05; 116 | } 117 | } 118 | } 119 | }, 120 | onError: function() { 121 | alert("An error ocurred while loading the application"); 122 | }, 123 | onLoad: function(app) { 124 | var gl = app.gl, 125 | canvas = app.canvas, 126 | program = app.program, 127 | camera = app.camera, 128 | view = new PhiloGL.Mat4, 129 | rCube = 0; 130 | 131 | gl.viewport(0, 0, canvas.width, canvas.height); 132 | gl.clearColor(0, 0, 0, 1); 133 | gl.clearDepth(1); 134 | gl.enable(gl.DEPTH_TEST); 135 | gl.depthFunc(gl.LEQUAL); 136 | 137 | camera.view.id(); 138 | 139 | //set buffers with cube data 140 | program.setBuffers({ 141 | 'aVertexPosition': { 142 | value: cube.vertices, 143 | size: 3 144 | }, 145 | 'aTextureCoord': { 146 | value: cube.texCoords, 147 | size: 2 148 | }, 149 | 'indices': { 150 | value: cube.indices, 151 | bufferType: gl.ELEMENT_ARRAY_BUFFER, 152 | size: 1 153 | } 154 | }); 155 | 156 | //load textures from image 157 | var img = new Image(); 158 | img.onload = function() { 159 | program.setTextures({ 160 | 'nearest': { 161 | data: { 162 | value: img 163 | } 164 | }, 165 | 166 | 'linear': { 167 | data: { 168 | value: img 169 | }, 170 | parameters: [{ 171 | name: gl.TEXTURE_MAG_FILTER, 172 | value: gl.LINEAR 173 | }, { 174 | name: gl.TEXTURE_MIN_FILTER, 175 | value: gl.LINEAR 176 | }] 177 | }, 178 | 179 | 'mipmap': { 180 | data: { 181 | value: img 182 | }, 183 | parameters: [{ 184 | name: gl.TEXTURE_MAG_FILTER, 185 | value: gl.LINEAR 186 | }, { 187 | name: gl.TEXTURE_MIN_FILTER, 188 | value: gl.LINEAR_MIPMAP_NEAREST, 189 | generateMipmap: true 190 | }] 191 | } 192 | }); 193 | 194 | function animate() { 195 | xRot += xSpeed; 196 | yRot += ySpeed; 197 | } 198 | 199 | function tick() { 200 | drawScene(); 201 | animate(); 202 | PhiloGL.Fx.requestAnimationFrame(tick); 203 | } 204 | 205 | function drawScene() { 206 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 207 | //draw Cube 208 | cube.position.set(0, 0, z); 209 | cube.rotation.set(xRot, yRot, 0); 210 | //update element matrix 211 | cube.update(); 212 | //get new view matrix out of element and camera matrices 213 | view.mulMat42(camera.view, cube.matrix); 214 | //set attributes, indices and textures 215 | program.setBuffer('aVertexPosition') 216 | .setBuffer('aTextureCoord') 217 | .setBuffer('indices') 218 | .setTexture(filters[filter]); 219 | //set uniforms 220 | program.setUniform('uMVMatrix', view) 221 | .setUniform('uPMatrix', camera.projection) 222 | .setUniform('uSampler', 0); 223 | //draw triangles 224 | gl.drawElements(gl.TRIANGLES, cube.indices.length, gl.UNSIGNED_SHORT, 0); 225 | } 226 | tick(); 227 | }; 228 | //load image 229 | img.src = 'crate.gif'; 230 | } 231 | }); 232 | } 233 | 234 | -------------------------------------------------------------------------------- /examples/lessons/7/index.js: -------------------------------------------------------------------------------- 1 | //Lighting form elements variables 2 | var $id = function(d) { return document.getElementById(d); }; 3 | 4 | function webGLStart() { 5 | var xRot = 0, xSpeed = 0, 6 | yRot = 0, ySpeed = 0, 7 | z = -5.0; 8 | 9 | //Get lighting form elements 10 | var lighting = $id('lighting'), 11 | ambient = { 12 | r: $id('ambientR'), 13 | g: $id('ambientG'), 14 | b: $id('ambientB') 15 | }, 16 | direction = { 17 | x: $id('lightDirectionX'), 18 | y: $id('lightDirectionY'), 19 | z: $id('lightDirectionZ'), 20 | 21 | r: $id('directionalR'), 22 | g: $id('directionalG'), 23 | b: $id('directionalB') 24 | }; 25 | //Create object 26 | var cube = new PhiloGL.O3D.Model({ 27 | vertices: [-1, -1, 1, 28 | 1, -1, 1, 29 | 1, 1, 1, 30 | -1, 1, 1, 31 | 32 | -1, -1, -1, 33 | -1, 1, -1, 34 | 1, 1, -1, 35 | 1, -1, -1, 36 | 37 | -1, 1, -1, 38 | -1, 1, 1, 39 | 1, 1, 1, 40 | 1, 1, -1, 41 | 42 | -1, -1, -1, 43 | 1, -1, -1, 44 | 1, -1, 1, 45 | -1, -1, 1, 46 | 47 | 1, -1, -1, 48 | 1, 1, -1, 49 | 1, 1, 1, 50 | 1, -1, 1, 51 | 52 | -1, -1, -1, 53 | -1, -1, 1, 54 | -1, 1, 1, 55 | -1, 1, -1], 56 | 57 | textures: 'crate.gif', 58 | 59 | texCoords: [0.0, 0.0, 60 | 1.0, 0.0, 61 | 1.0, 1.0, 62 | 0.0, 1.0, 63 | 64 | // Back face 65 | 1.0, 0.0, 66 | 1.0, 1.0, 67 | 0.0, 1.0, 68 | 0.0, 0.0, 69 | 70 | // Top face 71 | 0.0, 1.0, 72 | 0.0, 0.0, 73 | 1.0, 0.0, 74 | 1.0, 1.0, 75 | 76 | // Bottom face 77 | 1.0, 1.0, 78 | 0.0, 1.0, 79 | 0.0, 0.0, 80 | 1.0, 0.0, 81 | 82 | // Right face 83 | 1.0, 0.0, 84 | 1.0, 1.0, 85 | 0.0, 1.0, 86 | 0.0, 0.0, 87 | 88 | // Left face 89 | 0.0, 0.0, 90 | 1.0, 0.0, 91 | 1.0, 1.0, 92 | 0.0, 1.0], 93 | 94 | normals: [ 95 | // Front face 96 | 0.0, 0.0, 1.0, 97 | 0.0, 0.0, 1.0, 98 | 0.0, 0.0, 1.0, 99 | 0.0, 0.0, 1.0, 100 | 101 | // Back face 102 | 0.0, 0.0, -1.0, 103 | 0.0, 0.0, -1.0, 104 | 0.0, 0.0, -1.0, 105 | 0.0, 0.0, -1.0, 106 | 107 | // Top face 108 | 0.0, 1.0, 0.0, 109 | 0.0, 1.0, 0.0, 110 | 0.0, 1.0, 0.0, 111 | 0.0, 1.0, 0.0, 112 | 113 | // Bottom face 114 | 0.0, -1.0, 0.0, 115 | 0.0, -1.0, 0.0, 116 | 0.0, -1.0, 0.0, 117 | 0.0, -1.0, 0.0, 118 | 119 | // Right face 120 | 1.0, 0.0, 0.0, 121 | 1.0, 0.0, 0.0, 122 | 1.0, 0.0, 0.0, 123 | 1.0, 0.0, 0.0, 124 | 125 | // Left face 126 | -1.0, 0.0, 0.0, 127 | -1.0, 0.0, 0.0, 128 | -1.0, 0.0, 0.0, 129 | -1.0, 0.0, 0.0 130 | ], 131 | 132 | indices: [0, 1, 2, 0, 2, 3, 133 | 4, 5, 6, 4, 6, 7, 134 | 8, 9, 10, 8, 10, 11, 135 | 12, 13, 14, 12, 14, 15, 136 | 16, 17, 18, 16, 18, 19, 137 | 20, 21, 22, 20, 22, 23] 138 | }); 139 | 140 | PhiloGL('lesson07-canvas', { 141 | textures: { 142 | src: ['crate.gif'], 143 | parameters: [{ 144 | name: 'TEXTURE_MAG_FILTER', 145 | value: 'LINEAR' 146 | }, { 147 | name: 'TEXTURE_MIN_FILTER', 148 | value: 'LINEAR_MIPMAP_NEAREST', 149 | generateMipmap: true 150 | }] 151 | }, 152 | events: { 153 | onKeyDown: function(e) { 154 | switch(e.key) { 155 | case 'f': 156 | filter = (filter + 1) % 3; 157 | break; 158 | case 'up': 159 | xSpeed -= 0.02; 160 | break; 161 | case 'down': 162 | xSpeed += 0.02; 163 | break; 164 | case 'left': 165 | ySpeed -= 0.02; 166 | break; 167 | case 'right': 168 | ySpeed += 0.02; 169 | break; 170 | //handle page up/down 171 | default: 172 | if (e.code == 33) { 173 | z -= 0.05; 174 | } else if (e.code == 34) { 175 | z += 0.05; 176 | } 177 | } 178 | } 179 | }, 180 | onError: function() { 181 | alert("An error ocurred while loading the application"); 182 | }, 183 | onLoad: function(app) { 184 | var gl = app.gl, 185 | canvas = app.canvas, 186 | program = app.program, 187 | camera = app.camera, 188 | scene = app.scene; 189 | 190 | gl.viewport(0, 0, canvas.width, canvas.height); 191 | gl.clearColor(0, 0, 0, 1); 192 | gl.clearDepth(1); 193 | gl.enable(gl.DEPTH_TEST); 194 | gl.depthFunc(gl.LEQUAL); 195 | 196 | camera.view.id(); 197 | 198 | //Add object to our default scene 199 | scene.add(cube); 200 | 201 | function animate() { 202 | xRot += xSpeed; 203 | yRot += ySpeed; 204 | } 205 | 206 | function tick() { 207 | drawScene(); 208 | animate(); 209 | PhiloGL.Fx.requestAnimationFrame(tick); 210 | } 211 | 212 | function drawScene() { 213 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 214 | //Update Cube position 215 | cube.position.set(0, 0, z); 216 | cube.rotation.set(xRot, yRot, 0); 217 | cube.update(); 218 | //Update scene config with light info 219 | var lightConfig = scene.config.lights; 220 | lightConfig.enable = lighting.checked; 221 | lightConfig.ambient = { 222 | r: +ambient.r.value, 223 | g: +ambient.g.value, 224 | b: +ambient.b.value 225 | }; 226 | lightConfig.directional.direction = { 227 | x: +direction.x.value, 228 | y: +direction.y.value, 229 | z: +direction.z.value 230 | }; 231 | lightConfig.directional.color = { 232 | r: +direction.r.value, 233 | g: +direction.g.value, 234 | b: +direction.b.value 235 | }; 236 | //Render all elements in the Scene 237 | scene.render(); 238 | } 239 | tick(); 240 | } 241 | }); 242 | } 243 | 244 | 245 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /examples/particles/explorer.js: -------------------------------------------------------------------------------- 1 | /*global Float32Array, PhiloGL, O3D, Media*/ 2 | 3 | (function() { 4 | //Unpack PhiloGL modules 5 | PhiloGL.unpack(); 6 | 7 | //Utility fn to getElementById 8 | function $id(d) { 9 | return document.getElementById(d); 10 | } 11 | 12 | //index 13 | var size = 1024, 14 | plane = new Float32Array(size * size * 3), 15 | shape = new Float32Array(size * size * 4), 16 | i, l, i3, i4; 17 | 18 | for (i = 0, l = size * size; i < l; i++) { 19 | i3 = i * 3; 20 | i4 = i * 4; 21 | plane[i3 ] = (i % size) / size; 22 | plane[i3 + 1] = Math.floor(i / size) / size; 23 | 24 | shape[i4 ] = (i % size) / size - 0.5; 25 | shape[i4 + 1] = -0.4; 26 | shape[i4 + 2] = Math.floor(i / size) / size; 27 | } 28 | 29 | //Surface Mesh 30 | window.addEventListener('DOMContentLoaded', init, false); 31 | 32 | function init() { 33 | var object; 34 | //Create App 35 | PhiloGL('surface-explorer-canvas', { 36 | program: [{ 37 | id: 'surface', 38 | from: 'uris', 39 | path: './', 40 | vs: 'surface.vs', 41 | fs: 'surface.fs', 42 | noCache: true 43 | },{ 44 | id: 'simulation', 45 | from: 'uris', 46 | path: './', 47 | vs: 'simulation.vs', 48 | fs: 'simulation.fs', 49 | noCache: true 50 | },{ 51 | id: 'copy', 52 | from: 'uris', 53 | path: './', 54 | vs: 'copy.vs', 55 | fs: 'copy.fs', 56 | noCache: true 57 | }], 58 | camera: { 59 | position: { 60 | x: 0, y: 0, z: -1 61 | }, 62 | near: 0.05, 63 | far: 3000, 64 | fov: 45 65 | }, 66 | events: { 67 | onDragStart: function(e) { 68 | this.pos = { 69 | x: e.x, 70 | y: e.y 71 | }; 72 | }, 73 | onDragMove: function(e) { 74 | var z = this.camera.position.z, 75 | sign = Math.abs(z) / z, 76 | pos = this.pos; 77 | 78 | object.rotation.y += -(pos.x - e.x) / 100; 79 | object.rotation.x += sign * (pos.y - e.y) / 100; 80 | object.update(); 81 | pos.x = e.x; 82 | pos.y = e.y; 83 | }, 84 | onTouchStart: function(e) { 85 | e.stop(); 86 | this.pos = { 87 | x: e.x, 88 | y: e.y 89 | }; 90 | }, 91 | onTouchMove: function(e) { 92 | e.stop(); 93 | var z = this.camera.position.z, 94 | sign = Math.abs(z) / z, 95 | pos = this.pos; 96 | 97 | object.rotation.y += -(pos.x - e.x) / 100; 98 | object.rotation.x += sign * (pos.y - e.y) / 100; 99 | object.update(); 100 | pos.x = e.x; 101 | pos.y = e.y; 102 | }, 103 | onMouseWheel: function(e) { 104 | e.stop(); 105 | var camera = this.camera; 106 | camera.position.z += e.wheel; 107 | camera.update(); 108 | } 109 | }, 110 | onError: function(e) { 111 | console.warn(e); 112 | }, 113 | onLoad: function(app) { 114 | var gl = app.gl, 115 | canvas = gl.canvas, 116 | scene = app.scene, 117 | program = app.program, 118 | start = Date.now(); 119 | 120 | canvas.width = window.innerWidth - 20; 121 | canvas.height = window.innerHeight - 130; 122 | 123 | window.addEventListener('resize', function() { 124 | canvas.width = window.innerWidth - 20; 125 | canvas.height = window.innerHeight - 130; 126 | }); 127 | 128 | //program.surface.setBuffer('position', { 129 | //value: plane, 130 | //size: 3 131 | //}); 132 | 133 | //program.simulation.setBuffer('position', { 134 | //value: plane, 135 | //size: 3 136 | //}); 137 | 138 | app.setFrameBuffer('f1', { 139 | width: size, 140 | height: size, 141 | bindToTexture: { 142 | data: { 143 | type: gl.FLOAT, 144 | width: size, 145 | height: size, 146 | value: shape 147 | } 148 | } 149 | }) 150 | .setFrameBuffer('f2', { 151 | width: size, 152 | height: size, 153 | bindToTexture: { 154 | data: { 155 | type: gl.FLOAT, 156 | width: size, 157 | height: size, 158 | value: shape 159 | } 160 | } 161 | }); 162 | 163 | object = new O3D.Model({ 164 | vertices: plane, 165 | program: 'surface', 166 | drawType: "POINTS", 167 | //drawType: gl.LINE_LOOP, 168 | //drawType: gl.TRIANGLES, 169 | textures: ['f1-texture'], 170 | uniforms: { 171 | //timer: 0, 172 | size: 1024, 173 | pointColor: [1, 0, 0], 174 | opacity: 1, 175 | pointSize: 1 176 | } 177 | }); 178 | scene.add(object); 179 | 180 | //Basic gl setup 181 | gl.clearColor(0, 0, 0, 0); 182 | //gl.clearDepth(1.0); 183 | //gl.enable(gl.DEPTH_TEST); 184 | //gl.depthFunc(gl.LEQUAL); 185 | gl.enable(gl.BLEND); 186 | gl.blendFunc(gl.ONE, gl.SRC_ALPHA); 187 | //run loop 188 | loop(); 189 | 190 | //set properties, sample function and render 191 | function loop() { 192 | //app.setFrameBuffer('f2', true); 193 | //gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 194 | //gl.viewport(0, 0, size, size); 195 | //object.program = 'simulation'; 196 | //object.uniforms.textures = ['f1-texture']; 197 | 198 | //scene.renderToTexture('f2'); 199 | //app.setFrameBuffer('f2', false); 200 | 201 | Media.Image.postProcess({ 202 | width: size, 203 | height: size, 204 | fromTexture: 'f1-texture', 205 | toFrameBuffer: 'f2', 206 | program: 'simulation', 207 | uniforms: { 208 | timer: (Date.now() - start) / 100, 209 | waves: [0.3, 120, 0.5, 0, 210 | 0.5, 50, 0.2, 0], 211 | points: [0.5, 0.8, 60 / 2, 0, 212 | 0.2, 0.8, 20 / 2, 0, 213 | 0.3, 0.6, 30 / 2, 0, 214 | 0.5, 0.1, 10 / 2, 0, 215 | 0.5, 0.5, 15 / 2, 0, 216 | 0.2, 0.8, 80 / 2, 0, 217 | 0.4, 0.8, 60 / 2, 0, 218 | 0.6, 0.8, 20 / 2, 0, 219 | 0.7, 0.6, 30 / 2, 0, 220 | 0.8, 0.6, 10 / 2, 0, 221 | 0.9, 0.7, 15 / 2, 0, 222 | 0.0, 0.2, 80 / 2, 0] 223 | 224 | } 225 | //aspectRatio: 1, 226 | //toScreen: true 227 | }) 228 | .postProcess({ 229 | width: size, 230 | height: size, 231 | fromTexture: 'f2-texture', 232 | toFrameBuffer: 'f1', 233 | program: 'copy', 234 | //aspectRatio: 1, 235 | //toScreen: true 236 | }); 237 | 238 | //object.uniforms.timer = (Date.now() - start) / 100; 239 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 240 | gl.viewport(0, 0, canvas.width, canvas.height); 241 | 242 | scene.render(); 243 | Fx.requestAnimationFrame(loop); 244 | } 245 | } 246 | }); 247 | }; 248 | 249 | })(); 250 | -------------------------------------------------------------------------------- /examples/lessons/16/index.js: -------------------------------------------------------------------------------- 1 | function webGLStart() { 2 | var $id = function(d) { return document.getElementById(d); }; 3 | 4 | //unpack modules 5 | PhiloGL.unpack(); 6 | 7 | //create all models 8 | var models = {}; 9 | //Create moon 10 | models.moon = new O3D.Sphere({ 11 | nlat: 30, 12 | nlong: 30, 13 | radius: 2, 14 | textures: 'moon.gif', 15 | uniforms: { 16 | shininess: 5, 17 | 'enableSpecularHighlights': false, 18 | 'materialAmbientColor': [1, 1, 1], 19 | 'materialDiffuseColor': [1, 1, 1], 20 | 'materialSpecularColor': [0, 0, 0], 21 | 'materialEmissiveColor': [0, 0, 0] 22 | } 23 | }); 24 | //Create box 25 | models.box = new O3D.Cube({ 26 | textures: 'crate.gif', 27 | uniforms: { 28 | shininess: 5, 29 | 'enableSpecularHighlights': false, 30 | 'materialAmbientColor': [1, 1, 1], 31 | 'materialDiffuseColor': [1, 1, 1], 32 | 'materialSpecularColor': [0, 0, 0], 33 | 'materialEmissiveColor': [0, 0, 0] 34 | } 35 | }); 36 | models.box.scale.set(2, 2, 2); 37 | 38 | //Load macbook 39 | models.macbookscreen = new O3D.Model({ 40 | normals: [ 41 | 0, -0.965926, 0.258819, 42 | 0, -0.965926, 0.258819, 43 | 0, -0.965926, 0.258819, 44 | 0, -0.965926, 0.258819 45 | ], 46 | vertices: [ 47 | 0.580687, 0.659, 0.813106, 48 | -0.580687, 0.659, 0.813107, 49 | 0.580687, 0.472, 0.113121, 50 | -0.580687, 0.472, 0.113121 51 | ], 52 | texCoords: [ 53 | 1.0, 1.0, 54 | 0.0, 1.0, 55 | 1.0, 0.0, 56 | 0.0, 0.0 57 | ], 58 | textures: 'monitor-texture', 59 | drawType: 'TRIANGLE_STRIP', 60 | uniforms: { 61 | shininess: 0.2, 62 | 'enableSpecularHighlights': false, 63 | 'materialAmbientColor': [0, 0, 0], 64 | 'materialDiffuseColor': [0, 0, 0], 65 | 'materialSpecularColor': [0.5, 0.5, 0.5], 66 | 'materialEmissiveColor': [1.5, 1.5, 1.5] 67 | } 68 | }); 69 | 70 | new IO.XHR({ 71 | url: 'macbook.json', 72 | onError: function() { 73 | alert('Unable to load macbook model'); 74 | }, 75 | onSuccess: function(jsonString) { 76 | var json = JSON.parse(jsonString); 77 | json.shininess = 5; 78 | json.uniforms = { 79 | 'enableSpecularHighlights': true, 80 | 'materialAmbientColor': [1, 1, 1], 81 | 'materialDiffuseColor': [1, 1, 1], 82 | 'materialSpecularColor': [1.5, 1.5, 1.5], 83 | 'materialEmissiveColor': [0, 0, 0] 84 | }; 85 | models.macbook = new O3D.Model(json); 86 | createApp(models); 87 | } 88 | }).send(); 89 | 90 | function createApp(models) { 91 | //Create application 92 | PhiloGL('lesson16-canvas', { 93 | camera: { 94 | position: { 95 | x: 0, y: 0, z: -3 96 | } 97 | }, 98 | program: { 99 | from: 'uris', 100 | path: '../../../shaders/', 101 | vs: 'render-tex.vs.glsl', 102 | fs: 'render-tex.fs.glsl' 103 | }, 104 | scene: { 105 | lights: { 106 | enable: true, 107 | points: { 108 | position: { 109 | x: 1, y: 2, z: -1 110 | }, 111 | diffuse: { 112 | r: 0.8, g: 0.8, b: 0.8 113 | }, 114 | specular: { 115 | r: 0.8, g: 0.8, b: 0.8 116 | } 117 | } 118 | } 119 | }, 120 | textures: { 121 | src: ['moon.gif', 'crate.gif'], 122 | parameters: [{ 123 | name: 'TEXTURE_MAG_FILTER', 124 | value: 'LINEAR' 125 | }, { 126 | name: 'TEXTURE_MIN_FILTER', 127 | value: 'LINEAR_MIPMAP_NEAREST', 128 | generateMipmap: true 129 | }] 130 | }, 131 | onError: function() { 132 | alert("There was an error creating the app."); 133 | }, 134 | onLoad: function(app) { 135 | var screenWidth = 512, 136 | screenHeight = 512, 137 | screenRatio = 1.66, 138 | gl = app.gl, 139 | program = app.program, 140 | outerCamera = app.camera, 141 | innerCamera = new Camera(45, screenRatio, 0.1, 100, { 142 | position: { 143 | x: 0, y: 0, z: -17 144 | } 145 | }), 146 | outerScene = app.scene, 147 | innerScene = new Scene(program, innerCamera, { 148 | lights: { 149 | enable: true, 150 | points: { 151 | position: { 152 | x: -1, y: 2, z: -1 153 | }, 154 | diffuse: { 155 | r: 0.8, g: 0.8, b: 0.8 156 | }, 157 | specular: { 158 | r: 0.8, g: 0.8, b: 0.8 159 | } 160 | } 161 | } 162 | }), 163 | canvas = app.canvas, 164 | rho = 4, 165 | theta = 0, 166 | laptopTheta = 0, 167 | //models 168 | macbook = models.macbook, 169 | macbookscreen = models.macbookscreen, 170 | box = models.box, 171 | moon = models.moon; 172 | 173 | //create framebuffer 174 | program.setFrameBuffer('monitor', { 175 | width: screenWidth, 176 | height: screenHeight, 177 | bindToTexture: { 178 | parameters: [{ 179 | name: 'TEXTURE_MAG_FILTER', 180 | value: 'LINEAR' 181 | }, { 182 | name: 'TEXTURE_MIN_FILTER', 183 | value: 'LINEAR', 184 | generateMipmap: false 185 | }] 186 | }, 187 | bindToRenderBuffer: true 188 | }); 189 | 190 | //Basic gl setup 191 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 192 | gl.clearDepth(1.0); 193 | gl.enable(gl.DEPTH_TEST); 194 | gl.depthFunc(gl.LEQUAL); 195 | 196 | //Add objects to different scenes 197 | outerScene.add(macbook, macbookscreen); 198 | innerScene.add(moon, box); 199 | 200 | outerCamera.update(); 201 | innerCamera.update(); 202 | 203 | outerCamera.view.$translate(0, -0.5, 0); 204 | 205 | function drawInnerScene() { 206 | program.setFrameBuffer('monitor', true); 207 | 208 | gl.viewport(0, 0, screenWidth, screenHeight); 209 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 210 | 211 | theta += 0.01; 212 | 213 | moon.position = { 214 | x: rho * Math.cos(theta), 215 | y: 0, 216 | z: rho * Math.sin(theta) 217 | }; 218 | moon.update(); 219 | 220 | box.position = { 221 | x: rho * Math.cos(Math.PI + theta), 222 | y: 0, 223 | z: rho * Math.sin(Math.PI + theta) 224 | }; 225 | box.update(); 226 | 227 | innerScene.renderToTexture('monitor'); 228 | 229 | program.setFrameBuffer('monitor', false); 230 | } 231 | 232 | function drawOuterScene() { 233 | gl.viewport(0, 0, screenWidth, screenHeight); 234 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 235 | 236 | laptopTheta += 0.005; 237 | 238 | macbook.rotation.set(-Math.PI /2, laptopTheta, 0); 239 | macbook.update(); 240 | 241 | macbookscreen.rotation.set(-Math.PI /2, laptopTheta, 0); 242 | macbookscreen.update(); 243 | 244 | outerScene.render(); 245 | } 246 | 247 | function draw() { 248 | drawInnerScene(); 249 | drawOuterScene(); 250 | PhiloGL.Fx.requestAnimationFrame(draw); 251 | } 252 | 253 | //Animate 254 | draw(); 255 | } 256 | }); 257 | } 258 | } 259 | 260 | 261 | 262 | -------------------------------------------------------------------------------- /examples/lessons/8/index.js: -------------------------------------------------------------------------------- 1 | //Add Blend Fragment Shader 2 | PhiloGL.Shaders.Fragment.Blend = [ 3 | 4 | "#ifdef GL_ES", 5 | "precision highp float;", 6 | "#endif", 7 | 8 | "varying vec4 vColor;", 9 | "varying vec2 vTexCoord;", 10 | "varying vec3 lightWeighting;", 11 | 12 | "uniform bool hasTexture1;", 13 | "uniform sampler2D sampler1;", 14 | "uniform float alpha;", 15 | 16 | "void main(){", 17 | 18 | "if (hasTexture1) {", 19 | 20 | "gl_FragColor = vec4(texture2D(sampler1, vec2(vTexCoord.s, vTexCoord.t)).rgb * lightWeighting, alpha);", 21 | 22 | "}", 23 | 24 | "}" 25 | 26 | ].join("\n"); 27 | 28 | //Lighting form elements variables 29 | var $id = function(d) { return document.getElementById(d); }; 30 | 31 | function webGLStart() { 32 | var xRot = 0, xSpeed = 0, 33 | yRot = 0, ySpeed = 0, 34 | z = -5.0; 35 | 36 | //Get lighting form elements 37 | var lighting = $id('lighting'), 38 | ambient = { 39 | r: $id('ambientR'), 40 | g: $id('ambientG'), 41 | b: $id('ambientB') 42 | }, 43 | direction = { 44 | x: $id('lightDirectionX'), 45 | y: $id('lightDirectionY'), 46 | z: $id('lightDirectionZ'), 47 | 48 | r: $id('directionalR'), 49 | g: $id('directionalG'), 50 | b: $id('directionalB') 51 | }, 52 | blending = $id('blending'), 53 | alpha = $id('alpha'); 54 | 55 | //Create object 56 | var cube = new PhiloGL.O3D.Model({ 57 | vertices: [-1, -1, 1, 58 | 1, -1, 1, 59 | 1, 1, 1, 60 | -1, 1, 1, 61 | 62 | -1, -1, -1, 63 | -1, 1, -1, 64 | 1, 1, -1, 65 | 1, -1, -1, 66 | 67 | -1, 1, -1, 68 | -1, 1, 1, 69 | 1, 1, 1, 70 | 1, 1, -1, 71 | 72 | -1, -1, -1, 73 | 1, -1, -1, 74 | 1, -1, 1, 75 | -1, -1, 1, 76 | 77 | 1, -1, -1, 78 | 1, 1, -1, 79 | 1, 1, 1, 80 | 1, -1, 1, 81 | 82 | -1, -1, -1, 83 | -1, -1, 1, 84 | -1, 1, 1, 85 | -1, 1, -1], 86 | 87 | textures: 'glass.gif', 88 | 89 | texCoords: [0.0, 0.0, 90 | 1.0, 0.0, 91 | 1.0, 1.0, 92 | 0.0, 1.0, 93 | 94 | // Back face 95 | 1.0, 0.0, 96 | 1.0, 1.0, 97 | 0.0, 1.0, 98 | 0.0, 0.0, 99 | 100 | // Top face 101 | 0.0, 1.0, 102 | 0.0, 0.0, 103 | 1.0, 0.0, 104 | 1.0, 1.0, 105 | 106 | // Bottom face 107 | 1.0, 1.0, 108 | 0.0, 1.0, 109 | 0.0, 0.0, 110 | 1.0, 0.0, 111 | 112 | // Right face 113 | 1.0, 0.0, 114 | 1.0, 1.0, 115 | 0.0, 1.0, 116 | 0.0, 0.0, 117 | 118 | // Left face 119 | 0.0, 0.0, 120 | 1.0, 0.0, 121 | 1.0, 1.0, 122 | 0.0, 1.0], 123 | 124 | normals: [ 125 | // Front face 126 | 0.0, 0.0, 1.0, 127 | 0.0, 0.0, 1.0, 128 | 0.0, 0.0, 1.0, 129 | 0.0, 0.0, 1.0, 130 | 131 | // Back face 132 | 0.0, 0.0, -1.0, 133 | 0.0, 0.0, -1.0, 134 | 0.0, 0.0, -1.0, 135 | 0.0, 0.0, -1.0, 136 | 137 | // Top face 138 | 0.0, 1.0, 0.0, 139 | 0.0, 1.0, 0.0, 140 | 0.0, 1.0, 0.0, 141 | 0.0, 1.0, 0.0, 142 | 143 | // Bottom face 144 | 0.0, -1.0, 0.0, 145 | 0.0, -1.0, 0.0, 146 | 0.0, -1.0, 0.0, 147 | 0.0, -1.0, 0.0, 148 | 149 | // Right face 150 | 1.0, 0.0, 0.0, 151 | 1.0, 0.0, 0.0, 152 | 1.0, 0.0, 0.0, 153 | 1.0, 0.0, 0.0, 154 | 155 | // Left face 156 | -1.0, 0.0, 0.0, 157 | -1.0, 0.0, 0.0, 158 | -1.0, 0.0, 0.0, 159 | -1.0, 0.0, 0.0 160 | ], 161 | 162 | indices: [0, 1, 2, 0, 2, 3, 163 | 4, 5, 6, 4, 6, 7, 164 | 8, 9, 10, 8, 10, 11, 165 | 12, 13, 14, 12, 14, 15, 166 | 16, 17, 18, 16, 18, 19, 167 | 20, 21, 22, 20, 22, 23] 168 | }); 169 | 170 | PhiloGL('lesson08-canvas', { 171 | program: { 172 | from: 'defaults', 173 | fs: 'Blend' 174 | }, 175 | textures: { 176 | src: ['glass.gif'], 177 | parameters: [{ 178 | name: 'TEXTURE_MAG_FILTER', 179 | value: 'LINEAR' 180 | }, { 181 | name: 'TEXTURE_MIN_FILTER', 182 | value: 'LINEAR_MIPMAP_NEAREST', 183 | generateMipmap: true 184 | }] 185 | }, 186 | events: { 187 | onKeyDown: function(e) { 188 | switch(e.key) { 189 | case 'f': 190 | filter = (filter + 1) % 3; 191 | break; 192 | case 'up': 193 | xSpeed -= 0.02; 194 | break; 195 | case 'down': 196 | xSpeed += 0.02; 197 | break; 198 | case 'left': 199 | ySpeed -= 0.02; 200 | break; 201 | case 'right': 202 | ySpeed += 0.02; 203 | break; 204 | //handle page up/down 205 | default: 206 | if (e.code == 33) { 207 | z -= 0.05; 208 | } else if (e.code == 34) { 209 | z += 0.05; 210 | } 211 | } 212 | } 213 | }, 214 | onError: function() { 215 | alert("An error ocurred while loading the application"); 216 | }, 217 | onLoad: function(app) { 218 | var gl = app.gl, 219 | canvas = app.canvas, 220 | program = app.program, 221 | camera = app.camera, 222 | scene = app.scene; 223 | 224 | gl.viewport(0, 0, canvas.width, canvas.height); 225 | gl.clearColor(0, 0, 0, 1); 226 | gl.clearDepth(1); 227 | gl.enable(gl.DEPTH_TEST); 228 | gl.depthFunc(gl.LEQUAL); 229 | 230 | camera.view.id(); 231 | 232 | //Add object to our default scene 233 | scene.add(cube); 234 | 235 | function animate() { 236 | xRot += xSpeed; 237 | yRot += ySpeed; 238 | } 239 | 240 | function tick() { 241 | drawScene(); 242 | animate(); 243 | PhiloGL.Fx.requestAnimationFrame(tick); 244 | } 245 | 246 | function drawScene() { 247 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 248 | //Update Cube position 249 | cube.position.set(0, 0, z); 250 | cube.rotation.set(xRot, yRot, 0); 251 | cube.update(); 252 | if (blending.checked) { 253 | gl.blendFunc(gl.SRC_ALPHA, gl.ONE); 254 | gl.enable(gl.BLEND); 255 | gl.disable(gl.DEPTH_TEST); 256 | program.setUniform('alpha', +alpha.value); 257 | } else { 258 | gl.disable(gl.BLEND); 259 | gl.enable(gl.DEPTH_TEST); 260 | } 261 | //Update scene config with light info 262 | var lightConfig = scene.config.lights; 263 | lightConfig.enable = lighting.checked; 264 | lightConfig.ambient = { 265 | r: +ambient.r.value, 266 | g: +ambient.g.value, 267 | b: +ambient.b.value 268 | }; 269 | lightConfig.directional.direction = { 270 | x: +direction.x.value, 271 | y: +direction.y.value, 272 | z: +direction.z.value 273 | }; 274 | lightConfig.directional.color = { 275 | r: +direction.r.value, 276 | g: +direction.g.value, 277 | b: +direction.b.value 278 | }; 279 | //Render all elements in the Scene 280 | scene.render(); 281 | } 282 | tick(); 283 | } 284 | }); 285 | } 286 | 287 | -------------------------------------------------------------------------------- /examples/lessons/16/WebGLExport.py: -------------------------------------------------------------------------------- 1 | #!BPY 2 | 3 | """ 4 | Name: 'WebGL JavaScript (.js)' 5 | Blender: 244 6 | Group: 'Export' 7 | Tooltip: 'WebGL JavaScript' 8 | """ 9 | 10 | # -------------------------------------------------------------------------- 11 | # ***** BEGIN GPL LICENSE BLOCK ***** 12 | # 13 | # Copyright (C) 2010 Dennis Ippel 14 | # 15 | # This program is free software; you can redistribute it and/or 16 | # modify it under the terms of the GNU General Public License 17 | # as published by the Free Software Foundation; either version 2 18 | # of the License, or (at your option) any later version. 19 | # 20 | # This program is distributed in the hope that it will be useful, 21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | # GNU General Public License for more details. 24 | # 25 | # You should have received a copy of the GNU General Public License 26 | # along with this program; if not, write to the Free Software Foundation, 27 | # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 28 | # 29 | # ***** END GPL LICENCE BLOCK ***** 30 | # -------------------------------------------------------------------------- 31 | 32 | __author__ = "Dennis Ippel" 33 | __url__ = ("http://www.rozengain.com") 34 | __version__ = "0.2" 35 | 36 | __bpydoc__ = """ 37 | 38 | For more information please go to: 39 | http://www.rozengain.com 40 | """ 41 | import Blender 42 | from Blender import * 43 | import bpy 44 | import bpy 45 | import os 46 | from Blender.BGL import * 47 | 48 | EVENT_NOEVENT = 1 49 | EVENT_DRAW = 2 50 | EVENT_EXIT = 3 51 | EVENT_EXPORT = 4 52 | EVENT_BROWSEFILE = 5 53 | 54 | file_button = Draw.Create("") 55 | engine_menu = Draw.Create(1) 56 | exp_all = Draw.Create(0) 57 | exp_normals = Draw.Create(0) 58 | animation_button = Draw.Create(0) 59 | animation_start = Draw.Create(0) 60 | animation_end = Draw.Create(0) 61 | 62 | def export_scenejs(class_name, mesh): 63 | s = "var BlenderExport = {};\n" 64 | s += "BlenderExport.%s = function() {\n" % (class_name) 65 | s += "return SceneJS.geometry({\n" 66 | s += "type: \'%s\',\n" % (class_name) 67 | 68 | vertices = "vertices : [" 69 | indices = "indices : [" 70 | indexcount = 0; 71 | print len(mesh.faces) 72 | for f in mesh.faces: 73 | vertices += "[%.6f,%.6f,%.6f],[%.6f,%.6f,%.6f],[%.6f,%.6f,%.6f]," % (f.verts[0].co.x, f.verts[0].co.y, f.verts[0].co.z,f.verts[1].co.x, f.verts[1].co.y, f.verts[1].co.z,f.verts[2].co.x, f.verts[2].co.y, f.verts[2].co.z) 74 | indices += "[%i,%i,%i]," % (indexcount,indexcount+1,indexcount+2) 75 | indexcount += 3 76 | 77 | indices += "],\n"; 78 | vertices += "],\n"; 79 | 80 | s += vertices 81 | s += indices 82 | 83 | if(exp_normals == 1): 84 | s += "normals : [" 85 | for v in mesh.verts: 86 | s += "[%.6f, %.6f, %.6f]," % (v.no.x, v.no.y, v.no.z) 87 | 88 | s += "],\n" 89 | if (mesh.vertexColors): 90 | s += "colors : [" 91 | for face in mesh.faces: 92 | for (vert, color) in zip(face.verts, face.col): 93 | s += "[%.6f,%.6f,%.6f,%.6f]," % ( color.r / 255.0, color.g / 255.0, color.b / 255.0, color.a / 255.0) 94 | s += "]\n" 95 | if (mesh.faceUV): 96 | s += "texCoords : [" 97 | for face in mesh.faces: 98 | s += "[%.6f,%.6f],[%.6f,%.6f],[%.6f,%.6f]," % (face.uv[0][0], face.uv[0][1], face.uv[1][0], face.uv[1][1], face.uv[2][0], face.uv[2][1]) 99 | 100 | s += "]\n" 101 | 102 | s += "});\n};" 103 | 104 | return s 105 | 106 | def export_native(class_name, mesh, ob): 107 | s = "var BlenderExport = {};\n" 108 | s += "BlenderExport.%s = {};\n" % (class_name) 109 | 110 | vertices = "BlenderExport.%s.vertices = [" % (class_name) 111 | indices = "BlenderExport.%s.indices = [" % (class_name) 112 | indexcount = 0; 113 | 114 | for f in mesh.faces: 115 | vertices += "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f," % (f.verts[0].co.x, f.verts[0].co.y, f.verts[0].co.z,f.verts[1].co.x, f.verts[1].co.y, f.verts[1].co.z,f.verts[2].co.x, f.verts[2].co.y, f.verts[2].co.z) 116 | indexcount += 3 117 | 118 | indices += "];\n"; 119 | vertices += "];\n"; 120 | 121 | s += vertices 122 | s += indices 123 | 124 | s += "for(var i=0;i<%s;i++) BlenderExport.%s.indices.push(i);\n" % (indexcount, class_name) 125 | 126 | if(exp_normals == 1): 127 | s += "BlenderExport.%s.normals = [" % (class_name) 128 | for v in mesh.verts: 129 | s += "%.6f, %.6f, %.6f," % (v.no.x, v.no.y, v.no.z) 130 | 131 | s += "];\n" 132 | if (mesh.vertexColors): 133 | s += "BlenderExport.%s.colors = [" % (class_name) 134 | for face in mesh.faces: 135 | for (vert, color) in zip(face.verts, face.col): 136 | s += "%.6f,%.6f,%.6f,%.6f," % ( color.r / 255.0, color.g / 255.0, color.b / 255.0, color.a / 255.0) 137 | s += "];\n" 138 | if (mesh.faceUV): 139 | s += "BlenderExport.%s.texCoords = [" % (class_name) 140 | for face in mesh.faces: 141 | s += "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f," % (face.uv[0][0], face.uv[0][1], face.uv[1][0], face.uv[1][1], face.uv[2][0], face.uv[2][1]) 142 | s += "];\n" 143 | 144 | if animation_button.val: 145 | s += "BlenderExport.%s.frames = [" % (class_name) 146 | matrix = ob.getMatrix('worldspace') 147 | 148 | for frame in xrange(animation_start.val, animation_end.val): 149 | Blender.Set('curframe', frame) 150 | tmpMesh = Mesh.New() 151 | tmpMesh.getFromObject(ob.name) 152 | tmpMesh.transform(matrix) 153 | s+= "[" 154 | for f in tmpMesh.faces: 155 | for v in f.verts: 156 | s += "%.6f,%.6f,%.6f," % (v.co.x, v.co.y, v.co.z) 157 | 158 | s += "]," 159 | s += "];" 160 | 161 | return s 162 | 163 | 164 | def export_json(objects): 165 | result = [] 166 | result.append('{\n') 167 | 168 | for obj in objects: 169 | mesh = Mesh.New() 170 | mesh.getFromObject(obj, 0) 171 | 172 | indexCount = 0 173 | positions = [] 174 | normals = [] 175 | textureCoords = [] 176 | for face in mesh.faces: 177 | for vertex in face.verts: 178 | positions.extend(('%.6f' % value) for value in (vertex.co.x, vertex.co.y, vertex.co.z)) 179 | if exp_normals == 1: 180 | normals.extend(('%.6f' % value) for value in (vertex.no.x, vertex.no.y, vertex.no.z)) 181 | if mesh.faceUV: 182 | textureCoords.extend(('%.6f' % value) for value in (face.uv[0][0], face.uv[0][1], face.uv[1][0], face.uv[1][1], face.uv[2][0], face.uv[2][1])) 183 | indexCount += 3 184 | 185 | result.append('\t"%s" : {\n' % obj.name) 186 | 187 | result.append('\t\t"vertexPositions" : [') 188 | result.extend(', '.join(positions)) 189 | result.append('],\n') 190 | 191 | if exp_normals == 1: 192 | result.append('\t\t"vertexNormals" : [') 193 | result.extend(', '.join(normals)) 194 | result.append('],\n') 195 | 196 | result.append('\t\t"vertexTextureCoords" : [') 197 | result.extend(', '.join(textureCoords)) 198 | result.append('],\n') 199 | 200 | result.append('\t\t"indices" : [') 201 | result.append(', '.join(str(i) for i in range(indexCount))) 202 | result.append(']\n') 203 | 204 | 205 | result.append('\t},\n') 206 | 207 | 208 | result.append('}\n') 209 | return ''.join(result) 210 | 211 | 212 | 213 | def export_glge_js(class_name, mesh): 214 | s = "var BlenderExport = {};\n" 215 | s += "BlenderExport.%s = function() {\n" % (class_name) 216 | s += "var obj=new GLGE.Object(\'%s\');\n" % (class_name) 217 | s += "var mesh=new GLGE.Mesh();\n" 218 | vertices = "mesh.setPositions([" 219 | normals = "mesh.setNormals([" 220 | uvs = "mesh.setUV([" 221 | indices = "mesh.setFaces([" 222 | indexcount = 0; 223 | for f in mesh.faces: 224 | vertices += "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f," % (f.verts[0].co.x, f.verts[0].co.y, f.verts[0].co.z,f.verts[1].co.x, f.verts[1].co.y, f.verts[1].co.z,f.verts[2].co.x, f.verts[2].co.y, f.verts[2].co.z) 225 | if (f.smooth): 226 | normals += "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f," % (f.verts[0].no.x, f.verts[0].no.y, f.verts[0].no.z,f.verts[1].no.x, f.verts[1].no.y, f.verts[1].no.z,f.verts[2].no.x, f.verts[2].no.y, f.verts[2].no.z) 227 | else: 228 | normals += "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f," % (f.no.x, f.no.y, f.no.z,f.no.x, f.no.y, f.no.z,f.no.x, f.no.y, f.no.z) 229 | if (mesh.faceUV): 230 | uvs += "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f," % (f.uv[0][0], f.uv[0][1], f.uv[1][0], f.uv[1][1], f.uv[2][0], f.uv[2][1]) 231 | indices += "%i,%i,%i," % (indexcount,indexcount+1,indexcount+2) 232 | indexcount += 3 233 | 234 | indicies=indices[:len(indices)-1] 235 | normals=normals[:len(normals)-1] 236 | if (mesh.faceUV): 237 | uvs=uvs[:len(uvs)-1] 238 | vertices=vertices[:len(vertices)-1] 239 | 240 | indices += "]);\n"; 241 | normals += "]);\n"; 242 | uvs += "]);\n"; 243 | vertices += "]);\n"; 244 | 245 | s += vertices 246 | s += normals 247 | if (mesh.faceUV): 248 | s += uvs 249 | s += indices 250 | 251 | s += "var material=new GLGE.Material();\n" 252 | s += "obj.setMaterial(material);\n" 253 | s += "obj.setMesh(mesh);\n" 254 | s += "return obj;\n};" 255 | print s 256 | return s 257 | 258 | def export_glge_xml(class_name, mesh): 259 | s = "\n" 260 | s += "\n" 261 | s += "\n" % (class_name) 262 | vertices = "" 263 | normals = "" 264 | uvs = "" 265 | indices = "" 266 | indexcount = 0; 267 | for f in mesh.faces: 268 | vertices += "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f," % (f.verts[0].co.x, f.verts[0].co.y, f.verts[0].co.z,f.verts[1].co.x, f.verts[1].co.y, f.verts[1].co.z,f.verts[2].co.x, f.verts[2].co.y, f.verts[2].co.z) 269 | if (f.smooth): 270 | normals += "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f," % (f.verts[0].no.x, f.verts[0].no.y, f.verts[0].no.z,f.verts[1].no.x, f.verts[1].no.y, f.verts[1].no.z,f.verts[2].no.x, f.verts[2].no.y, f.verts[2].no.z) 271 | else: 272 | normals += "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f," % (f.no.x, f.no.y, f.no.z,f.no.x, f.no.y, f.no.z,f.no.x, f.no.y, f.no.z) 273 | if (mesh.faceUV): 274 | uvs += "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f," % (f.uv[0][0], f.uv[0][1], f.uv[1][0], f.uv[1][1], f.uv[2][0], f.uv[2][1]) 275 | indices += "%i,%i,%i," % (indexcount,indexcount+1,indexcount+2) 276 | indexcount += 3 277 | 278 | indicies=indices[:len(indices)-1] 279 | normals=normals[:len(normals)-1] 280 | uvs=uvs[:len(uvs)-1] 281 | vertices=vertices[:len(vertices)-1] 282 | 283 | indices += "\n"; 284 | normals += ";\n"; 285 | uvs += "\n"; 286 | vertices += "\n"; 287 | 288 | s += vertices 289 | s += normals 290 | if (mesh.faceUV): 291 | s += uvs 292 | s += indices 293 | 294 | s += "\n" 295 | s += "" 296 | 297 | return s 298 | 299 | def event(evt, val): 300 | if (evt == Draw.QKEY and not val): 301 | Draw.Exit() 302 | 303 | def bevent(evt): 304 | global EVENT_NOEVENT,EVENT_DRAW,EVENT_EXIT 305 | 306 | if (evt == EVENT_EXIT): 307 | Draw.Exit() 308 | elif (evt== EVENT_DRAW): 309 | Draw.Redraw() 310 | elif (evt== EVENT_EXPORT): 311 | sce = bpy.data.scenes.active 312 | 313 | obs = None 314 | 315 | if(exp_all == 1): 316 | # export all scene objects 317 | obs = [ob for ob in sce.objects if ob.type == 'Mesh'] 318 | else: 319 | # export the selected objects 320 | obs = [ob for ob in sce.objects.selected if ob.type == 'Mesh'] 321 | 322 | if (len(obs) == 0): 323 | Draw.PupMenu("Nothing to export. Please select a Mesh.") 324 | Draw.Exit() 325 | return 326 | 327 | if engine_menu.val == 6: 328 | filename = file_button.val 329 | if not filename.endswith(".json"): 330 | filename += ".json" 331 | out = open(filename, 'w') 332 | out.write(export_json(obs)) 333 | out.close() 334 | else: 335 | # export all object names to separate files 336 | for ob in obs: 337 | me = Mesh.New() 338 | me.getFromObject(ob,0) 339 | class_name = ob.name.replace(".", "") 340 | ext = "" 341 | if(engine_menu.val ==4): ext = ".xml" 342 | else: ext = ".js" 343 | out = open(file_button.val+""+class_name+ext, 'w')#file(file_button.val, 'w') 344 | data_string = "" 345 | 346 | if (engine_menu.val == 1): 347 | data_string = export_native(class_name, me, ob) 348 | elif(engine_menu.val == 2): 349 | data_string = export_scenejs(class_name, me) 350 | elif(engine_menu.val == 3): 351 | data_string = export_glge_js(class_name, me) 352 | elif(engine_menu.val == 4): 353 | data_string = export_glge_xml(class_name, me) 354 | elif(engine_menu.val == 5): 355 | data_string = export_copperlicht(class_name, me) 356 | 357 | out.write(data_string) 358 | out.close() 359 | 360 | Draw.PupMenu("Export Successful") 361 | elif (evt== EVENT_BROWSEFILE): 362 | if (engine_menu.val == 4): 363 | Window.FileSelector(FileSelected,"Export .xml", exp_file_name) 364 | elif (engine_menu.val == 6): 365 | Window.FileSelector(FileSelected,"Export .json", exp_file_name) 366 | else: 367 | Window.FileSelector(FileSelected,"Export .js", exp_file_name) 368 | Draw.Redraw(1) 369 | 370 | def FileSelected(file_name): 371 | global file_button 372 | 373 | if file_name != '': 374 | file_button.val = file_name 375 | else: 376 | cutils.Debug.Debug('ERROR: filename is empty','ERROR') 377 | 378 | def draw(): 379 | global file_button, exp_file_name, animation_button, animation_start, animation_end 380 | global engine_menu, engine_name, exp_normals, exp_all 381 | global EVENT_NOEVENT, EVENT_DRAW, EVENT_EXIT, EVENT_EXPORT 382 | exp_file_name = "" 383 | 384 | glClear(GL_COLOR_BUFFER_BIT) 385 | glRasterPos2i(40, 240) 386 | 387 | engine_name = "Native WebGL%x1|SceneJS%x2|GLGE JS%x3|GLGE XML%x4|JSON%x6" 388 | engine_menu = Draw.Menu(engine_name, EVENT_NOEVENT, 40, 100, 200, 20, engine_menu.val, "Choose your engine") 389 | 390 | file_button = Draw.String('File location: ', EVENT_NOEVENT, 40, 70, 250, 20, file_button.val, 255) 391 | Draw.PushButton('...', EVENT_BROWSEFILE, 300, 70, 30, 20, 'browse file') 392 | exp_normals = Draw.Toggle('Export normals', EVENT_NOEVENT, 250, 45, 100, 20, exp_normals.val) 393 | 394 | anim_down = 0 395 | 396 | if animation_button.val == 1: 397 | anim_down = 1 398 | 399 | animation_button = Draw.Toggle('Export animation frames (native WebGL only)', EVENT_NOEVENT, 400, 70, 300, 20, animation_button.val, 'Export keyframe animation') 400 | animation_start = Draw.Number('Start frame', EVENT_NOEVENT, 400, 45, 160, 20, animation_start.val, 1, 9999) 401 | animation_end = Draw.Number('End frame', EVENT_NOEVENT, 400, 20, 160, 20, animation_end.val, 2, 9999) 402 | 403 | exp_all = Draw.Toggle('Export ALL scene objects', EVENT_NOEVENT, 40, 45, 200, 20, exp_all.val) 404 | 405 | Draw.Button("Export",EVENT_EXPORT , 40, 20, 80, 18) 406 | Draw.Button("Exit",EVENT_EXIT , 140, 20, 80, 18) 407 | 408 | Draw.Register(draw, event, bevent) 409 | --------------------------------------------------------------------------------