Animation frames shifted a few pixels away from last frames location - animation

In Libgdx I've been using textureAtlas and for loops to get animation which nearly works, for whatever reason the animation shifts as if the numbers in the for loop aren't correct or the frames each have padding and I can't figure out why. I use https://code.google.com/archive/p/libgdx-texturepacker-gui/downloads and these are the settings I use: https://imgur.com/a/VIYY0ax and here's a video of what it looks like: https://imgur.com/a/bo0denv.
I've tried many combinations of settings when making the texture atlas and it does result in various combinations, I even got it to work once but I had to add a new sprite to the texture atlas and couldn't replicate it successfully. All images are exactly the same size and the pigeon is in the same spot in all of them. The sprites placement (attached to box2body that doesn't move on x axis) and size are never changed
Here's the code for the for loop:
for (int i = 0; i < 4; i++) {
frames.add(new TextureRegion(getTexture(), 4395 + (i * 74), 42, 74, 74));
}
healedPigeonFlying = new Animation<>(0.15f, frames);
frames.clear();
I expect the pigeons body to stay in the same place yet it shifts around as if numbers are wrong or padding is between each frame.

After switching to TexturePacker I was given a warning that solved my problem; apparently using images OVER 4096x4096 will cause issues (like in this post) on almost all modern phones, and images OVER 2048x2048 will cause issues on slightly older phones. My image was 8192x8192. I promptly switched back to my old program and managed to squeeze all my sprites into two different 2048x2018 texture atlas's and it works like a charm.

Related

Not calling glclear results in weird artifacts

im wanting to NOT call glClear for the depth or color bit because i want to be able to see all the previously rendered frames. And it does work except it repeats the model all over the x and y axis, and also causes some strange grey blocky lines. Is there a way to accomplish this? Im using opengl es 3 on android. Thank you for any help.
The contents of the default framebuffer at the start of a frame is undefined, especially on tile-based renderers, which most of the mobile GPUs are. Your "repeats" in the X and Y axis are likely just showing how big the tiles are on your particular GPU (e.g. it's just dumping out whatever is in the GPU local tile RAM, repeated N times to completely cover the screen).
If you want to render on top of the previous frame you need to configure the rendering context configuration to use EGL_BUFFER_PRESERVED (the default is EGL_BUFFER_DESTROYED). E.g:
eglSurfaceAttrib(m_display, m_surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
Note 1: this will incur some overhead (the surface is effectively copied back into tile-local memory), whereas starting with a surface discard or invalidate, or a clear is usually free.
Note 2: this will only preserve color data; there is no means to preserve depth or stencil across frames for the default framebuffer.

Poor performance - SVG animations

So I'm creating some animations for a client and I've been playing with two.js because I liked its SVG capabilities. Unfortunately I'm having issues with performance.
I'm plotting 100 circles on the screen. Each circle contains 6 further circles for a total of 700 circles being rendered on load.
The circles react to mouse movements on the x-axis and cascade slowly downwards on the y-axis.
Currently in Chrome its only running at around 32FPS. In Firefox it barely even works!
I've also tried two.js's webgl renderer but while there is a slight performance increase, the elements just don't look as good as SVG.
The source is here: https://github.com/ashmore11/verifyle/tree/develop
path to file: src/coffee/elements/dots
Let me know if there's any more info I can provide.
What you've made is very beautiful!
Hmmm, so there are many factors as to why the performance isn't as stellar as you'd like.
The size of the drawable area matters (i.e: the <svg /> or <canvas /> element). The bigger the area the more pixels to render.
The amount of elements added to the DOM. Yes there are 100 dots, but each dot is comprised of many elements.
Of those elements the amount of changes an element has on any given frame.
Finally, of the elements changing how many operations (i.e: opacity, scale, translation, etc.)
These considerations compound in most computer generated imagery to affect real-time rendering. The goal is basically to reduce the load on any one of those dimensions and see if it's enough to give you the performance you're looking for. You're gonna have to get creative, but there are options. Here are a few things off the top of my head that you can do to try to speed things up:
Reducing the amount of shapes will make it run faster ^^
For something like this Two.Types.canvas might be fastest.
Instead of moving each dot split the translation into 2 or 3 groups and move them based on the container groups. Kind of like a foreground and background parallax.
If you're sticking with Two.Types.svg try animating only a handful of dots on any given frame. This way you're not doing entire traversal of the whole scene every frame and each dot isn't animating every frame.
Pseudo code for this might look like:
// ... some array : dots inferred ... //
var now = Date.now();
var index, length = 12;
two.bind('update', function() {
for (var i = index; i < Math.min(index + 12, dots.length); i++) {
var dot = dots[i];
dot.scale = (Math.sin(now / 100) + 1) / 4 + 0.75;
}
index = (index + 12) % dots.length;
});
If none of these are giving you anything substantial you're looking for than I would highly recommend turning in each Dot into a texture and drawing those textures either directly through canvas2d or with WebGL and a library. Three.js will be able to render hundreds of thousands of these: http://threejs.org/examples/#webgl_particles_sprites You'll have to rethink a lot of how the texture itself is generated and how the opacity varies between the lines and of course it'll look slightly different as you described in your question. Bitmap is different from Vector >_<
Hope this helps!

What's a good way to optimise rendering a 2D tile game in XNA?

EDIT: I've opted for the second approach as I got 150+ fps even when all 3 tile layers fill the entire screen.
EDIT 2: I read a lot about vertex buffer objects and how they would be great for static geometry and although I still have no idea how to turn my 2D tiles into a VBO and store it on the GPU memory, it definitely seems like the way to go if anyone else is looking for a fast way to render static geometry/quads.
I'm making a game like Super Meat Boy and was wondering if it would be better/faster to store level tiles in an array list and do a camera bounds overlap test to see if it should be rendered.
foreach(Tile tile in world.tiles) {
if(Overlap(camera.bounds, tile))
render(tile);
}
Or would a 2D array storing every grid square and only reading off between camera bounds be better?
int left = (int)(camera.position.x - camera.width/2);
int right = (int)(camera.position.x + camera.width/2) + 1;
int top = (int)(camera.position.y - camera.height/2); // WHY XNA DO YOU UPSIDE DOWN!!!
int bottom = (int)(camera.position.y + camera.width/2) + 1;
for(int x = left; x < right; x++) {
for(int y = top; y < bottom; y++) {
render(world.tiles[x][y]);
}
}
The camera can fit 64*36 tiles on screen which is 2300 odd tiles to read off using the latter approach but is doing an overlap test with every tile in the level any better? I read an answer about joining matching adjacent tiles into a larger quad and just repeating the texture (although I'm using a texture atlas so I'm not sure how to repeat a region on a texture).
Cheers guys.
As per my past experience I can share the details. In 2D map, normally map is like 0 - N long. Now N is far longer then screen size. Now at first I tried to loading everything at once. But it is bit of a overhead. Ok, it was like very much of a overhead. And I endup with 0 FPS. As I want different kind of object for me. So, even repeating same object and saving memory is not working. Then I tried bounding things with reference to screen. So, objects are there and but they are not getting rendered. So, it is moved from away from draw pipe line. And game back to life.
Now, for further performance with C# 4.0 I can use TPL and async and await with draw. It is like better version of threading. So, you can throw stuff there and let it be render at will.
Here is deal wiht XNA or any kinda graphics library. There is complete graphics rendering pipeline. And that makes things whole lot slow. Specifically if PC is old and only have 64MB graphics card to support only wide screen. Your game will be deployed to any kinda machine right??!!
So, if I explain in language of XNA, update is simple code and run it as fast as it can, there is nothing to stop it. But draw is has complete pipe line ahead of it. And that is sole reason of having begin and end. So, after end it can start pushing things to pipe line. [Here] (http://classes.soe.ucsc.edu/cmps020/Winter11/readings/hlsl.pdf) article for reference.
So, here is a deal rendering pipeline is needed but there is no need that is should be slow and blocking. Just make it multi-threaded and things will quite faster for you. If you want more terse then you have to use C# at it fullest including Linked list and stuff. But that will be like last stage.
I hope I have given enough details to provide you an answer. Please let me know if any further details needed.

Scrolling parallax background, infinitely repeated in libgdx

I'm making a 2D sidescrolling space shooter-type game, where I need a background that can be scrolled infintely (it is tiled or wrapped repeatedly). I'd also like to implement parallax scrolling, so perhaps have one lowest background nebula texture that barely moves, a higher one containing far-away stars that barely moves and the highest background containing close stars that moves a lot.
I see from google that I'd have each layer move 50% less than the layer above it, but how do I implement this in libgdx? I have a Camera that can be zoomed in and out, and in the physical 800x480 screen could show anything from 128x128 pixels (a ship) to a huge area of space featuring the textures wrapped multiple times on their edges.
How do I continuosly wrap a smaller texture (say 512x512) as if it were infinitely tiled (for when the camera is zoomed right out), and then how do I layer multiple textures like these, keep them together in a suitable structure (is there one in the libgdx api?) and move them as the player's coords change? I've looked at the javadocs and the examples but can't find anything like this problem, apologies if it's obvious!
Hey I am also making a parrallax background and trying to get it to scroll.
There is a ParallaxTest.java in the repository, it can be found here.
this file is a standalone class, so you will need to incorporate it into your game how you want. and you will need to change the control input since its hooked up to use touch screen/mouse.
this worked for me. as for repeated bg, i havent gotten that far yet, but i think you just need to basic logic as in, ok one screen away from the end, change the first few screens pos to line up at the end.
I have not much more to say regarding to the Parallax Scrolling than PFG already did. There is indeed an example in the repository under the test folder and several explanations around the web. I liked this one.
The matter with the background is really easy to solve. This and other related problems can be approached by using modular algebra. I won't go into the details because once shown is very easy to understand.
Imagine that you want to show a compass in your screen. You have a texture 1024x16 representing the cardinal points. Basically all you have is a strip. Letting aside the considerations about the real orientation and such, you have to render it.
Your viewport is 300x400 for example, and you want 200px of the texture on screen (to make it more interesting). You can render it perfectly with a single region until you reach the position (1024-200) = 824. Once you're in this position clearly there is no more texture. But since it is a compass, it's obvious that once you reach the end of it, it has to start again. So this is the answer. Another texture region will do the trick. The range 825-1023 has to be represented by another region. The second region will have a size of (1024-pos) for every value pos>824 && pos<1024
This code is intended to work as real example of a compass. It's very dirty since it works with relative positions all the time due to the conversion between the range (0-3.6) to (0-1024).
spriteBatch.begin();
if (compassorientation<0)
compassorientation = (float) (3.6 - compassorientation%3.6);
else
compassorientation = (float) (compassorientation % 3.6);
if ( compassorientation < ((float)(1024-200)/1024*3.6)){
compass1.setRegion((int)(compassorientation/3.6*1024), 0, 200, 16);
spriteBatch.draw(compass1, 0, (Gdx.graphics.getHeight()/2) -(-250 + compass1.getTexture().getHeight()* (float)1.2), Gdx.graphics.getWidth(), 32 * (float)1.2);
}
else if (compassorientation > ((float)(1024-200)/1024*3.6)) {
compass1.setRegion((int)(compassorientation/3.6*1024), 0, 1024 - (int)(compassorientation/3.6*1024), 16);
spriteBatch.draw(compass1, 0, (Gdx.graphics.getHeight()/2) -(-250 + compass1.getTexture().getHeight()* (float)1.2), compass1.getRegionWidth()/200f * Gdx.graphics.getWidth() , 32 * (float)1.2);
compass2.setRegion(0, 0, 200 - compass1.getRegionWidth(), 16);
spriteBatch.draw(compass2, compass1.getRegionWidth()/200f * Gdx.graphics.getWidth() , (Gdx.graphics.getHeight()/2) -(-250 + compass1.getTexture().getHeight()* (float)1.2), Gdx.graphics.getWidth() - (compass1.getRegionWidth()/200f * Gdx.graphics.getWidth()) , 32 * (float)1.2);
}
spriteBatch.end();
You can use setWrap function like below:
Texture texture = new Texture(Gdx.files.internal("images/background.png"));
texture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
It will draw background repeatedly! Hope this help!
Beneath where you initialize your Texture for the object. Then beneath that type in this
YourTexture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
Where YourTexture is your texture that you want to parallax scroll.
In Your render file type in this code.
batch.draw(YourTexture,0, 0, 0 , srcy, Gdx.graphics.getWidth(),
Gdx.graphics.getHeight());
srcy +=10;
It is going to give you an error so make a variable called srcy. It is nothing too fancy.
Int srcy

how to draw complex shapes on the html canvas tag with the best performance?

I am using the HTML canvas tag to draw around 3000, vector lines on a small area (900x500) the target platform is mobile which has inherently lower spec'd hardware. On my desktop I can make the 3000 vector lines render, using moveto and lineto in about 25ms. However on the mobile device it's more like 700ms which is significantly slower. What is the most effective way to render these lines which make up a complex shape using canvas? Would the canvas pixel API be better suited to this task?
My current code looks something like this:
var myArray = []; //contains 3000 objects with X & Y & type
for(var i = 0; i<myArray.length; i++) {
if(myArray.type = "moveTo") {
canvasElement.moveTo(myArray[i].X, myArray[i].Y);
} else {
canvasElement.lineTo(myArray[i].X, myArray[i].Y);
}
}
canvasElement.stroke();
Thanks
Are these lined connected to each other? If so, you could try rendering the shapes they produce using moveto, lineto, lineto, etc. this taking nearly 50% (or less) of the time.
For disconnected lines which are similar, e.g. 3 pixels long, horizontal, you could render small 'sprites' for the commonly occurring ones - it might be quicker to draw them as images then.
Otherwise, if you have a graphic of which only small portions change, you could try clipping to the region of change and redrawing only the lines which fall within it.

Resources