Repository: greggman/tdl
Branch: master
Commit: 6b633052599e
Files: 38
Total size: 463.7 KB
Directory structure:
gitextract_7m630dcz/
├── .gitignore
├── Gruntfile.js
├── README.md
├── bower.json
├── docs.md
├── example/
│ ├── example-requirejs.html
│ ├── example-requirejs.js
│ ├── example.html
│ ├── example2.html
│ ├── line.html
│ └── picking.html
├── js/
│ └── require.js
├── jsdoc.conf.json
├── package.json
└── tdl/
├── base-rs.js
├── base.js
├── buffers.js
├── clock.js
├── fast.js
├── fps.js
├── framebuffers.js
├── fullscreen.js
├── io.js
├── loader.js
├── log.js
├── math.js
├── misc.js
├── models.js
├── particles.js
├── primitives.js
├── programs.js
├── quaternions.js
├── screenshot.js
├── shader.js
├── string.js
├── sync.js
├── textures.js
└── webgl.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
docs
*.Makefile
*.mk
*.ncb
*.ninja
*.props
*.pyc
*.rules
*.scons
*.sdf
*.sln
*.suo
*.targets
*.user
*.vcproj
*.vcxproj
*.vcxproj.filters
*.vpj
*.vpw
*.vpwhistu
*.vtg
*.xcodeproj
*~
.*.sw?
.DS_Store
.cproject
.gdb_history
.gdbinit
.metadata
.project
tags
Thumbs.db
v8.log
node_modules
================================================
FILE: Gruntfile.js
================================================
"use strict";
module.exports = function(grunt) {
grunt.initConfig({
jsdoc: {
tdl: {
src: ['tdl/*.js'],
options: {
destination: 'docs/gen',
configure: 'jsdoc.conf.json',
template: 'node_modules/ink-docstrap/template',
private: false,
},
},
},
clean: [
'docs/gen',
],
uglify: {
my_target: {
files: {
'build/tdl.min.js': [
'tdl/base.js',
'tdl/buffers.js',
'tdl/clock.js',
'tdl/fast.js',
'tdl/fps.js',
'tdl/framebuffers.js',
'tdl/fullscreen.js',
'tdl/io.js',
'tdl/loader.js',
'tdl/log.js',
'tdl/math.js',
'tdl/misc.js',
'tdl/models.js',
'tdl/particles.js',
'tdl/primitives.js',
'tdl/programs.js',
'tdl/quaternions.js',
'tdl/screenshot.js',
'tdl/shader.js',
'tdl/string.js',
'tdl/sync.js',
'tdl/textures.js',
'tdl/webgl.js',
],
},
},
},
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-jsdoc');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ['clean', 'jsdoc', 'uglify']);
};
================================================
FILE: README.md
================================================
TDL
===
Please check out [TWGL](http://twgljs.org). It's arguably the spiritual successor to TDL.
TDL is a **low-level** library for WebGL apps. It currently focuses on speed of rendering rather than ease of use.
Some [terse docs can be found at here](docs.md)
Note: By **low-level** I mean TDL doesn't currently provide any 3D knowledge.
There are almost no built in shaders. There is no scene graph. There are just some objects for wrapping WebGL
shaders and helping to easily associate vertex data with attributes and update uniforms.
Example: Assuming a shaders like this.
In WebGL you'd do this
// At init time:
var program = UtilToCompileShaders("vshader", "fshader");
var positionLoc = gl.getAttribLocation(program, "position");
var texcoordLoc = gl.getAttribLocation(program, "texcoord");
var worldMatLoc = gl.getUniformLocation(program, "u_worldMatrix");
var projectionMatLoc = gl.getUniformLocation(program, "u_projectionMatrix");
var textureLoc = gl.getUniformLocation(program, "u_texture");
var positions = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positions);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positionData), gl.STATIC_DRAW);
var tecoords = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoords);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texcoordData), gl.STATIC_DRAW);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, someImage);
// At draw time
gl.bindBuffer(gl.ARRAY_BUFFER, positions);
gl.enableVertexAttribArray(programLoc);
gl.vertexAttribPointer(programLoc, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, positions);
gl.enableVertexAttribArray(texcoordLoc);
gl.vertexAttribPointer(tecoordLoc, 2, gl.FLOAT, false, 0, 0);
gl.useProgram(program);
gl.uniformMatrix4f(projectionMatLoc, false, projectionMatrix);
for (var i = 0; i < 3; ++i)
{
gl.uniformMatrix4f(worldMatLoc, false, computeWorldMatrix(i));
gl.drawArrays(gl.TRIANGLES, 0, num);
}
In TDL that would be shortened to
// At init time.
var program = tdl.programs.loadProgramFromScriptTags("vshader", "fshader");
var arrays = {
position: new tdl.primitives.AttribBuffer(3, positionData),
texcoord: new tdl.primitives.AttribBuffer(2, texcoordData),
};
var textures = {
u_texture: new tdl.textures.loadTexture(someImage),
}
var model = new tdl.models.Model(program, arrays, textures);
// At Draw time
var sharedUniforms = {
u_projectionMatrix: projectionMatrix,
};
var perObjectUniforms = {
u_worldMatrix: worldMatrix,
};
model.drawPrep(sharedUniforms);
for (var i = 0; i < 3; ++i)
{
perObjectUnifirms.u_worldMatrix = computeWorldMatrix(i);
model.draw(perObjectuniforms);
}
================================================
FILE: bower.json
================================================
{
"name": "tdl",
"version": "0.0.8",
"authors": [
{
"name": "Gregg Tavares",
"email": "github@greggman.com",
"homepage": "http://games.greggman.com"
}
],
"description": "A JavaScript library for WebGL",
"main": "tdl/base.js",
"moduleType": [
"amd"
],
"keywords": [
"webgl",
"tdl"
],
"license": "MIT",
"homepage": "https://github.com/greggman/tdl",
"repository": "git://github.com/greggman/tdl.git",
"ignore": [
"**/.*",
"*.md",
"Gruntfile.js",
"package.json",
"bower.json",
"node_modules",
"docs",
"build",
"example",
"js",
"bower_components",
"test",
"tests"
]
}
================================================
FILE: docs.md
================================================
TDL Docs
========
I hope the code is pretty straight forward. There's some simple examples here
http://greggman.github.com/tdl/example/example.html
http://greggman.github.com/tdl/example/example2.html
http://greggman.github.com/tdl/example/picking.html
More complex samples can be found at http://webglsamples.googlecode.com
Briefly...
Your startup code should look like this
canvas = document.getElementById("canvas");
gl = tdl.webgl.setupWebGL(canvas);
if (!gl) {
return; // Do nothing
}
Where "canvas" is the id of the canvas you want to draw into.
tdl.webgl.setupWebGL will replace the contents of the containing div
with a link to getting a WebGL capable browser if the user's browser
does not support WebGL.
Otherwise...
Loading Shaders
---------------
var program = tdl.programs.loadProgram(vertexShaderSource, fragmentShaderSource);
Compiles your shaders and creates a Program object.
Loading Textures
----------------
var textures = {
name1: tdl.textures.loadTexture(url),
name2: tdl.textures.loadTexture(url)
};
Loads your textures. The property names must match whatever you called the samplers
in your shaders. loadTexture can take `[url]` for an image, `[r,g,b,a]` for solid
texture. `[url,url,url,url,url,url]` for a cubemap and also `[url]` for a cubemap
where all 6 faces are in a cross. It can also take an img or canvas tag.
Create Vertices or a Mesh
-------------------------
var arrays = tdl.primitives.createSphere(1, 10, 10);
Creates vertices
The tdl.primitives functions return an object like this
{
position: AttribBuffer,
normal: AttribBuffer,
texCoord: AttribBuffer
};
The property names must match the attributes in your vertex shader if you want to
add more.
A call to tdl.primitives.addTangentsAndBinormals adds the fields "tangent" and
"binormal"
Create a Model
--------------
Once you have a program, a texture object and an arrays object you make a new
model with
var model = new tdl.models.Model(program, array, textures);
Rendering
---------
To draw the model there are 2 functions, `model.drawPrep(uniformMap)` and
`model.draw(uniformMap)`.
Both of them take an object with uniformName/value pairs.
model.drawPrep binds the program, binds all the textures and attributes and
sets whatever uniforms you pass in.
model.draw sets any more uniforms you pass in and then calls gl.drawElements.
The idea is you call `model.drawPrep` once and then `model.draw` to draw a
bunch of the same model, changing as few uniforms as possible. This is the
fastest way to use WebGL.
Your rendering loop should look something like this
function render() {
var time = tdl.webgl.animationTime();
model.drawPrep({...});
model.draw({...});
tdl.webgl.requestAnimationFrame(render, canvas);
}
render(); // call the first render manually to start it off.
Math
----
The math is a little funky. There are 2 math libraries, math.js and fast.js.
math.js comes from O3D and uses `JavaScript` arrays. A Matrix in that
library is a an array of numbers. fast.js uses `Float32Array` for its storage
and most functions take a destination object as the first argument.
Theoretically this is faster because you can avoid a certain number of
allocations. It also means the numbers in the array do not have to be queried
and converted from `JavaScript` Number to floats before calling glUniform.
================================================
FILE: example/example-requirejs.html
================================================
WebGL TDL Example
================================================
FILE: example/example-requirejs.js
================================================
var main = function(
TDLBuffers,
TDLFast,
TDLFps,
TDLLog,
TDLMath,
TDLModels,
TDLPrimitives,
TDLPrograms,
TDLTextures,
TDLWebGL) {
// globals
var gl; // the gl context.
var canvas; // the canvas
var math; // the math lib.
var fast; // the fast math lib.
var g_fpsTimer; // object to measure frames per second;
var g_logGLCalls = true; // whether or not to log webgl calls
var g_debug = false; // whether or not to debug.
var g_drawOnce = false; // draw just one frame.
//g_drawOnce = true;
//g_debug = true;
var g_eyeSpeed = 0.5;
var g_eyeHeight = 2;
var g_eyeRadius = 9;
function ValidateNoneOfTheArgsAreUndefined(functionName, args) {
for (var ii = 0; ii < args.length; ++ii) {
if (args[ii] === undefined) {
TDLLog.error("undefined passed to gl." + functionName + "(" +
TDLWebGL.glFunctionArgsToString(functionName, args) + ")");
}
}
}
function Log(msg) {
if (g_logGLCalls) {
TDLLog.log(msg);
}
}
function LogGLCall(functionName, args) {
if (g_logGLCalls) {
ValidateNoneOfTheArgsAreUndefined(functionName, args)
TDLLog.log("gl." + functionName + "(" +
TDLWebGL.glFunctionArgsToString(functionName, args) + ")");
}
}
function createProgramFromTags(vertexTagId, fragmentTagId) {
return TDLPrograms.loadProgram(
document.getElementById(vertexTagId).text,
document.getElementById(fragmentTagId).text);
}
/**
* Sets up Planet.
*/
function setupSphere() {
var textures = {
diffuseSampler: TDLTextures.loadTexture('assets/sometexture.png')};
var program = createProgramFromTags(
'sphereVertexShader',
'sphereFragmentShader');
var arrays = TDLPrimitives.createSphere(0.4, 10, 12);
return new TDLModels.Model(program, arrays, textures);
}
function initialize() {
math = TDLMath;
fast = TDLFast;
canvas = document.getElementById("canvas");
g_fpsTimer = new TDLFps.FPSTimer();
gl = TDLWebGL.setupWebGL(canvas);
if (!gl) {
return false;
}
if (g_debug) {
gl = TDLWebGL.makeDebugContext(gl, undefined, LogGLCall);
}
Log("--Setup Sphere---------------------------------------");
var sphere = setupSphere();
var then = 0.0;
var clock = 0.0;
var fpsElem = document.getElementById("fps");
// pre-allocate a bunch of arrays
var projection = new Float32Array(16);
var view = new Float32Array(16);
var world = new Float32Array(16);
var worldInverse = new Float32Array(16);
var worldInverseTranspose = new Float32Array(16);
var viewProjection = new Float32Array(16);
var worldViewProjection = new Float32Array(16);
var viewInverse = new Float32Array(16);
var viewProjectionInverse = new Float32Array(16);
var eyePosition = new Float32Array(3);
var target = new Float32Array(3);
var up = new Float32Array([0,1,0]);
var lightWorldPos = new Float32Array(3);
var v3t0 = new Float32Array(3);
var v3t1 = new Float32Array(3);
var v3t2 = new Float32Array(3);
var v3t3 = new Float32Array(3);
var m4t0 = new Float32Array(16);
var m4t1 = new Float32Array(16);
var m4t2 = new Float32Array(16);
var m4t3 = new Float32Array(16);
var zero4 = new Float32Array(4);
var one4 = new Float32Array([1,1,1,1]);
// Sphere uniforms.
var sphereConst = {
viewInverse: viewInverse,
lightWorldPos: lightWorldPos,
specular: one4,
shininess: 50,
specularFactor: 0.2};
var spherePer = {
lightColor: new Float32Array([0,0,0,1]),
world: world,
worldViewProjection: worldViewProjection,
worldInverse: worldInverse,
worldInverseTranspose: worldInverseTranspose};
var frameCount = 0;
function render() {
++frameCount;
if (!g_drawOnce) {
TDLWebGL.requestAnimationFrame(render, canvas);
}
var now = (new Date()).getTime() * 0.001;
var elapsedTime;
if(then == 0.0) {
elapsedTime = 0.0;
} else {
elapsedTime = now - then;
}
then = now;
g_fpsTimer.update(elapsedTime);
fpsElem.innerHTML = g_fpsTimer.averageFPS;
clock += elapsedTime;
eyePosition[0] = Math.sin(clock * g_eyeSpeed) * g_eyeRadius;
eyePosition[1] = g_eyeHeight;
eyePosition[2] = Math.cos(clock * g_eyeSpeed) * g_eyeRadius;
gl.colorMask(true, true, true, true);
gl.depthMask(true);
gl.clearColor(0,0,0,0);
gl.clearDepth(1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
gl.enable(gl.CULL_FACE);
gl.enable(gl.DEPTH_TEST);
fast.matrix4.perspective(
projection,
math.degToRad(60),
canvas.clientWidth / canvas.clientHeight,
1,
5000);
fast.matrix4.lookAt(
view,
eyePosition,
target,
up);
fast.matrix4.mul(viewProjection, view, projection);
fast.matrix4.inverse(viewInverse, view);
fast.matrix4.inverse(viewProjectionInverse, viewProjection);
fast.matrix4.getAxis(v3t0, viewInverse, 0); // x
fast.matrix4.getAxis(v3t1, viewInverse, 1); // y;
fast.matrix4.getAxis(v3t2, viewInverse, 2); // z;
fast.mulScalarVector(v3t0, 10, v3t0);
fast.mulScalarVector(v3t1, 10, v3t1);
fast.mulScalarVector(v3t2, 10, v3t2);
fast.addVector(lightWorldPos, eyePosition, v3t0);
fast.addVector(lightWorldPos, lightWorldPos, v3t1);
fast.addVector(lightWorldPos, lightWorldPos, v3t2);
// view: view,
// projection: projection,
// viewProjection: viewProjection,
Log("--Draw sphere---------------------------------------");
sphere.drawPrep(sphereConst);
var across = 6;
var lightColor = spherePer.lightColor;
var half = (across - 1) * 0.5;
for (var xx = 0; xx < across; ++xx) {
for (var yy = 0; yy < across; ++yy) {
for (var zz = 0; zz < across; ++zz) {
lightColor[0] = xx / across;
lightColor[1] = yy / across;
lightColor[2] = zz / across;
var scale = (xx + yy + zz) % 4 / 4 + 0.5;
fast.matrix4.scaling(m4t0, [scale, scale, scale]);
fast.matrix4.translation(m4t1, [xx - half, yy - half, zz - half]);
fast.matrix4.mul(world, m4t0, m4t1);
fast.matrix4.mul(worldViewProjection, world, viewProjection);
fast.matrix4.inverse(worldInverse, world);
fast.matrix4.transpose(worldInverseTranspose, worldInverse);
sphere.draw(spherePer);
}
}
}
// Set the alpha to 255.
gl.colorMask(false, false, false, true);
gl.clearColor(0,0,0,1);
gl.clear(gl.COLOR_BUFFER_BIT);
// turn off logging after 1 frame.
g_logGLCalls = false;
}
render();
return true;
}
initialize();
}
requirejs(
[ '../tdl/buffers',
'../tdl/fast',
'../tdl/fps',
'../tdl/log',
'../tdl/math',
'../tdl/models',
'../tdl/primitives',
'../tdl/programs',
'../tdl/textures',
'../tdl/webgl',
],
main);
================================================
FILE: example/example.html
================================================
WebGL TDL Example
================================================
FILE: example/example2.html
================================================
WebGL TDL Example
WebGL Spheres
================================================
FILE: example/line.html
================================================
WebGL TDL Example
================================================
FILE: example/picking.html
================================================
WebGL TDL Example
================================================
FILE: js/require.js
================================================
/*
RequireJS 2.1.11 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
Available via the MIT or new BSD license.
see: http://github.com/jrburke/requirejs for details
*/
var requirejs,require,define;
(function(ca){function G(b){return"[object Function]"===M.call(b)}function H(b){return"[object Array]"===M.call(b)}function v(b,c){if(b){var d;for(d=0;dthis.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&&
(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=
this.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,"defined",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||""),f=m(a.prefix+"!"+J,this.map.parentMap),r(f,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f);
if(this.events.error)g.on("error",t(this,function(a){this.emit("error",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C("fromtexteval",
"fromText eval for "+b+" failed: "+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if("string"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,"defined",t(this,function(a){this.defineDep(b,
a);this.check()}));this.errback&&r(a,"error",t(this,this.errback))}c=a.id;f=k[c];!s(N,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m,
nextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b,
a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+"/"+(a.main||"main").replace(ja,"").replace(R,"")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild=
!0);if("string"===typeof f){if(G(c))return w(C("requireargs","Invalid require call"),d);if(a&&s(N,f))return N[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C("notloaded",'Module name "'+j+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[j]}L();i.nextTick(function(){L();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==
d&&(!("."===g||".."===g)||1g.attachEvent.toString().indexOf("[native code"))&&!Z?(O=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)):
(g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1)),g.src=d,L=g,D?y.insertBefore(g,D):y.appendChild(g),L=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(K=b.getAttribute("data-main"))return q=K,r.baseUrl||(E=q.split("/"),q=E.pop(),Q=E.length?E.join("/")+"/":"./",r.baseUrl=
Q),q=q.replace(R,""),h.jsExtRegExp.test(q)&&(q=K),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(g=L))P&&"interactive"===P.readyState||U(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),g=P;g&&(b||
(b=g.getAttribute("data-requiremodule")),h=F[g.getAttribute("data-requirecontext")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this);
================================================
FILE: jsdoc.conf.json
================================================
{
"tags" : {
"allowUnknownTags" : false
},
"plugins" : ["plugins/markdown"],
"templates" : {
"cleverLinks" : false,
"monospaceLinks" : false,
"dateFormat" : "ddd MMM Do YYYY",
"outputSourceFiles" : false,
"outputSourcePath" : false,
"systemName" : "ThreeDLibrary",
"footer" : "",
"copyright" : "copyright Google, Greggman",
"navType" : "vertical",
"theme" : "cerulean",
"linenums" : true,
"collapseSymbols" : false,
"inverseNav" : true,
"highlightTutorialCode" : true
},
"markdown" : {
"parser" : "gfm",
"hardwrap" : true
}
}
================================================
FILE: package.json
================================================
{
"name": "tdl",
"version": "0.0.8",
"description": "Some WebGL Library",
"main": "tdl/base.js",
"directories": {
"doc": "docs",
"example": "example"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://github.com/greggman/tdl.git"
},
"keywords": [
"WebGL"
],
"author": "Greggman",
"license": "MIT",
"bugs": {
"url": "https://github.com/greggman/tdl/issues"
},
"homepage": "https://github.com/greggman/tdl",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-uglify": "^0.7.0",
"grunt-jsdoc": "^0.5.7"
}
}
================================================
FILE: tdl/base-rs.js
================================================
/*
* Copyright 2014, Gregg Tavares.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Gregg Tavares. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// emulate tdl/base.js for require.js
define(function() {
// Was base.js already included?
var haveBaseJS = (this.tdl !== undefined);
if (haveBaseJS) {
tdl.provide('tdl.base-rs');
return;
}
this.tdl = {base:{}};
this.goog = {};
var noop = function() {};
// Let's assume if the user is using require JS they don't need tdl.require
// If that's not the case we'd need provide a version of tdl.require that
// ignores the tdl files but not the user's files. Probably hooked into requirejs
tdl.require = noop;
tdl.provide = noop;
/**
* Determine whether a value is an array. Do not use instanceof because that
* will not work for V8 arrays (the browser thinks they are Objects).
* @param {*} value A value.
* @return {boolean} Whether the value is an array.
*/
tdl.base.isArray = function(value) {
var valueAsObject = /** @type {!Object} */ (value);
return typeof(value) === 'object' && value !== null &&
'length' in valueAsObject && 'splice' in valueAsObject;
};
/**
* A stub for later optionally converting obfuscated names
* @private
* @param {string} name Name to un-obfuscate.
* @return {string} un-obfuscated name.
*/
tdl.base.maybeDeobfuscateFunctionName_ = function(name) {
return name;
};
/**
* Makes one class inherit from another.
* @param {!Object} subClass Class that wants to inherit.
* @param {!Object} superClass Class to inherit from.
*/
tdl.base.inherit = function(subClass, superClass) {
/**
* TmpClass.
* @ignore
* @constructor
*/
var TmpClass = function() { };
TmpClass.prototype = superClass.prototype;
subClass.prototype = new TmpClass();
};
/**
* Parses an error stack from an exception
* @param {!Exception} excp The exception to get a stack trace from.
* @return {!Array.} An array of strings of the stack trace.
*/
tdl.base.parseErrorStack = function(excp) {
var stack = [];
var name;
var line;
if (!excp || !excp.stack) {
return stack;
}
var stacklist = excp.stack.split('\n');
for (var i = 0; i < stacklist.length - 1; i++) {
var framedata = stacklist[i];
name = framedata.match(/^([a-zA-Z0-9_$]*)/)[1];
if (name) {
name = tdl.base.maybeDeobfuscateFunctionName_(name);
} else {
name = 'anonymous';
}
var result = framedata.match(/(.*:[0-9]+)$/);
line = result && result[1];
if (!line) {
line = '(unknown)';
}
stack[stack.length] = name + ' : ' + line
}
// remove top level anonymous functions to match IE
var omitRegexp = /^anonymous :/;
while (stack.length && omitRegexp.exec(stack[stack.length - 1])) {
stack.length = stack.length - 1;
}
return stack;
};
/**
* Gets a function name from a function object.
* @param {!function(...): *} aFunction The function object to try to get a
* name from.
* @return {string} function name or 'anonymous' if not found.
*/
tdl.base.getFunctionName = function(aFunction) {
var regexpResult = aFunction.toString().match(/function(\s*)(\w*)/);
if (regexpResult && regexpResult.length >= 2 && regexpResult[2]) {
return tdl.base.maybeDeobfuscateFunctionName_(regexpResult[2]);
}
return 'anonymous';
};
/**
* Pretty prints an exception's stack, if it has one.
* @param {Array.} stack An array of errors.
* @return {string} The pretty stack.
*/
tdl.base.formatErrorStack = function(stack) {
var result = '';
for (var i = 0; i < stack.length; i++) {
result += '> ' + stack[i] + '\n';
}
return result;
};
/**
* Gets a stack trace as a string.
* @param {number} stripCount The number of entries to strip from the top of the
* stack. Example: Pass in 1 to remove yourself from the stack trace.
* @return {string} The stack trace.
*/
tdl.base.getStackTrace = function(stripCount) {
var result = '';
if (typeof(arguments.caller) != 'undefined') { // IE, not ECMA
for (var a = arguments.caller; a != null; a = a.caller) {
result += '> ' + tdl.base.getFunctionName(a.callee) + '\n';
if (a.caller == a) {
result += '*';
break;
}
}
} else { // Mozilla, not ECMA
// fake an exception so we can get Mozilla's error stack
var testExcp;
try {
eval('var var;');
} catch (testExcp) {
var stack = tdl.base.parseErrorStack(testExcp);
result += tdl.base.formatErrorStack(stack.slice(3 + stripCount,
stack.length));
}
}
return result;
};
/**
* Returns true if the user's browser is Microsoft IE.
* @return {boolean} true if the user's browser is Microsoft IE.
*/
tdl.base.IsMSIE = function() {
var ua = navigator.userAgent.toLowerCase();
var msie = /msie/.test(ua) && !/opera/.test(ua);
return msie;
};
return {};
});
================================================
FILE: tdl/base.js
================================================
/*
* Copyright 2009, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @fileoverview Base for all tdl sample utilties.
*
* The main point of this module is to provide a central place to
* have an init function to register an tdl namespace object because many other
* modules need access to it.
*/
/**
* A namespace for all the tdl utility libraries.
* @namespace
*/
var tdl = tdl || {};
/**
* Define this because the Google internal JSCompiler needs goog.typedef below.
*/
var goog = goog || {};
if (!window.Int32Array) {
window.Int32Array = function() { };
window.Float32Array = function() { };
window.Uint16Array = function() { };
}
/**
* A macro for defining composite types.
*
* By assigning goog.typedef to a name, this tells Google internal JSCompiler
* that this is not the name of a class, but rather it's the name of a composite
* type.
*
* For example,
* /** @type {Array|NodeList} / goog.ArrayLike = goog.typedef;
* will tell JSCompiler to replace all appearances of goog.ArrayLike in type
* definitions with the union of Array and NodeList.
*
* Does nothing in uncompiled code.
*/
goog.typedef = true;
/**
* Reference to the global context. In most cases this will be 'window'.
*/
tdl.global = this;
/**
* Some javascripts don't support __defineGetter__ or __defineSetter__
* so we define some here so at least we don't get compile errors.
* We expect the initialzation code will check and complain. This stubs
* are just here to make sure we can actually get to the initialization code.
*/
//if (!Object.prototype.__defineSetter__) {
// Object.prototype.__defineSetter__ = function() {}
// Object.prototype.__defineGetter__ = function() {}
//}
//
/**
* Flag used to force a function to run in the browser when it is called
* from V8.
* @type {boolean}
*/
tdl.BROWSER_ONLY = true;
/**
* Array of namespaces that have been provided.
* @private
* @type {!Array.}
*/
tdl.provided_ = [];
/**
* Creates object stubs for a namespace. When present in a file,
* tdl.provide also indicates that the file defines the indicated
* object.
* @param {string} name name of the object that this file defines.
*/
tdl.provide = function(name) {
// Ensure that the same namespace isn't provided twice.
if (tdl.getObjectByName(name) &&
!tdl.implicitNamespaces_[name]) {
throw 'Namespace "' + name + '" already declared.';
}
var namespace = name;
while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {
tdl.implicitNamespaces_[namespace] = true;
}
tdl.exportPath_(name);
tdl.provided_.push(name);
};
/**
* Namespaces implicitly defined by tdl.provide. For example,
* tdl.provide('tdl.events.Event') implicitly declares
* that 'tdl' and 'tdl.events' must be namespaces.
*
* @type {Object}
* @private
*/
tdl.implicitNamespaces_ = {};
/**
* Builds an object structure for the provided namespace path,
* ensuring that names that already exist are not overwritten. For
* example:
* "a.b.c" -> a = {};a.b={};a.b.c={};
* Used by tdl.provide and tdl.exportSymbol.
* @param {string} name name of the object that this file defines.
* @param {Object} opt_object the object to expose at the end of the path.
* @param {Object} opt_objectToExportTo The object to add the path to; default
* is |tdl.global|.
* @private
*/
tdl.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
var parts = name.split('.');
var cur = opt_objectToExportTo || tdl.global;
var part;
// Internet Explorer exhibits strange behavior when throwing errors from
// methods externed in this manner. See the testExportSymbolExceptions in
// base_test.html for an example.
if (!(parts[0] in cur) && cur.execScript) {
cur.execScript('var ' + parts[0]);
}
// Parentheses added to eliminate strict JS warning in Firefox.
while (parts.length && (part = parts.shift())) {
if (!parts.length && tdl.isDef(opt_object)) {
// last part and we have an object; use it.
cur[part] = opt_object;
} else if (cur[part]) {
cur = cur[part];
} else {
cur = cur[part] = {};
}
}
};
/**
* Returns an object based on its fully qualified external name. If you are
* using a compilation pass that renames property names beware that using this
* function will not find renamed properties.
*
* @param {string} name The fully qualified name.
* @param {Object} opt_obj The object within which to look; default is
* |tdl.global|.
* @return {Object} The object or, if not found, null.
*/
tdl.getObjectByName = function(name, opt_obj) {
var parts = name.split('.');
var cur = opt_obj || tdl.global;
for (var pp = 0; pp < parts.length; ++pp) {
var part = parts[pp];
if (cur[part]) {
cur = cur[part];
} else {
return null;
}
}
return cur;
};
/**
* Implements a system for the dynamic resolution of dependencies.
* @param {string} rule Rule to include, in the form tdl.package.part.
*/
tdl.require = function(rule) {
// TODO(gman): For some unknown reason, when we call
// tdl.util.getScriptTagText_ it calls
// document.getElementsByTagName('script') and for some reason the scripts do
// not always show up. Calling it here seems to fix that as long as we
// actually ask for the length, at least in FF 3.5.1 It would be nice to
// figure out why.
var dummy = document.getElementsByTagName('script').length;
// if the object already exists we do not need do do anything
if (tdl.getObjectByName(rule)) {
return;
}
var path = tdl.getPathFromRule_(rule);
if (path) {
tdl.included_[path] = true;
tdl.writeScripts_();
} else {
throw new Error('tdl.require could not find: ' + rule);
}
};
/**
* Path for included scripts.
* @type {string}
*/
tdl.basePath = '';
/**
* Object used to keep track of urls that have already been added. This
* record allows the prevention of circular dependencies.
* @type {Object}
* @private
*/
tdl.included_ = {};
/**
* This object is used to keep track of dependencies and other data that is
* used for loading scripts.
* @private
* @type {Object}
*/
tdl.dependencies_ = {
visited: {}, // used when resolving dependencies to prevent us from
// visiting the file twice.
written: {} // used to keep track of script files we have written.
};
/**
* Tries to detect the base path of the tdl-base.js script that
* bootstraps the tdl libraries.
* @private
*/
tdl.findBasePath_ = function() {
var doc = tdl.global.document;
if (typeof doc == 'undefined') {
return;
}
if (tdl.global.BASE_PATH) {
tdl.basePath = tdl.global.BASE_PATH;
return;
} else {
// HACKHACK to hide compiler warnings :(
tdl.global.BASE_PATH = null;
}
var expectedBase = 'tdl/base.js';
var scripts = doc.getElementsByTagName('script');
for (var script, i = 0; script = scripts[i]; i++) {
var src = script.src;
var l = src.length;
if (src.substr(l - expectedBase.length) == expectedBase) {
tdl.basePath = src.substr(0, l - expectedBase.length);
return;
}
}
};
/**
* Writes a script tag if, and only if, that script hasn't already been added
* to the document. (Must be called at execution time.)
* @param {string} src Script source.
* @private
*/
tdl.writeScriptTag_ = function(src) {
var doc = tdl.global.document;
if (typeof doc != 'undefined' &&
!tdl.dependencies_.written[src]) {
tdl.dependencies_.written[src] = true;
var html = '