Skip to content
kripken edited this page Mar 4, 2013 · 11 revisions

Emscripten supports GL in three ways:

  • The WebGL-friendly subset of OpenGL, basically what maps directly to WebGL, and is approximately OpenGL ES 2.0 minus client-side data and a few other things. This is stable, and recommended since it is the most efficient - each GL command basically becomes a direct WebGL command, so performance is predictable and fast. If you write new code, we recommend you write to this subset of OpenGL.

  • OpenGL ES 2.0 emulation. Compile with -s FULL_ES2=1 to get this (there is no compile-time way for us to automatically know if you need it, sadly), and it adds client-side data. That means you can do glDrawArrays etc. without a bound buffer, and our GL bindings will set up the buffer automatically (since WebGL requires that a buffer be bound). This is not as efficient as the WebGL-friendly subset, since while we can bind buffers for you, we don't know what the optimal pattern of buffer creation/sizing/etc. is. But this option is very useful if you have a lot of code that is OpenGL ES 2.0.

  • OpenGL emulation of older desktop and mobile versions. This includes support for GL 1.x features like immediate mode and various commands like glNormalPointer etc. Emscripten support for such emulation is sufficient to run Sauerbraten (BananaBread project) and several other real-world codebases, but is definitely not complete in the sense of supporting all older GL features (which would be an enormous task, and very hard to do efficiently).

  • Online demos:

  • Complete OpenGL game engine (shows emulation of non-WebGL elements of OpenGL)

  • OpenGL ES 2.0 gears

  • Run python tests/runner.py browser.test_glgears for an example. For other examples, run just python tests/runner.py browser.

  • Code is in src/library_gl.js.

What is the "WebGL-friendly subset of OpenGL"?

The WebGL-friendly subset of OpenGL is basically what maps directly to WebGL, call to call. That includes almost all of OpenGL ES 2.0, except for client-side arrays. The reason they are missing from WebGL is because they are less efficient than properly using GPU-side data. Similarly, if we emulated client-side arrays here, we would end up with very bad performance, since we would need to upload the data on each call to glDrawArrays etc. (Even if there are two calls one after the other, we can't know the data did not change!) So in practical terms full OpenGL ES 2.0 emulation would be convenient, but lead to bad performance so in practice you would need to properly rewrite your code to a WebGL-friendly subset anyhow.

Writing for the WebGL-friendly subset of OpenGL

See the files in tests/glbook and their git history for some simple examples ported to that subset.

A very useful tool is the webgl.verbose option in Firefox. If you compile code that uses clientside arrays, that option will give you a warning when there isn't a bound buffer and so forth. It will also warn you of other differences between OpenGL and WebGL.

What if I need additional GL features not supported yet?

Feel free to file issues with testcases that do not work, and we will look into them.