Hi guys,
I am working a 2D tile based side scroller and attempting to use a texture atlas as suggested by many here to avoid multiple texture bind calls.
I was able to fix bleeding using half pixel correction using GL_NEAREST filtering, but I need a fix when using mipmaps. My issue is that my atlas is tightly packed 32x32 but I want my main character to be scaled to 48x48. When scaled (either up or down) it looks horrible when using GL_NEAREST so I decided to use mipmaps (GL_LINEAR_MIPMAP_LINEAR) which looks great, but breaks my fix for bleeding. All of my textures are POT btw.
I have tried google but can’t seem to find a fix. My relevent code is below and I would appreciate any suggestions.
Texture Loader:
public static Texture loadTexture(String pathToFile)
{
int width = 0;
int height = 0;
BufferedImage img;
int[] pixels = null;
int id = 0;
ByteBuffer bb = null;
InputStream is;
try
{
is = ResourceManager.class.getClassLoader().getResourceAsStream(pathToFile);
img = ImageIO.read(is);
width = img.getWidth();
height = img.getHeight();
pixels = img.getRGB(0, 0, width, height, null, 0, width);
is.close();
bb = BufferUtils.createByteBuffer((width * height) * 4);
id = glGenTextures();
} catch (IOException e)
{
System.out.println(e.getMessage());
System.exit(1);
}
for(int i=0; i<pixels.length; i++)
{
byte r = (byte) ((pixels[i] >> 16) & 0xFF);
byte g = (byte) ((pixels[i] >> 8) & 0xFF);
byte b = (byte) ((pixels[i]) & 0xFF);
byte a = (byte) ((pixels[i] >> 24) & 0xFF);
bb.put(r);
bb.put(g);
bb.put(b);
bb.put(a);
}
bb.flip();
glBindTexture(GL_TEXTURE_2D, id);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bb);
glBindTexture(GL_TEXTURE_2D, 0);
return new Texture(id,width,height);
}
SpriteSheet code:
public SpriteSheet(Texture texture, int tileSize)
{
this.texture = texture;
this.tileSize = tileSize;
// Figure out how many texture coordinates we will have
rows = texture.getHeight() / tileSize;
cols = texture.getWidth() / tileSize;
// Initialize the float buffers
textureCoordinates = new FloatBuffer[rows * cols];
vertexData = BufferUtils.createFloatBuffer(8);
vertexData.put(new float[] {0,0,tileSize,0,tileSize,tileSize,0,tileSize});
vertexData.flip();
// Calculate all the texture coordinates ahead of time
for(int i=0; i<rows; i++)
{
for(int j=0; j<cols; j++)
{
float srcX = j * tileSize;
float srcY = i * tileSize;
float u = (srcX + 0.5f) / texture.getWidth();
float v = (srcY + 0.5f) / texture.getHeight();
float u2 = (srcX + tileSize) / texture.getWidth();
float v2 = (srcY + tileSize) / texture.getHeight();
//displayPosX -= displayPosX%0.1f;
//displayPosY -= displayPosY%0.1f;
textureCoordinates[i * cols + j] = BufferUtils.createFloatBuffer(8);
textureCoordinates[i * cols + j].put(new float[] {u,v,u2,v,u2,v2,u,v2});
textureCoordinates[i * cols + j].flip();
}
}
}