Webgl 1 Context And Loop
This is an introduction to creating WebGL contexts with getContext and animating with requestAnimationFrame.
WebGL
WebGL is supported on most modern browsers, including mobile devices, and is an easy way to get started with OpenGL-style programming.
For this tutorial, we will be using javascript. If you are new to javascript or need a refresher, Mozilla’s developer site is a great resource. Their WebGL API Information is very handy as well.
I suggest using Chrome for developing WebGL apps. In Chrome, You can navigate to View > Developer > Developer Tools to see output from your code.
Contexts
In the land of OpenGL (The “GL” stands for “Graphics Library” … or sometimes Language) and all its flavors (OpenGL ES, WebGL), a rendering context is a channel on which drawing states are transmitted to the device’s window. A single application can have many contexts, but only one is current at any given time on any given thread of execution.
A WebGLRenderingContext is created by calling getContext("webgl") on canvas element canvas.getContext("webgl") (note, for version 2.0, one will eventually pass in “webgl2”). The following four lines of code grab a canvas element, initialize a web context on it, set the clear color to red, and then clears the screen (with red):
var canvas = document.getElementById("canvas");
var gl = canvas.getContext("webgl");
gl.clearColor(1.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT| gl.DEPTH_BUFFER_BIT);
Below is a WebGL context, though you wouldn’t know it just by looking at it (since it’s just a red rectangle)
Here is the full code to generate the above context. Note we also check to make sure the context was created successfully. A global variable GL holds our context so we can use it in other functions later on.
Animation Frames
So far we have just initialized a WebGL context and cleared the view to red once. In order for anything to happen over time, we must add an function that is called repeatedly. In javascript, the current protocol for this is handled by a function that calls itself.
We will add four functions:
- Request: a
requestAnimFramefunction that is called by thewindowitself. - Loop: an
animationLoopfunction that callsrequestAnimationFrame, passing itself as the argument, and then calls therenderfunction. - Render: a
renderfunction that actually does the drawing. - Start: a
startfunction that initializes the WebGL rendering context and then begins theanimationLoop
Request
The requestAnimFrame function provides cross-platform support and finds the suitable frames-per-second at which your device should operate. For some more details on this see Paul Irish’s post. We will just copy this code, which finds the best option given the browser in use:
window.requestAnimFrame = ( function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
// if none of the above exist, use non-native timeout method
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
} ) ();
Loop
The animationLoop calls the requestAnimFrame function:
function animationLoop(){
// we request a new frame
requestAnimFrame( animationLoop );
// and call render function (defined below)
render();
}
Render
Draw things onto the context:
function render(){
timer++;
GL.clearColor( .5*(1+ Math.sin( timer/30.0 )), 0.0, .5*(1+Math.cos( timer/30.0 )), 1.0);
GL.clear(GL.COLOR_BUFFER_BIT| GL.DEPTH_BUFFER_BIT);
}
Start
Initialize the Context and Begin the Animation Loop
function start(){
initWebGL();
animationLoop();
}
Here is the full code for initializing a context and starting an animation loop in WebGL: