html5 gaming - developer.blackberry.com gaming - nov-01.pdf · webgl frameworks ivank lib 2d with...

43
HTML5 Gaming Erik Oros ([email protected] | @WaterlooErik) November 15, 2012

Upload: others

Post on 29-Aug-2019

11 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

HTML5 Gaming

Erik Oros ([email protected] | @WaterlooErik)

November 15, 2012

Page 2: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

BlackBerry Loves HTML5

2

Page 3: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Canvas2D

3

Page 4: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

What is Canvas2D?

A surface for programmatic rendering of shapes/images.

Unlike SVG, no scene graph.

<canvas id=“canvas2D” width=“640” height=“480”>

HTML5 canvas is not supported.

</canvas>

var canvas = document.querySelector(‘#canvas2d’);

var context = canvas.getContext(‘2d’);

4

Page 5: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Canvas 2D Functionality

Rects, Paths, Images, Text, Transforms, Shadows, Line Caps and Joins, Colors and Styles, Animations, Clipping

All images attributed to Mozilla Contributors from https://developer.mozilla.org/en-US/docs/Canvas_tutorial and used under the Creative Commons Attribution-Sharealike license. 5

Page 6: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Basic Example

function drawPath(context) {

context.beginPath();

context.moveTo(3, 0);

context.lineTo(10, 0);

context.quadraticCurveTo(30, 0, 20, 13);

context.quadraticCurveTo(0, 14, 0, 13);

context.closePath();

context.fillStyle = "#c0c0c0";

context.fill();

}

6

Page 7: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Basic Example

function init() {

var elem = document.getElementById('myCanvas');

var canvasContext = elem.getContext('2d');

canvasContext.fillRect(0, 0, 125, 95);

var transX = [ 0.15, 0, 1.15, 1, 0.85, 2, 1.85 ];

var transY = [ 0.0, 0.7, 0, 0.7, 1.4, 0.5, 1.2 ];

canvasContext.translate(20,20);

for(var i=0; i<7; i++) {

canvasContext.save();

canvasContext.translate(30*transX[i], 30*transY[i]);

drawPath(canvasContext);

canvasContext.restore();

}

} 7

Page 8: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Hardware Acceleration

BlackBerry PlayBook 2.0

Hardware acceleration through GPU.

Paths are tessellated and passed to

OpenGL ES 2.0.

BlackBerry PlayBook 2.1

Updated graphics drivers for

increased performance.

BlackBerry 10

Hardware and software improvements will continue the trend.

8

Page 9: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

KineticJS

Interact with rendered objects.

http://www.kineticjs.com

FabricJS

Interactive object model on top of canvas.

http://fabricjs.com

Cocos2d-HTML5

http://www.cocos2d-x.org/

CakeJS

JavaScript scene graph library.

http://code.google.com/p/cakejs/

ImpactJS

http://impactjs.com

Box2D

Physic engine.

http://box2d.org

Canvas2D Frameworks

9

Page 10: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Cocos2d-HTML5 Example

Custom ControlsOverlay.js created.

Joysticks and buttons.

Sprite art by Clint Bellanger

http://www.OpenGameArt.org

Tile art by Daniel Cook

http://www.LostGarden.com

Work In Progress

Documentation.

Open source.

10

Page 11: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

WebGL

Page 12: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

What is WebGL?

OpenGL ES 2.0 in your web browser.

Khronos open standard.

Hardware accelerated graphics for the web.

It’s fully integrated.

It is not a plug-in.

Standards compliant browsers.

Chrome

Firefox

Safari

Opera

What about mobile?

BlackBerry PlayBook.

BlackBerry 10.

http://caniuse.com/webgl

Page 13: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

TunnelTilt is WebGL

First WebGL demo on PlayBook 2.0

Available on BlackBerry App World

Open-sourced on www.github.com/blackberry

Key Features: Accelerometer and Collision Detection

Page 14: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Photojam for Facebook is WebGL

Instant Filters and Effects via WebGL.

Connects directly with Facebook.

Special thanks to James Gibbons.

14

Page 15: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

WebGL Frameworks

IvanK Lib

2D with WebGL; simplicity and performance.

http://lib.ivank.net/

J3D by Bartek Drozdz (Open source, MIT)

Leverage Unity3D scenes in your WebGL applications.

https://github.com/drojdjou/J3D

Inka3D (Closed source)

Leverage Maya scenes in your WebGL applications.

http://www.inka3d.com

CubicVR.js by Charles Cliffe (Open source, MIT)

Full-fledged WebGL framework, JSON/Collada imports, physics.

https://github.com/cjcliffe/CubicVR.js

Page 16: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Three.js is WebGL

Created by Ricardo Cabello as a 3D JavaScript library.

One of the most popular WebGL frameworks in use.

Large community involvement.

Under active development.

Distributed under MIT license.

https://github.com/mrdoob/three.js

Images from: http://mrdoob.github.com/three.js/ 16

Page 17: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Pure WebGL vs. Three.js

Exercise: Drawing a square in 6 steps.

17

Pure WebGL Three.js

Create a Canvas. Import Three.js.

Get a WebGL context. Setup scene.

Setup a GLSL program. Setup camera.

Setup geometry. Add geometry with material.

Setup shaders.

Render. Render

Page 18: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

18

Step 1 of 6

Pure WebGL (Lines: 1) Create canvas.

<canvas id=“myCanvas” width=“1024” height=“512”></canvas>

Three.js (Lines: 1) Import Three.js.

<script src=“js/Three.js”></script>

Page 19: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

19

Step 2 of 6

Pure WebGL (Lines: 3) Get WebGL context.

var canvas = document.querySelector(“#myCanvas”); var gl = canvas.getContext(“experimental-webgl”);

Three.js (Lines: 2) Setup scene.

scene = new THREE.Scene();

Page 20: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

20

Step 3 of 6

Pure WebGL (Lines: 8) Setup GLSL program.

var vertexShader = createShaderFromScriptElement(gl, “2d-vertex-shader”); var fragmentShader = createShaderFromScriptElement(gl, “2d-fragment-shader”); var program = createProgram(gl, [vertexShader, fragmentShader]); gl.useProgram(program); var positionLocation = gl.getAttribLocation(program, “a_position”);

Three.js (Lines: 5) Setup camera.

camera = new THREE.PerspectiveCamera(FOV, ASPECT_RATIO, NEAR_PLANE, FAR_PLANE); camera.position.z = 1000.0; scene.add(camera);

Page 21: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

21

Step 4 of 6

Pure WebGL (Lines: 13) Buffer geometry.

var buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(

[-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0] ), gl.STATIC_DRAW);

gl.enableVertexAttribArray(positionLocation); gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);

