Andengine dynamic texture sometimes not loading - android

I am having problems with dynamic loading of textures.
When a user double taps on the screen, the background and other sprites are changed. There is no error produced, but some times the textures are cleared and new textures are just not loaded.
This is my initial onCreateResource
ITextureRegion BackgroundTextureRegion;
BitmapTextureAtlas MainTexture1;
//Initiate Textures
MainTexture1 = new BitmapTextureAtlas(this.getTextureManager(),1000,1000, TextureOptions.BILINEAR);
//Clear Textures
MainTexture1.addEmptyTextureAtlasSource(0, 0, 1000,1000);
//Assign Image Files to TextureRegions
BackgroundTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(MainTexture1, this, "Evening.jpg",0,0);
//Loading the Main Texture to memory
MainTexture1.load();
There is no problem until after this point. After this when user double taps or swipes the background, I change the texture dynamically. Here is the code:
MainTexture1.clearTextureAtlasSources();
MainTexture1.addEmptyTextureAtlasSource(0, 0, 1000,1000);
BitmapTextureAtlasTextureRegionFactory.createFromAsset(MainTexture1, this, "WinterNight.jpg",0,0);
This usually changes the texture and I am getting the desired result. But in some devices (eg. Samsung Tab 2), 1 in 10 times the the MainTexture1 is cleared but its not loaded with new image.
So it just gives a black screen, how do I correct this?

MainTexture1.clearTextureAtlasSources();
// MainTexture1.addEmptyTextureAtlasSource(0, 0, 1000,1000);
BitmapTextureAtlasTextureRegionFactory.createFromAsset(MainTexture1, this, "WinterNight.jpg",0,0);
MainTexture1.load();
Try this

runOnUiThread(new Runnable() {
#Override
public void run() {
MainTexture1.clearTextureAtlasSources();
MainTexture1.addEmptyTextureAtlasSource(0, 0, 1024, 1024);
BitmapTextureAtlasTextureRegionFactory.createFromAsset(MainTexture1, this, "WinterNight.jpg",0,0);
MainTexture1.load();
}
});
Like this.
If it is not working try with creating another textureatlas instead of same atlas.

Related

How to draw smooth circle in Libgdx

I am trying to draw an circle to Libgdx which is created from Image not ShapeRenderer. But when I try to draw image to SpriteBatch it does not draw smoothly.
I checked the image resolution and Image Dimension is 1673x1673 and Sprite Size is 80x80.
//This is my GameState code
#Override
public void render(float delta) {
update(delta);
SpriteBatch sb = game.batch;
Color bg = ThemeFactory.getInstance().getTheme().backgroundColor;
Gdx.gl.glClearColor(bg.r, bg.g, bg.b, bg.a);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
sb.setProjectionMatrix(camera.combined);
sb.begin();
for(int i =0;i<elements.size();i++){
if(!(elements.get(i) instanceof Arrow)){
elements.get(i).render(sb);//HERE IS DRAWING HAPPENING
}
}
sb.end();
barriers.render(sb);
renderHud();
}
My circle constructor and rendering code is below.
public Circle(Texture texture, Size size, Vector3 position){
mSprite = new Sprite(texture);
mSprite.setSize(size.width, size.height);//80x80
mSprite.setPosition(position.x, position.y);
mSprite.setOriginCenter();
}
#Override
public void render(SpriteBatch sb) {
mSprite.draw(sb);
}
2 tips:
1. Raise up sampling
2. use libgdx mipmap for your texture
I recommend using : filter 1: MipMapLinearNearest,Nearest or filter 2: Linear,Linear
filter 1 is fast, filter 2 is high quality
for more info read this
Filtering
The minification/magnification filters define how the image is handled upon scaling. For "pixel-art" style games, generally Filter.Nearest is suitable as it leads to hard-edge scaling without blurring. Specifying Filter.Linear will use bilinear scaling for smoother results, which is generally effective for 3D games (e.g. a 1024x1024 rock or grass texture) but not always so for a 2D game. In OpenGL, the terms used are GL_NEAREST and GL_LINEAR, respectively.
Use filter in your texture.
Eg.
texture.setFilter (TextureFilter.Nearest, TextureFilter.Nearest );
For more information about filters, refer this blog: http://www.badlogicgames.com/wordpress/?p=1403

