Do we need to add a texture to the texture cache to get the benefits of autobatching? - cocos2d-x

Normally, when one loads the sprite frame cache from a file by calling:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(filename);
internally, the texture corresponding to that file is added to the texture cache by calling:
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(texturePath.c_str());
which is basically creating a Texture2D object from that image and storing it in an unordered_map.
This does not happen internally when I generate my texture on the fly, and add sprite frames to the frame cache by calling the code below within a loop:
I generate a texture on the fly, and add sprite frames to the SpriteFrameCache by doing:
SpriteFrame* frame;
if (!isRotated) {
frame = SpriteFrame::createWithTexture(texture, rect, isRotated, offset, originalSize);
}else{
frame = SpriteFrame::createWithTexture(texture, rect, isRotated, offset, originalSize);
}
SpriteFrameCache::getInstance()->addSpriteFrame(frame, frameName);
It seems that no calls are made internally to addImage() in the texture cache, when I add frames this way (by calling addSpriteFrame()), even though all the sprite frames are using the same texture.
The counter on the bottom left that displays the number of openGL calls says there are only 2 calls, regardless of how many frames I add to the screen.
When calling
p Director::getInstance()->getTextureCache()->getCachedTextureInfo()
I get the output:
(std::__1::string) $0 = "\"/cc_fps_images\" rc=4 id=254 999 x 54 # 16
bpp => 105 KB\nTextureCache dumpDebugInfo: 1 textures, for 105 KB
(0.10 MB)\n"
Which is the texture that shows the fps rate.... so there is no sign of my texture, but at the same time there is no problem adding frames that use that texture.
So my question is: Will there be a performance problem later on because of this ? Should I add the texture to the texture cache manually ? Are there any other problems that I may encounter by adding my sprite frames this way ?
Also, my texture is created by using Texture2D* tex = new Texture2D(), and then initWithData(). So should I keep a reference to this pointer, and call delete later ? Or is it enough to just call removeUnusedTextures?

