does the spritebatch draws multiple stages with a single batch? Libgdx - 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.

Related

How to slow down the All actions of cocos2dx Game

I'm implementing a game on cocos2d-x.
Now I implemented a "Replay of My Game" feature (Game shows from start)
But I want to replay my game at the speed of 1x , 2x , 3x , 4x. When changing speed to 2x all actions (move and rotate etc.) should work with respect to new changed variable.
How can I do that by changing the general speed of CCAction?
I want a general solution. I know the solution with variables or scheduler,
but I want a general solution.
You can use following code to slow or fast all scheduler and action:-
float val = 2.0; // to fast
val = 0.5; // to slow
Director->getInstance()->setTimeScale(val);
Default value is 1.0;
Write a class like CCEaseIn by yourself.
Rewrite update(float time).
m_pInner->update(powf(time, m_fRate)); // this is what update() like in CCEaseIn
The code may be changed like this:
m_pInner->update(func(time));
func(float time) is the function to change the time. like time/2 which means to 0.5x, time*2 means 2x. You may save some param to make the function more adaptable.

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

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.

Scala JPanel rendering synchronisation

I'm doing a simulation program in Scala and I'm trying to render the simulation in a JPanel by overriding the paintComponent:
override def paintComponent(g: Graphics2D) = {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paintComponent(g)
tx1 = g.getTransform()
g.setColor(new Color(0,0,0))
simulator.getVehicles foreach{vehc =>
g.translate(vehc.getPos.x,vehc.getPos.y)
g.draw(new Ellipse2D.Double(-Vehicle.rad, -Vehicle.rad, Vehicle.diam, Vehicle.diam))
g.drawLine(0,0,(Vehicle.rad*vehc.getDir.x).toInt,(Vehicle.rad*vehc.getDir.y).toInt)
g.setTransform(tx1)
}
}
I have the simulation itself running on a different thread:
def run{
//logic loop
time = System.currentTimeMillis();
dt = 1000/60
while(loop)
{
getVehicles.foreach{
_.move
}
collider.solvecollisions()
Thread.sleep(dt- (time - System.currentTimeMillis()))
time = System.currentTimeMillis();
}}
GetVehicles returns a Buffer[Vehicle] of all simulated vehicles.
My problem is that there is jittering in the rendering. What I mean is that sometimes some of the vehicles are rendered a timestep later than others.
I presume this happens because the simulation loop updates the positions at the same time the render loop fetches the positions, and there is some overlap. i.e. when rendering begins in timestep n,half of the vehicles are rendered and then timestep n+1 happens and the rest of the vehicles are rendered a timestep further. First I thought this was a problem to be solved with double buffering, but since paintComponent already does that, I dont think thats the case.
Any ideas how to fix this? I tried simply rendering getVehicles.clone but that didn't help because the references to the vehicles are still the same.
Thanks!
It appears that your vehicle models are mutable things (_.move). Then if simulation and painting run in different threads, it is no surprise that you don't get a consistent world view in Swing.
I can see the following solutions, depending on your requirements:
run the simulation updates on the event-dispatch-thread. Advantage: no need to change your code at all. Disadvantage: may render the GUI sluggish if simulation is heavy
create one global "world" lock to which you synchronize. Advantage: requires very little change to the code. Disadvantage: Unless GUI updates are at low rate, both simulation and rendering block each other. Might be useful if GUI updates are a fraction of simulation rate.
adopt an immutable model, and your simulation will then create one consistent updated world in each step. Advantage: rendering and simulations will automatically be consistent. Probably the fastest solution. Disadvantage: You need to rewrite your simulation. Probably the best solution.
Change your var mutable state to STM reference cells. Might work nicely if GUI rate is low compared to simulation rate, because then this "optimistic" approach might work with relatively few rollbacks. I'm not sure how this works out with Scala-STM and the renderer doing only read access. Perhaps you need a full multi-versioned STM to avoid rollbacks.
To outline the immutable variant:
trait Vehicle {
def move: Vehicle // return updated model
}
trait Collisions {
def solve(in: Seq[Vehicle]): Seq[Vehicle] // return corrected models
}
trait World {
def vehicles: Seq[Vehicle]
}
trait Simulator {
protected def coll: Collisions
// create updated world
def run(prev: World): World = new World {
val vehicles = coll.solve(prev.vehicles.map(_.move))
}
}

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.

