Technical Lead of Tools & Middleware @Ubisoft Blue Byte and prior Producer @Bigpoint Software Engineer and Video Gamer from the heart! Speaking in Code and KPI's and elaborating on everything Online Games.
Posts by Savas Ziplies
  1. The "Gaming Developer" Dilemma ( Counting comments... )
  2. Under Pressure ( Counting comments... )
  3. (Don't Fear) The (C)Reaper ( Counting comments... )
  4. 3...2...1... planned! ( Counting comments... )
  5. What happened to the middle class of gaming? ( Counting comments... )
  6. WebGL - Part 2: In the beginning there was... ( Counting comments... )
  7. WebGL - Part 1: A new challenger appears... ( Counting comments... )
  8. There are no Casual Games… ( Counting comments... )
Technology/ Code /

As I did not want to be as somewhat polemic as last time I checked several different pragmatic ideas I could post about. I weighted each against the other but with the news that the final draft of WebGL was released I decided to go this route and present some information, basics and a furthermore small tutorial in the following parts about WebGL!

A new challenger appears

Twelve years after HTML4 and eleven years after XHTML1.0 the WorldWideWeb Consortium "finally" dropped all efforts to standardize another, a different and more XML-based standard for the Web and continued where they left off to extend HTML4 to built it up to the requirements of our current time. As we are easily able to define that our current web-browsing habits are influenced by multimedia-based content with YouTube, Facebook, Farmville, Podcasts, ... the new standard would have to be more multimedia flexible. And W3C listened!

The consequent successor HTML5 was finally started in 2008. Now, only three years later the standard is seeing the finishing line and most released drafts have already been implemented in common browsers such as Firefox, Chrome or Safari through WebKit. It provides special video, audio and canvas elements, support for codecs such as OGG Theora/Vorbis and MP4 (still a little dependent on decisions and implementation as it is still not final, possibly WebM), semantic support based on RDFa, sectioning etc. and a native 3D API named WebGL!

WebGLWebGL is a specification, independent from HTML5 but depending on the Canvas element of the standard. It is implemented as a context of the canvas and can be programmed (for now, actually more will be possible) through JavaScript and shaders. Speed and some specifics are dependent on the actual implementation i.e. the Browser but in general interchangeable in-between different Webengines.

Therefore, WebGL offers native in-browser support for 3D development. But actually the idea of 3D in your Browser is not a new challenge for our beloved internet...

3D on the Web

Already in the early days of the WorldWideWeb several different developers, companies and initiatives tried to establish 3D in the browser to provide a more persuasive environment for the user, correlating what was currently being established in games, that became more and more 3D focused during these years.
Already released in 1995 the Virtual Reality Modeling Language (VRML) tried to bring 3D to the Web. VRML 1.0 allowed to define the geometry, textures, materials etc. and especially scripts to visualize a 3D scene in a common textfile format. This scene was additionally able to retrieve additional data from different URLs as well as to react to events and triggers through special Java/JavaScript programs in its script nodes. Later it was extended to allow animations, sounds and other multimedia assets in 1997 with the VRML 2.0 standard.
The problem with VRML was mainly that it required a plugin to be installed in your browser as well as much processing power. Most plugins weren't optimized and the scenes described in a very high-level style required too much load. There were some initiatives but besides some world viewers and websites of authorities no one really jumped onto VRML.

In 2001 the Web3D Consortium built a new high-level abstraction for 3D in the Browser: X3D. X3D extended VRML with more standards and especially profiles, shaders, gis and networking. It still requires a plugin or player and was therefore not as perceived as wished for.

As WebGL is more established and well-supported already by nearly every big browser on the market the Web3D initiative now jumps onto that train without giving up VRML and X3D. With X3DOM the initial specification and implementation is now being made available on your browser without the need of plugin a but with the power of WebGL and Canvas.

Nevertheless, in this multi-part series I will only focus on WebGL directly. If you want to know more about these "historic" approaches just follow the given links.

OpenGL in the Browser

In contrast to VRML or X3DOM WebGL follows a more direct ("low-level" in comparison) approach to 3D in the Browser. As the name suggests WebGL is based on OpenGL and specified by The Khronos Group. It is based on OpenGL ES 2.0 (nowadays good known from iOS and Android) and supports GLSL in version ES1.0. It docks onto the HTML5 canvas as a drawing context and with that it is fully integrated in the Document Object Model (DOM) and therefore allows full interaction with the general HTML Layout and Objects (e.g. overlaying, CSS styles, ...).

As mentioned, as well as OpenGL WebGL is low-level and fully based around shaders. Therefore, things like defining simple geometry and scenes in an easy XML format as it is possible with X3D is not part of the WebGL standard itself. Possible implementations and APIs on top are nevertheless feasible (and already developed to some degree).

You can nearly cope everything you know about OpenGL ES 2.0 into WebGL. But there are some limitations (besides what is currently still different in-between the different Browser implementations). One important difference is that WebGL has no support for non-power-of-two textures (you could disable mipmapping). You have to resize dynamically. But in general you can feel with WebGL as you do with ES2.0 in other programming languages. It even looks similar. Let's have a look at an exemplary draw() method (taken from the OpenGL ES 2.0 Programming Guide):

function Draw(esContext) {
   var userData = esContext.userData;
 
   // Set the viewport
   gl.viewport( 0, 0, esContext.width, esContext.height );
 
   // Clear the color buffer
   gl.clear( gl.COLOR_BUFFER_BIT );
 
   // Use the program object
   gl.useProgram( userData.programObject );
 
   // Load the vertex position
   gl.bindBuffer( gl.ARRAY_BUFFER, userData.vertPosObject );
   gl.vertexAttribPointer( userData.positionLoc, 3, gl.FLOAT, false, 0, 0 );
   gl.enableVertexAttribArray( userData.positionLoc );
 
   // Load the index buffer
   gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, userData.indicesObject );
 
   // Load the MVP matrix
   gl.uniformMatrix4fv( userData.mvpLoc, false, getAsFloat32Array(userData.mvpMatrix) );
 
   // Draw the cube
   gl.drawElements( gl.TRIANGLES, userData.numIndices, gl.UNSIGNED_SHORT, 0 ); 
}

