working with large sprite sheets on iphone - iphone

I am trying to use sprite sheet animation in my application.
The first POC with a small sprite sheet worked fine but as i change the sprite sheet to a bigger one, i get "check_safe_call: could not restore current frame" warning and the application quits.
A quick search revealed that this problem meant my app is taking too much memory or the image is too huge in dimension.
My image is 4.9 Mb and dimensions are 6720 * 10080 (oops!!). i read that iphone allows maximum 3 Mb image with dimensions up to 1024 * 1024. Also that the sprite sheet image dimensions should be a power of two.
So please let me know how i can use a sprite sheet this big.
One approach could be to cut the sprite sheet into many smaller sprite sheets and use them one at a time.
Please suggest if you know any other/better approach to accommodate bigger sprite sheets and whether the problem with my sprite sheet is size (4.9 Mb) OR dimensions (6720 * 10080).
(Just FYI, i am not trying to play a movie so using MP4 file instead is not an option for me. i need to animate the sprite sheet based on accelerometer input and i have been able to achieve that in my POC with smaller sprite sheet.)
Thanks,
Swapnil

You should cut up the sprite sheet into multiple textures as you describe. The iPhone's memory and graphics chip simply can't hold an image/texture of that size in memory at once. By splitting up the sprite sheet it will deal with loading/unloading the appropriate textures into memory when you use them.
You might also consider optimizing the image format. Using the PVRTC format can save a huge amount of memory, but it is only well-suited to certain kinds of images. See this Apple page for more information.

