Handling large maps with CCTMXLayer - iphone

I'm just getting things going in my game and I'm using CCTMXLayer for my tiled background. Everything is going fine when my map is 30x30 tiles, but my world is about 500x500 tiles. I would just use a map that size, but it lags terribly during animation. Any ideas as to handle a really large, tiled map without having lag?

Being biased here: check out Koboldtouch, specifically what features I added to make tilemaps more useful. Among them no limits on map size, tilesets, layers - as much as can fit in memory.
The only alternative is HKTMXTiledMap. I never actually used it, the forum thread is full of (unresolved?) issues.
The CCTMXTiledMap is not only slow, you can only create 128x128 tiles tilemap with a single layer and all tiles set to non-empty. 500x500 is only possible if you leave enough empty tiles so you never go above 16,384 tiles on the map. Unlikely. Restrictive.

Related

is non-square tilable atlas effective

I have a building model with 6K faces and I want to texture with some pretty high detail 512x512 tilable textures (which represent about 32cm x 32cm), and I'd like to be as mobile-friendly as possible, but not necessarily with old phones but for like GearVR capable phones.
The model happens to have mostly long horizontal quads eg
|-----------|---|----------------|
|-----------|---|----------------|
|-----------| |----------------|
|-----------| |----------------|
|-----------|---|----------------|
|-----------|---|----------------|
So the uv's of each of those horizontal sections can be stacked on one tileable texture, to achieve both horizontal and vertical tiling.
Further, if the tiles were 512x512 textures, I could stack 8 of them in a 512x4096 non-square (but power of two) texture.
That way I could texture the main mesh with a single texture or one extra for metalic.
Is this reasonable, or should I keep them as separate 512x512 textures? Wouldn't separate textures mean like 8x the draw calls which would be far worse than a non-square 512x4096 texture?
After some research, I found the technique of stacking textures and tiling horizontally is called using a trim sheet, and is very much valid, and used extensively game development to be able to re-use high-detail textures on many different objects.
https://www.youtube.com/watch?v=IziIY674NAw
The trim sheet info I found though did not cover 'non square' which is the main question. But from several sources I found that some devices do not support non-quare and some do, and some do but don't do compression well on non-square, so it's a 'check your target devices' issue.
Assuming a device does support non-square, it should in fact save memory to have a strip of textures, and should save draw calls, but your engine may just 'repeat them horizontally until square' for you when importing the texture to 'be safe' (so again, check target devices and engines). It would perhaps be wise to limit to 4 rather than 16 stacked textures, to avoid 'worst case scenarios'.
Hopefully, the issue will be addressed by either having video cards able to do several materials in 1 draw call, or by more universal handling the texture strips well, but it seems state of the art has not focused on that yet.
Another solution is more custom, but some people have created custom shaders that use vertex color information on a mesh to choose which part of a texture to use, and then tile from there. Apparently the overhead turned out to be quite low, and it was a success, so it's good to have an idea about 'backup plans'. This however would be an engine/environment/device specific kind of optimization, not a general modeling practice.
http://www.gamasutra.com/blogs/MarkHogan/20140721/221458/Unity_Optimizing_For_Mobile_Using_SubTile_Meshes.php

Unity: How many tmx tiles can I run without lag

Does unity have any limits when it comes to .tmx files? I am creating a .tmx map on tiled and each tile is 16x16 pixels. I am making a game and I would like to make it fairly universal and make sure most graphics cards can handle it but I'm not sure whether I should divide my map in to chunks that will load when the boarder is crossed or just load the whole map, as I'm not sure if I would be able to program the game to only load say a 50x50 texture and render more of the map as the player moves. So does unity have a maximum number of tiles it can render? Thanks in advance
Open statistics window and see performance stats of your game. Mostly and basicly, Draw Calls is defined your game's parformance. For example FPS decreases under 60 for more than 2500 draw calls on most of PCs.
Assume that your map is 128x128, if you use 16x16 tiles you need 64 nodes otherwise if you use 32x32 tiles you need 16 nodes. More nodes means more loading.
Just check stats and get visuals under control for better performance.

