5

I am writing a small app that at the moment generates a random map of textures.

I am drawing this map as a 10 x 15 group of "quads" which are infact all triangle strips. I use the "map" to grab an int which I then take as the location of the texture for this square in the textureAtlas. so for example 0 is the bottom left "tile". The atlas is 128 x 128 and split into 32 pixel tiles.

However I seem to be getting some odd artifacts where the texture from the one tile is creeping in to the next tile. I wondered if it was the image itself but as far as I can tell the pixels are exactly where they should be. I then looked at the texture coords I was specifying but they all look exact (0.0, 0.25, 0.5, 0.75, 1.0 - splitting it into the 4 rows and columns I would expect).

The odd thing is if I run it on the emulator I do not get any artifacts.

Is there a setting I am missing which would cause bleeding of 1 pixel? It seemed to only be vertical too - this could be related to on the phone I am "stretching" the image in that direction as the phone's screen is larger than normal in that direction.

I load the texture like so:

//Get a new ID
    int id = newTextureID(gl);

    //We will need to flip the texture vertically
    Matrix flip = new Matrix();
    flip.postScale(1f, -1f);

    //Load up and flip the texture
    Bitmap temp = BitmapFactory.decodeResource(context.getResources(), resource);

    //Store the widths for the texturemap
    int width = temp.getWidth();
    int height = temp.getHeight();
    Bitmap bmp = Bitmap.createBitmap(temp, 0, 0, width, height, flip, true);
    temp.recycle();

    //Bind
    gl.glBindTexture(GL10.GL_TEXTURE_2D, id);

    //Set params
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR);

    //Push onto the GPU
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);

    TextureAtlas atlas = new TextureAtlas(id, width, height, tileSize);
    return atlas;

I then render it like so:

gl.glBindTexture(GL10.GL_TEXTURE_2D, currentAtlas.textureID);
    //Enable the vertices buffer for writing and to be used during our rendering
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    //Specify the location and data format of an array of vertex coordinates to use
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

    //Enable the texture buffer
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
    gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer);

I would take a picture, but I am unsure how to get a screen cap from the phone...

If anyone knows of how I can capture the current frame and perhaps put it out into a file I will do that if it helps explain what is going on!

Look forward to your response.

Edit: Here is a screencap - note I run the app in landscape but cap is in portrait. Also excuse the horrible textures :D they were merely a place holder / messing around.

ScreenCap

iexus
  • 677
  • 11
  • 26
  • While I can't help you with the issue, you can use the program `ddms` in the tools directory of the SDK to take a screenshot of the device (ctrl-s). – richq Oct 18 '10 at 19:11
  • Thank you! I knew there must be a manner by which people did it. Looks like a generally useful tool too. – iexus Oct 18 '10 at 19:14

1 Answers1

11

Well, after speaking to a friend I managed to solve this little problem.

It turns out that if you wish to have exact pixel perfect textures you have to specify the edge of the texture to be halfway into the pixel.

To do this I simply added half a pixel or subtracted half a pixel to the measurement for the texture coords.

Like so:

//Top Left
            textureCoords[textPlace] = xAdjust*currentAtlas.texSpaceWidth + currentAtlas.halfPixelAdjust;        textPlace++;
            textureCoords[textPlace] = (yAdjust+1)*currentAtlas.texSpaceHeight - currentAtlas.halfPixelAdjust;    textPlace++;

This was simply calculated when loading the texture atlas:

(float)(0.5 * ((1.0f / numberOfTilesInAtlasRow) / pixelsPerTile));

Although if the height was different to the width of each tile (which could happen) you would need to calculate them individually.

This has solved all the artifacts so I can continue on. Hope it helps someone else!

iexus
  • 677
  • 11
  • 26
  • hi. can u explain in more details? I do not understand how to apply these formulas to my atlas.vAs i c for non tiled atlas xAdjust it is x shift to sprite in atlas. But why i should multiply it to atlas witdh. Are they in pixels? thanks. – Sergey Kopanev Apr 28 '12 at 08:43
  • This worked great for me, though I still had some problems with the lines when rendering far away and using mipmapping. – Thane Brimhall Jul 16 '13 at 15:35