Three.js (Lines: 9) Add geometry with material.

geometry = new THREE.CubeGeometry(1024, 600, 0); material = new THREE.MeshBasicMaterial({color: 0x00FF00, wireframe: false}); mesh = new THREE.Mesh(geometry, material); scene.add(mesh);

Page 22: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

22

Step 5 of 6

Pure WebGL (Lines: 24) Setup shaders.

<script id=“2d-vertex-shader” type=“x-shader/x-vertex”> attribute vec2 a_position; void main() {

gl_Position = vec4(a_position, 0.0, 1.0); }

</script> <script id=“2d-fragment-shader” type=“x-shader/x-fragment”>

void main() { gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // Green.

} </script>

Page 23: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

23

Step 6 of 6

Pure WebGL (Lines: 25) Render.

gl.drawArrays(gl.TRIANGLES, 0, 6);

Three.js (Lines: 13) Render.

renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); renderer.render(scene, camera);

Result:

Page 24: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Peaks and Valleys

WebGL, Virtual Controls, Audio…

Page 25: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

What Is Peaks and Valleys?

HTML5 gaming sample.

Combines a number of concepts:

Endless terrain based on heightmap.

Skybox texturing.

Ambient and directional lighting.

Pixel blending.

Joystick and button controls.

www.github.com/blackberry/WebGL-Samples

Page 26: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Original (Fixed 150 x 150)

Generate a square.