definitely keep it within powers of 2. also, keep the sprites within the spritesheet in containers that are powers of 2 (say, you have a 17x31 sprite... put it in a 32x32 container). the problem with your sprite sheet is both the 4.9mb and the dimensions. i would consider using adobe fireworks or pngcrusher to bring the size of your sprite sheet down considerably.
mike weller's right about splitting the sprite sheet up (you simply cannot max 1024). i think the best bet would be to reorganize what you're doing with your sprite sheet into elements (though it's tough to say without knowing particulars). only things that move should have multiple frames. overlay those over a background (from the same spritesheet) by calling there location on the spritesheet and tossing them into play.

Related

Webdesign: PNG-Image width limitations

I want to make a kind of slideshow based on scrolling the webpage.
My problem is that I have an image width of 78720x1015px in png-format.
The width of the image is determined by one single image of 1920px which is 41 times arranged next to each other. - It should be like a cartoon where an image moves by 100% (margin: -100%) and generates a feeling of a movie.
However, this results in an image width of 1920px x 41pics = 78720px.
This is of an enormous width, but what I am wondering about is that the filesize is only 975kB which is in my opinion not that big!? - However, somehow it takes a very long time to load the picture in the Webbrowser and the image is not of such quality as in my ImageViewer on Desktop.
Question 1: What do I have to consider when dealing with such a big image-width? What are the limits?
Question 2: Is there a better way make such kind of a slideshow? - Consider that the sliding itself shouldn't be visible. It should be like a movie based on about 40 pictures.
Thanks in advance!
PNG compresses very well, especially if it's a cartoon like you say that may use only a limited number of colours.
However, when loaded into memory, the device must load all that pixel data into RAM to display it. That's almost 80 million pixels in your case, which would be around 320Mb of uncompressed data. This is probably why the browser is struggling, and especially so if you're using margin to move it around as that requires a full re-draw of the image.
You may have better results with transform, as this should use hardware acceleration and also avoids the reflow part of a redraw since transforms don't affect page layout.
But the better solution would be to break it down into individual images. Have your code load in the next image, scroll it across, then load the next while scrolling and unload the one that's now off-screen to provide a relatively seamless view.

Unity3d - Using a panoramic background in a 2D scroller game?

This is for Unity3D 4.3+
I have a ridiculously large background I wish to use for a 2D scroller game. The background is 10 times the width of a landscape device (10240 x 1024). (The basic loop background goes behind that and is not an issue.)
I understand I can cut the background into 10 images of 1024 x 1024 each (basic sprites). But, I'm unsure of the best approach to go forward...
One way is to pre-load all the background sprites and then do a simple scrolling of them all. But take too much memory.
However, keeping in mind this is aimed for mobiles and tablets, isn't possible to do a loading/offloading of the background as the player progresses? Like this: Initially load 2 background images (bg-1 and bg-2).
Once the camera has passed bg-1, the unload bg-1 and load bg-3. Then when player passes bg-2, then offload bg-2 and load bg-4 and repeat. Thus only 2 bg images loaded at a time.
The player can not go backwards, so that helps me in this scenario.
Any thoughts on the best approach?
Thank you.
You can use Resources.Load function to load assets dynamically(link). Or just load them all in a list and reference from there.

Cocos2d and iPhone: Parallax Background with multiple texture atlases gives many memory warnings

The problem I am trying to solve is:
I have 6 stripes which I need to move at different speed. A texture sheet of 2048*2048 is not enough and to deal with this I splitted the image in two (top and bottom half), so each stripe is exactly 960*640pixels. The general algorithm is to allocate a top and bottom half for each stripe and move them at each frame making sure to reposition them at the top of the screen when they exit the user's view. My class implementation, a direct modification of ParallaxBackground in the ShootEmUp example from this book, is giving too many memory warnings when run and analyzed using Instruments. See analysis below:
OpenGL analysis:
Activity monitor:
What concerns me is the high number of memory warnings in both analysis (24 and 5 respectively).
EDIT: Below you can find a comment which explains the solution
2048x2048 is maximum possible size of texture for new devices. you can read about it in Apple OpenGL ES Programming Guide
Remember that Cocos2D always saves images with a width/height being a power of 2. So if your image is 960x640 pixels it'll use memory as if the image is 1024x1024 pixels.
Also remove textures you no longer need (and when outofmemory gets called).
[[CCTextureCache sharedTextureCache] removeUnusedTextures];
You can also use images in a lower quality to save memory.
[CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA4444];
Whenever you need to load higher quality images or gradients you can put it back.
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
Following the comment-suggestion to my question by LearnCocos2d the correct answer-solution was to simply reboot the device.. (see his comment above).
Thanks!

Big animation iPhone with CCSpriteFrameCache - plist

I have a problem when try to load the big animation with about 54 images (320x480 each image) into CCSpriteFrameCache, I can't use plist for this. How can I make the animation work? At this time, my animation can't work on iPhone 2G, 3G, and iPod.
Thank for your help,
John
You won´t be able to do it...
Consider playing a video or just animating an small portion of the screen.
Your best bet is to determine why the animation has 54 images that are all the width/height of the screen. This is an unnecessary number of images.
Break the animation down:
Is the background 'static' (does it move around, change constantly, etc?)
If it moves around a bit, but is really part of a much larger "canvas" then simply export out the entire background canvas and perform the movements yourself using the Cocos2D Actions available to you (CCMoveTo, CCJumpTo, CCDelayTime, CCSequence, etc)
What in the animation moves around, and how does it move around?
Can it be broken into much smaller bits and the frames for the various "characters"
or "movable objects" within the scene be exported out onto a sprite sheet (saved out
via Zwoptex?)
A good animation sequence should be a series of much smaller images, all working together in unison to create the final "animation sequence".
If you break it down, I wouldn't be surprised if you were able to reduce your 54 images at 320x480 each down to a handful of 512x512 spritesheets (ala Zwoptex).
If your having trouble breaking it down, I would be available to look at the final animation and help you determine what could be minimized to reduce the overhead.

Large scrolling background in OpenGL ES

I am working on a 2D scrolling game for iPhone. I have a large image background, say 480×6000 pixels, of only a part is visible (exactly one screen’s worth, 480×320 pixels). What is the best way to get such a background on the screen?
Currently I have the background split into several textures (to get around the maximum texture size limit) and draw the whole background in each frame as a textured triangle strip. The scrolling is done by translating the modelview matrix. The scissor box is set to the window size, 480×320 pixels. This is not meant to be fast, I just wanted a working code before I get to optimizing.
I thought that maybe the OpenGL implementation would be smart enough to discard the invisible portion of the background, but according to some measuring code I wrote it looks like background takes 7 ms to draw on average and 84 ms at maximum. (This is measured in the simulator.) This is about a half of the whole render loop, ie. quite slow for me.
Drawing the background should be as easy as copying some 480×320 pixels from one part of the VRAM to another, or, in other words, blazing fast. What is the best way to get closer to such performance?
That's the fast way of doing it. Things you can do to improve performance:
Try different texture-formats. Presumably the SDK docs have details on the preferred format, and presumably smaller is better.
Cull out entirely offscreen tiles yourself
Split the image into smaller textures
I'm assuming you're drawing at a 1:1 zoom-level; is that the case?
Edit: Oops. Having read your question more carefully, I have to offer another piece of advice: Timings made on the simulator are worthless.
The quick solution:
Create a geometry matrix of tiles (quads preferably) so that there is at least one row/column of off-screen tiles on all sides of the viewable area.
Map textures to all those tiles.
As soon as one tile is outside the viewable area you can release this texture and bind a new one.
Move the tiles using a modulo of the tile width and tile height as position (so that the tile will reposition itself at its starting pos when it have moved exactly one tile in length). Also remember to remap the textures during that operation. This allows you to have a very small grid/very little texture memory loaded at any given time. Which I guess is especially important in GL ES.
If you have memory to spare and are still plagued with slow load speed (although you shouldn't for that amount of textures). You could build a texture streaming engine that preloads textures into faster memory (whatever that may be on your target device) when you reach a new area. Mapping as textures will in that case go from that faster memory when needed. Just be sure that you are able to preload it without using up all memory and remember to release it dynamically when not needed.
Here is a link to a GL (not ES) tile engine. I haven't used it myself so I cannot vouch for its functionality but it might be able to help you: http://www.mesa3d.org/brianp/TR.html