so I'm doing lwjgl, so far I have the loading of 16x16 textures from a 256x256 spritesheet all working, using this code to get the location of the textures:

 public  Vector2f[] calculateUVMapping(int texture, int atlasWidth, int atlasHeight) {
    int textureIndex = texture;

    int u = textureIndex % atlasWidth;
    int v = textureIndex / atlasHeight;

    float xOffset = 1f / atlasWidth;
    float yOffset = 1f / atlasHeight;

    float uOffset = (u * xOffset);
    float vOffset = (v * yOffset);

    Vector2f[] UVList = new Vector2f[4];

    UVList[0] = new Vector2f(uOffset, vOffset); // 0,0
    UVList[1] = new Vector2f(uOffset, vOffset + yOffset); // 0,1
    UVList[2] = new Vector2f(uOffset + xOffset, vOffset + yOffset); // 1,1
    UVList[3] = new Vector2f(uOffset + xOffset, vOffset); // 1,0

    return UVList;

This takes the texture ID from left to right, top to bottom in the atlas, starting from 0 and the amount of textures the atlas holds, so to get the first texture in a 256x256 sheet (holds 16 textures in each row and column) I'd do calculateUVMapping(0,16,16), along with he corresponding endings for the vector and variable.

Now, say I want to have a 200x20 texture in another 256x256 sheet, or any nonsquare texture, actually, and I want to apply that to a quad- could this code work for getting the co-ords for it, or what code should I use for those?

  • \$\begingroup\$ Your code appears to be limited in that you're treating the texture as an index-based array of equally-sized sprites. Why not expect certain texture types to be in certain places and just ask for the type when retrieving texture coordinates? That's what Minecraft used to do, with mods simply scaling values to allow for higher-resolution textures. \$\endgroup\$ – fastinvsqrt Jul 31 '14 at 20:05
  • \$\begingroup\$ The code was originally meant for loading terrain textures, in a grid, that's why it does that :) How would doing the Minecraft method look like? \$\endgroup\$ – Rando Hinn Jul 31 '14 at 20:17
  • \$\begingroup\$ I know, but you asked if your code would work for what you were asking. It could, but only if all sprites in the texture were the same size. As for the Minecraft method, I have something similar to what I was describing here (that method plus the next two after it). \$\endgroup\$ – fastinvsqrt Jul 31 '14 at 20:54

Simply calculate UVs (0,0 point is left bottom, 1,1 point is right top) assuming you v got sprite texture dimensions sp in pixels just divide it by texture size:

SpriteDimensions sp; //that you must know

Vector2f[] UVList = new Vector2f[4];

UVList[0] = new Vector2f(sp.x / tex_width, sp.y / tex_height); // 0,0
UVList[1] = new Vector2f(sp.x / tex_width, (sp.y + sp.height) / tex_height); // 0,1
UVList[2] = new Vector2f((sp.x + sp.width) / tex_width, (sp.y + sp.height) / tex_height); // 1,1
UVList[3] = new Vector2f((sp.x + sp.width) / tex_width, sp.y / tex_height); // 1,0
  • \$\begingroup\$ sp values are the overall spritesheet values? \$\endgroup\$ – Rando Hinn Jul 31 '14 at 21:07
  • \$\begingroup\$ Coordinates (in pixels) of one "picture" in atlas. Example: "enemy1" at 100,200 and 50px wide and 100px high. You just have to know there to look for you data and pass it somehow. \$\endgroup\$ – wondra Jul 31 '14 at 21:17
  • \$\begingroup\$ Actually, wait.. doesn't work.. is the tex_width and tex_height the atlas size in px? \$\endgroup\$ – Rando Hinn Aug 1 '14 at 7:00
  • \$\begingroup\$ Yes, it is. Well, this was more illustration then real piece of code - it performs what is said in the first sentence. If you got a problem, it is most likely because of flipped Y axis. \$\endgroup\$ – wondra Aug 1 '14 at 7:03
  • \$\begingroup\$ Negative, I accidentally used int's in the SpriteDimension :D \$\endgroup\$ – Rando Hinn Aug 1 '14 at 7:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.