Time Slow/Speed Up Power Up

I'm creating a collecting game, and I want to create a time slow/speed up powerup.
Any ideas on how to do that in Flash/AS3?
One way I thought of was simply changing the frame rate. I can slow down the frame rate. But when I try to increase the frame rate beyond 60, Flash caps it at 60.
Thank you in advance for your help.
I like to do time-based movement instead of frame-based movement for better consistency. The general concept is to check the amount of time passed between frames and base movement on that instead of frames which can alternate (e.g. you can have 60FPS for a bit and then it slows down to 30FPS). You can do a simple calculation based on time passed for movement, for instance player.x += player.speed * timeDiff but that can result in odd situations if the time passed between frames happens to be really large (for instance, the player can end up missing lots of collisions since you are moving him in one large movement). Instead, I like to use a game loop to move the player X times based on the amount of time that has passed between frames, ensuring that collisions and any other game loop events will be properly checked.
This also has the advantage that it is easy to adjust the speed.
Here is the basic concept:
private var speedMultiplier:int = 100;//100 normal speed, 0 paused
private var currRealTime:int = getTimer();
private var currGameTime:int = currRealTime;
private var globalLastTime:int = currRealTime;
private var totalTimeDiffRemainder:int = 0;
private var loopTime:int = 20;//every 20 ms run our actions
public function getGameTimer():int
{
return currGameTime;
}
private function updateGameTime():void
{
var realTime:int = getTimer();
currGameTime = currGameTime + speedMultiplier/100*(realTime - currRealTime);
currRealTime = realTime;
}
private function runEvents(event:Event):void
{//ENTER_FRAME event
var totalTimeDiff:int = getGameTimer() - globalLastTime + totalTimeDiffRemainder;
globalLastTime = getGameTimer();
while (totalTimeDiff > loopTime)
{//every 20 ms run all our actions
totalTimeDiff -= loopTime;
//run all your game loop events here, such as collision checks
}
totalTimeDiffRemainder = totalTimeDiff;
updateGameTime();
}
So every time an ENTER_FRAME event fires, we will check the time passed since the last ENTER_FRAME event and then run our actions once for each 20ms that has elapsed and pass the remainder over to the next ENTER_FRAME event. For instance, if it's been 47 ms since the last ENTER_FRAME, we will run our actions twice and pass over 7 remaining ms to the next ENTER_FRAME event.
In order to pause, slow down, or speed up the game, all you have to do is modify speedMultiplier. Changing speedMultiplier to 0 will pause the game, 50 is half speed 100 is normal speed, 200 double speed, etc.
I believe the general way to do this would be to use an MVC like setup where your model holds all the data for the game elements (character position/orientation, enemies, dynamic map elements) then the controller is modifying the model. With the controller modifying the model this way you could add a multiplier to the model, and use the multiplier when having the controller update the model for "physics" or other modifying dynamic elements in the game.
Roughly:
Model
public var speedMultiplier:Number=1;
public var playerXSpeed:Number;
public var playerYSpeed:Number;
Controller (I'm assuming you make a controller class and pass the view to the constructor and are listening for events from the view in the controller).
private function enterFrame_handler(event:Event):void
{
var playerSprite:Sprite = mainView.playerSprite;
playerSprite.x += playerXSpeed*speedMultiplier; //only problem I can see here is your player skipping past certain elements, to avoid this you could use a loop to make each motion and do checks but it's more CPU intensive
//var enemySprites:Vector<EnemySprite>;
//other game physics here, reduce speed due to drag, fix any invalid values etc.
}
Edit
Actually in thinking this through some more, although I do generally like using an MVC setup myself since it allows one to have a single sprite that does all the drawing; you could also use the same concept of a speedMultiplier shown here without necessarily changing around any software patterns. If you end up needing to do it with a loop because you need it to do checks for every spot it would hit as an object moves along, you may need to have your default speedMultiplier be something like 10 so you could set it down to 1 to get 1/10th speed with all the same checks as it would get at 10 being normal speed (again only issue here being it has to do whatever calculations 10 times for every update, in this case you may want to use a timer instead of the frame rate to control the overall calculation speed).