Deploying C++ to JavaScript using Emscripten

If you paid attention during the post-GDC news, you probably heard that Epic Games and Mozilla teamed up to get the Unreal Engine running in the browser, without plugins, in a matter of four days. The secret? Emscripten.

Alon Zakai has worked three years on Emscripten, and its an amazing piece of software.

Literally, you take C++ (or technically, something that compiles to LLVM), and out comes JavaScript. Not only can you do basic code, you can take large, complex projects with myriad dependencies, and actually run it in the browser.

Let’s take one of my previous samples, and port it to the browser. Ready?

Setup

Getting things set up was the hardest part. Fortunately, there was a great step-by-step tutorial that helped me get the pieces installed. I am using Windows, so I went through the Using Emscripten from Visual Studio 2010┬átutorial. I went through the first portion for setup, and skipped the second part, since I didn’t need Visual Studio integration.

If you are on Mac or Linux, more information is provided at https://github.com/kripken/emscripten/wiki/Tutorial

Build Script

Really, that’s all. This is my original build script, but using “emcc” instead of my previous compiler, and the output has a “.js” extension (I also removed directory paths, since Git gists don’t support them).

The “-s” flag in emcc is used to pass settings. I set “FULL_ES2″ to 1 (true) because my project was written for OpenGL ES 2.0, which is compatible with WebGL. The Emscripten default is to provide compatibility for desktops version of GL, that need some bootstrapping.

Source Code

This project draws a simple triangle. There’s only one conditional at this level. In order to run the main loop properly, “emscripten_set_main_loop” emulates the constant pulse that a “while” loop usually provides.

In the SDLStage class, I changed the step() method to skip most of the normal event loop. That’s it. This compiles and runs in the browser.

You can check out the final project here: http://www.joshuagranick.com/examples/simplegl
You can see the full gist here: https://gist.github.com/jgranick/5430948

Other Notes

The resulting output can be large. So far, the best way to handle the size is to enable gzip compression on your server. If you are using Apache, the easiest way to do this is with a basic .htaccess file in the same directory as the project, like this:

There are a lot of creative ways to use Emscripten, whether you build an entire project or only a library. Combined with the ability to target asm.js, there is a lot of potential to take web content to the next level.

  • Arthur Ostapenko

    Cool! Is there any benchmarks available anywhere?

  • http://www.joshuagranick.com Joshua Granick

    Here are some recent benchmarks, comparing canvas performance with WebGL:

    http://www.goodboydigital.com/pixi-js-bunnymark/
    https://www.scirra.com/blog/107/boosting-mobile-html5-game-performance-with-webgl

    I have not tested asm.js for CPU performance, but have heard anecdotal numbers such as:

    https://twitter.com/kripken/status/320608686802350080

  • Artsiom T.

    When will it be available in NME?

  • Hugues FREI

    Why the Adobe team could not do for their Flash Player plugin
    like the Epic Game and Mozilla team did for their Unreal 3 engine plugin
    to compile the code of their plugin into a basic javascript final code instead of a native code

    to make it run inside the browser without any plugin !
    and also use WebGL when necessary and possible
    for the rendering of the 3D objects !

    Epic Game and Mozilla said that the final speed is only two times lower
    than the speed with a native plugin.

    I think it would be quite fantastic to see flash contents playing
    inside the native iOS Safari HTML5 mobile web browsers
    on all the iOS iPad and iPhone mobile devices all over the world ?

    It would be so fine to have no problem to play with Flash content
    in all mobile web browsers even those without any native code Flash Player plugin.

    And finally, what a buzz for the Adobe dev teams and colleagues if it’s well done ?