Archive for the ‘iPod Touch’ Category

OpenGL ES 1.1 and the iPhone

Wednesday, December 3rd, 2008

What can make an iPhone developer sulk and refuse to program for two hours?  OpenGL ES is the answer, and it has nothing to do with OpenGL ES per se. 

Largely it’s my fault.  I should have done my research upfront. But with all the talk of the OpenGL ES 2.0 standard, I started to assume that it was supported on the iPhone.  After three hours of learning about vertex and fragment shaders in OpenGL ES 2.0, and writing a few to render a 2D blob for my upcoming iPhone physics engine (more on this later..) I got stuck trying to make it work on the iPhone itself.  

Not surprising really.  The hardware in the iPhone only supports the OpenGL ES 1.1 standard, and as such the API has no calls to any vector or fragment program related goodness.  

Lucky for me, I was just trying to do some shadows and shading of 2D sprites, so I could kinda fake it using some blending and scaling, but I guess the more adventurous effects will just have to wail until the next iPhone generation or later. 

So before you end up crossed armed and sulking as hard as you can at your computer, only do things based on the 1.1 standard, not the 2.0.

Optimizing Objective C for iPhone

Monday, November 24th, 2008

There are so many apps out there for the iPhone that are doing some pretty graphics/algorithmically intensive stuff.  Most are right on the money when it comes to responsiveness, but some are just woeful!    

Perhaps it’s the promises of fame and fortune that seems synonymous with iPhone programming, but many developers new to Objective C are doing straight ports or just writing plain ObjC code until their app ‘works’ then just release it.  There seems to be a feeling that if an app is slow, the device just can’t handle it.  

I’ve been stepping through the hoops of (relatively) computationally heavy apps at the moment with the creation of a generic physics engine for use in a bunch of 2D based games.  Because it was my first app with serious algorithms in it, I didn’t give optimization much thought. And if you believe most ‘Good Software Practice” guidelines, that was a good thing. (optimize last, or you’ll be optimizing things that need no optimization at all.)

But perhaps some thought is necessary.  At the beginning, it’s very nice to go down the path of using pure ObjC throughout your code.  Let’s face it – it has a nice set of design features that make you feel like you’re on a fluffy cloud rather than the hard stainless steel bench of C.  And if you’re particularly sick like me, [you setLovesSquareBrackets:YES]. But of course the nice features of ObjC come at a cost, and the biggest one is the passing of messages.  C/C++ programmers often forget that when invoking a method on an object in ObjC, you are actually passing a message to the object which has to be converted into a function call at runtime.  Great for flexible, extendable libraries – bad for speed.

So you can either start your development with core components using plain C calls, or you can do what I did and wait until the ‘end’ and use the profiler.  The ‘Instruments’ tool in conjunction with remote iPhone SDK debugging is great.  You can actually run the app on the device and get statistics about what you’re app is doing and when – without a huge penalty to performance.  

Take a typical recording and keep an eye out for the msg_send call, and how much time is spent there.  You may actually find that you’ve introduced a dependency lock that’s slowing things down or you may have an update timer that’s just being ridiculous and updating a billion times a second. 

But if you find out that a lot of time is spent calling msg_send, all hope is not lost.  You can still do some optimizations that help out.  For the other things I’ll talk about them later. 

In simple cases, you do some of the internal work of ObjC yourself and cut out the middle man (sourced from here):

-naive {
  for(i=0; i<50000000; i++)
    [obj hello];
}

-optimised {
  typedef id (*hello_t)(id, SEL, ...);
  hello_t ref = [obj methodFor:@selector(hello)];
  for(i=0; i<500000000UL; i++)
    ref(obj,@selector(hello));
} 

which will work in a lot of cases.

But sometimes, you just have to revert to C.  Go back to the profiler and see what’s happening.  If there are still a lot of msg_send calls clogging up your execution time, then you’ll have to strip out the offenders and just write C functions.  It’s really not that bad..

iPhone/iPod Accelerometer Issues

Monday, November 17th, 2008

If you’re struggling with odd behavior from your device’s accelerometer ‘every now and again’ then you’re not alone.  

This post comments on the problem and some work arounds, and this is what I’ve found:

Problem:

A few devs out there have noticed the following symptoms

  • The accelerometer will not respond via the delegate at all in your app about 5% of the time when running your app
  • When combined with OpenGLES surfaces, the first drawn frame will be drawn between every new frame drawn to the surface.  This results in a flickering effect where a ‘ghost’ of your initial drawing is interlaced with your normal frames.  

Although some have reported these two problems being one and the same, I found them to be quite separate. I think many people are using the accelerometers+OpenGLES for games, and because the problems happen infrequently they seem related.  I could be wrong of course.  For the same reasons I could just be imagining that they aren’t related.

Work-arounds (not really solutions):

Accelerometer not working

For the accelerometer, many have found (and I have too) that the problem seems to go away if you set the update frequency and delegate much later on in your app.

[[UIAccelerometer sharedAccelerometer] setUpdateInterval: (1.0 / kAccelerometerFrequency)];

[[UIAccelerometer sharedAccelerometer] setDelegate:self];

Typically, you’ll call the above lines in

 - (void)applicationDidFinishLaunching:(UIApplication *)application

but that’s what causes the problems. Anyones best guess is that it just takes too long for the accelerometer to get ready some times and it just ignores your set delegate request. 

Flashing graphics

I can’t confirm that this fix works, but some have reported that using kEAGLColorFormatRGBA8 instead of kEAGLColorFormatRGB565 on your OpenGLES surface will stop it happening.  I’ll give it a try and post my results here. If anyone can confirm or deny this fix, we’d love to hear from you.