BlackBerry Loves HTML5
2
Canvas2D
3
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
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
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
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
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
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
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
WebGL
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
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
Photojam for Facebook is WebGL
Instant Filters and Effects via WebGL.
Connects directly with Facebook.
Special thanks to James Gibbons.
14
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
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
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
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>
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();
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);
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);
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>
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:
Peaks and Valleys
WebGL, Virtual Controls, Audio…
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
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
_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
});
}
};
/* 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
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
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
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
Blending Colours and Textures
Special thanks to Chandler Prall.
http://chandler.prallfamily.com/2011/06/blending-webgl-textures
TODO
Pre-rendered textures. 32
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
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
Traversing Peaks and Valleys
Minimize triangles via gl.TRIANGLE_STRIP.
35
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();
}
};
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
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
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
Learning Resources
40
Learning Resources
Frameworks (Three.JS, CubicVR, etc.)
www.learningwebgl.com
www.learningthreejs.com
www.html5canvastutorials.com
www.html5rocks.com
Box2DWeb Tutorials by Seth Ladd (http://blog.sethladd.com)
http://creativejs.com/2011/09/box2d-javascript-tutorial-series-by-seth-ladd/
WebGL: Up and Running by Tony Parisi
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