opengl 2D texture problem

Started by
8 comments, last by reinac 12 years, 4 months ago
Hy guys!

I have a big problem I can not solve.

I have a list of Items which I draw with the same texture (bitmap). When I render it the first time, it is all fine but if I render more items , the texture of my new item does not look like the texture from the first one, while it should be the same texture !?

Maybe you know my problem?

Please tell me if I should post some code or pictures of my problem. smile.png

reimac
Advertisement
You should definitely post some code and pictures if possible. At the moment it sounds as if you might upload your texture multiple times and the buffer you reference is too small that might be causing memory corruption or you might be referencing the wrong texture later or ... I could go on, but these are quite random guesses and most likely won't help you. So yes, code is needed.
Thanks for the fast reply! :)

I can upload a picture tomorrow. I copied some parts of the code which could be the cause of my probs?!

in the item class i move and draw it


@Override
public void Draw(GL10 gl)
{
// move basket
move(gl);

// enable use of textures
gl.glEnable(GL10.GL_TEXTURE_2D);
// bind texture pointer to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, iar_textures[0]);

// enabled vertex buffer for writing and to be used during rendering
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// enable the use of UV coordinates
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

// specifies location and data format of array of vertex coordinates to use when rendering
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
// Point to our texture buffer and where our UV coordinates are
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

// draw vertices
gl.glDrawElements(GL10.GL_TRIANGLES, sar_Indices.length,
GL10.GL_UNSIGNED_SHORT, indexBuffer);

// disable the vertex buffer
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
// disable the use of UV coordinates
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

// disable use of textures
gl.glDisable(GL10.GL_TEXTURE_2D);
}

/**
* move item
*
* @param gl gl10 reference
*/
private void move(GL10 gl)
{
// translate position
gl.glTranslatef(f_posX, f_posY, 0f);

// calculate new y position
f_posY = GamePhysics.MoveY(-1, 20f, f_posY);
}


And in my ItemManager Class I loop through the arraylist, which contains all items


// loop through items array
for(int i = 0; i < items.size(); i++)
{
// save current matrix
gl.glPushMatrix();
// draw item on position i
items.get(i).Draw(gl);
// restore the last matrix
gl.glPopMatrix();
}


thx
Maybe , because I use the same bitmap for all items as texture? Because at debugging mode I can see that each item has the same bitmap id?!

Ok I think this produces my error!

I had a TextureManager class which loads all my textures in a bitmap array at program start!

Each item has to get his texture with this method


public static Bitmap GetTexture(int textureId)
{
// extract texture and return it
return textures[textureId];
}


Now I changed the method, so that only a copy is returned, not the source bitmap.


public static Bitmap GetTexture(int textureId)
{
// extract texture and return it
return textures[textureId].copy(Bitmap.Config.RGB_565, true);
}


Now there are no troubles, but are there other solutions?!
Yes, different textures should have different textureID-s passed to glBindTexture, if that's what you mean. You seem to be using OpenGL ES and developing for Android and I'm not exactly familiar with it. I would guess that you'd still have to call glGenTextures first to generate texture ID's and then upload each texture bitmap to GPU. On Android it may be with GLUtils.texImage2D, but that's just a guess.

I doubt even on Android a bitmap copy would be needed as normally uploading to GPU creates another copy anyway so the problem might be instead that wrong textureId is passed to GetTexture, wrong textureID is used later when accessing already uploaded GPU textures or that textures are uploaded more than once and original texture has become corrupt in the meantime.

If you could tell what does iar_textures contain (where and how is it created and filled with data) and how do you upload the textures then maybe I could come up with a better guess.
iar_textures is used for storing the generated texture from gl.glGenTextures.

I have an abstract class called DrawableObject. The Item class extends it.

Here are some parts of the DrawableObject class


public DrawableObject(GL10 gl, int textureId, float startPosX, float startPosY,
float width, float height)
{
// set starting position
this.f_posX = startPosX;
this.f_posY = startPosY;
// set bounding
this.f_width = width;
this.f_height = height;

// load bitmap texture
bitmap = TextureManager.GetTexture(textureId);

// load and initialize texture
loadTexture(gl);

// initialize objects structure (vertices, texture)
Initialize();
// allocate needed memory
allocateMemory();
}

/**
* load and set up texture
*
* @param gl gl10 reference
*/
private void loadTexture(GL10 gl)
{
// generate one texture
gl.glGenTextures(1, iar_textures, 0);
// tell opengl where our texture is located
gl.glBindTexture(GL10.GL_TEXTURE_2D, iar_textures[0]);

// create nearest filtered texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

// set up texture behavior not to be repeated
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

// bind loaded bitmap to created texture id
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

// clean up resources
bitmap.recycle();
}

You are recycling the bitmap in loadTexture method. Did you have it there before you added returning copy of the bitmap not the original bitmap from TextureManager.GetTexture? It would clear the bitmap and next time GetTexture with same id would have returned a recycled bitmap. Maybe that was the problem?
Hi.!

Sorry but I can't follow what you mean.

Did you mean if I added the bitmap.recycle()?! If that was the question, no I only changed the GetTexture(..) method.
Yes, that's what I meant. I think that if you remove the bitmap.recycle() method then you can probably use the original version of bitmap:

public static Bitmap GetTexture(int textureId)
{
// extract texture and return it
return textures[textureId];
}
ok, apparently this was the prob. Thanks !!! :)

Now I can work with the source image file. But is it ok to leave the bitmap.recycle statement?! Or is it possible that I will run in some memory problems if I don't recycle.
What is the exact purpose of it?

This topic is closed to new replies.

Advertisement