I am to write a game for Android, and I have to choose between Canvas or OpenGL for drawing. I have read that Canvas doesn´t have a good frame rate, but what is good? Imagine you were going to write an Angry Birds type game, would Canvas frame rate be enough?
I initially wrote my game using Canvas but then needed to switch to OpenGL for the following reasons:
Using Canvas, your sprites are stored on the heap (unless you specifically cache them to the disk) this puts a limit on the total size of your sprite assets depending on the phone – not good! I found this was around 42mb on my phone – note this is the uncompressed size of bitmaps. If you have several types of entity, each with different animations then you can reach this size very quickly.
OpenGL stores your sprite assets separately to the heap which increases the memory available dramatically.
Canvas doesn’t scale very well. The more .draw(…) calls you make, the slower it will run. The relationship is fairly linear.
Using OpenGL you can batch your draw calls together to improve performance.
It can be intimidating starting with OpenGL which makes Canvas seem appealing. However from experience I wish I had just started with OpenGL. My recommendation would be to ‘bite the bullet’ and go with OpenGL if you are making a game.
To make things a bit easier to get started, I have written some helpful utility classes that do all the nitty gritty OpenGL for you. They allow you to make simple .draw(..) calls similar to when using Canvas. The following video tutorial should get you started:
It seems that as newer Android devices and operating systems come out Google have increased the performance of Canvas. A user of the utility class I describe above got back to me with the following email after doing some benchmarking:
Drawing 500 sprites at random positions across canvas each frame.
Here are the results: Huawei Honor (Gingerbread, single core 1.4 Ghz):
SpriteBatcher: 19-20 FPS, Canvas: 23-24 FPS
Nexus 7 (JellyBean, 4 cores 1.3 Ghz): SpriteBatcher: 29-30 FPS,
Canvas: 57-58 FPS
Now, in my reply to this user I explained that this could be to do with inefficiencies in the way I’ve written the utility class SpriteBatcher. However from my own experience with Canvas back on an HTC Desire running Froyo 2.2 I can say that it was definitely slower sprite for sprite!
On later operating systems and devices it may have overtaken on efficiency but some of the points in my original response are still valid. For example, getting around hitting an OutOfMemoryException without having to resort to caching textures onto the disc etc.
If I learn more, I’ll continue to update this answer.
It all depends on the type of game you need to implement.
Considering that you are asking for a canvas implementation, I guess you are referring to a pure 2D sprites game.
If the sprites are not many and the number is very low, the truth is that potentially you want notice a big difference (consider that many many games with basic 2D graphics use canvas).
If performance matters or you have a very high number of sprites then it is worth to implement an OpenGL based system.
Consider that using OpenGL you will benefit of the GPU dedicated hardware so that your CPU will be offloaded of the burden of graphics rendering.
Moreover, you will benefit of much much more flexibility than a canvas implementation using blending, lighting, post processing effects. There is really no limits in what you can do.
A simple example is rotation and scaling that using a 3D engine such as OpenGL is very cheap and offers excellent results.
Canvas must really be adopted for simple implementations.
P.S. if you go for OpenGL ES 2.0 and programmable pipeline, you have really no limits in what you achieve (glowing, blurring and thousands different options). The limit is really our fantasy in that case.
If you’re going to do such a big game you should definitely consider using AndEngine: http://www.andengine.org/
If used right, it’s a great help. Sadly there’s not documentation in the code. But the forum on the site is quite okay. And even here on SO more and more questions regarding AndEngine appear. Luckily there are a bunch of good examples to get you started.
AndEngine uses OpenGL – so you don’t have to mess around with possibly low framerates while drawing on the canvas.
Check out the examples App: https://market.android.com/details?id=org.anddev.andengine.examples