Litmus Test
The other night Danny and I were talking about tag clouds and a possible experiment that could be done using something called Wordle (see this post for more info about Wordle). The experiments requires that the news cycle be on “autopilot,” i.e., a general representation of what’s going on in the world over a long stretch of time. The recent swath of high-profile celebrity deaths has thrown a kink into the works (to put it lightly), so hopefully I’ll be able to put up some results in a week or two.
In completely other news, I’ve located another excellent source of OpenGL ES tutorials, this time from Simon Maurice. Jeff Lamarche, whose tutorials I posted a few weeks ago, has also added some new content and updated his project template to work with the new iPhone OS. Good stuff.
Phantom Functions
Not that they’re very spooky, but function calls that don’t do anything can be a real time-sink. The call in question: glPolygonOffset(), a terribly useful function which I was using to prevent Z-fighting. Everything worked as expected in the iPhone simulator, but nothing happened when run from the real hardware! After an hour of searching through the code and documentation, it turns out the answer is pretty straightforward: polygon offset is not supported by the hardware.
The fact that the compiler didn’t kick out a warning or error would seem to suggest that the feature is available in later models. My test platform uses PowerVR’s MBX Lite 3D GPU, as do all models up until Monday’s announcement. Still, Apple is able to tailor the SDK’s header files exactly to their devices capabilities, so it’s a touch frustrating. On the bright side, there’s a workaround for coders who needed glPolygonOffset to draw edge geometry:
#define EDGE_OFFSET 0.00001
glDepthRange(EDGE_OFFSET, 1.0);
/* draw all non-edge geometry */
glDepthRange(0.0, 1.0 - EDGE_OFFSET);
/* draw all edges */
There’s a couple more good ideas actually, but the above code works fine for a low-power device.
Pointing Fingers
An array is useful, and a pointer is useful, and if a pointer pointing at a dynamic array is more useful yet, then surely a dynamic array of pointers must be made of awesome sauce. Cocoa has spoiled me a bit, what with NSMutableArray acting as just the ticket, but at a probable expense. Complexity and abstraction layers are the enemy of framerate, so I’ve turned to C arrays to solve a time-sensitive problem. After a couple hours of poking around, I’ve found a solution, though I can’t tell if this is elegant, hackish, or just downright silly:
typedef struct {
GLuint *texturePtr;
} TextureStruct;
TextureStruct * allTextures;
So what’s going on here? Originally, the plan was to have an array of GLuints to keep track of loaded textures (there’s no sense of loading the same data twice on a handset with little memory after all). The array doesn’t know how big it will be at compile time, and more importantly, it might grow or shrink during runtime, so a declaration of GLuint * texture; seemed like the logical thing. Problem is, arrays hold data, but this array must hold pointers. Wrapping the pointer inside a struct and then declaring a pointer/array of the new structure does the trick, but it feels crude.
It’s a strange feeling though, that the actual data doesn’t have any central location. A texture is loaded when an object needs it, but the texture doesn’t belong to the object, nor does it belong to the above structure/pointer/array monstrosity. It just hangs out.
OpenGL ES from the Ground Up
Back in developer land, I’ve found something terribly interesting. A fellow by the name of Jeff Lamarche has written up an OpenGL ES tutorial geared towards iPhone Devs. OpenGL has always terrified me, so this will be a great resource. Better yet, OpenGL, as hinted by the word “open,” is intended to be a very portable cross-platform tool, so the lessons learned should be equally portable.