Looks pretty familiar, doesn't it? A description of what this all means and how to really program it in JavaScript and embed it into a WebSite will follow in the coming parts.

Browser support

For the User
First of all you have to be able to see and test WebGL developments. Currently the easiest way to use WebGL is to install the current Chrome Browser. Since version 9 it has enabled WebGL support in its stable release. If you want to use other Browsers such as Mozilla or Safari you would have to get the according nightly builds. In each case you might need to configure the according download. For a small "manual" have a look here or be lazy and use Chrome.

For the Developer
If you want to develop WebGL in a supporting Browser, you check for and enable WebGL through JavaScript by actually just trying and checking for success. There are two things you have to do:

  • Check if the browser supports WebGL in general
  • Find/Get a canvas and enable the WebGL context for it

To check if your browser or more specifically the current window you are in allows WebGL you check for a specific window flag:

if(window.WebGLRenderingContext) //This Window supports WebGL in general!

If this context returns true at least the Browser does support WebGL. Now, you need to check a canvas and enable the WebGL context in that canvas. Normally, you would specify a <canvas> element and hand this to a check and enabling function:

function(canvas) {
  //Several names to check because of still diverse implementations
  var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
 
  //The context we want to fill
  var context = null;
 
  //Iterate over all names and test for success
  for(var i = 0; i &lt; names.length; ++i) {
    try {
      context = canvas.getContext(names[i]); //Optional parameters can be handed to the implementation
    } catch(e) {}
 
    //As soon as we got one - SUCCESS!
    if(context) {
      break;
    }
  }
 
  return context;
}

If no context can be received but the WebGLRenderingContext says it may do WebGL, some other problems occurred. If the browser supports, you have enabled and retrieved the WebGL context and can start developing applications in your browser with fancy JavaScript.

The "new" power of JavaScript

Actually, nothing is "new" about JavaScript. The JavaScript used to first make a clock tick down on a Website, later to "do AJAX" or now to develop WebGL is pretty much all the same and based around the ECMAScript standard. Even if it contains Java in its name it has nothing to do with it. The former LiveScript is supposedly just named JavaScript to establish it with the already established Java... and probably because of a somehow Netscape/Sun partnership. But do not hesitate: The interpretation of JavaScript during runtime has been incredibly speeded up especially over the last years as more and more client programming is now part of normal websites and administrative interfaces reload and rebuild many things on-the-fly.

For JavaScript itself, it is first and foremost a prototyping programming language. This means that instead of developing a class-based architecture structure that is instanciated and dependent to the initial implementation and used throughout your development, in JavaScript you "re-use" the same classes for all instances with all given methods (called behaviours) that are added at first or also during runtime. These can be extended by the developer. Further the instances made from the structure are the states. In general you could say that prototyping is based on copying: It copies the "prototype" over and over again! Now, the most important thing about the prototype implementation of JavaScript is that it also holds a link to its "prototype" and therefore derives recursively through the prototyping hierarchy to find what we request.

A very simple example: We define a Blog!

var personalBlog = { title="Personal Blog", author="Savas Ziplies" };

Now we define a second blog:

var altDevBlog = { title="AltDev Blog" };

and assign our personalBlog as prototype:

//This does not work in all JavaScript implementation (as not all have the direct prototype to be settable), but for the example we rely on it!
altDevBlog.__proto__ = personalBlog;

Now we query

alert(altDevBlog.author + "@" + altDevBlog.title);

and will get the following result: Savas Ziplies@AltDev Blog! As you can see, even if I have not defined "author" in altDevBlog I may still access it as I specifically set the prototype of altDevBlog to personalBlog, therefore the "author" not available is resolved at the prototype personalBlog and printed. This hierarchy can go on and on forever and can be a performance issue if not consciously developed against. But in general prototyping and JavaScript itself offers many patterns that go well with WebGL and designs in general.

Therefore, JavaScript depends on a little different "thinking" approach. But besides that JavaScript also provides "somehow" object-oriented principles, delegation, dynamic typing, closures, run-time evaluation (very helpful indeed) and much more. Actually, JavaScript is a very powerful and somewhat interesting programming language but just seems awkward to most people because of its syntax, the name and because it is an interpreted language. Nevertheless, you can do practically everything with it, also relying on nearly every design pattern described.

To be concluded...

As I do not want to write a book as I did last time (yeah, hard to believe ^^'), this is it for today. You now know some history, the basic standard and how to "use" WebGL applications. The next parts will feature of course further explanations of WebGL, an additional introduction to JavaScript (and some of the creepy stuff you can do with it), presenting already existing WebGL libraries and an exemplary tutorial game developed fully in WebGL (as well as some twists and tweaks around networking and dynamic loading). In addition we will try to clarify how WebGL stands against other 3D in the Browser such as Flash3D, Unity3D and Shiva3D.

To already give you a taste of what to come and what is possible with WebGL, have a look at these publicly available WebGL Samples over at Googlecode, the astonishing Google Body example or the nice presentation of GLGE in the video.

[youtube width="640" height="390"]http://www.youtube.com/watch?v=Vva36undIss[/youtube]

Also published on INsanityDesign.com