Tuesday, October 4, 2011

WhirlyGlobe 1.2 - What's Coming

I'm working on WhirlyGlobe 1.2 at the moment.  Well, I'm working on things and those things will wind up in 1.2.  Here's a list of some of those things.


Here's what I mean by caching.  WhirlyGlobe reads fairly generic data sets: geodetic shape files.  These are relatively unstructured lists of points, linears, and areal features with matching attribution.  All the coordinates are in (latitude,longitude).  Turning these into what you see on the screen involves a bit of processing.

What I'm doing internally is batching all that data into a small set of Drawables and tossing those over to the renderer.  To cache, I save that data out in a form compatible with OpenGL and load it back in on startup.

The caching is mostly finished.  I had a client who wanted to load all the Natural Earth 10m country vectors at once.  Turns out it's possible, even on the iPad1.

Bitmap Fonts

When you add text to the label layer in WhirlyGlobe it's rendering it to a UIImage and turning that into a texture.  That's not deeply efficient.  If you add a whole bunch of labels together, it is stitching those images together into Texture Atlases, so that's not as bad as it could be.  Still, it uses more memory than it should.

The obvious next step is to use a giant texture made up of all the various characters you might want to use.  There are standards for this sort of thing and tools to generate the textures, such as BMFont.  It's just a matter of actually doing the work.

Grid Layer

This one's pretty simple.  It's just a layer that drops down lines at the lat/lon boundaries.  It's in there now, it just doesn't work all that well.

Lofting Layer

The lofting layer is part of WhirlyGraph.  That's the thing that creates transparent geometry for country outlines.  In that sense, this isn't all that new.

What is new is integrating it into the regular toolkit.  I was doing an early version of caching to make it fast enough to use for the bigger countries.  Now caching is worked out, I'll switch the lofting layer over and integrate with the main toolkit.

Particle Generator

I've had requests for simple particle generation, much like in the Smule apps.  It's easy enough, but making it fast requires some design.

You'll most likely be restricted to a fairly simple set of parameters: particle color, speed, and various randomizers.  I think I'll avoid fireworks for the first go and we'll stick to fairly basic fountains.

The Farther Future

That's all for 1.2, I think.  Of course, some of this might slip and anything a client needs gets priority.

There are already some interesting things in store for 1.3.  In particular, discussions with other groups related to doing data fetching over the network.  We'll see how those go.


  1. Hi,

    Just downloaded the 1.1 code. Nice job!

    Wondering if there is any support for tappable markers that can be placed on the globe? I can see that you can tell where a tap is on the globe and it would be easy to find a nearby point, but I don't see any way to render a pin that rotates along with the globe.

    Am I missing something? Thanks.

  2. Oh, that's a good point. I never implemented the simple "Put icon here" functionality. I think I'll add that to 1.2.

    In the mean time, you could do the same thing by adding a label with an icon. Just make the label empty.

  3. Hi there - I very much enjoy WhirlyGlobe so far. I am however having trouble trying to remove labels that I created previously. Could you please shed some light? I've created a question here --> http://stackoverflow.com/questions/7731783/how-to-remove-labels-using-whirlyglobe-ios


  4. Thank you very much for your answer. One more quick question if you don't mind -

    I'm creating a Texture as follows:
    WhirlyGlobe::Texture labelIcon = Texture(@"fancy-globe", @".png");
    WhirlyGlobe::SimpleIdentity labelID = labelIcon.getId();

    When I add my labels as follows I do not see my image but only a white box appended to the yellow background of my label. Am I missing a step here?

    // Current position
    float lat = [[values objectAtIndex:8] floatValue];
    float lon = [[values objectAtIndex:9] floatValue];

    // Location Label and Text
    SingleLabel *interimLabel = [[[SingleLabel alloc] init] autorelease];
    interimLabel.text = [NSString stringWithFormat:@"PRN %d",[[values objectAtIndex:1] intValue]];
    interimLabel.iconTexture = labelID;
    [interimLabel setLoc:GeoCoord::CoordFromDegrees(lon, lat)];
    [locationArray addObject:interimLabel];
    [allLabels addObject:interimLabel];

  5. You just need to send the texture to the rendering engine:
    scene->addChangeRequest(new AddTextureReq(labelIcon));

  6. Hmm - getting a compiler problem with the line "sceneRenderer.scene->addChangeRequest(new AddTextureReq(labelIcon));" in the code below. The compiler error is "No matching function for call to 'WhirlyGlobe::AddTextureReq::AddTextureReq(WhirlyGlobe::Texture&)'". I see the constructor in the GlobeScene.h header file and I'm using the example in your starter pack to experiment with. Sorry, the C++ syntax is new to me - do you see something obviously wrong here? Thanks again!


    // Need an empty scene and view
    theScene = new WhirlyGlobe::GlobeScene(4*texGroup.numX,4*texGroup.numY);
    sceneRenderer.scene = theScene;

    // Create the WhirlyGlobe texture for our labels
    WhirlyGlobe::Texture labelIcon = Texture(@"fancy-globe", @".png");
    LabelSceneRep *labelRep = new LabelSceneRep();
    sceneRenderer.scene->addChangeRequest(new AddTextureReq(labelIcon));
    WhirlyGlobe::SimpleIdentity labelID = labelIcon.getId();

  7. WhirlyGlobe::Texture *labelIcon = new Texture(@"fancy-globe", @".png");
    sceneRenderer.scene->addChangeRequest(new AddTextureReq(labelIcon));
    WhirlyGlobe::SimpleIdentity labelID = labelIcon->getId();

    Once you create a Texture and hand it over to the renderer, you don't need to worry about deleting it.

  8. Thanks for the answer - I have those textures being added now. I've been trying to set the background of the EAGLView transparent so I can put a nice UIImageView behind it. The globe currently renders with a black background that blocks you from viewing anything behind it. So far I've tried the following to no avail. I've also read a few blogs on modifying the -initWithCoder method on EAGLView.m but I'm not exactly sure where that is - Surely this is possible, would you mind shedding some light on how to do this? Thanks.

    self.glView = [[[EAGLView alloc] init]autorelease];
    self.glView.opaque = NO;
    self.glView.backgroundColor = [UIColor clearColor];

    // Draw Transparent Background
    -(void)drawFrame {
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

  9. Setting the background color is one piece, I think. Make sure all the various UIViews in the hierarchy have their backgroundColor set.

    You also need to set the clear color. I added a setClearColor method to the SceneRendererES1 class. I forget if that's in 1.1 or just the trunk.

    Other than that, I'm not sure. Never tried it myself.

  10. Hi, thanks a lot for WhirlyGlobe definitively a great framework.
    I would like to modify the Sphere center location on screen and didn't find any simple way to achieve this. Did I'missed something ?

  11. Everything is centered around a sphere at (0,0,0) with a radius of 1.0, so that would be tricky.

    What are you trying to do?

  12. Currently the sphere is centered at the middle of the screen (512,384 on ipad) I would like to center it upper on the vertical axis (256, 384) to get more space below the globe for displaying additional information.

  13. I see what you're doing there.

    Well, two ways to do it, then. One would be to make the window smaller. The other would be to override the WhirlyGlobeView and change the projection its producing.

  14. Thanks for your answer, I've tried the window resize but it generates strange side effects on the vertical pan. By overriding WhirlyGlobeView I suspect you mean to override GlobeView.mm.

  15. Yup, that's where the code is. The class is named WhirlyGlobeView.

    I think you'd need to mess with calcModelMatrix. I'd have to work through the math myself to figure out if that would be sufficient. But that's where I'd start.