Texture mapping into a tile

Hello everyone,

I’m stuck on this task and do not know how to resolve this. I need to draw tile-grid with textures, my world represents a tiled grid, where the width and height of each tile equal 1. When I drawing I calculate a vertex buffer which contains vertices of the tiles which are visible for the camera, like on the screen:

(so I have one VBO for all these vertices I do not have here any texture coords)
Also, I have an element buffer which contains indexes and I draw them using GL_TRIANGLE_STRIP mode:

Real result:

And on this step all work just fine, but next I need to map on each square his texture, which I receive from the web, all textures differents. How I can do it? I’m using OpenGL ES 2.0 and C++.

OK, what if I have in one VBO with all vertices needed to draw tile grid and also texture coords, but how then I can draw different textures? For example if I have 4 different separate textures, for each tile in tile grid when i will draw I can bind and have active only one texture per drawcall?

I can have one hardcoded VBO with tile vertices and texture vertices, and just draw each tile separately using model matrix OR I can have one VBO with all tile-grid vertices one VBO with hardcoded texture vertices and draw all them through glDrawElements with offset to map concerete texture to concrete tiles. But these approaches mostly similar and both don’t fit me, why? Because when I draw tiles and then zoom on the big zoom levels I begin to see that the tiles diverge between themselves, I think this is because floating points loss in precision. So I need to use GL_TRIANGLE_STRIP to have adjacent parties between tiles, but then I can’t draw them through glDrawElements with offset and OpenGL ES 2.0 dont have gl_VertexID, so I needed alternative for this, I think, but I don’t know how to implement it???

With ES 2.0 (and no extensions), the only options are to either:

  1. pack the textures into a texture atlas (i.e. a single texture where each individual texture occupies a rectangular “tile” within the atlas), or
  2. bind each texture to a separate texture image unit, have a sampler2D uniform for each one, and select the appropriate texture using mix, switch, ?: etc. Note that calling texture2D within non-uniform flow control results in undefined behaviour if the minification filter uses mipmaps.

The NV_texture_array extension provides an alternative to texture atlases, but I have no idea how widely supported it is.

Also, note that an M×N grid of tiles using a texture atlas requires 4×M×N vertices (i.e. each tile requires 4 distinct vertices), not (M+1)×(N+1), as vertices which share spatial coordinates typically don’t share texture coordinates. It has to be drawn using GL_TRIANGLES rather than GL_TRIANGLE_STRIP.

1 Like

So, even with a texture atlas I can’t use GL_TRIANGLE_STRIP? But then I will have the issue with gaps between tiles too?

You can’t have a texture seam (a discontinuity in the mapping) in the middle of a triangle strip. Well, not unless you introduce degenerate (zero-area) triangles, which largely defeats the point of using triangle strips. Aside from that, there really isn’t much of an advantage to using triangle strips with modern OpenGL. With glBegin/glEnd, it had the advantage of not having to repeat vertices. With glDrawElements it only reduces the size of the element array, which might have been an issue back when the element array was held in client memory and transferred for each draw call.

Only if you create such an issue. Tile gaps would only happen if the vertex positions on the edges between those triangles are not binary-identical values. So… make them identical. It isn’t hard; it gets done all the time.