So my question is: Will there be a performance problem later on
because of this ?
It depends how many times you'd be using this texture.
Should I add the texture to the texture cache manually ?
Again, it depends how many you'd use it. If it's created dynamically few or more times caching will improve performance as you don't have to recreate it again and again.
Are there any other problems that I may encounter by adding my sprite
frames this way ?
I don't think so.
Also, my texture is created by using Texture2D* tex = new Texture2D(),
and then initWithData(). So should I keep a reference to this pointer,
and call delete later ?
Well if you just want to abandon tex (making it local variable), because you created sprite from it you can do it. But sprite simply has a pointer to this texture. If you'll release texture itself it'll disappear (probably will become a black rectangle).
Or is it enough to just call removeUnusedTextures?
This just clears TextureCache map. If your texture isn't here it won't release it.
You'd have to specify use case of this texture. If - let's imagine - you have a texture, which contains a bullet (which you created using initWithData), which is used frequently. You just can have one texture object stored in your scene and you have to create all bullet sprites from this one texture. Using TextureCache it won't be any faster. However you have to remember to release texture memory when you don't need it anymore (for example when you leave scene), because you create Texture2D using new keyword, not create principle (like Sprite::create, Texture2D doesn't have it), which auto manages memory.

Related

does the spritebatch draws multiple stages with a single batch? Libgdx

The title says it all.
does calling multiple Stages draw() method with the same SpriteBatcher object happens only in a single batch or it is one Stage = one batch?
I have a situation where i dont want to use actors for the background of the game, i just draw it directly. But the algo looks like this.
begin batch
draw background
end batch
call all stage draw
If your answer is: the spritebatch will draw multiple stages in one batch, then I can say that it is more efficient to put each sprites as a member to an Actor object and then add all Actor object to the Stage object, then call the stage draw. This way, i can minimize the call to begin batch and end batch which can improve performance as what i know.
Looking at the Stages code, it seems like it calls batch.begin() and batch.end():
public void draw () {
Camera camera = viewport.getCamera();
camera.update();
if (!root.isVisible()) return;
Batch batch = this.batch;
if (batch != null) {
batch.setProjectionMatrix(camera.combined);
batch.begin();
root.draw(batch, 1);
batch.end();
}
if (debug) drawDebug();
}
So adding your Actors to the Stage might reduce the draw calls.
But remember, that if the Batch is full, it will be flush()ed anyways, which results in a draw call.
So it does not necessarily decrease the number of draw calls. Also don't think about performance to much, as long as you don't have perforrmance problems. If the other solutions seams "cleaner", i guess it is not worth changing it.
One important thing to remeber, when working with more then one Batch is, to call end() for one, before calling begin() for the other. You should never have 2 Batches "running" at the same time.

Game hangs when there is too many Sprites in TextureAtlas

To render crisp graphics with sprites, I decided to provide a dedicated sprite folder for every resolution size. I have 55 such folders, each folder contains 57 .png files (which means the total number is 57*55 = 3135 files). I put all 55 folders into a single folder, and run Texture Packer on that folder. In the output folder, I get 1 pack.atlas files and 212 packX.png files (X runs from 1 to 212)
in my code, I create these fields in my Assets class
private static TextureAtlas atlas;
private static Sprite logo;
// ... total of 57 Sprite fields....
And in the initialize method of the Assets class, which is called at the beginning of the game:
atlas = new TextureAtlas(Gdx.files.internal("pack.atlas"));
logo = atlas.createSprite(getWidthPath() + "logo"); //getWidthPath() returns the appropriate folder path based on the resolution size. As stated above, there are 55 such folder
//...atlas.createSprite 57 times for 57 fields....
I have done this for a smaller number of folder (3 folder) and the game runs well. However, when I decided to support all 55 resolution folders, the game cannot load on Android and can load on Desktop but really slow at the beginning.
So is it true that the large number of Sprites referenced by the pack.atlas files caused the hang?
I think if I just run TexturePacker on each resolution folder, I will get 55 pack.atlas files (instead of 1) and each pack.atlas file will now reference to 57 sprites (instead of 3135 files), the game should run fine, but it's too laborious
As #noone said, packing all sprites of different resolution sizes into one TextureAtlas destroys the meaning of an atlas. I mustpack one atlas for each resolution. But the problem is how to do it automatically?
After seeing that TexturePacker settings does not allow this, finally I have to modify the source code of class TexturePacker a little bit and build my own custom Libgdx build from the instruction here
I only change the main function to accept one more parameter (true or false) to specify whether or not you should pack into subfolders of the input folder. It's not a conventional way to specify options but it's enough for my case.
here is the modified main function in class TexturePacker.java
static public void main (String[] args) throws Exception {
String input = null, output = null, packFileName = "pack.atlas";
boolean optionSeparateFolder = false;
switch (args.length) {
case 4:
packFileName = args[3];
case 3:
optionSeparateFolder = Boolean.parseBoolean(args[2]);
case 2:
output = args[1];
case 1:
input = args[0];
break;
default:
System.out.println("Usage: inputDir [outputDir] [packToSeparateFolder] [packFileName]");
System.exit(0);
}
File inputFile = new File(input);
if (!optionSeparateFolder) {
if (output == null) {
output = new File(inputFile.getParentFile(), inputFile.getName() + "-packed").getAbsolutePath();
}
process(input, output, packFileName);
}
else{
String[] childrenOfInput = inputFile.list();
File outputFile = new File(output);
for (int i=0; i<childrenOfInput.length; i++){
process(inputFile.getAbsolutePath()+"/"+childrenOfInput[i],outputFile.getAbsolutePath()+"/"+childrenOfInput[i],packFileName);
}
}
}
I think if I just run TexturePacker on each resolution folder, I will get 55 pack.atlas files (instead of 1) and each pack.atlas file will now reference to 57 sprites (instead of 3135 files), the game should run fine, but it's too laborious.
Running the packer 55 times is too laborious, but creating each sprite in 55 different variations is not?
You should come up with a different approach, since this one will not work out. I assume one of your atlas pages is 1024x1024. So roughly 1MB. Having 212 such pages would result in 212MB just for the sprites. And the user will only use ONE such set of sprites, resulting actively using 1MB, but still carrying 211MB of useless other sprite sets around.
Furthermore by not grouping your assets in any sane way (like 1 atlas for each resolution) you completely destroy the purpose of an atlas. The TextureAtlas is used to reduce the amount of OpenGL texture bindings which reduce performance. But in your case the resulting atlas has all needed assets anywhere in those 212 pages. That means while rendering, behind the scenes you will still have lots of texture bindings, because of those 212 pages and scattered sprites.
You might have a look at Viewport. It helps you dealing with different resolutions and there are many strategies implemented. You should rather use this approach than supplying one set of sprites for each possible resolution. If you want pixel perfect sprite rendering for each resolution, you will still need those 55 different variations, but then you need to repack 55 versions of your app instead of packing 55 versions in one single app.

How To Store a Dungeon Map

I'm using AS3, but general programming wisdom unspecific to AS3 is great too!
I am creating my first game, a top-down dungeon crawler with tile-based navigation, and I am deciding how to store my maps. I need to be able to access a specific tile at any point in time. My only thought so far is to use nested Vectors or Arrays with the first level being the row and the second being the column, something like this:
private var map:Array = new Array(Array(0,1,0,0,1,1,0),Array(0,1,0,1,0,1,0));
private var row2col3:uint = map[1][2];
/*map would display as such:*/
#|##||#
#|#|#|#
Ultimately, the idea is to build a Map class that will be easily extensible and, again, allow free access to any specific tile. I am looking for help in determining an effective/efficient design architecture for that Map class.
Thanks!
As stated in the comments I would upload and give my source code for a 12 hour challenge project to create a tile based level editor. The source code can be found at: GitHub BKYeates
This level editor focuses on textures being a power of 2, and uses blitting for drawing on all the textures. It can read, write, and store partial tiles. There is also some functionality to erase and draw on collision boxes.
Now in regards to how the storage should be setup, it is really up to you. If you are going to be storing lots of information I recommend using Vectors. Vectors perform faster than most other container types except for ByteArray (if used correctly). In my level editor I used a Vector with a particular setup.
The Vector I used named _map in a class called tilemodel. tilemodel is responsible for updating all the storage information when a change is made. The _map variable is setup like so:
_map = new Vector.<Vector.<Vector.<Object>>>();
This is a pretty heavily nested Vector and in the end stores, can you believe it, an Object! Which admittedly really chunks out the performance gains you get from using Vector when you are indexing the furthest nested elements.
But ignore that because the indexing gain from this setup is really key. The reason it is setup this way is because I can reference a layer, a row, and a column to grab a specific tile object. For example, I have a tile on layer 2 in row 12 column 13 that I want to access:
var tileObject:Object = _map[2][12][13];
That works perfectly for pretty much any scenario I could use in my tile based game, and the speed is comparatively better than that of a Object or Dictionary when this is being accessed multiple times (i.e. - in a loop which happens often).
The level editor is designed to use all blitting and leave onus to my management classes for storage. The speed gain from doing this is very high, and the way it is currently setup the tilemodel can store partial bitmaps making it slightly more flexible than your standard rigidness of a power of 2 texture reader.
Feel free to look through the source code. But here is a summary of what some of the classes do:
tilecontroller - Issues state changes and updates to tilemanager and tilemodel
tilemanager - Responsible for texture drawing and removal.
tilemodel - Stores and updates the current map on state changes.
r_loader - Loads all assets from assetList.txt (paths set to images
there).
hudcontroller - Currently this was the last thing I was working on, lets you draw on collision boxes that are stored in a separate file alongside the map.
g_global & g_keys - Global constants and static methods use
ubiquitously
LevelEditor - Main class, also designed as "View" class ( see MVC pattern: MVC Pattern )
Also as I've mentioned it can read back all the storage. The class used for that I did not upload to GitHub, but figured I would show the important method here:
//#param assets needs to be the list of loaded bitmap images
public function generateMap( assets:* ):void {
var bmd:BitmapData = new BitmapData( g_global.stageWidth, g_global.stageHeight, true, 0 );
_canvas = new Bitmap( bmd, "auto", true );
_mapLayer.addChild( _canvas );
_canvas.bitmapData.unlock();
g_global.echo( "generating map" );
var i:int, j:int, m:int;
for ( m = 0; m < _tiles.length; m++ ) {
for ( i = 0; i < _tiles[m].length; i++ ) {
for ( j = 0; j < _tiles[m][i].length; j++ ) {
//wondering why im type casting in this evaluation? _tiles[i][j].tile == int( _tiles[i][j].tile )
//the level editor stores tiles that are larger than the grid size at indices containing values that are a percent of the tile size
var tile:Object = _tiles[m][i][j];
if ( tile != null && int( tile.tile ) == tile.tile ) {
addTile( g_global.GRIDSIZE * tile.column, g_global.GRIDSIZE * tile.row, { index:tile.tile, bitmap:assets[ tile.tile ] }, tile.rotation );
}
}
}
}
_canvas.bitmapData.lock();
}
Anyway I hope this information finds you well. Good luck!
I asked a similar question a while back: https://gamedev.stackexchange.com/questions/60433/is-it-more-efficient-to-store-my-tile-grid-as-a-dictionary-or-an-array. I'm not sure that it would really matter whether it's an Array or a Vector (the differences in efficiency seem to differ between FP versions, etc.).
But, yeah, you probably want to use one or the other (not a Dictionary or anything), and you probably want to index it like [y * width + x], not [x][y]. Reasons: Efficiency and not having overly complicated data structures.
Also if you need to be able to regularly access the Array or Vector outside of that class, just make the variable internal or public or whatever; making it private and wrapping over it with functions, while being more prim-and-proper class design, would still be overkill.
One method I am using right now for my own thing is that I'm storing my tiles in a black and white pixel bitmap (and wrote a wrapper around that). I'm not sure how efficient this is overall as I've never benchmarked it and just wrote it quickly to create a map for testing purposes, but I am finding that it does offer an advantage in that I can draw my maps in an image editor and view them easily while still allowing random pixel/tile access.
Looking at your sample code, I'm guessing you have only two types of tiles right now, so you could just use black and white pixels as well if you want to try it.
I've done the 2d array method as well (using it still actually for other parts) which works fine too, but perhaps can be harder to visualise at larger sizes. Looking forward to Bennett's answer.

How to avoid memory leaks in this case?

In order to prevent memory leaks in ActionScript 3.0, i use a member vector in classes that have to work with vectors, for example:
public class A
{
private var mHelperPointVector:Vector.<Point> = new Vector.<Point>();
public static GetFirstData():Vector.<Point>
{
mHelperPointVector.length = 0;
....
return mHelperPointVector;
}
public static GetSecondData():Vector.<Point>
{
mHelperPointVector.length = 0;
....
return mHelperPointVector;
}
}
and then i have consumers who uses GetFirstData and GetSecondData methods, storing references to vectors returned by these methods, for example:
public function OnEnterFrame():void
{
var vector:Vector.<Point> = A.GetSecondData();
....
}
This trick seems to be good, but sometimes i need to process the vector returned by GetSecondData() after some period of time, and in this case, this vector becomes overwritten by another call to GetSecondData() or GetFirstData()...The solution is to copy vector to a new vector...but in this case is better to avoid this trick at all. How do you deal with these problems? I have to work with a big amount of vectors (each of length between 1-10).
The thing about garbage collection is just trying to avoid instantiating (and disposing of) as much as possible. It's hard to say what would be the best approach since I can't see how/why you're using your Vector data, but at first glance I think that with your approach you'll be constantly losing data (you're pretty much creating the equivalent of weak instances, since they can be easily overwritten) and changing the length of a Vector doesn't really avoid garbage collection (it may delay and reduce it, but you're still constantly throwing data away).
I frankly don't think you'd have memory leaks with point Vectors unless you're leaking the reference to the Vector left and right. In which case, it'd be better to fix these leftover references, rather than simply coming up with a solution to reuse the same vectors (which can have many more adverse effects).
However, if you're really concerned about memory, your best solution, I think, is either creating all vectors you need in advance (if it's a fixed number and you know their length ahead of time) or, better yet, using Object Pools. The latter would definitely be a more robust solution, but it requires some setup on your end, both by creating a Pool class and then when using it. To put it in code, once implemented, it would be used like this:
// Need a vector with length of 9
var myVector:Vector.<Point> = VectorPool.get(9);
// Use the vector for stuff
...
// Vector not needed anymore, put it back in the pool
VectorPool.put(myVector);
myVector = null; // just so it's clear we can't use it anymore
VectorPool would control the list of Vectors you have, letting other parts of your code "borrow" vectors as needed (in which they would be marked as being "used" inside the VectorPool) and give them back (marking them back as unused). Your code could also create vectors on the spot (inside get()), as needed, if no usable vectors are available within the list of unused objects; this would make it more flexible (not recommended in some cases since you're still spending time with instantiation, but probably negligible in this case).
This is a very macro explanation (you'd still have to write VectorPool), but object pools like that are believed to be the definitive solution to avoid re-instantiating as well as garbage collection of objects that are just going to be reused.
For reference, here's what I used as a very generic Object Pool:
https://github.com/zeh/as3/blob/master/com/zehfernando/data/ObjectPool.as
Or a more specialized one, that I use in situations when I need a bunch of throwaway BitmapData instances of similar sizes:
https://github.com/zeh/as3/blob/master/com/zehfernando/data/BitmapDataPool.as
I believe the implementation of a VectorPool class in the molds of what you need would be similar to the link above.
As a side note, if performance is a concern, I'd suggest using vectors of fixed length too, e.g.
// Create a vector of 9 items, filled with `nulls`
var myPoints:Vector.<Point> = new Vector.<Point>(9, true);
This makes it faster since you won't have micro allocations over time. You have to set the items directly, instead of using push():
myPoints[0] = new Point(0, 0);
But that's actually a forced advantage since setting the vector items is faster than push().

Can I use AS3 Stage3D AGAL to achieve CUDA like processing?

I have a program what detects a ball in a 320x240 stream runtime, but if I stream bigger resolution, it gets too slow. I'm assuming if I could use the GPU to calculate each pixels (with their neighbor frames, and neigbor pixels) it would be faster. Anyone knows if I can get data BACK from the GPU with AGAL?
in sort, I have the loop below, what goes through each pixel of the frame, and I want to calculate the most on GPU, to achive better performance.
for(var i:int=cv.length-1; i>1;i--){
if( (110*255) < (cv[i] & 0x0000FF00) && (cv[i] & 0x0000FF00) < (150*255)){ //i zöld
if( (cv[i+2] & 0x0000FF00) > (150*255) ) { //i+2 világos
if(floodhere(cv, i+2)){ //méret nagy
prevDiff[i]=0xffffffff; //fehér
close.push(i);
}
else prevDiff[i]=0xffff0000 //méret kicsi -> piros
} else {
prevDiff[i]=0xff000055 //kék
}
} else {
prevDiff[i]=0xff000000 //fekete
}
}
You can use AGAL to make fast calculations on the GPU, just be aware of the limits.
It goes roughly like this:
You need to upload you data as as textures (a n*m matrices), one datapoint is a 3x8 bit value. Uploading any kind of big data to the GPU is slow, thus you should not do it in every frame. Getting the texture back to Actionscript is slow too.
You can upload data to the GPU to its global variable memory (but only a limited amount)
The GPU will run your AGAL program parallel on every element on this matrix, and the output will be an n*m matrix too.
Every program instance has access to 3 things: Its coordinates, the global variables, and the uploaded matrices. The output of your program will be written to an output matrix to the same position. If you write multiple programs, the can access this output matrix quickly, but getting it back to the normal memory (for actionscript manipulation) is slow.
AGAL programs are very limited compared to Actionscript:
- max. 256 instructions.
- no loops, functions, classes. You only have mathematical operators and conditionals ("if-else").
- cannot write to the global memory
You may be able to use PixelBender. It also works in separate thread(s) and makes use of multicore CPUs so is much quicker than actionscript.
See http://www.flashmagazine.com/tutorials/detail/using_pixel_bender_to_calculate_information/ for an example
No way to get data back. You can only get color back. Moreover, to get pixel color in actionscript you should copy data from texture to bitmapdata wich is VEEEERY slow.