Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining UIView animation blocks and OpenGL ES rendering

I am developing an iP* game and I make use of both UIKit and OpenGL ES 2.0. The UIKit elements are rendered over the OpenGL view and occupy a significant (arbitrary) amount of screen space. I must admit that Apple has done an excellent work and the frame rate of the game is always 60 FPS.

In order to come to this conclusion I made many tests regarding the performance:

  1. I added lots of static (not moving) UIViews over the OpenGL view -- OK!
  2. I animated using custom code the same UIViews (modified the center property in the drawFrame method of my game) -- OK!.
  3. I added many OpenGL ES elements under the UIViews -- OK!
  4. I added many moving OpenGL ES elements under the UIViews -- OK!

So, now I want to make use of the Core Animation Framework in order to animate the UIKit elements. I make use of

[UIView animateWithDuration:delay:options:animations:completion:]

in oder to perform the animations (I target iOS 4 or newer).

The problem now is that the frame rate has this weird behavior: Sometimes I get 60 fps with many many UIKit animating elements (30 elements is OK for me) and some other times the frame rate is obviously under 60 fps even with a single animating UIKit element but I cannot measure it with Instruments! Let me explain more: When I open Instruments and monitor the core animation and/or OpenGL driver I get always 60 fps. But it is obvious that this is not the case, I can see with my eyes the OpenGL animations to move much slower than the corresponding UIKit animations on the top. If I remove the UIKit elements from the view the frame rate comes back to normal. A similar situation with the one I describe here happens in any OpenGL ES game when the user changes the volume of the device while playing the game. When the transparent view that shows the current volume starts fading out and until it completely fades away the frame rate drops drastically, but in the instruments (I ve made this test too) it is stuck on 60 fps!

So, to sum up: sometimes I get real 60 fps with block animations with no ups and downs for a run and some other times I get fake 60 fps with no ups and downs.

Do you have any solution to this? All tests were performed on an iPad 2 and iPhone 3GS with iOS 5.1

like image 846
Summon Avatar asked Apr 12 '12 09:04

Summon


1 Answers

I managed to solve the problem and now I can combine UIView block/core based animations in my OpenGL game without any performance drop.

The solution is quite simple:

  1. For each UIView that you want in your OpenGL app, keep its bounds, center and transform properties in your OpenGL screen coordinate system (e.g. create the following properties: GLBounds, GLCenter, GLTranform) and update them accordingly whenever you change one of the corresponding UIView properties.
  2. When you start the game, load the UIViews but set them to hidden. So, UIKit does not draw on top of the OpenGL view (this way the frame drop issue is completely elliminated).Instead draw the UIViews yourself using the GL* properties you created in step 1, and using the corresponding textures (the images/colors you used for every UIView).
  3. Animate the hidden UIViews properties (bounds, center and transform) using block/core animation depending on the animation you want to achieve (which in turn updates your GL* properties) and in your OpenGL draw method use the GL* properties to draw the UIViews! To get the actual values for bounds, center and transform when a UIView is animating (and update the GL* properties) use its presentationLayer property.

Best,

like image 126
Summon Avatar answered Oct 02 '22 00:10

Summon