From 6b53a01d5282daa1b6c4c9f353559734909bb423 Mon Sep 17 00:00:00 2001 From: D1plo1d Date: Wed, 6 Feb 2013 17:23:52 -0500 Subject: [PATCH 1/3] Scoping the $ utility function so that it does not conflict with jquery or any other libraries --- src/camera.js | 3 +- src/core.js | 84 ++++++++++++++++++++++++++------------------------ src/event.js | 1 + src/fx.js | 2 ++ src/io.js | 1 + src/math.js | 1 + src/media.js | 1 + src/o3d.js | 1 + src/program.js | 1 + src/scene.js | 3 +- src/shaders.js | 1 + src/webgl.js | 1 + 12 files changed, 57 insertions(+), 43 deletions(-) diff --git a/src/camera.js b/src/camera.js index 260737e5..df1c0a7f 100644 --- a/src/camera.js +++ b/src/camera.js @@ -4,7 +4,8 @@ (function () { //Define some locals var Vec3 = PhiloGL.Vec3, - Mat4 = PhiloGL.Mat4; + Mat4 = PhiloGL.Mat4, + $ = PhiloGL.$; //Camera class var Camera = function(fov, aspect, near, far, opt) { diff --git a/src/core.js b/src/core.js index 209dedc7..533cdff3 100644 --- a/src/core.js +++ b/src/core.js @@ -8,6 +8,7 @@ this.PhiloGL = null; //with a gl context, a camera, a program, a scene, and an event system. (function () { PhiloGL = function(canvasId, opt) { + var $ = PhiloGL.$; opt = $.merge({ context: { /* @@ -166,7 +167,7 @@ PhiloGL.unpack = function(branch) { branch[module] = PhiloGL[module]; }); branch.gl = gl; - branch.Utils = $; + branch.Utils = PhiloGL.$; }; //Version @@ -176,47 +177,48 @@ PhiloGL.version = '1.5.2'; var gl, app, globalContext = this; //Utility functions -function $(d) { - return document.getElementById(d); -} - -$.empty = function() {}; +(function() { + PhiloGL.$ = function (d) { + return document.getElementById(d); + } + var $ = PhiloGL.$; -$.time = Date.now; + $.empty = function() {}; -$.uid = (function() { - var t = $.time(); + $.time = Date.now; - return function() { - return t++; - }; -})(); + $.uid = (function() { + var t = $.time(); -$.extend = function(to, from) { - for (var p in from) { - to[p] = from[p]; - } - return to; -}; + return function() { + return t++; + }; + })(); -$.type = (function() { - var oString = Object.prototype.toString, - type = function(e) { - var t = oString.call(e); - return t.substr(8, t.length - 9).toLowerCase(); - }; - - return function(elem) { - var elemType = type(elem); - if (elemType != 'object') { - return elemType; + $.extend = function(to, from) { + for (var p in from) { + to[p] = from[p]; } - if (elem.$$family) return elem.$$family; - return (elem && elem.nodeName && elem.nodeType == 1) ? 'element' : elemType; + return to; }; -})(); -(function() { + $.type = (function() { + var oString = Object.prototype.toString, + type = function(e) { + var t = oString.call(e); + return t.substr(8, t.length - 9).toLowerCase(); + }; + + return function(elem) { + var elemType = type(elem); + if (elemType != 'object') { + return elemType; + } + if (elem.$$family) return elem.$$family; + return (elem && elem.nodeName && elem.nodeType == 1) ? 'element' : elemType; + }; + })(); + function detach(elem) { var type = $.type(elem), ans; if (type == 'object') { @@ -252,12 +254,12 @@ $.type = (function() { } return mix; }; -})(); -$.splat = (function() { - var isArray = Array.isArray; - return function(a) { - return isArray(a) && a || [a]; - }; -})(); + $.splat = (function() { + var isArray = Array.isArray; + return function(a) { + return isArray(a) && a || [a]; + }; + })(); +})(); diff --git a/src/event.js b/src/event.js index 2fff5c62..a8c7749a 100644 --- a/src/event.js +++ b/src/event.js @@ -2,6 +2,7 @@ //Handle keyboard/mouse/touch events in the Canvas (function() { + var $ = PhiloGL.$; //returns an O3D object or false otherwise. function toO3D(n) { diff --git a/src/fx.js b/src/fx.js index e2ec44c8..7d196e06 100644 --- a/src/fx.js +++ b/src/fx.js @@ -1,4 +1,6 @@ (function() { + var $ = PhiloGL.$; + //Timer based animation var Fx = function(options) { this.opt = $.merge({ diff --git a/src/io.js b/src/io.js index a51d24c4..4284ca64 100644 --- a/src/io.js +++ b/src/io.js @@ -2,6 +2,7 @@ //Provides loading of assets with XHR and JSONP methods. (function () { + var $ = PhiloGL.$; var IO = {}; var XHR = function(opt) { diff --git a/src/math.js b/src/math.js index eba1807b..876b087d 100644 --- a/src/math.js +++ b/src/math.js @@ -2,6 +2,7 @@ //Vec3, Mat4 and Quat classes (function() { + var sqrt = Math.sqrt, sin = Math.sin, cos = Math.cos, diff --git a/src/media.js b/src/media.js index dbaba33a..b975920d 100644 --- a/src/media.js +++ b/src/media.js @@ -2,6 +2,7 @@ //media has utility functions for image, video and audio manipulation (and //maybe others like device, etc). (function() { + var $ = PhiloGL.$; var Media = {}; var Image = function() {}; diff --git a/src/o3d.js b/src/o3d.js index d87641e5..a9d2f93d 100644 --- a/src/o3d.js +++ b/src/o3d.js @@ -2,6 +2,7 @@ //Scene Objects (function () { + var $ = PhiloGL.$; //Define some locals var Vec3 = PhiloGL.Vec3, Mat4 = PhiloGL.Mat4, diff --git a/src/program.js b/src/program.js index aa3f90c2..c288620e 100644 --- a/src/program.js +++ b/src/program.js @@ -3,6 +3,7 @@ //buffers attributes and uniforms (function() { + var $ = PhiloGL.$; //First, some privates to handle compiling/linking shaders to programs. //Creates a shader from a string source. diff --git a/src/scene.js b/src/scene.js index 398ea8e9..7a2b1e4c 100644 --- a/src/scene.js +++ b/src/scene.js @@ -4,7 +4,8 @@ (function() { //Define some locals var Vec3 = PhiloGL.Vec3, - Mat4 = PhiloGL.Mat4; + Mat4 = PhiloGL.Mat4, + $ = PhiloGL.$; //Scene class var Scene = function(program, camera, opt) { diff --git a/src/shaders.js b/src/shaders.js index 1ee3d8f2..f70b4490 100644 --- a/src/shaders.js +++ b/src/shaders.js @@ -2,6 +2,7 @@ //Default Shaders (function() { + var $ = PhiloGL.$; //Add default shaders var Shaders = { Vertex: {}, diff --git a/src/webgl.js b/src/webgl.js index c27e4ff2..35b0a4c8 100644 --- a/src/webgl.js +++ b/src/webgl.js @@ -2,6 +2,7 @@ //Checks if WebGL is enabled and creates a context for using WebGL. (function () { + var $ = PhiloGL.$; var WebGL = { From f22b9bc3cba5d473067211874a654ac74bd4c012 Mon Sep 17 00:00:00 2001 From: D1plo1d Date: Wed, 6 Feb 2013 19:19:32 -0500 Subject: [PATCH 2/3] Removing app from the global namespace. Less namespace polution is good. --- src/core.js | 31 +++++++++++++++++-------------- src/io.js | 1 + src/media.js | 4 +++- src/o3d.js | 1 + src/program.js | 2 ++ src/scene.js | 3 +++ 6 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/core.js b/src/core.js index 533cdff3..0bd4390d 100644 --- a/src/core.js +++ b/src/core.js @@ -80,7 +80,7 @@ this.PhiloGL = null; count--; if (count === 0 && !error) { loadProgramDeps(gl, programLength == 1? p : programs, function(app) { - opt.onLoad(app); + opt.onLoad(PhiloGL.app); }); } }, @@ -122,14 +122,14 @@ this.PhiloGL = null; //get Scene var scene = new PhiloGL.Scene(program, camera, optScene); - //make app instance global to all framework - app = new PhiloGL.WebGL.Application({ + PhiloGL.app = new PhiloGL.WebGL.Application({ gl: gl, canvas: canvas, program: program, scene: scene, camera: camera }); + var app = PhiloGL.app; //Use program if (program.$$family == 'program') { @@ -159,22 +159,25 @@ this.PhiloGL = null; })(); -//Unpacks the submodules to the global space. -PhiloGL.unpack = function(branch) { - branch = branch || globalContext; - ['Vec3', 'Mat4', 'Quat', 'Camera', 'Program', 'WebGL', 'O3D', - 'Scene', 'Shaders', 'IO', 'Events', 'WorkerGroup', 'Fx', 'Media'].forEach(function(module) { - branch[module] = PhiloGL[module]; - }); - branch.gl = gl; - branch.Utils = PhiloGL.$; -}; +(function() { + globalContext = this; + //Unpacks the submodules to the global space. + PhiloGL.unpack = function(branch) { + branch = branch || globalContext; + ['Vec3', 'Mat4', 'Quat', 'Camera', 'Program', 'WebGL', 'O3D', + 'Scene', 'Shaders', 'IO', 'Events', 'WorkerGroup', 'Fx', 'Media'].forEach(function(module) { + branch[module] = PhiloGL[module]; + }); + branch.gl = gl; + branch.Utils = PhiloGL.$; + }; +}); //Version PhiloGL.version = '1.5.2'; //Holds the 3D context, holds the application -var gl, app, globalContext = this; +var gl //Utility functions (function() { diff --git a/src/io.js b/src/io.js index 4284ca64..1196e2ae 100644 --- a/src/io.js +++ b/src/io.js @@ -267,6 +267,7 @@ //Load multiple textures from images var Textures = function(opt) { + var app = PhiloGL.app; opt = $.merge({ src: [], noCache: false, diff --git a/src/media.js b/src/media.js index b975920d..37d9ef57 100644 --- a/src/media.js +++ b/src/media.js @@ -19,7 +19,8 @@ }), scene = new PhiloGL.Scene({}, camera); return function(opt) { - var program = app.program.$$family ? app.program : app.program[opt.program], + var app = PhiloGL.app, + program = app.program.$$family ? app.program : app.program[opt.program], textures = opt.fromTexture ? $.splat(opt.fromTexture) : [], framebuffer = opt.toFrameBuffer, screen = !!opt.toScreen, @@ -38,6 +39,7 @@ scene.add(plane); } + var app = PhiloGL.app; if (framebuffer) { //create framebuffer if (!(framebuffer in app.frameBufferMemo)) { diff --git a/src/o3d.js b/src/o3d.js index a9d2f93d..d4b29cc0 100644 --- a/src/o3d.js +++ b/src/o3d.js @@ -237,6 +237,7 @@ }, setTextures: function(program, force) { + var app = PhiloGL.app; this.textures = this.textures? $.splat(this.textures) : []; var dist = 5; for (var i = 0, texs = this.textures, l = texs.length, mtexs = PhiloGL.Scene.MAX_TEXTURES; i < mtexs; i++) { diff --git a/src/program.js b/src/program.js index c288620e..9166e1c4 100644 --- a/src/program.js +++ b/src/program.js @@ -263,6 +263,7 @@ ['setBuffer', 'setBuffers', 'use'].forEach(function(name) { Program.prototype[name] = function() { + var app = PhiloGL.app; var args = Array.prototype.slice.call(arguments); args.unshift(this); app[name].apply(app, args); @@ -273,6 +274,7 @@ ['setFrameBuffer', 'setFrameBuffers', 'setRenderBuffer', 'setRenderBuffers', 'setTexture', 'setTextures'].forEach(function(name) { Program.prototype[name] = function() { + var app = PhiloGL.app; app[name].apply(app, arguments); return this; }; diff --git a/src/scene.js b/src/scene.js index 7a2b1e4c..cfade0ad 100644 --- a/src/scene.js +++ b/src/scene.js @@ -212,6 +212,7 @@ }, renderToTexture: function(name, opt) { + var app = PhiloGL.app; opt = opt || {}; var texture = app.textures[name + '-texture'], texMemo = app.textureMemo[name + '-texture']; @@ -260,6 +261,7 @@ //setup picking framebuffer setupPicking: function() { + var app = PhiloGL.app; //create picking program var program = PhiloGL.Program.fromDefaultShaders(), floor = Math.floor; @@ -285,6 +287,7 @@ //returns an element at the given position pick: function(x, y, lazy) { + var app = PhiloGL.app; //setup the picking program if this is //the first time we enter the method. if (!this.pickingProgram) { From 818b319c5550870b2ee3796172906ebaf1f1f2c8 Mon Sep 17 00:00:00 2001 From: D1plo1d Date: Wed, 6 Feb 2013 21:18:17 -0500 Subject: [PATCH 3/3] Refactoring in support for multiple simultaneous gl contexts --- src/core.js | 40 ++++++++++++++++++++-------------------- src/io.js | 3 +-- src/media.js | 5 ++--- src/o3d.js | 15 +++++++++------ src/program.js | 40 ++++++++++++++++++++++++++-------------- src/scene.js | 11 +++++++---- src/webgl.js | 5 +++++ 7 files changed, 70 insertions(+), 49 deletions(-) diff --git a/src/core.js b/src/core.js index 0bd4390d..b1a21d47 100644 --- a/src/core.js +++ b/src/core.js @@ -51,16 +51,21 @@ this.PhiloGL = null; optEvents = opt.events, optTextures = opt.textures, optProgram = $.splat(opt.program), - optScene = opt.scene; + optScene = opt.scene + program = null; - //get Context global to all framework - gl = PhiloGL.WebGL.getContext(canvasId, optContext); + //Get the 3D context, holds the application + var gl = PhiloGL.WebGL.getContext(canvasId, optContext); + PhiloGL.glConstants = gl; if (!gl) { opt.onError("The WebGL context couldn't been initialized"); return null; } + //make app instance + var app = new PhiloGL.WebGL.Application({gl: gl}); + //get Program var popt = { 'defaults': 'fromDefaultShaders', @@ -80,7 +85,7 @@ this.PhiloGL = null; count--; if (count === 0 && !error) { loadProgramDeps(gl, programLength == 1? p : programs, function(app) { - opt.onLoad(PhiloGL.app); + opt.onLoad(app); }); } }, @@ -94,13 +99,15 @@ this.PhiloGL = null; optProgram.forEach(function(optProgram, i) { var pfrom = optProgram.from, program; + optProgram.gl = gl; + optProgram.app = app; for (var p in popt) { if (pfrom == p) { - try { + //try { program = PhiloGL.Program[popt[p]]($.extend(programCallback, optProgram)); - } catch(e) { - programCallback.onError(e); - } + //} catch(e) { + // programCallback.onError(e); + //} break; } } @@ -122,14 +129,10 @@ this.PhiloGL = null; //get Scene var scene = new PhiloGL.Scene(program, camera, optScene); - PhiloGL.app = new PhiloGL.WebGL.Application({ - gl: gl, - canvas: canvas, - program: program, - scene: scene, - camera: camera - }); - var app = PhiloGL.app; + app.program = program; + app.canvas = canvas; + app.scene = scene; + app.camera = camera; //Use program if (program.$$family == 'program') { @@ -149,7 +152,7 @@ this.PhiloGL = null; onComplete: function() { callback(app); } - })); + }), app); } else { callback(app); } @@ -176,9 +179,6 @@ this.PhiloGL = null; //Version PhiloGL.version = '1.5.2'; -//Holds the 3D context, holds the application -var gl - //Utility functions (function() { PhiloGL.$ = function (d) { diff --git a/src/io.js b/src/io.js index 1196e2ae..d468699d 100644 --- a/src/io.js +++ b/src/io.js @@ -266,8 +266,7 @@ }; //Load multiple textures from images - var Textures = function(opt) { - var app = PhiloGL.app; + var Textures = function(opt, app) { opt = $.merge({ src: [], noCache: false, diff --git a/src/media.js b/src/media.js index 37d9ef57..57ebca2a 100644 --- a/src/media.js +++ b/src/media.js @@ -18,8 +18,8 @@ position: { x: 0, y: 0, z: 1.205 } }), scene = new PhiloGL.Scene({}, camera); - return function(opt) { - var app = PhiloGL.app, + return function(opt, app) { + var gl = app.gl, program = app.program.$$family ? app.program : app.program[opt.program], textures = opt.fromTexture ? $.splat(opt.fromTexture) : [], framebuffer = opt.toFrameBuffer, @@ -39,7 +39,6 @@ scene.add(plane); } - var app = PhiloGL.app; if (framebuffer) { //create framebuffer if (!(framebuffer in app.frameBufferMemo)) { diff --git a/src/o3d.js b/src/o3d.js index d4b29cc0..4ba8d940 100644 --- a/src/o3d.js +++ b/src/o3d.js @@ -157,12 +157,13 @@ }, setIndices: function(program) { + var glc = PhiloGL.glConstants if (!this.$indices) return; if (this.dynamic) { program.setBuffer('indices-' + this.id, { - bufferType: gl.ELEMENT_ARRAY_BUFFER, - drawType: gl.STATIC_DRAW, + bufferType: glc.ELEMENT_ARRAY_BUFFER, + drawType: glc.STATIC_DRAW, value: this.$indices, size: 1 }); @@ -237,7 +238,8 @@ }, setTextures: function(program, force) { - var app = PhiloGL.app; + var app = program.app; + glc = PhiloGL.glConstants; this.textures = this.textures? $.splat(this.textures) : []; var dist = 5; for (var i = 0, texs = this.textures, l = texs.length, mtexs = PhiloGL.Scene.MAX_TEXTURES; i < mtexs; i++) { @@ -245,10 +247,10 @@ var isCube = app.textureMemo[texs[i]].isCube; if (isCube) { program.setUniform('hasTextureCube' + (i + 1), true); - program.setTexture(texs[i], gl['TEXTURE' + (i + dist)]); + program.setTexture(texs[i], glc['TEXTURE' + (i + dist)]); } else { program.setUniform('hasTexture' + (i + 1), true); - program.setTexture(texs[i], gl['TEXTURE' + i]); + program.setTexture(texs[i], glc['TEXTURE' + i]); } } else { program.setUniform('hasTextureCube' + (i + 1), false); @@ -272,7 +274,8 @@ }, unsetState: function(program) { - var attributes = program.attributes; + var attributes = program.attributes, + gl = program.gl; //unbind the array and element buffers gl.bindBuffer(gl.ARRAY_BUFFER, null); diff --git a/src/program.js b/src/program.js index 9166e1c4..a94bdf3f 100644 --- a/src/program.js +++ b/src/program.js @@ -26,7 +26,7 @@ }; //Creates a program from vertex and fragment shader sources. - var createProgram = function(gl, vertexShader, fragmentShader) { + var createProgram = function(vertexShader, fragmentShader, gl, app) { var program = gl.createProgram(); gl.attachShader( program, @@ -207,10 +207,10 @@ }; //Program Class: Handles loading of programs and mapping of attributes and uniforms - var Program = function(vertexShader, fragmentShader) { - var program = createProgram(gl, vertexShader, fragmentShader); + var Program = function(vertexShader, fragmentShader, gl, app) { + var program = createProgram(vertexShader, fragmentShader, gl); if (!program) return false; - + var attributes = {}, attributeEnabled = {}, uniforms = {}, @@ -240,6 +240,10 @@ this.attributes = attributes; this.attributeEnabled = attributeEnabled; this.uniforms = uniforms; + this.app = app; + this.gl = gl; + + return this; }; Program.prototype = { @@ -263,7 +267,7 @@ ['setBuffer', 'setBuffers', 'use'].forEach(function(name) { Program.prototype[name] = function() { - var app = PhiloGL.app; + var app = this.app; var args = Array.prototype.slice.call(arguments); args.unshift(this); app[name].apply(app, args); @@ -274,7 +278,7 @@ ['setFrameBuffer', 'setFrameBuffers', 'setRenderBuffer', 'setRenderBuffers', 'setTexture', 'setTextures'].forEach(function(name) { Program.prototype[name] = function() { - var app = PhiloGL.app; + var app = this.app; app[name].apply(app, arguments); return this; }; @@ -283,10 +287,11 @@ //Get options in object or arguments function getOptions(args, base) { var opt; - if (args.length == 2) { + if (args.length == 3) { opt = { vs: args[0], - fs: args[1] + fs: args[1], + gl: args[2] }; } else { opt = args[0] || {}; @@ -296,23 +301,30 @@ //Create a program from vertex and fragment shader node ids Program.fromShaderIds = function() { - var opt = getOptions(arguments), + var $ = PhiloGL.$, + opt = getOptions(arguments), vs = $(opt.vs), - fs = $(opt.fs); - return preprocess(opt.path, vs.innerHTML, function(vectexShader) { + fs = $(opt.fs), + gl = opt.gl, + app = opt.app + program = null; + preprocess(opt.path, vs.innerHTML, function(vectexShader) { return preprocess(opt.path, fs.innerHTML, function(fragmentShader) { - opt.onSuccess(new Program(vectexShader, fragmentShader), opt); + opt.onSuccess(program = new Program(vectexShader, fragmentShader, gl, app), opt); }); }); + return program; }; //Create a program from vs and fs sources Program.fromShaderSources = function() { - var opt = getOptions(arguments, {path: './'}); + var opt = getOptions(arguments, {path: './'}) + gl = opt.gl, + app = opt.app; return preprocess(opt.path, opt.vs, function(vectexShader) { return preprocess(opt.path, opt.fs, function(fragmentShader) { try { - var program = new Program(vectexShader, fragmentShader); + var program = new Program(vectexShader, fragmentShader, gl, app); if(opt.onSuccess) { opt.onSuccess(program, opt); } else { diff --git a/src/scene.js b/src/scene.js index cfade0ad..d8f617f1 100644 --- a/src/scene.js +++ b/src/scene.js @@ -41,6 +41,7 @@ }, opt || {}); this.program = opt.program ? program[opt.program] : program; + this.app = this.program.app; this.camera = camera; this.models = []; this.config = opt; @@ -212,7 +213,8 @@ }, renderToTexture: function(name, opt) { - var app = PhiloGL.app; + var app = this.app, + gl = app.gl; opt = opt || {}; var texture = app.textures[name + '-texture'], texMemo = app.textureMemo[name + '-texture']; @@ -232,6 +234,8 @@ world = view.mulMat4(object), worldInverse = world.invert(), worldInverseTranspose = worldInverse.transpose(); + app = program.app, + gl = app.gl; obj.setState(program); @@ -261,9 +265,9 @@ //setup picking framebuffer setupPicking: function() { - var app = PhiloGL.app; + var app = this.app; //create picking program - var program = PhiloGL.Program.fromDefaultShaders(), + var program = PhiloGL.Program.fromDefaultShaders({app: app, gl: app.gl}), floor = Math.floor; //create framebuffer app.setFrameBuffer('$picking', { @@ -287,7 +291,6 @@ //returns an element at the given position pick: function(x, y, lazy) { - var app = PhiloGL.app; //setup the picking program if this is //the first time we enter the method. if (!this.pickingProgram) { diff --git a/src/webgl.js b/src/webgl.js index 35b0a4c8..623d0b64 100644 --- a/src/webgl.js +++ b/src/webgl.js @@ -79,6 +79,7 @@ $$family: 'application', setBuffer: function(program, name, opt) { + var gl = this.gl; //unbind buffer if (opt === false || opt === null) { opt = this.bufferMemo[name]; @@ -158,6 +159,7 @@ }, setFrameBuffer: function(name, opt) { + var gl = this.gl; //bind/unbind framebuffer if (typeof opt != 'object') { gl.bindFramebuffer(gl.FRAMEBUFFER, opt? this.frameBuffers[name] : null); @@ -235,6 +237,7 @@ }, setRenderBuffer: function(name, opt) { + var gl = this.gl; if (typeof opt != 'object') { gl.bindRenderbuffer(gl.RENDERBUFFER, opt? this.renderBufferMemo[name] : null); return; @@ -270,6 +273,7 @@ }, setTexture: function(name, opt) { + var gl = this.gl; //bind texture if (!opt || typeof opt != 'object') { gl.activeTexture(opt || gl.TEXTURE0); @@ -401,6 +405,7 @@ }, use: function(program) { + var gl = this.gl; gl.useProgram(program.program); //remember last used program. this.usedProgram = program;