AndEngine Texture very strange - android

Does anyone know why this is happening?
Code to load image:
gameOverAtlas = new BuildableBitmapTextureAtlas(
activity.getTextureManager(), 1024, 1024,
TextureOptions.DEFAULT);
deathScreen1 = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(gameOverAtlas, activity,
"deathscreen1.png");
engine.getTextureManager().loadTexture(
this.gameOverAtlas);
engine.getTextureManager().loadTexture(
this.mAutoParallaxBackgroundTexture);
engine.getTextureManager().loadTexture(
this.gameOverAtlas);
try {
this.gameTextureAtlas
.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(
0, 1, 0));
this.gameTextureAtlas.load();
this.gameOverAtlas
.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(
0, 1, 0));
this.gameOverAtlas.load();
this.playerAtlas
.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(
0, 1, 0));
this.playerAtlas.load();
} catch (final TextureAtlasBuilderException e) {
Debug.e(e);
}
}
Then attaching the sprite:
gameOverScreen = new Sprite(0, 0, 650, 400, ResourceManager.getInstance().deathScreen1,vbom);
attachChild(gameOverScreen);
I get this error:

Looks like you are calling loadTexture before building the texture atlas.
move:
engine.getTextureManager().loadTexture(
this.gameOverAtlas);
engine.getTextureManager().loadTexture(
this.mAutoParallaxBackgroundTexture);
engine.getTextureManager().loadTexture(
this.gameOverAtlas);
after the try/Catch block.
Also if your texture is the same size as the dimensions of the TextureAltas it will fail unless you set the padding and spacing parameters to 0.
As an aside, if you are making a texture atlas that contains only a single texture region, there is no need to use a buildable texture atlas.
The special feature of the BuildableTexture atlas is that it will fit many regions for you into the atlas, meaning you do not need to use a program like TexturePacker and teh texturePacker extension for andengine.

Since its buildable texture, not normal one, you are loading it with bit different way
try
{
gameTexture.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 0, 1));
gameTexture.load();
}
catch (TextureAtlasBuilderException e)
{
Debug.e(e);
}
Keep in mind those 3 last parameters, you can control padding etc.

Related

OpenGL ES 2.0 render to framebuffer/texture results in black texture