Raise all included vertices.

Repeat.

Average with neighbours.

Current (Dynamic 1024 x 1024)

Image as height map.

Web Workers progressively loading.

Heightmap from: http://en.wikipedia.org/wiki/Heightmap

Generating the Landscape

26

Page 27: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

_this = this;

this.worker = new Worker('./js/GLTerrainWorker.js');

this.worker.addEventListener('message', function (e) {

var params = e.data;

if (params.cmd === 'update') {

gl.bindBuffer(gl.ARRAY_BUFFER, _this.vBuffer);

gl.bufferData(gl.ARRAY_BUFFER, params.vertices, gl.DYNAMIC_DRAW);

_this.vBuffer.itemSize = 3;

_this.vBuffer.numItems = params.vertices.length / _this.vBuffer.itemSize;

/* Repeat for normal and index buffers. */

}

this.working = false;

}, false);

this.worker.working = true;

this.worker.postMessage({

'cmd': 'init',

'width': assets.json.terrain.width,

'height': assets.json.terrain.height,

'tileSize': assets.json.terrain.tileSize,

'vertices': assets.json.terrain.vertices,

'normals': assets.json.terrain.normals,

'offset': 60.0

});

Web Workers: GLTerrain.js

27

GLTerrain.prototype.update = function (px, pz) {

/* Only request an update if we're not already working. */

if (this.worker.working === false) {

this.worker.working = true;

this.worker.postMessage({

'cmd': 'update',

'px': -px,

'pz': -pz

});

}

};

Page 28: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

/* Initialize event listener for messages. */

self.addEventListener('message', function (e) {

var params = e.data;

if (params.cmd === 'update') {

self.update(params);

} else if (params.cmd === 'init') {

self.init(params);

}

}, false);

self.update = function (params) {

/* ~70 lines and ~14400 executions:

* Calculate new vertex, normal, and index arrays.

*/

setTimeout(function () {

self.postMessage({

'cmd': 'update',

'message': 'complete',

'vertices': new Float32Array(vertices),

'normals': new Float32Array(normals),

'indices': new Uint16Array(indices)

});

}, 3000);

};

Web Workers: GLTerrainWorker.js

28

Page 29: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Generating the Skybox

Two easy steps:

Paint the inside of a box.

Place box on head/camera.

The magic happens with:

gl.disable(gl.DEPTH_TEST);

Don’t forget to turn this back on.

TODO

360° Skybox With Cloud Movement 29

Page 30: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Lighting

float weighting = max(dot(aVertexNormal, vec3(0.0, -1.0, 1.0)), 0.0);

vWeighting = vec3(0.2, 0.2, 0.2) + vec3(0.6, 0.6, 0.6) * weighting;

Calculate the dot product between the vertex normal and the direction of the light source.

Set a minimum (ambient) light and add the directional component.

vLightWeighting gets passed to the fragment shader.

30

Page 31: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Blending Colours and Textures

Fragment shader blends colours and textures.

vec4 diffuseSand = vec4(0.8, 1.0, 0.0, 1.0);

vec4 diffuseGrass = texture2D(texture1, vec2(vTextureCoord.s, vTextureCoord.t));

vec4 diffuseRock = vec4(0.5, 0.5, 0.5, 1.0);

vec4 diffuseSnow = vec4(1.0, 1.0, 1.0, 1.0);

vec4 color = vec4(1.0, 1.0, 1.0, 1.0);

color = mix(diffuseSand, color, min(abs( 400.0 - vPosition.y) / 500.0, 1.0));

color = mix(diffuseGrass, color, min(abs( 800.0 - vPosition.y) / 200.0, 1.0));

color = mix(diffuseRock, color, min(abs(1000.0 - vPosition.y) / 300.0, 1.0));

color = mix(diffuseSnow, color, min(abs(1200.0 - vPosition.y) / 300.0, 1.0));

gl_FragColor = vec4(color.rgb * vLightWeighting, color.a);

31

Page 33: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Input System

Original

Expanded virtualjoystick.js by Jerome Etienne for multi-touch controls.

Current

CSS3 driven panels.

