1
votes

I'm writing an lwjgl texture atlas for opengl, and my texture atlas creation works fine, but when I go to render it, the object shows up, but it is completely black. I think that this because my texture coordinates are in the empty section of my texture atlas. Since I haven't set up blending properly, and since the object is the first thing I render, the alpha becomes completely black. I know this because I rendered a test quad at 0,0,0 and could see the outline of the object. When I rendered them in the other order, the outline wasn't there, because that time the blending worked properly. Here is my texture coordinate shifting code to change the coordinates m_height and m_width are the height and width of the whole texture atlas and the x, y, w, and is the location, width, and height of the texture in the atlas, x, y are from the top left corner, and the texCoordinate2D is from the bottom left I believe, which is why I do the m_height-y-h. It works fine with a normal texture and not an atlas.

public TexCoordinate2D getTextureCoord(int x, int y, int w, int h,
                                       TexCoordinate2D coord) {
    int nx = x;
    int ny = (m_height - y) - h;
    //to fix m_repeat
    float cx = coord.getX();//going to fix repeat here
    float cy = coord.getY();
    int cpx = (int) (nx + (cx * w));
    int cpy = (int) (ny + (cy * h));
    float ncoordx =  cpx/(float) m_width;
    float ncoordy =  cpy/(float) m_height;
    System.out.println("Rect: " + x + " " + y + " " + w + " " + h);
    System.out.println("Coord: x: " + coord.getX() + " y: " + coord.getY());
    System.out.println("Coord--> pixel: x: " + cpx + " y: " + cpy);
    System.out.println("Pixel-->Coord: x: " + ncoordx + " y: " + ncoordy);
    TexCoordinate2D newCoord = new TexCoordinate2D(ncoordx, ncoordy);
    m_coordinates.add(newCoord);
    return newCoord;
}

Here is some printout

Rect: 0 0 512 512 #The rectangle from the top left corner of atlas
Coord: x: 0.5004405 y: 0.55040383 #The input coord from bottom left corner of texture
Coord--> pixel: x: 256 y: 3865 #The pixel location in the atlas of the input coord  the from bottom left corner
Pixel-->Coord: x: 0.0625 y: 0.9436035 #The coordinates in the atlas (The finished product)
Rect: 3072 0 256 256 #Starts again
Coord: x: 0.56088686 y: 0.5795429
Coord--> pixel: x: 3215 y: 3988
Pixel-->Coord: x: 0.7849121 y: 0.9736328
Rect: 2560 0 512 512
Coord: x: 0.18178056 y: 0.35738176
Coord--> pixel: x: 2653 y: 3766
Pixel-->Coord: x: 0.6477051 y: 0.9194336

So what is the bug?

1
I am having trouble verifying your texture coordinate math in this example, what resolution texture atlas are you using? - Andon M. Coleman
I am using a 4096x4096 texture, a huge one - Vastsuperking

1 Answers

1
votes

(0,0) is bottom left in OpenGL normalized texture coordinates and (1,1) is top right.

From your example output, I see:

Rect: 1024 0 512 512
Coord: x: 0.737651 y: 0.30223513
Coord--> pixel: x: 1401 y: 4249
Pixel-->Coord: x: 0.34212455 y: 1.0376068  (texture coordinates ?)

You are using texture coordinates in this example that are outside the normalized range. When this happens, the behaviour depends on the texture wrap state. The coordinates could simply be clamped, a border color might be used, the texture might repeat (default), mirroring might be used, etc.

Given the default texture wrap behaviour (repeat), your T coordinate of (1.0376068) essentially becomes (0.0376068). Texture wrapping in the context of a texture atlas rarely makes sense, so having coordinates that are out of range probably means you're doing something wrong :)

You also need to be aware that your texture coordinates need to be aligned to texel centers or nearby texels in your atlas may bleed when you sample from an off-center position. Since it's rarely possible to get every pixel on the screen to map to a texel center for anything but the simplest of geometry, the usual solution is to live with it... Place a border around each texture in the atlas so that even if the nearest texel is close to the edge of your texture, texture filtering never gets its hands on samples from adjacent textures.