I'm using libgdx but this is pretty much vanilla opengl es 2.0 stuff. Just try and ignore the Gdx.gl prefix everywhere ^^ I'm testing it on my desktop as well as android device and it's the same story in both cases.
I have the following code in my window resize event. It is supposed to delete the frame buffer and associated textures if they already were created, and then make some new ones the right size. I'm not sure if this is even correct to delete the textures and framebuffer like i am doing.
if (depthTexture >= 0)
{
Gdx.gl.glDeleteTexture(depthTexture);
depthTexture = -1;
}
if (colorTexture >= 0)
{
Gdx.gl.glDeleteTexture(colorTexture);
colorTexture = -1;
}
if (depthBuffer >= 0)
{
Gdx.gl.glDeleteFramebuffer(depthBuffer);
depthBuffer = -1;
}
IntBuffer intBuffer = BufferUtils.newIntBuffer(16); // See http://lwjgl.org/forum/index.php?topic=1314.0;wap2
intBuffer.clear();
Gdx.gl.glGenFramebuffers(1, intBuffer);
frameBuffer = intBuffer.get(0);
intBuffer.clear();
Gdx.gl.glGenTextures(1, intBuffer);
colorTexture = intBuffer.get(0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
Gdx.gl.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_RGBA, width, height
, 0, GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, null);
Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_NEAREST);
Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_NEAREST);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, 0);
intBuffer.clear();
Gdx.gl.glGenTextures(1, intBuffer);
depthTexture = intBuffer.get(0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
Gdx.gl.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_DEPTH_COMPONENT, width, height
, 0, GL20.GL_DEPTH_COMPONENT, GL20.GL_UNSIGNED_SHORT, null);
Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_NEAREST);
Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_NEAREST);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, 0);
Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, frameBuffer);
Gdx.gl.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER, GL20.GL_COLOR_ATTACHMENT0
, GL20.GL_TEXTURE_2D, colorTexture, 0);
Gdx.gl.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER, GL20.GL_DEPTH_ATTACHMENT
, GL20.GL_TEXTURE_2D, depthTexture, 0);
int status = Gdx.gl.glCheckFramebufferStatus(GL20.GL_FRAMEBUFFER);
if (status != GL20.GL_FRAMEBUFFER_COMPLETE)
{
System.out.println("frame buffer not complete. status " + Integer.toHexString(status));
System.exit(0);
}
Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, 0);
status = Gdx.gl.glCheckFramebufferStatus(GL20.GL_FRAMEBUFFER);
if (status != GL20.GL_FRAMEBUFFER_COMPLETE)
{
System.out.println("default buffer not complete. status " + Integer.toHexString(status));
System.exit(0);
}
I am not sure at all if i have made mistakes in setting up the render buffer or either the color texture or depth texture attachments. Anyway, on to the rendering loop
// update cameras and things
// setup rendering to off screen framebuffer
Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, frameBuffer);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
// draw things
// setup rendering to default framebuffer
Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, 0);
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
shader.begin();
// setup shader stuff
Gdx.gl.glActiveTexture(0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
shader.setUniformi("u_fbDepth", 0);
Gdx.gl.glActiveTexture(1);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
shader.setUniformi("u_fbColor", 1);
// draw things with shader
shader.end();
Again i am not sure i am setting things up the right way. The idea here is hopefully pretty clear. Render to the off screen frame buffer then use the depth and color textures from that frame buffer as textures to sample in the final shader that renders to the default framebuffer.
The depth and color textures that end up in my fragment shader are just empty however. Black screen. I know the fragment shader is not the problem - if i sample a different texture i see the texture as expected. I know that the drawing its self is not the problem - if i render what i would want to render to the off screen frame buffer directly to the default frame buffer i see what i expect.
I got it. There's a bit of a gotcha with setting active textures. The function glActiveTexture expects one of the GL_TEXTURE0 type constants, but the shader uniform just wants to be the integer in the constant name.
basically
Gdx.gl.glActiveTexture(0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
shader.setUniformi("u_fbDepth", 0);
Gdx.gl.glActiveTexture(1);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
shader.setUniformi("u_fbColor", 1);
needed to be
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
shader.setUniformi("u_fbDepth", 0);
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE1);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
shader.setUniformi("u_fbColor", 1);

Flickery Textures in andEngine

I'm having problems with my textures in andEngine
public void onCreateResources(
OnCreateResourcesCallback pOnCreateResourcesCallback)
throws Exception {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
mTextureAtlas = new BuildableBitmapTextureAtlas(getTextureManager(),
480, 800);
fruitTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(mTextureAtlas, this, "fruitsprites.png");
fruitBG = BitmapTextureAtlasTextureRegionFactory.createFromAsset(
mTextureAtlas, this, "gamebg.png");
try {
mTextureAtlas
.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(
0, 1, 1));
} catch (TextureAtlasBuilderException e) {
e.printStackTrace();
}
mTextureAtlas.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
// TODO Auto-generated method stub
}
This causes my whole texture atlas to appear on the screen; on my S4, the texture flickers continuously and the textures are upside down - it looks like the image was chopped up partially in a triangle.
On the emulator, the contents of the entire texture atlas is shown, the screen doesn't flicker, but the textures are upsidedown.
Also fruitBGSprite.setVisible(true); just makes the texture completely invisible (but the screen does not flicker)My goal right now is to set just 1 texture as my background.
create mTextureAtlas variable of ITexture class and fruitTextureRegion,fruitBG variables of ITextureRegion

Android draw texture extension drawing white textures