Best practices drawing onto a very large graphics context

I need to draw onto a very, very wide context (possibly going into the 100,000's of pixels in width)
The stuff that I am drawing is simple (exclusively lines, ellipses and arcs).
Currently, I am using a tiling mechanism to render pieces of this image as SVG graphics in UIWebViews sitting in a UIScrollView. Horrible, I know. Performance is so bad it makes me want to hurt myself.
So I'm left with no choice but to draw things directly in Quartz. The problem is that I couldn't find any good information on handling such a large drawing.
The commands will be stored in a array (i.e [0] - line from x1,x2 to y1,2 [2] - arc at x1,x2,h,v etc...) which makes it possible to immediately determine what needs to be drawn at any point of time.
How should I best go about handling the actual drawing? Make a ginormous context then draw onto it, erasing the parts that go off screen? Can I draw straight into the UIScrollView?
Or am I supposed to performing some sort of tiling? Creating smaller views and drawing on them?
Look into CATiledLayer. It supports huge dimensions, yet only draws "tiles" that are visible. This means that in your drawLayer:inContext: you need to calculate how to draw the tile you were asked to draw. That might be quite complicated to implement but the performance boost makes up for this. I use this to draw a "strip" that is often over 20.000 pixels wide, tiled into 256 pixel pieces (this is the default).
You not only want this because of speed but also due to memory: if you really had a view or layer that were that big it would take up immense amounts of memory. Tiling is the only solution here.
See this nice article by Michael Heyeck on how to use CATiledLayer (Apple has a demo as well, but I think the linked article is better).
If the stuff you are drawing is not static then using CATiledLayer(s) doesn't work very well. A better solution is presented partly in http://www.mlsite.net/blog/?p=1342 . I've used this as a basis from some interactive drawing. A little slow but I'm still optimizing. Use http://red-glasses.com/index.php/tutorials/catiledlayer-how-to-use-it-how-it-works-what-it-does/ as a check list of whether you should use CATiledLayer(s) or not.

How should I organize OpenGL ES 1.x 2D layer tree?

I'm developing a cute puzzle app - http://gotoandplay.freeblog.hu/categories/compactTangram/ - , and for performance reasons I decided to render the view with OpenGL. I started to learning it, I'm ok with buffers, vertices, textures in a really basic way.
The situation:
In the game user manipulates 7 puzzlePiece, each has 5 sublayers to get some pretty lighting feel. Most of the textures are 256x256. The user manipulates only one piece at a time, so the rest is unchanged during play. A skeleton of app without any graphic here: http://gotoandplay.freeblog.hu/archives/2009/11/11/compactTangram_v10_-_puzzle_completement_test/
The question:
How should I organize them? Is it a good idea to "predraw" the actual piece states in separate framebuffers(?)/textures(?) or I can simply redraw every piece/layers (1+7*5=36 sprite) in a timestep? If I use "predraw", then what should I do? Drawing to a puzzePiece framebuffer? Then how can I draw it into the scene framebuffer? Or is there a simplier way to "merge" textures?
Hope you can understand my question, if it seems too dim please take a look at my idea on how render an actual piece in my blog (there is a simple flash implemetation of what I'm gonna do) here: http://gotoandplay.freeblog.hu/archives/2010/01/07/compactTangram_072_-_tan_rendering_labs/
A common way of handling textures is to pack all your images into a 'texture atlas' at the start of the game/level.
Your maximum texture size is 1024x1024 and you can have about three of them in memory on the iPhone.
When you have all the images in these 'super textures' you can just draw the relevant area of the large texture. This has the advantage that you have to bind textures less often and you gain better performance, as well as cutting out any excess space used by the necessity to put small images in power-of-two size textures.

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