CPatton
CPatton

Reputation: 63

Computing texture coordinates for a single tile with a texture atlas in OpenGL

I'm trying to use a texture atlas in a game program I'm writing in C#/OpenGl with the OpenTK library.

I loaded my texture atlas as a texture in OpenGL (dimension is 256x256) and each tile is 32x32.

To get the first tile of the atlas to display, I used this code:

GL.Begin(BeginMode.Quads);
GL.TexCoord2(0, 0); GL.Vertex2(0, 0);
GL.TexCoord2(0.125f, 0); GL.Vertex2((32 * zoom), 0);
GL.TexCoord2(0.125f, 0.125f); GL.Vertex2((32 * zoom), (32 * zoom));
GL.TexCoord2(0, 0.125f); GL.Vertex2(0, (32 * zoom));
GL.End();

0.125 was computed by dividing 1/8, 8 being the number of tiles in a row/column.

I've got no idea how to compute the second tile's coordinates this way! I tried using 0.125 and 0.25 in place of 0 and 0.125 respectively, but this renders nothing. I'm guessing you aren't allowed to use a value greater than zero for (EDIT)the first (0) texture coordinates?

If anyone could help or provide a better way of doing this, it would be much appreciated!

Upvotes: 3

Views: 1819

Answers (3)

The texture coordinates are between 0 and 1. Imagine it as a translation of your grid of tiles but instead of each being 32x32, they are 0.125fx0.125f. Also, 256/8 = 32. You got the number by doing 32/256.

To get the second tile (assuming you're going across horizontally) you need to shift (ie. add 0.125f) to your texture coordinates x values. Example:

GL.TexCoord2(0.125f, 0); GL.Vertex2(0, 0);
GL.TexCoord2(0.25f, 0); GL.Vertex2((32 * zoom), 0);
GL.TexCoord2(0.25f, 0.125f); GL.Vertex2((32 * zoom), (32 * zoom));
GL.TexCoord2(0.125f, 0.125f); GL.Vertex2(0, (32 * zoom));

Upvotes: 0

sharoz
sharoz

Reputation: 6345

  1. Get rid of the "* zoom". Just place a call to gl.scale(zoom,zoom,1) before gl.begin.
  2. look through the 8x8 tiles in a nested loop like this:

    GL.Scale(zoom*32,zoom*32,1);
    GL.Begin(BeginMode.Quads);
    for (int i=0; i<8; i++)
    for (int j=0; j<8; j++)
    {
    var x = i/8.0; // texture scale
    var y = j/8.0;
    GL.TexCoord2(x, y); GL.Vertex2(i, j);
    GL.TexCoord2(x+0.125f, y); GL.Vertex2(i+1, j);
    GL.TexCoord2(x+0.125f, y+0.125f); GL.Vertex2(i+1, j+1);
    GL.TexCoord2(x, y+0.125f); GL.Vertex2(i, j+1);
    }
    GL.End();
    GL.Scale(1.0/(zoom*32),1.0/(zoom*32),1); // unzoom

Upvotes: 1

genpfault
genpfault

Reputation: 52166

Give this a shot:

int col = 0;
int row = 0;
float tex_w = 256;
float tex_h = 256;
float tile_w = 32;
float tile_h = 32;
float w_factor = tile_w / tex_w;
float h_factor = tile_h / tex_h;

float x_tex_beg = w_factor*(col+0);
float x_tex_end = w_factor*(col+1);
float y_tex_beg = h_factor*(row+0);
float y_tex_end = h_factor*(row+1);

Upvotes: 2

Related Questions