I started writing a game for Android using OpenGL-ES and just finished the draw code which uses the glDrawTexfOES extension. When I tested it on the emulator it works fine but testing it on my Samsung Galaxy S2 it seems all the textures are drawn white.
To make sure I didn't make any mistakes I copied the source from a tutorial and ran it with the same results. The tutorial code I am using can be seen here.
My textures are .PNG format and power of two and I am loading from the R.drawable folder although I have tried some other locations such as drawable-nodpi as I have seen suggested.
I have also checked the result of glGenTextures which I have read can give odd values for certain phones but seems to be giving the correct values (1,2,3..).
Does anybody know why this could be happening or suggest some other checks I can do to figure out what is going wrong?
Here is a slightly modified version of the example code I linked above to keep things simple.
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
gl10.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
// Set the background colour to black ( rgba ).
gl10.glClearColor(0.0f, 0.0f, 0.0f, 1);
// Enable Flat Shading.
gl10.glShadeModel(GL10.GL_FLAT);
// We don't need to worry about depth testing!
gl10.glDisable(GL10.GL_DEPTH_TEST);
// Set OpenGL to optimise for 2D Textures
gl10.glEnable(GL10.GL_TEXTURE_2D);
// Disable 3D specific features.
gl10.glDisable(GL10.GL_DITHER);
gl10.glDisable(GL10.GL_LIGHTING);
gl10.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);
// Initial clear of the screen.
gl10.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Test for draw texture
// Test for device specific extensions
String extensions = gl10.glGetString(GL10.GL_EXTENSIONS);
boolean drawTexture = extensions.contains("draw_texture");
Log.i("OpenGL Support - ver.:",
gl10.glGetString(GL10.GL_VERSION) + " renderer:" +
gl10.glGetString(GL10.GL_RENDERER) + " : " +
(drawTexture ? "good to go!" : "forget it!!"));
// LOAD TEXTURE
mTextureName = new int[1];
// Generate Texture ID
gl10.glGenTextures(1, mTextureName, 0);
assert gl10.glGetError() == GL10.GL_NO_ERROR;
// Bind texture id / target (we want 2D of course)
gl10.glBindTexture(GL10.GL_TEXTURE_2D, mTextureName[0]);
// Open and input stream and read the image
InputStream is = mContext.getResources().openRawResource(R.drawable.asteroid);
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(is);
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// Build our crop region to be the size of the bitmap (ie full image)
mCrop = new int[4];
mCrop[0] = 0;
mCrop[1] = imageHeight = bitmap.getHeight();
mCrop[2] = imageWidth = bitmap.getWidth();
mCrop[3] = -bitmap.getHeight();
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
assert gl10.glGetError() == GL10.GL_NO_ERROR;
bitmap.recycle();
}
public void onSurfaceChanged(GL10 gl10, int i, int i1) {
gl10.glViewport(0, 0, i, i1);
/*
* Set our projection matrix. This doesn't have to be done each time we
* draw, but usually a new projection needs to be set when the viewport
* is resized.
*/
float ratio = (float) i / i1;
gl10.glMatrixMode(GL10.GL_PROJECTION);
gl10.glLoadIdentity();
gl10.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
}
public void onDrawFrame(GL10 gl) {
// Just clear the screen and depth buffer.
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Begin drawing
//--------------
// These function calls can be experimented with for various effects such as transparency
// although certain functionality maybe device specific.
gl.glShadeModel(GL10.GL_FLAT);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
// Setup correct projection matrix
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glOrthof(0.0f, mWidth, 0.0f, mHeight, 0.0f, 1.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glEnable(GL10.GL_TEXTURE_2D);
// Draw all Textures
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureName[0]);
((GL11)gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, mCrop, 0);
((GL11Ext)gl).glDrawTexfOES(0, 0, 0, imageWidth, imageHeight);
// Finish drawing
gl.glDisable(GL10.GL_BLEND);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPopMatrix();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glPopMatrix();
}
Have you tried to have all the images on drawable-nodpi and nowhere else?
I don't think it may be important but try these lines just before attaching the rendering.
glSurfaceView.setZOrderOnTop(true);
glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
glSurfaceView.getHolder().setFormat(PixelFormat.RGBA_8888);
The error can be related with transparency and PNG format.
If it doesn't work, could you please paste the code related with GLSurfaceView and the Renderer?
Thanks!

How to load and draw texture correctly in OpenGLES with Mono for Android

I recently was porting my own 2D rendering engine to Android by using Mono for Android
Everything went well except I cannot draw the texture at all, all textures are looking like empty.
So I started a new clean project to test it, and I wrote it according to the sample code for java, what I found out is that I cannot draw the texture either.
Here is the code I used for testing:
class GLView1 : AndroidGameView
{
public GLView1(Context context)
: base(context)
{
this.GLContextVersion = OpenTK.Graphics.GLContextVersion.Gles1_1;
}
// This gets called when the drawing surface is ready
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// Run the render loop
Run();
}
bool initialized = false;
int[] textureID = new int[1];
// This gets called on each frame render
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
if (!initialized)
{
initialized = true;
GL.Enable(All.Texture2D);
GL.GenTextures(1, textureID);
GL.ShadeModel(All.Smooth);
GL.BindTexture(All.Texture2D, textureID[0]);
Bitmap bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.Icon);
Android.Opengl.GLUtils.TexImage2D(Android.Opengl.GLES10.GlTexture2d, 0, Android.Opengl.GLES10.GlRgba, bitmap, 0);
bitmap.Recycle();
GL.TexParameter(All.Texture2D, All.TextureMinFilter, (int)All.Nearest);
GL.TexParameter(All.Texture2D, All.TextureMagFilter, (int)All.Linear);
}
GL.ClearColor(0.5f, 0.5f, 0.5f, 1.0f);
GL.Clear((uint)All.ColorBufferBit);
GL.BindTexture(All.Texture2D, textureID[0]);
GL.EnableClientState(All.VertexArray);
GL.EnableClientState(All.TextureCoordArray);
GL.FrontFace(All.Cw);
GL.VertexPointer(2, All.Float, 0, square_vertices);
GL.TexCoordPointer(2, All.Float, 0, uv);
GL.DrawArrays(All.TriangleStrip, 0, 4);
SwapBuffers();
}
float[] uv ={
0,1,
0,0,
1,1,
1,0,
};
float[] square_vertices = {
-0.5f, -0.5f,
0.5f, -0.5f,
-0.5f, 0.5f,
0.5f, 0.5f,
};
byte[] square_colors = {
255, 255, 0, 255,
0, 255, 255, 255,
0, 0, 0, 0,
255, 0, 255, 255,
};
}
What I saw on my Android device is just a big white square.
PS: I tested it again with Android Emulator, and it seems this code works in android emulator, but on my real device it is still showing a big white square.
What am I doing wrong here?
It could be a problem with BitmapFactory.decodeResource(). I was getting the same issue, but when I use openRawResource() to open the resource as a stream and then use BitmapFactory.decodeStream() to load the bitmap then the textures suddenly appear.
Looking further at BitmapFactory.decodeResource(), it seems to scale based on the target device's pixel density. See this: http://blog.poweredbytoast.com/loading-opengl-textures-in-android
This would cause all your neat power-of-2-sized textures to be funny sized that the hardware acceleration doesn't recognise (the emulator doesn't care about non-power-of-2 sizes). So, use the code from the link above, copied here for your convenience:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inScaled = false;

