Thursday, September 6, 2012

WhirlyGlobe 2.0: New Features

The WhirlyGlobe API is now officially on version 2.0.  Looking back, I'm impressed with what got done since 1.2.  Yay me.

The WhirlyGlobe Component is what I'm pushing for new users.  It's much easier to use and I'm liking the early feedback.  There's still a complex toolkit underneath it and that's what this is.

You can get WhirlyGlobe 2.0 from github.

Of iPad Melting & Sales Offices

I have two main sets of users:  The folks who want to toss a few markers on a spinny globe (sales offices) and the hard core map display folks (iPad melting).  The Component is for the first group, but WhirlyGlobe 2.0 is for the second.

A lot of 2.0 features were developed for specific clients.  They're just kind enough to let me release it all for free!  Ha, as if.  I have a big complicated contract and a lawyer with a specialty in intellectual property.

Anyway, what clients want can be summed up like so:  MORE!  BIGGER!  So that's what 2.0 is about.  I'll break the updates down by popularity.

Some Interesting Random Features

You're going to get bored the further down you read.  I'm already getting bored.  So let's start with some useful features.

On Demand Rendering

WhirlyGlobe is now keeping track of whether anything moved or faded or changed.  If it didn't, then the toolkit stops rendering.  It'll start again when something moves or changes.  Really, it should have already been doing that, so let's never speak of this again.

One of these iPads is busy melting a hole in your lap.  Can you tell which?

Oh and it doesn't work with particle systems, because... well that's kind of obvious.  Just turn it off if you're using particle systems.

Vector Layer Enhancements

Vector lines can now support width and be filled.  Under the right circumstances this looks really cool.  All my cool examples are proprietary.  So... yeah.  It works, trust me.

We can now read GeoJSON for vector features.  It's slow (woo, text) but easy to understand and a bit more web-y than Shapefiles.

UIView Overlays

You can now tie a UIView to a geographic location and have WhirlyGlobe move it around for you.  It'll even disappear when it's behind the globe.

That screen label is a UIView.  Trust me.

This has to be the #1 feature that people were pissed off wasn't already there.  Use it sparingly.  If you use this for more than a handful of UIViews it will be slow.  If you then complain that it's slow I'll set up a video chat so I can stare at you disapprovingly.

Quad Display Layer and Its Ilk

I've discussed these before and there's not much more to say.  They're awesome and incredibly useful for paging image data.

Oh, OpenStreetMap you so... free.

You can also page vector data with them, but you have to set up the data sources yourself.  I realize that can be difficult and that's why I charge by the hour.

Here's a short list of things you can do with the quad display layer:

  • Page from a MapBox Tiles database
  • Read from a network data source in the standard(ish) Google Tile Format
  • Set up data with ImageChopper and page it locally with a SphericalEarthQuadLayer
    • ImageChopper has been updated to produce an image pyramid
  • Page from your own data source with a TileQuadLoader
  • Read data on demand from a properly organized vector data source.
Much of the good stuff has been hooked up to the WhirlyGlobe Component and you can use it there.

Screen Space Objects

You can call them 2D markers, screen space objects or billboards.  Whatever you want to call them, they're now in WhirlyGlobe.

Screen space objects are pretty simple.  Give WhirlyGlobe a location to track and it'll move the label or marker around appropriately.  They'll also disappear if they fall behind the globe.

Both labels and markers support them.  Just set the @screen attribute to YES.  They'll show up correctly in the selection layer too.

Performance Enhancements

WhirlyGlobe sits on top of a real rendering engine.  A small, simple one but a rendering engine nonetheless.  These changes all center on the rendering engine itself.  The first one is, hey, you can now measure performance in the renderer.

Culling is important, but not ideal.  Basically, you have objects in memory that you're not rendering.  That sucks, but it does happen.  The rendering engine now has a culling tree it will sort Drawables in to and then consult before rendering.

OpenGL buffer management is always great fun, if you find annoying and weird things fun.  Luckily, I do.  So now I'm managing buffer and texture IDs so we can reuse them rather than allocate them, which is slow.  So slow.

Usually you want to do Z buffering.  Sometimes you want to kick it old school with priority based rendering.  Actually, in general you don't want to do that, but I do occasionally.  So now that's an option in the renderer.

Things I Changed Just To Mess With You

Some things I changed because I was in a mood to.  The big one was the great renaming and sorting.  Files moved around, I got strict about naming and the WhirlyKit/WhirlyGlobe distinction appeared.  WhirlyMap is also in there, but that's going to change name again.  Just because.

The layer thread teardown has changed a bit.  You can now ask the layer thread to release or delete things for you.  This was actually to fix a few ordering problems, but it's still kind of weird.

Layers changed a bit in general.  There's now a shutdown call and you're expected to respect shutdown and dealloc, but you may not get one before the other.  The number of people writing their own layers is vanishingly small, so I'm not going to sweat it.

Other Things I'll Use More Later

Some things are in WhirlyGlobe 2.0 but not fully formed.  I'm using them here and there, but their full potential has yet to be realized.  So be warned.

On demand paging was a big theme of 2.0.  The quad display layers are pretty tightly coupled with what the viewer is doing, but the UpdateDisplayLayer is not.  It's a fairly casual update based on time and location.  That's useful for... you know... stuff.

Support for random coordinate systems is halfway there in WhirlyGlobe.  I've got Spherical Mercator and a few others, but it's hardly complete.  That will change when the map toolkit comes out.

WhirlyGlobe 1.2 added caching for complex features, such as lofted polygons, but I was never entirely happy with it.  Right now the GeometryLayer exists to throw random polygons into the scene.  At some point in the future, these two will meet... somehow.

Sometimes you need to update geometry every frame.  Not as much as you think you do, so be cautious.  If you really, really do there is now an Active Model construct for doing it.

A Scene Graph is a nice generic way to represent 3D geometry for rendering.  I'm not a big fan, as they can be kind of bloated.  I've added one to be compatible with a file format (not in the toolkit) that thinks in those terms, but I'd prefer if people didn't use it.

Onward To The Future!

WhirlyGlobe is about where I want it to be.  The future holds some performance enhancements (legal, I promise) and a lot more client driven features.  And at some point I'll need to tackle OpenGL ES 2.0.

The next big thing should be a flat map toolkit based on WhirlyGlobe.  Stay tuned.


  1. Wow, you obviously are stepping up with WhirlyGlobe! I'm impressed!

    I'm curious, why would using UIView slow down the app, but not 2D markers? Does UIView have some inherent characteristics that make it not-so-suitable?

  2. Thanks!

    Markers and labels are batched. By the time they get to the renderer they should consist of a handful of drawables which we can dump right on top of the scene. UIViews require more individualized processing and a separate compositing step.

    Apple's gotten way more efficient with recent releases, but there's still extra work to do for a UIView.

    There's potential for even greater speedup in future versions of WhirlyGlobe. If I move the screen space objects to a custom shader I can avoid the batching step each and process more screen space objects.

  3. Is there any glue to add a skybox? I mean something like Apple class GLKSkyboxEffect. Thanks!

  4. There's no support for a skybox at present. You'd need to render it yourself in the render loop.