Transcript

PowerPoint Presentation

WebGLIs it a game changer for web based game development?

Iker Jamardo

HTML5 Developers Conference

2013/10/23

1

About Ludei...

San Francisco based company.

Started developing native iOS and Android games.

More than 18M users have downloaded a game by Ludei.

Developers of CocoonJS platform to push HTML5 game and app development.

10K+ developers, 500+ games

About me...

Iker Jamardo Zugaza

@judax

I run engineering @ Ludei.

Passionate about software architecture. A C/C++ and Java lover (refurbished to JavaScript).

Former University Professor and Researcher.

Designed and implemented the core of Ludeis cross-platform technology.

What is WebGL?

Stands for Web Graphics Library.

Maintained by the non-profit Khronos Group http://www.khronos.org

A Web Standard JavaScript API for accessing the underlying graphics hardware without the need of plugins.

WebGL 1.0 is based on OpenGL ES 2.0

Available in the major desktop browsers:

http://get.webgl.org & http://caniuse.com/webgl

Advantages of WebGL

Allows low level access to the graphics hardware while still being in a web based environment, with all its advantages:

Cross-platform

Rapid prototyping: JavaScript.

Execute and update anytime and anywhere.

Integration with document level content.

There are ways to access native features without leaving the JavaScript + HTML space.

Great communication environment.

Lets see WebGL in action!

For commercial purposes:

http://carvisualizer.plus360degrees.com/threejs/

For Games:

http://www.webgl.com/category/webgl-games/

http://playtankworld.com/

https://triggerrally.com/

http://www.goodboydigital.com/runpixierun/

https://turbulenz.com/games/save-the-day/

Is WebGL just for 3D content?

WebGL is not for 3D visualization only. 2D apps/games can benefit from access to the graphics hardware.

Canvas 2D Vs WebGL contexts APIs:

The 2D context provides a high level graphics API:

Primitives, complex paths, gradients, ...

The WebGL context is a low level graphics hardware management API similar to OpenGL.

Some program level code + GPU shader code.

What does WebGL look like?

Accessing the WebGL context in the application code:

// WebGL is bound to an HTML5 canvas.

// Either get it from the document or create a new one.

var canvas = document.createElement(canvas);

// Get the WebGL context from the canvas.

// Depending on the browser, there are different context

// names:

// experimental-webgl: Chrome, Opera, IE11

// moz-webgl: Mozilla Firefox

// webkit-3d: Safari

var gl = canvas.getContext(experimental-webgl);

What does WebGL look like?

The simplest vertex shader:

attribute vec3 aVertexPosition;

uniform mat4 uMVMatrix;

uniform mat4 uPMatrix;

void main(void) {

gl_Position = uPMatrix * uMVMatrix *

vec4(aVertexPosition, 1.0);

}

What does WebGL look like?

The simplest fragment shader:

precision mediump float;

void main(void) {

gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);

}

What does WebGL look like?

Basic steps to setup a WebGL application:

Initialization phase:

Retrieve the WebGL context.

Setup WebGL data: array buffers, textures, lights, ...

Load shader programs and get the connections to the shader code variables (attributes and uniforms).

Update and render loop phase:

Update your app/game logic.

Render you app/game.

Pass information to the shaders.

Execute the shaders: vertex -> fragment

What does WebGL look like?

Learning WebGL lesson 1

precision mediump float;

void main(void) {

gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);

}

attribute vec3 aVertexPosition;

uniform mat4 uMVMatrix;

uniform mat4 uPMatrix;

void main(void) {

gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);

}

var gl;

function initGL(canvas) {

try {

gl = canvas.getContext("experimental-webgl");

gl.viewportWidth = canvas.width;

gl.viewportHeight = canvas.height;

} catch (e) {

}

if (!gl) {

alert("Could not initialise WebGL, sorry :-(");

}

}

function getShader(gl, id) {

var shaderScript = document.getElementById(id);

if (!shaderScript) {

return null;

}

var str = "";

var k = shaderScript.firstChild;

while (k) {

if (k.nodeType == 3) {

str += k.textContent;

}

k = k.nextSibling;

}

var shader;

if (shaderScript.type == "x-shader/x-fragment") {

shader = gl.createShader(gl.FRAGMENT_SHADER);

} else if (shaderScript.type == "x-shader/x-vertex") {

shader = gl.createShader(gl.VERTEX_SHADER);

} else {

return null;

}

gl.shaderSource(shader, str);

gl.compileShader(shader);

if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {

alert(gl.getShaderInfoLog(shader));

return null;

}

return shader;

}

var shaderProgram;

function initShaders() {

var fragmentShader = getShader(gl, "shader-fs");

var vertexShader = getShader(gl, "shader-vs");

shaderProgram = gl.createProgram();

gl.attachShader(shaderProgram, vertexShader);

gl.attachShader(shaderProgram, fragmentShader);

gl.linkProgram(shaderProgram);

What does WebGL look like?

if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {

alert("Could not initialise shaders");

}

gl.useProgram(shaderProgram);

shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");

shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");

}

var mvMatrix = mat4.create();

var pMatrix = mat4.create();

function setMatrixUniforms() {

gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);

gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);

}

var triangleVertexPositionBuffer;

var squareVertexPositionBuffer;

function initBuffers() {

triangleVertexPositionBuffer = gl.createBuffer();

gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);

var vertices = [

0.0, 1.0, 0.0,

-1.0, -1.0, 0.0,

1.0, -1.0, 0.0

];

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

triangleVertexPositionBuffer.itemSize = 3;

triangleVertexPositionBuffer.numItems = 3;

squareVertexPositionBuffer = gl.createBuffer();

gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);

vertices = [

1.0, 1.0, 0.0,

-1.0, 1.0, 0.0,

1.0, -1.0, 0.0,

-1.0, -1.0, 0.0

];

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

squareVertexPositionBuffer.itemSize = 3;

squareVertexPositionBuffer.numItems = 4;

}

function drawScene() {

gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);

gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);

mat4.identity(mvMatrix);

mat4.translate(mvMatrix, [-1.5, 0.0, -7.0]);

gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);

gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);

setMatrixUniforms();

gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);

mat4.translate(mvMatrix, [3.0, 0.0, 0.0]);

gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);

gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);

setMatrixUniforms();

gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);

}

function webGLStart() {

var canvas = document.getElementById("lesson01-canvas");

initGL(canvas);

initShaders();

initBuffers();

gl.clearColor(0.0, 0.0, 0.0, 1.0);

gl.enable(gl.DEPTH_TEST);

drawScene();

}

What does WebGL look like?