My AndEngine onLoadResources() does not seem to be efficient

I'm using AndEngine to create a live wallpaper. However, in my onLoadResources() method I am currently loading 3 different textures:
#Override
public void onLoadResources() {
prefs = PhysicsWallpaperActivity.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
prefs.registerOnSharedPreferenceChangeListener(this);
this.mAutoParallaxBackgroundTexture = new BitmapTextureAtlas(2048, 2048, TextureOptions.DEFAULT);
this.mAutoParallaxImage1Texture = new BitmapTextureAtlas(2048, 2048, TextureOptions.DEFAULT);
this.mAutoParallaxImage2Texture = new BitmapTextureAtlas(2048, 2048, TextureOptions.DEFAULT);
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
this.mParallaxLayerBackground = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxBackgroundTexture, this, "background.jpg", 0, 0);
this.mParallaxLayerImage1 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxImage1Texture, this, "image1.jpg", 0, 0);
this.mParallaxLayerImage2 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxImage2Texture, this, "image2.png", 0, 800);
this.mEngine.getTextureManager().loadTexture(this.mAutoParallaxBackgroundTexture);
this.mEngine.getTextureManager().loadTexture(this.mAutoParallaxImage1Texture);
this.mEngine.getTextureManager().loadTexture(this.mAutoParallaxImag2Texture);
}
I feel like this is not the most efficient way to do this. But if I have all my BitmapTextureAtlasTextureRegionFactorys 'images' pointing to just a single BitmapTextureAtlas, and those 'images' are at the same coordinates, the images will load together on top of each other even if I only call 1 of them.
An example of the problem is here:
#Override
public void onLoadResources() {
prefs = PhysicsWallpaperActivity.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
prefs.registerOnSharedPreferenceChangeListener(this);
this.mAutoParallaxBackgroundTexture = new BitmapTextureAtlas(2048, 2048, TextureOptions.DEFAULT);
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
this.mParallaxLayerBackground = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxBackgroundTexture, this, "background.jpg", 0, 0);
this.mParallaxLayerImage1 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxBackgroundTexture, this, "image1.jpg", 0, 0;
this.mParallaxLayerImage2 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxBackgroundTexture, this, "image2.png", 0, 800);
this.mEngine.getTextureManager().loadTexture(this.mAutoParallaxBackgroundTexture);
}
^ I would have liked to use the code like this because it seems more efficient, but 'image1' and 'image2' automatically load on top of each other even if I only call 1 of them.
Am I doing this the right way? Or is there a more efficient way?
Your textures can contain more than one resource. Think of it like a sprite sheet. or like gluing photos to a big white sheet of paper. you do not need a new texture for each texture region. For example:
Say you have a star image, that is 250x250 pixels and a spaceship image that is 100x100 pixels. You could put both of these on a texture that measure 512x256.
You create a texture region for the star(250x250) at 0, 0.
Then create a second texture region for the spaceship at 251, 0.
In that scenario there is still some leftover area for other images blow the spaceship, if they are small enough to fit. The Image below shows how your texture would look if you could see it in memory.
Hope this helps.
Your Textures are huge! Are you very sure you need them that big?

Categories

Resources