I will make the following assumptions (which can be relaxed but you'll get my drift) about your mesh and texture:
- they are both square shaped
- the mesh's extents in x and z range from 0 to TERRAIN_WIDTH (which is some positive integer, inclusive).
If the above assumptions hold, your texture coordinates for some vertex of your terrain mesh
v = (v_x, v_y, v_z)
is simply
texcoord = (v_x / TERRAIN_WIDTH, v_z / TERRAIN_WIDTH)
This texcoord is passed to your fragment shader and used for texture lookups. You can generate this texcoord directly inside your vertex shader using either a const value, or better, a uniform value.
uniform float TERRAIN_WIDTH; // or a less flexible const float TERRAIN_WIDTH;
uniform mat4 ModelViewProjection;
in vec4 Position; // x and z assumed to be in 0 .. TERRAIN_WIDTH (inclusive)
out vec2 TexCoord;
void main()
{
TexCoord = Position.xz / TERRAIN_WIDTH:
gl_Position = ModelViewProjection * Position;
}
Warning: Untested code!
EDIT: In regards to tiling: The above does still hold. However, TERRAIN_WIDTH should be replace with something like TILE_WIDTH. I still assume an overall square mesh and square tiles.
For instance, if you terrain has dimensions 256x256 and is made up of 4 tiles with dimensions 128x128, the texcoords for the vertex at (240, 0, 240) are computed as:
texcoord = (240 / TILE_WIDTH, 240 / TILE_WIDTH) = (240 / 128, 240 / 128) = (1.875, 1.875)
Using GL_REPEAT as the TEXTURE_WRAP_S and TEXTURE_WRAP_T mode (the default), the integer part (i.e. 1) will simply be ignored and the resulting texcoord is (0.875, 0.875).
You can see, this is again in [0, 1] and will lookup the same texel for (240, 0, 240) as for (112, 0, 112). Thus, you get your tiling effect using the same texture.
Note: For tiling to work visually, your texture need to be tiling as well or the illusion will literally burst at the seams. ;)