views:

1361

answers:

2

I'm working on a game where I need to let the player look at a plane (e.g., a wall) through a lens (e.g., a magnifying glass). The game is to run on the iPhone, so my choices are Core Animation or OpenGL ES.

My first idea (that I have not yet tried) is to do this using Core Animation.

  1. Create the wall and objects on it using CALayers.
  2. Use CALayer's renderInContext: method to create an image of the wall as a background layer.
  3. Crop the image to the lens shape, scale it up, then draw it over the background.
  4. Draw the lens frame and "shiny glass" layer on top of all that.

Notes:

  • I am a lot more familiar with Core Animation than OpenGL, so maybe there is a much better way to do this with OpenGL. (Please tell me!)
  • If I am using CALayers that are not attached to a view, do I have to manage all animations myself? Or is there a straightforward way to run them manually?
  • 3D perspective is not important; I'm just magnifying a flat wall.
  • I'm concerned that doing all of the above will be too slow for smooth animation.

Before I commit a lot of code to writing this, my question is do you see any pitfalls in the plan above or can you recommend an easier way to do this?

+2  A: 

That is how I'd do it, it sounds like a good plan.

Whether you choose OGL or CA the basic principle is the same so I would stick with what you're more comfortable with.

  1. Identify the region you wish to magnify
  2. Render this region to a separate surface
  3. Render any border/overlay onto of the surface
  4. Render your surface enlarged onto the main scene, clipping appropriately.

In terms of performance you will have to try it and see (just make sure you test on actual hardware, because the simulator is far faster than the hardware). If it IS to slow then you can look at doing steps 2/3 less frequently, e.g every 2-3 frames. This will give some magnification lag but it may be perfectly acceptable.

I suspect that performance between OGL / CA will be roughly equivalent. CA is built ontop of the OGL libraries but your cost is going to be doing the actual rendering, not the time spent in the layers.

Andrew Grant
CA is a lot slower than OGL. Magnitudes slower actually.
lajos
How did you get your figures? In terms of raw image composition, that isn't my experience. The bottleneck is by far the time spent rasterizing the image.
Andrew Grant
I have tested animating both CALayers and UIViews. UIViews for some reason were a lot faster.
lajos
Oh, and they are both a lot slower than opengl.
lajos
+2  A: 

I have implemented a magnifying glass on the iPhone using a UIView. CA was way too slow.

You can draw a CGImage into a UIView using it's drawRect method. Here's the steps in my drawRect:

  1. get the current context
  2. create a path for clipping the view (circle)
  3. scale the current transformation matrix (CTM)
  4. move the current transformation matrix
  5. draw the CGimage

You can have the CGImage prerendered, then it's in the graphics memory. If you want something dynamic, draw it from scratch instead of drawing a CGImage.

Very fast, looks great.

lajos
Are you saying the magnifying lens is a subview of the background view? You say faster than CA but faster than doing what with CA? You are very unclear.
benzado
In my app the magnifying glass follows the touch. When I tried using CA, it was less responsive than the UIView implementation.The magnified view is a subview of the background view.
lajos