WebGL for OpenGL ES programmers

I’ve been meaning to look into WebGL for a while now. Coming from an OpenGL (and then an OpenGL ES 2.0) programming background, I figured it should be relatively “easy” to get up to speed with some basic primitive drawing.

Luckily, I was not disappointed: WebGL’s specification was heavily based on OpenGL ES’ and knowledge can be easily transferred between the two. In this post I outline the main differences and similitudes between these two standards.

WebGL

Screenshot of “WebGL Test” – a test program built to determine if WebGL is supported on a browser – Click on the image for the live version.

I was surprised to learn that WebGL, as an API, is even slimmer than OpenGL ES 2.0. OpenGL ES 2.0 had already done away with many features from ES 1.1, so WebGL being even smaller, really feels minimal. This is not a bad thing at all, but may make the learning curve a little more steep for developers just getting started with the *GL APIs.

In order to try WebGL, I decided to create a simple test application that determines if your browser supports it. A screenshot of the application can be seen above. The live version can be accessed by clicking on it or clicking here.

Some of the main things that struck me from WebGL while building this application were:

  • Javascript is the only binding. This might sound obvious, but it’s worth mentioning. WebGL development is done in Javascript (unless you are Notch).
  • No in-system memory Vertex Arrays: usage of VBOs is mandatory. It is the only way to submit geometry to the GPU. I think this decision makes a lot of sense, considering that if data were kept in system RAM as a Javascript array, copying to the GPU every frame may be prohibitively expensive. One of the best practices in OpenGL is to cache data in the GPU’s RAM and WebGL makes it mandatory.
  • Javascript types: WebGL provides several Javascript objects/wrappers that help use the API. Some function calls have been changed from the ES 2.0 spec to accommodate Javascript conventions. The glTexImage2D function, in particular, has a very different signature and seems unable to accept a raw array of bytes as texture data. Javascript Image objects help here.
  • Data must be loaded into WebGL using helper types like Float32Array, which tightly packs vertex data into consecutive memory. This is mandatory for populating VBOs.
  • You will have to deal with interleaved array data and feel comfortable counting bytes to compute strides and offsets. It’s the only way to keep the number of VBOs reasonable and is also one of the best practices for working with OpenGL and WebGL.

On the other hand, just like in ES 2.0:

  • There is no fixed-function pipeline. The T&L pipeline has to be coded.
  • Shaders are mandatory. The current types are vertex and fragment shaders.
  • Old data upload functions, such as immediate mode and display lists, are not supported.
  • There is no matrix stack, nor matrix helper functions. Be prepared to roll your own and try to leverage shaders as much as possible to avoid expensive computations in Javascript.

Conclusion

All things considered, I had fun programming WebGL. While developing the application, I found that most issues I encountered were not caused by WebGL, but rather by “surprises” in the way the Javascript programming language works.

I find WebGL, with its fast iteration cycles (just change the code, save and refresh the browser window), a reasonable tool for prototyping 3D applications and quickly trying out ideas.

The joy of not requiring the user to install any plugins and being able to present 3D data to them right in the browser is the icing on the cake and makes it a very interesting tool for people working in the 3D field.

Stay tuned for more WebGL goodness coming soon!

Fiddling with the HTML5 Canvas

I’ve been doing some experimenting with HTML5’s Canvas element. After some brushing up on Javascript, I started working on a couple of proof-of-concept scripts to see how well the platform can be used.

I have not been disappointed. Javascript, as a language, has evolved quite a bit since the old days of document.write(), with DOM editing as the one true way to manage dynamic content. Having said that, I find that Javascript is still quirky and flawed.

Here’s a short script I wrote (fewer than 160 lines) that animates a girl wearing the traditional Oktoberfest outfit. She walks back and forth within a given 500×500 area. This is not a video, your browser is doing the math to update her animations and move her around in realtime!

You should be able to see the demo just above this message, if you have a fairly recent browser that supports the HTML5 Canvas element. I was actually surprised about how mainstream Canvas support is: Chrome ≥ 22, Firefox ≥ 15, IE ≥ 9; Opera ≥ 12.1; Safari ≥ 5.1, Android ≥ 2.1 and Safari Mobile ≥ 3.2, all support this new element.

The animation atlas was taken from this cool website with resources free to use. The script “slices” the image, taking the appropriate frames to draw depending on the time simulation and the direction the character is walking towards (left or right).

Sprite animation atlas.

Sprite animation atlas.

Despite Javascript’s gotchas, with the addition of the HTML5 Canvas element, it’s become a nice tool that allows hacking together some easy 2D (or even 3D!) graphics and display them in a browser.

See you next time!