How load a lot of textures in andengine - android

I am trying to load textures as follows:
private Texture mTexture;
...
public Textures(final BaseGameActivity activity, final Engine engine) {
this.mTexture = new Texture(2048, 1024,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mBackgroundTextureRegion = TextureRegionFactory.createFromAsset(
this.mTexture, activity, "img/back.png", 0, 0);
this.mSwingBackTextureRegion = TextureRegionFactory.createFromAsset(
this.mTexture, activity, "img/player.png", 836, 0);
...
I want to load more than 200 textures. However, the current method that I am using is too long.
Are there faster methods to complete it?
I am working in GLES1.

The easiest way to do it is with Texture Packer, found here
This allows you to add multiple image files in to one easy to load spritesheet. The engine loads this spritesheet in to a texture and creates a class that lets you easily reference each image from that spreadsheet. Turn 200 TextureRegions in to 1 TexturePack.
I'm using GLES2 and I'm not sure where the source files are for GLES1. Poke around the forums and you should be able to find out how to use them. There has been plenty of talk about it.

There is a texture packer built in AndEngine which does this automagically. Try searching the AndEngine forum.
http://www.andengine.org/forums/

Related

AndEngine - one textureAtlas for all textureRegion in a scene; possible?

I noticed that I can keep one atlas for one textureRegion although I can draw same region multiple times as a sprite. Is it possible to keep all textureRegions in one textureAtlas in a scene?
My special case is, I am generating images instead of using any image file. I do this with BaseBitmapTextureAtlasSourceDecorator and generate the region from IBitmapTextureAtlasSource.
Yes. Generally, though, you should only create atlases with a a max width/height of 1024 (these sizes must be powers of 2, by the way), to be efficient.
On another note, I've found it easier to use BuildableBitmapTextureAtlas. With this kind of atlas, you don't have to specify where in the atlas you are placing your textures. I think it also might take care of sprite-bleeding to some degree (not sure, though). It's the same idea really... Here is an example from my project:
BuildableBitmapTextureAtlas buttonAtlas = new BuildableBitmapTextureAtlas(getTextureManager(), 512, 512, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
model.moveLeftButtonTR = BitmapTextureAtlasTextureRegionFactory.createFromAsset(buttonAtlas, this, "moveleft_button.png");
model.moveRightButtonTR = BitmapTextureAtlasTextureRegionFactory.createFromAsset(buttonAtlas, this, "moveright_button.png");
model.handleBlockButtonTR = BitmapTextureAtlasTextureRegionFactory.createFromAsset(buttonAtlas, this, "handleblock_button.png");
model.restartButtonTR = BitmapTextureAtlasTextureRegionFactory.createFromAsset(buttonAtlas, this, "restart_button.png");
try{ buttonAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 1)); }
catch(Exception e){ e.printStackTrace(); }
buttonAtlas.load();
In your case, use the following method:
BitmapTextureAtlasTextureRegionFactory.createFromSource(BuildableBitmapTextureAtlas atlas, IBitmapTextureAtlasSource source)
In summary, the atlas just holds all the textures you add to it. Then you load this atlas into memory so that these textures can be retrieved quickly. You can then use a single instance of a texture to build as many independent sprites as you wish.

How to detect if bitmap is too large for texture

So I have done a lot of looking around and the answer to this seems to be to use:
int[] maxSize = new int[1];
gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxSize, 0);
to detect the size of the texture, now my issue is how do I create or get access to the gl var that holds the function I need? Is it already there somewhere? I would like to support android 2.2 and above, so the 4.0+ new trick wont work. If this is a repeat question just point me in the right direction in the comments and I will take t down. Couldn't seem to find a good explanation of how to set this up properly anywhere, just those two lines of code.
If you take a look on how OpenGL Apps are made you will notice there are the main app thread (main activity) and a renderer class(http://developer.android.com/guide/topics/graphics/opengl.html). The heart of the renderer class if the method public void onDrawFrame(GL10 gl) , this is called by the android infrastructure when the frame needs to be redraw.
So basically, a context object (GL10 gl var) is passed to the renderer (yours) when required and there you can check your max texture size.

setTextureRegion AnimatedSprite

I'm developping a game which implements gif sprites...
After start with gif I used png image and for change the TextureRegion of my sprite I followed this guide: Sprite.setImage() in andengine and it worked very well.
Now I want to do the same thing with AnimatedSprite. Can someone tell me How i can edit the org.anddev.andengine.entity.sprite.AnimatedSprite.java to create:
sprite.setAnimatedTextureRegion(PixelPerfectTiledTextureRegion textureRegion)
P.S I use also PixelPerfect
The AnimatedSprite class uses the same texture region declared in BaseSprite, so the code in the link you gave will work - just paste it in the AnimatedSprite.java file:
public void setTiledTextureRegion(TiledTextureRegion textureRegion) {
this.mTextureRegion = textureRegion;
}
Note: If the different tiled textures have different number of tiles (So each has a different animation parameters associated with it) you should handle it in your code. It may get complicated, so I'd just create a new AnimatedSprite instead of replacing the texture region.

How to create a circular loop of animations in AndEngine?

I want to do an "chain" or circular loop of animations as can be described below:
LABEL start
do Anim1->Anim2->Anim3->Anim4
GOTO start
The above will do a circular loop: Anim1->Anim2->Anim3->Anim4 and back to Anim1 and so on.
I am not able to merge all the PNGs in one Texture because Andengine/Android is limited in loading the resources. However, when I split my initial large tile into 4 smaller tiles, everything works fine.
I tried to use an AnimationListener inside Anim1. When onAnimationFinished() is called, I detach Anim1, and run Anim2 and do this in chain of inner functions. However, when I am in Anim4, I do not know how to go back to the start and attach Anim1.
Note: All this problem could be solved if you know how I can pack a set of 150 PNGs that individually quite large but fit in a tile of 4096x4096 px.
Thank you for your help!
EDIT (following JiMMaR's proposed solution):
I am using Texture Packer and the overall Texture exceeds 4096*4096, causing an OutOfMemory error on Android.
At the moment, I have split the Textures into four tiles and I four PNG tilemaps.
You can use 'Texture Packer' to see if all your images can fit in 4096 x 4096.
You can download Texture Packer from here. (NOTE: Texture Packer supports AndEngine data output too)
You can use "BuildableBitmapTextureAtlas" and "BlackPawnTextureAtlasBuilder" classes to pack your PNGs into one texture atlas.
You should post some code so we can see the implementation.
Try to use several AnimatedSprites with animation listeners in each one. This way you can start the animation of the next sprite in the onAnimationFinished() call.
private class AnimationLooperListener implements IAnimationListener{
private AnimatedSprite nextSpriteToAnimate;
public AnimationLooperListener(AnimatedSprite sprite){
nextSpriteToAnimate = sprite;
}
/** other methods are hidden */
public void onAnimationFinished(AnimatedSprite sprite){
sprite.setVisible(false);
nextSpriteToAnimate.setVisible(true);
nextSpriteToAnimate.animate(100, new AnimationLooperListener(sprite);
}
}
AnimatedSprite sprite1 = new AnimatedSprite(0, 0, tiledTextureRegion, vertex);
AnimatedSprite sprite2 = new AnimatedSprite(0, 0, tiledTextureRegion, vertex);
AnimatedSprite sprite2 = new AnimatedSprite(0, 0, tiledTextureRegion, vertex);
AnimationLooperListener listener1 = new AnimationLooperListener(sprite2);
AnimationLooperListener listener2 = new AnimationLooperListener(sprite3);
AnimationLooperListener listener3 = new AnimationLooperListener(sprite1);
sprite1.animate(100, listener1);
sprite2.animate(100, listener2);
sprite3.animate(100, listener3);
This way, you have an animation loop, between several sprites that can be created using several TiledTextureRegions.

Why OpenGL ES texture mapping is very slow?

I have an Android application that displays VGA (640x480) frames using OpenGL ES. The application reads each frame from a movie file and updates the texture accordingly.
My problem is that, it is taking almost 30 ms. to draw each frame using OpenGL. Similar test using the Canvas/drawBitmap was around 6 ms on the same device.
I'm following the same OpenGL calls that VLC Media Player is using, so I'm assuming that those are optimized for this purpose.
I just wanted to hear your thoughts and ideas about it?
Are you sure that the bitmap are loaded with RBG_565?Try this :
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
bm = BitmapFactory.decodeByteArray(temp, 0, temp.length,opt);
Let me know!
Which are the calls you are using ?
make sure that u create texture only once (glTexImage2D) and next time just update it with new buffer.You can also disable other gl things like depthbuffer,stencil,accumulation,lighting, etc...
If none of these helps , check you opengl implementation. make sure that that uses hardware(gpu)

Categories

Resources