In a game we're developing we need to animate a large sprite, of size 485x485 and the animation has about 30 frames. We have a problem animating such artifacts. I have tried some solutions as listed below, but unfortunately we haven't been able to come up with a solution yet.
Tiling
It looks like putting every frame in one big tile is not an option because:
The texture size needs to be a power of two, so it shows up as black on most devices
When I make the texture size a power of two, it becomes too big for most devices too handle
Recommended maximum texture size of AndEngine seems to be 1024x1024.
Seperate sprites
The other option is loading each texture, and thus each frame, seperately and putting it in a Sprite (as described here). This works quite well and toggling the visibility of each sprite at the right time causes the user to see the animation.
The problem with this method is that loading the whole animation takes quite some time. This is not visible when initially loading the game because of the loading screen, but later in the game the animation needs to be changed and the game needs then about 2-3 seconds to load. Putting a loading screen up is not an option.
Loading on seperate thread
I tried to put loading the textures in a seperate, newly created thread, but even while the thread loads the textures the drawing of the game seems to be paused.
Other options?
I don't know any option, and it appears no one else tried to animate a texture greater than 50x50 pixels because it is very difficult to find anyone with a similar case.
My question is: Is it even properly possible to animate large textures in AndEngine?
I think your problem is going to run up against device limitiations, not andengine limitations. Designing for mobile, there are few android devices that could run that.
However, you may be able to come up with an alternative solution using VertexShaders and FramentShaders. This si an important features of Andengine GLES2
Here is an article describing that approach:
http://code.zynga.com/2011/11/mesh-compression-in-dream-zoo/
Related
Say I need to make several full-screen animation that would consist of about 500 frames each.
Animation should be playing at a reasonable speed - supposedly not less, then 20fps - and pictures should be of a reasonable quality, not overly compressed.
What method do you think should I use?
So far I tried:
1. storing each frame as a compressed JPEG
2. before animation starts, loading each frame into a byteArray
3. as the animation plays, decode corresponding byteArray into a bitmap
and draw it on a surface view.
Problem - speed is too low, usually about 5-10 FPS.
I have thought of two other options.
turning all animations into one movie file... but I guess there might be problems with starting, pausing and seeking to the exactly right frame... what do you think?
another option I thought about was using OPENGL ( while I never worked with it before ), to play animation frame by frame. What do you think, would opengl be able to handle it?
Thanks!
edit, i managed to peek into talkingtom, and found that it contains about 20megs of well compressed JPEGs, like this.
You could handle it in a couple of different ways.
It sounds like decoding is your bottleneck. You could try making all the 3 steps including the decoding before playing the animation, so you will just have to draw the already-converted bitmaps.
OpenGL is definitely up to the task in the sense that it will probably never be your bottleneck. But as said above, the drawing does not seem to be the problem.
Animating on the device. In case you are animating geometric objects or pixmaps and the animation has a common background you could reuse, separate the animation into "actors" and move them around - this will require much less data.
EDIT : Complex animations on mobile devices are rarely full-screen movies or series of images - the amount of (redundant) data would be overwhelming (as you have noticed already). They are animated 2D and 3D models. For 3D it is advisable to use OpenGL, for 2D, common canvas drawing may be enough. To make it even more efficient, you could split the model into separate parts and animate them separately (would look similar to SouthPark animations). You can combine this with using spritesheets (like separate small movie strips) to animate separate parts. This would give you much more flexibility while still using less data than a compressed movie.
I really think you need to turn it into a movie file - that will give you some appropriate compression and android can do all the work with the media player. I believe getting to the right frame is fairly easy but you may have to use lower compression on the video stream to make this work.
Maybe using universal tween engine can fix your performance problem.
(I tried to stuff the question with keywords in case someone else has this issue - I couldn't find much help.)
I have a custom View in Android that contains an LED bargraph that displays levels received via socket communication. It's basically just a clipped image. The higher the level, the less clipped the image is.
When I update the level and then invalidate the View, some devices seem to "collect" multiple updates and render them in chunks. The screen visibly hesitates for say 1/10th of a second, then rapidly paints multiple frames, and then hesitates again. It looks like it's overwhelmed and dropping frames.
However, when changing another UI control on the screen, the LED bargraph paints much more frequently and smoothly. I'm thinking Android is trying to help me by "collecting" multiple invalidations and then doing them all at once. Perhaps by manipulating controls, I'm "increasing" my frame rate simply by giving it "more to do" so it delays less between actual paints.
Unlike animation (with smooth transitions) I want to show the absolute latest value as quickly as possible. My data samples aren't faster than 10-20fps anyway.
Is there an easy way to "force" a paint at certain points, or is this a limit of how Views work? Should I be implementing this in a SurfaceView instead? (I have not played with that yet... want advice first.) Thanks in advance for suggestions.
(Later that same day...)
Update: I found a page in the Docs that does suggest implementing my widget as a SurfaceView is the way to go:
http://developer.android.com/guide/topics/graphics/2d-graphics.html
(An hour after that...)
SurfaceView seems overkill for what I want to do. The best-practice method is to "own" the whole canvas, but I have already developed the rest of my controls and layouts and they work well. It must be possible to get some better performance with what I have, especially since interacting with the UI makes the redraw speed satisfactory.
It turns out SurfaceView was the way to go. I was benchmarking on an older phone which didn't help. (The frame rate using a standard View was fine on an ASUS eeePad). I had to throw away some code, but the end result is smoother and faster with SurfaceView. Further, I was able to re-use more code than I expected and actually dramatically simplified my multitouch handling code (since everything I want to touch is in the same SurfaceView.
FYI: I'm still only getting about 15fps on Droid X, but half of the CPU load appears to be data packet processing. The eeePad is doing almost 40fps now -- and my data rate is only 20 samples/sec.
So... a win I guess. I want the Droid X to run better, but it flies on a real tablet.
My game already consists of an atlas the size of 1024x1024 as I am aware that is the max size for a texture. The problem is I need about 1-2 more of these 1024x1024 textures. That should give me 3 glBindTexture() calls which I know is huge performance drag. I have not tested it yet because I am having other problems currently but would this slow my application by a considerable amount? Is there another solution?
If you are worried about any performance loss, I'd recommend you to profile your application so you really can see where your application's bottleneck is, and then come back if it turns out to be horrible.
Three big atlas textures are still better than many small textures that you bind over and over again.
Currently my game has around 6 512x512 texture atlases and I still dont require any loading screens on any phone so far. Although if you are going to do a lot of binding you may want to look into making a Batcher class that will submit all of your vertices to the GPU at one, it will speed up your application considerably
I created a map app that uses a very large image as my map. It shows high resolution tiles when the user zooms in to a certain degree and a lower-res bitmap of the whole image when zoomed out past 50%. It works OK, on my origional droid sometimes I can see a very slight lag due to the new tiles being drawn into and from the garbage collector.
Im now thinking about how OpenGL ES would be a better way to render. Ive never touched it before, but from what ive been reading in different turoials, it seems i could create a quad that has 8 faces or so, and enable culling so it only draws the images that are currently visible on the screen.
Would this eliminate the lag completely? In my test app now I have tiles being loaded on app startup but i can tell the lag is due to those tiles being drawn for the first time. Thanks.
I have written an OpenGL-based map view and it's bloody awesome if I say so myself. Sadly it's for a commercial project so I can't offer code. I can however tell you that it has 1 rendering thread, a pool of 8 tile downloading threads, and (most pertinent to your question) 1 storage thread that loads and saves tiles to the NAND flash or the SD card. Rendering is done one tile at a time, each tile being 2 triangles (there are no quads in ES). It's still blisteringly quick.
I'm working with my friend on our first Android game. Basic idea is that every frame of the game the whole surface is redrawn (1 large bitmap) in 2 steps:
Background with some static image (PNG) wipes out previous frame
Then it is sprinkled all over with large number of particles which produces effect of soapy bubbles where there's a pool of about 20 bitmaps which randomly gets picked to produce illusion that all bubbles (between 200 - 300) are all different. Bubbles positions updated on each frame (~50ms) producing effect of moving bubbles.
The math engine is in C (JNI) and currently all drawing is done using android.graphics package very similar (since that was the example I was using) to Lunar Lander.
It works but animation is somewhat jerky and I can feel by temperature of my phone that it is very busy. Will we benefit from switching to OpenGL? And as a bonus question: what would be a good way to optimize the drawing mechanism (Lunar Lander like) we have now?
Now I've started to work with OpenGL ES, I would also use it for 2D graphics. This way is the most flexible and it's extremely fast (look at this example code. It's about 2D rendering, and there you can see the power of OpenGL.
It's not the easiest thing to start with, but there are some good tutorials out there - for example, this is a very good one.
Don't redraw the entire screen each time. That's what causes your low framerate. Use the invalidate method to mark the areas that have changed each frame.