Pages

Monday, November 26, 2012

EjectaGL - WebGL on iOS with Ejecta!

Summary: 
I am starting a project EjectaGL which adds WebGL binding to the awesome Ejecta project by Dominic Szablewski. EjectaGL extends the Ejecta framework to provide a WebGL implementation on vanilla JavascriptCore without any of the DOM overhead. EjectaGL provides a way to develop WebGL apps that can be shipped to the iOS app store(Not tested, but very possibly). It is far from being complete - So please contribute if you are interested! 


EjectaGL is distributed in the same MIT license as Ejecta.

Longer story:
I had worked on Voxel Flyer for js13kgames - A WebGL based game in less than 13K compressed Javascript. I wanted to keep developing it but I sort of wished it would work on iOS too. A search for WebGL on iOS usually yields the jailbreak method for enabling WebGL on iOS which is not very useful if you want to ship your WebGL app on the App Store. It feels like Apple might open up WebGL at any time but that never seems to happen. I always wanted to look into adding WebGL binding to AppMobi's directCanvas - but that never happened due to the complexity of the directCanvas code(and not to mention that the open source version has hardly seen the updates of their recent XDK).

Meanwhile I saw that Dominic from Phobos Labs(on whose work directCanvas is actually based upon) released Ejecta, a newer version of his iOS library to provide a barebones fast implementation of Canvas and Audio without all the DOM overhead. This time I felt the code was much more friendlier and  I could actually have a real shot at implementing WebGL on top of Ejecta. 

So couple of days back I started reading my fist tutorial on Objective-C and started hacking Ejecta! The result is EjectaGL. EjectaGL replaces the onscreen 2D canvas with a WebGL enabled canvas. At the current stage it's just a proof of concept and I am discovering and fixing issues as I am porting each lesson from  http://learningwebgl.com/. I tried porting Voxel Flyer to it and discovered that there is something wrong with the way uniforms are being passed in which I'm yet to finish debugging.

So basically it's in a very nacent stage but things are looking mostly doable. I can definitely use some help from people to add more bindings, port more examples and review my code for memory leaks(I'm sure there are few there given my newness to Obejctive-C) and other issues.

Check out the screenshot of Voxel Flyer running in the emulator with buggy lighting turned off at an astounding 9 frames/second. (You can run this demo by downloading the github source, creating an App/ folder and copying the contents of examples/VoxelFlyer to it)





As for some implementation details the one major caveat is the absence of Typed arrays in the current JavascriptCore that Ejecta uses(It might be coming some time later though). I have tried to work around it by implementing a very primitive pseudo typed array in Objective-C. Basically you can instantiate a typed array but that's about it. I found that most WebGL code just create the typed Float32Array, Uint16Array just before binding to the buffer anyway and don' do much with the contents anyway. There could be issues with libraries like glMatrix that use typed arrays for fast matrix calculations. Currently I just replace the typed array with a regular array in my stripped down version of glMatrix. I see a workaround here of implementing glMatrix itself in Objective-C that doesn't have typed array in it's method interface but can use the internal representation of EjectaGL's typed array which can then be passed on to EjectaGL. A similar strategy can be adopted if we want to get libraries like three.js also running on EjectaGL(though that would be a big undertaking of it's own).

There are not lot of WebGL APIs implemented currently but I don't see any other major issues in doing that (other than the typed arrays). Also I am thinking of adding stuff like rendering offline to a 2D Canvas and using that a texture in WebGL (My Voxel Flyer originally had a mini map that was a 2D canvas on top of the WebGL canvas).

So for now I just wanted to quickly mention the project and get the ball rolling so that I can ask for help and also make sure there is no duplication of effort (I am pretty sure 100 different people were also thinking of a similar project).

I think there are lot of applications for this project - It would be nice to get all those nice shader/demos working on the mobile device, possibly even the three.js ones. I also see a possibility of using all the cool WebGL shader effects available on Construct2 to be now fully exportable to the iOS target. 

Drop me a line here or on twitter - @vikerman

Update : EjectaGL is now merged into Ejecta main! You can get it at https://github.com/phoboslab/Ejecta

7 comments:

  1. What about using Dean McNamee's implementation from Plask? https://github.com/deanm/v8_typed_array/blob/master/v8_typed_array.h

    ReplyDelete
    Replies
    1. Ejecta is using JavscriptCore from Webkit and not V8. Dominic is actually going to look at adding support for Typed array supposedly already part of Javascript core but not exposed through APIs.

      Delete
  2. Very cool, I tried to do that for Titanium, using their Javascriptcore and emulating the WebGL calls thru an extension. Managed to get some basic lessons from learningwebgl.com to render. Will definitely check your project out.

    ReplyDelete
  3. This is fantastic! I Love Ejecta and have just started getting serious about WebGL... perfect timing ;)

    ReplyDelete
  4. Strange - link to github is broken and google and github know nothing of ejectagl source code. could you help?

    ReplyDelete
    Replies
    1. Hi Vladimir - EjectaGL is actually now part of Ejecta main! So you can find it in https://github.com/phoboslab/Ejecta

      Delete
  5. Hi, I see on this link http://codehum.com/stuff/ejectagl/ that we can load shader files using ejectaGL, but I can not find this feature in phoboslab/Ejecta. Any idea how we can easily load shaders file with phoboslab/Ejecta ?

    ReplyDelete