Repurposed ControlsOverlay.js from Cocos2D-HTML5 to WebGL.

https://github.com/oros/ControlsOverlay.js

33

Page 34: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Freewill.js

freewill = new Freewill({ 'container': document.querySelector('#easle') });

/* Add a button. */

button = freewill.addButton({

'image': './images/freewill/buttonred.png',

'pos': [ w - 106.0, h - 98.0 ],

'opacLow': 0.3

});

/* Add a Joystick to control camera rotation. */

rotation = freewill.addJoystick({

'imageBase': './images/freewill/dpad.png',

'imagePad': './images/freewill/pad.png',

'fixed': false,

'trigger': [w / 2.0, 0.0, w / 2.0, h - 108.0],

'opacLow': 0.0

}); 34

Page 35: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Traversing Peaks and Valleys

Minimize triangles via gl.TRIANGLE_STRIP.

35

Page 36: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

TODO: HTML5 Audio

Current

HTML5 <audio> elements.

Loads JSON via AJAX.

Simultaneous playback.

TODO

Integrate into PeaksAndValleys.

Explore SoundJS.

36

var tracks = {};

function Audio() {

var xhr = new XMLHttpRequest();

xhr.open('GET', 'audio/audio.json', true);

xhr.responseType = 'text';

xhr.onload = function () {

if (this.status === 200) {

var json = eval(this.response);

for (var n = 0; n < json.length; n = n + 1) {

var item = json[n];

tracks[item.name] = document.createElement('audio');

tracks[item.name].setAttribute('src', 'audio/' + item.file);

tracks[item.name].setAttribute('preload', 'auto');

tracks[item.name].setAttribute('loop', 'true');

if (item.playOnLoad === true) {

tracks[item.name].setAttribute('autoplay', 'true');

}

tracks[json[n].name].load();

}

}

};

xhr.send();

}

Audio.prototype.playTrack = function (name) {

if (tracks[name] && tracks[name].paused === true) {

tracks[name].play();

}

};

Audio.prototype.stopTrack = function (name) {

if (tracks[name] && tracks[name].paused === false) {

tracks[name].pause();

}

};

Page 37: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

TODO: BlackBerry Messenger

Register Application blackberry.event.addEventListener('onaccesschanged', function (accessible, status) {

if (status === 'allowed') {

this.registered = accessible;

/* We’re ready for BBM functionality! */

}

}, false);

blackberry.bbm.platform.register({

uuid: ‘http://www.famkruithof.net/uuid/uuidgen'

});

Invite To Download (2% generating 20%) (V)(;,,;)(V) if (this.registered === true) {

blackberry.bbm.platform.users.inviteToDownload();

} 37

Page 38: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

TODO: Can Do!

Additonal Social Integration

Facebook, Twitter, etc.

Multiplayer

Node.js and Socket.io.

Rendering multiple players/models in one area.

3D Interactions

Ray tracing.

Cut Scenes, Model Animation, etc.

Popular components of many games.

38

Page 39: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

TODO: Wish List

Web Audio API

Low latency audio.

True multi-channel audio.

Scoreloop

Currently available to native developers.

Simplifies social gaming (leader boards, achievements, etc.)

Monetization

Looking beyond sales revenue.

Subscription, digital goods, etc.

39

Page 40: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

Learning Resources

40

Page 42: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

BlackBerry Got Game Port-a-thon

November 16th and 17th

Tiered Rewards

$100 per eligible application (up to 20.)

Between 2 and 5: BlackBerry PlayBook

First 100 to submit 5+: BlackBerry Dev Alpha

First 10 to submit 10+: Paid trip to GDC 2013 in San Francisco

More Information / Virtual Registration

http://devblog.blackberry.com/2012/11/got-game-port-a-thon

42

Page 43: HTML5 Gaming - developer.blackberry.com Gaming - Nov-01.pdf · WebGL Frameworks IvanK Lib 2D with WebGL; simplicity and performance.  J3D by Bartek Drozdz (Open source, MIT)

THANK YOU

Erik Oros ([email protected] | @WaterlooErik)

November 15, 2012