How to accelerate quartz 2d - iphone

I have the scene stored in array as collection of shapes that is represented by sequence of points. I'm drawing this scene with CGContextMoveToPoint, CGContextAddLineToPoint, CGContextSetFillColorWithColor and CGContextFillPath functions. The problem is that i need to redraw scene on timer event with short interval (0.01 sec) and the scene redrawing is very slow. Is there a way to accelerate this stuff? Or only OpenGLES can help me?

Quartz 2D (Core Graphics) graphics are not accelerated on the iPhone. Path fills are likely CPU bound as well. If you want hardware acceleration, you'll have to convert your scene to OpenGL ES (triangle strips and textures). Even using OpenGL ES, you will have to optimize your graphics fairly well to get a 60 Hz frame rate (0.017 sec).
One other possibility is to pre-render your shapes into CALayers, and just animate the layers (scale, rotate, overlay, hide, etc.) CALayer animation is also hardware assisted.

Related

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:
I added lots of static (not moving) UIViews over the OpenGL view -- OK!
I animated using custom code the same UIViews (modified the center property in the drawFrame method of my game) -- OK!.
I added many OpenGL ES elements under the UIViews -- OK!
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
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:
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.
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).
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,

quartz 2d / openGl / cocos2d image distortion in iphone by moving vertices for 2.5d iphone game

We are trying to achieve the following in an iphone game:
Using 2d png files, set-up a scene that seems 3d. As the user moves the device, the individual png files would warp/distort accordingly to give the effect of depth.
example of a scene: an empty room, 5 walls and a chair in the middle. = 6 png files layered.
We have successfully accomplished this using native functions like skew and scale. By applying transformations to the various walls and the chair, as the device is tilted moved, the walls would skew/scale/translate . However, the problem is since we are using 6 png files, the edges dont meet as we move the device. We need a new solution using a real engine.
Question:
we are thinking of instead of applying skew/scale transformations, that if given the freedom to move the vertices of the rectangular images, we could precisly distort images and keep all the edges 100% aligned.
What is the best framework to do this in the LEAST amount of time? Are we going about this the correct way?
You should be able to achieve this effect (at least in regards to the perspective being applied to the walls) using Core Animation layers and appropriate 3-D transforms.
A good example of constructing a scene like this can be found in the example John Blackburn provides here. He shows how to set up layers to represent the walls in a maze by applying the appropriate rotation and translation to them, then gives the scene perspective by using the trick of altering the m34 component of the CATransform3D for the scene.
I'm not sure how well your flat chair would look using something like this, but certainly you can get your walls to have a nice perspective to them. Using layers and Core Animation would let you pull off what you want using far less code than implementing this using OpenGL ES.
Altering the camera angle is as simple as rotating the scene in response to shifts in the orientation of the device.
If you're going to the effort of warping textures as they would be warped in a 3D scene, then why not let the graphics hardware do the hard work for you by mapping the textures to 3D polygons, then changing your projection or moving polygons around?
I doubt you could do it faster by restricting yourself to 2D transformations --- the hardware is geared up to do 3x3 (well, 4x4 homogenous) matrix multiplication.

How to use particle effects in view based application?

How to use particle effects in view based application?
I have created a game using view based application and I want to use a particle effects in my game. But, I don't have any idea about using a particle in view based application.
Please give some/any idea.
In generally... you can't. Use fullscreen GL for regular particle effect.
Particle effect requires massive count of sprite drawing and alpha blending. You can do this with GL, however, a GL view cannot be overlay over other UIViews.
Normal UIView is implemented with backing CALayer. This is a kind of GL drawing, but optimized for smooth animation of low density UI, not for massive drawing count. So it's performance is too low and unacceptable for particle effect.
I tested CALayer based particle, and 128 particles were max fps with meaningful fps in 3GS.

Quartz2d vector images vs OpenGL vector description?

How big of a difference is the description language of Quartz2d to OpenGL ES?
It seems they are similar in description power... except that Quartz is mostly 2d and that OpenGL is out of the box 3d ( but can be made 2d focused ).
Are the mappings from 2dQuartz to 2d OpenGL ES that different? Im sure there must be differences in some specific features that might be handled differently on one vs another... but to do a translator?
Anyone have experience with both OpenGL and Quartz2d have some insights?
Quartz and OpenGL ES are two completely different animals. While they both have a C-based API that deals with a state machine and that draws into a context, their purposes are dissimilar. In Quartz you specify lines, Bezier and quadratic curves, arcs, or rectangles, as well as fills, gradients, and shadows / glows. In OpenGL ES, you provide vertices, raster textures, and lighting information, from which a scene is generated.
They are both useful in particular cases. You might draw a 2-D static element using Quartz, into a view, layer, or texture, and then place and move that view or layer in 3-D space using Core Animation or do the same for a texture using OpenGL ES.
Rather than try to overlay one API on the other, use whichever is more appropriate for what you are doing, or look to a framework like cocos2d which lets you build and animate 2-D scenes or Core Animation where you can do Quartz drawing into a layer but still use a nicely abstracted API for moving these layers around.

OpenGL ES as a 2D Platform

I've seen a lot of bandying about what's better, Quartz or OpenGL ES for 2D gaming. Neverminding libraries like Cocos2D, I'm curious if anyone can point to resources that teach using OpenGL ES as a 2D platform. I mean, are we really stating that learning 3D programming is worth a slight speed increase...or can it be learned from a 2D perspective?
GL is likely to give you better performance, with less CPU usage, battery drain, and so on. 2D drawing with GL is just like 3D drawing with GL, you just don't change the Z coordinate.
That being said, it's easier to write 2D drawing code with Quartz, so you have to decide the trade-off.
Cribbed from a similar answer I provided here:
You probably mean Core Animation when you say Quartz. Quartz handles static 2-D drawing within views or layers. On the iPhone, all Quartz drawing for display is done to a Core Animation layer, either directly or through a layer-backed view. Each time this drawing is performed, the layer is sent to the GPU to be cached. This re-caching is an expensive operation, so attempting to animate something by redrawing it each frame using Quartz results in terrible performance.
However, if you can split your graphics into sprites whose content doesn't change frequently, you can achieve very good performance using Core Animation. Each one of those sprites would be hosted in a Core Animation CALayer or UIKit UIView, and then animated about the screen. Because the layers are cached on the GPU, basically as textures, they can be moved around very smoothly. I've been able to move 50 translucent layers simultaneously at 60 FPS (100 at 30 FPS) on the original iPhone (not 3G S).
You can even do some rudimentary 3-D layout and animation using Core Animation, as I show in this sample application. However, you are limited to working with flat, rectangular structures (the layers).
If you need to do true 3-D work, or want to squeeze the last bit of performance out of the device, you'll want to look at OpenGL ES. However, OpenGL ES is nowhere near as easy to work with as Core Animation, so my recommendation has been to try Core Animation first and switch to OpenGL ES only if you can't do what you want. I've used both in my applications, and I greatly prefer working with Core Animation.