Drawing 200 textures in LibGdx based Android game

When I draw more around 100-200 textures all in the same screen, the device becomes very slow and the app crashes without any exceptions. Could you please let me know any best way to have 100 textures without compromising the performance.
I am using the TextureRegion from TextureAtlas.
MainGame
public void render(SpriteBatch sb) {
// TODO Auto-generated method stub
// System.out.println("BallPoolGame Screen - render");
batch = sb;
sb.setProjectionMatrix(camera.combined);
sb.begin();
sb.draw(BACKGROUND_BALL_POOL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
cellManager.draw(sb);
ballManager.draw(sb);
sb.end();
}
private void setGameTextures() {
gameScreenAtlas = new TextureAtlas("data/texturetutorialpack.pack");
RED_BALL = gameScreenAtlas.findRegion("redball");
// RED_BALL.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
BLUE_BALL = gameScreenAtlas.findRegion("blueball");
// BLUE_BALL.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
GREEN_BALL = gameScreenAtlas.findRegion("greenball");
// GREEN_BALL.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
}
CellManager
public void draw(SpriteBatch sb){
batch=sb;
showImageTexture(MODEL1,207,1);
if(showSelectedCell){
if(allPossiblePathSize>0)
setupBoardCellTexture();
showImage(CELL_SELECTED, rowCoordinate[cellRow], colCoordinate[cellCol]);
}
}
private void setupBoardCellTexture(){
for(CellGrid c : masterGrid){
if(cellTextureIndicator[c.getRow()][c.getCol()]==1){
showImage(CELL_ALL_PATH_TEXTURE,c.getRowCoordinate() ,c.getColCoordinate() );
}
}
}
private void showImage(TextureRegion tr, float rowCoordinate, float colCoordinate) {
batch.draw(tr, colCoordinate,rowCoordinate);
}
BallManager
public void draw(SpriteBatch sb) {
batch = sb;
setupBoardBallTexture();
if (moveTheBall) {
updateBallPosition();
showImage(ball.getTextureRegion(), moveRow + 6, moveCol + 6);
}
squeezeBalls.draw(sb);
}
You are missing some essential data about your app to answer than question:
How big is one texture on average (Size: widthxheight)
On which device is this error occuring (some devices might have less fillrate than others)
What texture filter does the TextureAtlas use (LINEAR, NEAREST, ...)
I guess that you are trying to draw many textures event if they are out of sight. If that is the case you have to implement a check if the cell is visible to the camera.
Another guess would be that you are trying to draw too many elements with the LINEAR TextureFilter. When using linear as a texture filter the gpu needs to sample way more points then with nearest (i think it was 4 times the samples; so in theory your gpu draws 400-800 textures; depending on images size that are too much for mobile gpu fillrates)
Try to describe more circumstances then i can give probably more insight in your problem.

What might be causing only half of textures to be drawn in an Android game?

I've had reports from a couple of users (from 85000 downloads) of the problem shown in the image below. No doubt it has occurred a few more times than this, but it's certainly rare.
I'm unable to reproduce the problem and don't believe it's specific to device as some users would appear to be playing the game perfectly happily on the same device models that have reported the problem.
The letters are drawn onto a frame buffer first to build them up from the circular background with the character drawn on top. They are then copied off and a new texture is created.
The background is also put together from multiple components on a frame buffer and copied off to create a texture, so I'm not too sure why that appears to work perfectly well when the letters don't. The background is drawn using the same FrameBuffer and the same SpriteBatch instance.
What it does look like
What it should look like
Method that create the images
private static Texture getTextureUsingGpu(String letter, Bubble.BubbleType bubbleType) {
if (!enabled)
return null;
StrokeFontHelper font = Assets.strokeFont;
font.setSettings(Fonts.BUBBLE_TEXT_SETTINGS);
TextureRegion tx = getBlockImage(letter, bubbleType);
FrameBuffer fb = TextureLoader.getFrameBuffer();
fb.begin();
Gdx.gl20.glClearColor(0.0f, 0.0f, 0.0f, 1);
// Make sure everything is really really clear! Trying to fix graphics glitches on some phones
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_STENCIL_BUFFER_BIT | GL20.GL_SUBPIXEL_BITS);
float width = tx.getRegionWidth();
float height = tx.getRegionHeight();
TextureLoader.sb.begin();
tx.flip(false, !tx.isFlipY());
TextureLoader.sb.disableBlending();
TextureLoader.sb.draw(tx, 0, 0);
TextureLoader.sb.enableBlending();
// Removed character drawing code to make it more readable
TextureLoader.sb.end();
Pixmap pm = ScreenUtils.getFrameBufferPixmap(0, 0, (int) width,
(int) height);
PixmapTextureData data = new PixmapTextureData(pm, Format.RGBA8888,
false, false, true);
Texture result = new Texture(data);
result.setFilter(TextureFilter.Linear, TextureFilter.Linear);
cacheTexture(letter, result, pm);
fb.end();
return result;
}
public static FrameBuffer getFrameBuffer() {
if (frameBuffer == null || frameBuffer.getWidth() != Gdx.graphics.getWidth() || frameBuffer.getHeight() != Gdx.graphics.getHeight()) {
if (frameBuffer != null)
frameBuffer.dispose();
// Create the highest quality frame buffer we can get away with
try {
frameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
} catch (Exception e) {
try {
frameBuffer = new FrameBuffer(Pixmap.Format.RGB888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
} catch (Exception e2) {
frameBuffer = new FrameBuffer(Pixmap.Format.RGB565, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
}
}
// Set up the camera correctly for the frame buffer
camera = new OrthographicCamera(frameBuffer.getWidth(), frameBuffer.getHeight());
camera.position.set(frameBuffer.getWidth() * 0.5f, frameBuffer.getHeight() * 0.5f, 0);
camera.update();
sb.setProjectionMatrix(camera.combined);
}
return frameBuffer;
}
Edit
I've done some fiddling with this and have a very helpful user who has been testing versions for me. Here's what I've established.
If I use a ShapeRenderer rather than a SpriteBatch then I can draw over the whole area as expected.
It is almost certainly the point at which I draw textures to the FrameBuffer using the SpriteBatch that the problem occurs. It just doesn't draw to the bottom half of the textures. What's on the FreameBuffer is copied to the pixmap correctly.
Another Edit I've got a new visual glitch reported by a user. I don't know if this might shed some more light on a problem.

Android AndEngine Ontouch Animation

I am creating an app using AndEngine for the first time. My app is animation-oriented i.e. it has a number of images which on click animate. Most of these animations are frame by frame animations. I am using AndEngine because I require some animations with particle system, gravity and other stuff. Can someone help me with a simple onclick animation code in AndEngine or maybe point me to some good tutorial since all AndEngine tutorials are game tutorials that do not have frame by frame animation. Any help would be appreciated.
Before starting: note that this answer is using the TexturePacker extension for AndEngine.
For my frame by frame animations I am using a program called Texture Packer, which is supported by AndEngine. You actually just drag all your images to there, and it exports 3 files you need to use inside your project. The file are: .xml , .java , .png
By doing that i'm creating a big bitmap (try to stay below or equal to 2048x2048) with all the frames inside of it.
After assuming you have those files created, you need to copy them to your project. the .png and .xml go into the same directory, most likely under assets/gfx/ ... and the .java file should be located in the src directory with the rest of your classes.
Now lets check out some code..
First of all we will need to load all the textures from the files.. we will do that using the following code:
Those are the variables we will use to create our animatable object.
private TexturePack dustTexturePack;
private TexturePackTextureRegionLibrary dustTexturePackLibrary;
public TiledTextureRegion dust;
The following code actually loads the single textures from the bitmap into our variable
try {
dustTexturePack = new TexturePackLoader(activity.getTextureManager(),"gfx/Animations/Dust Animation/").loadFromAsset(activity.getAssets(),"dust_anim.xml");
dustTexturePack.loadTexture();
dustTexturePackLibrary = dustTexturePack.getTexturePackTextureRegionLibrary();
} catch (TexturePackParseException e) {
Debug.e(e);
}
TexturePackerTextureRegion[] obj = new TexturePackerTextureRegion[dustTexturePackLibrary.getIDMapping().size()];
for (int i = 0; i < dustTexturePackLibrary.getIDMapping().size(); i++) {
obj[i] = dustTexturePackLibrary.get(i);
}
dust = new TiledTextureRegion(dustTexturePack.getTexture(), obj);
As you can see, we are using the TiledTextureRegion object. what we've done until now is actually loading the textures, and giving our TiledTextureRegion object all the info needed about the regions of the smaller images located in our big bitmap.
Later on, to use this in any part of our game, we can do the following: (notice that my "dust" variable is located inside a ResourceManager class, and therefore its public - this info is given for the next code)
AnimatedSprite dustAnimTiledSprite = new AnimatedSprite(500, 125, resourcesManager.dust, vbom);
myScene.attachChild(dustAnimTiledSprite);
At last, to animated the object in a specific given time, we just use the simple method animate, just like this :
dustAnimTiledSprite.animate(40, 0);
(In this case, the duration of each frame is 40, and there is 0 loops - will be animated once)
** Not too sure what's the difference between AnimatedSprite to TiledSprite. but this is how I show simple animations in my game.
I hope this is what you were looking for. good luck
This is sprite sheet with 8 frames
Player.sprite.animate(
new long[] { 100, 100 }, 7, 8,
false, new IAnimationListener() {
public void onAnimationStarted(
AnimatedSprite pAnimatedSprite,
int pInitialLoopCount) {
}
public void onAnimationLoopFinished(
AnimatedSprite pAnimatedSprite,
int pRemainingLoopCount,
int pInitialLoopCount) {
}
public void onAnimationFrameChanged(
AnimatedSprite pAnimatedSprite,
int pOldFrameIndex,
int pNewFrameIndex) {
}
public void onAnimationFinished(
AnimatedSprite pAnimatedSprite) {
Player.sprite.animate(
new long[] { 100,
100, 100,
100, 100,
100, 100 },
0, 6, true);
}
});

android opengl GLUtil.texImage2d

i hava a bmp size =512*512,and now i want to use it to render a surface
since the surface is not plain, i cut the surface into small piece of rectangle(num = rowMax * colMax), the code like this:
draw(GL10 gl)
{
int[] textures = new int[];
gl.glBindTexture(...);
gl.glTxtParameterf(...);
for(int row =0; row< maxRow; row++)
{
for(int col=0; col<maxCol; col++
{
GLUtil.texImage2D(GL10.GL_TEXTURE_2D , bitmap,0 );// bitmap is the 512*512 bmp
//generate 4 point coordinate
...
//generate texture uv coordinate
...
//draw it
gl.glDrawArray(...);
}
}
}
it works fine.
but when i take the statement:
GLUtil.texImage2D(GL10.GL_TEXTURE_2D , bitmap,0 );
out of the loop,(since i think this may take a lot of time )
it doesn't work,i don't know w
}
Maybe I didn't understand the way your program works, but from what i understand you have num different textures that you need to draw.
Were you to take the texImage2D out of the loop, you would load just one texture instead of num texture so obviously that wouldn't work.
Another thing to know about open gl, is that you don't need to call GLUtil.texImage2D every time you draw, but only every time the texture changes.
Once you call texImage2D, the current state of bitmap is saved to the texture memory of the GL context, under the texture name you previously called glBindTexture(GL10.GL_TEXTURE_2D, /*texture name here*/) with, so next time you need to draw the texture, you only need to call glBindTexture with the name of the texture, and that's it, no costly operations needed.
What you should do is make it so that each texture's name (a unique integer to represent the texture) is it's position (=(row * maxCol) + col) + 1 (so that you don't have a texture named 0 (reserved texture name).
Also, you should create an array of booleans the size of num called mDirty, so that each cell is true when the texture corresponding to the position of the cell has changed and needs to be reloaded.
This way, you can in the loop just check whether mDirty[(row * maxCol) + col] == true, and if it is true, then call texImage2D, and set mDirty[(row * maxCol) + col] to false to indicate that the texture is updated in the gl memory.

Categories

Resources