5
\$\begingroup\$

Let me start with I am currently learning OpenGl-es using Android.

I have been having the hardest time trying to design a simple and logical way of making tiles (2d flat polygons). The tutorials tell me to just keep the polygon as a float array of veticies:

private float vertices[] = {
      -1.0f,  1.0f, 0.0f,  // 0, Top Left
      -1.0f, -1.0f, 0.0f,  // 1, Bottom Left
       1.0f, -1.0f, 0.0f,  // 2, Bottom Right
       1.0f,  1.0f, 0.0f,  // 3, Top Right
};

That in and of itself is easy enough. I modified the code to suit my desired polygon and it drew fantastic. Now I wanted to draw more tiles and have a scrolling feature (look around the world). But I'm not sure what's the best way to do so.

Should I leave every tile with a float array of indices and when it comes time to move the tile, directly modify thefloat values?

Is it a good idea to create an ArrayOfPoints (Point just being a container for exactly 3 float values) class to hold all of the points and then have methods that cycle through the points and change their values in a more safe fashion?

Does anyone have any tutorials on simple tile based map building so I can look at how they do their maps?

(Note: these questions are based on what I have read on animating. That is to say that you change the coordinates of the object in relation to the origin and leave the camera at 0,0,0. If it is more proper to just leave objects where they are, I guess my question loses value.)

\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

I've tried lots of variations myself; the recipe I've found best is:

Put any tile textures into a texture atlas. In this way, you can draw your whole map in a single draw-op because they are all using the same texture.

Mipmap the texture atlas, natuarally. For a large number of tiles you may spill over one texture 'page' in the atlas and it turns into multiple pages. If you keep that in mind, it won't be a big deal to retrofit support for pages if you need it.

If your tiles are a nice fixed size then just use the smallest non-float data-type for the vertex components for the points that you can e.g. bytes if the map is less than 256x256. Texture coordinates also help not being float.

Now build your map VBO using interleaved texture coordinates and vertices for a GL_TRIANGLE_STRIP array. I imagine that each vertex data starting on a nice 4-byte boundary is a good idea, but I have no empirical data to support that. Its just a hunch. Avoid element index arrays.

It depends on the camera position and such, but I found the best performance is to regenerate the tile array to draw all visible tiles each time the camera moves! This has, in my code, won more framerate than approaches of keeping all vertices GPU-side in blocks or such and issuing multiple calls to draw all the bits that are visible.

So what I normally do is, if the camera moves, compute the visible tiles and make an array of them, that I draw. Then if the next frame the camera hasn't moved, at that point promote it to be the vbo for subsequent frames until the camera moves again.

You could use gl_VertexID in the vertex shader to avoid needing x and z components for your vertices at all. (I haven't tried that, I've had problems with gl_VertexID on integrated Intel drivers on the desktop, stopping my cross-platform efforts in that direction. But on Android (Imagination/NVidia/Mali) devices it likely works well and is well worth the effort.)

If your map has varying heights then you have to have three components (or, with gl_VertexID, one) for the vertices but otherwise you don't need that y and then you don't need to track the normals per vertex either.

I rather hope someone weighs in with sounder advice to try something I haven't thought of myself, so as to improve my engine too ;)

\$\endgroup\$
2
  • \$\begingroup\$ Thank you for your detailed answer. It may take me a while to decipher it though. As I said just starting learning gl. But for the most part I kinda get what you're saying. \$\endgroup\$
    – ahodder
    Commented Sep 20, 2011 at 15:48
  • \$\begingroup\$ Here's the code to make a triangle strip to go around a cylinder: gamedev.stackexchange.com/questions/17214/… Now imagine you just laid that flat. The problem becomes going from the end of one line to the beginning of the next, and this can be done with a 'degenerate' triangle - a triangle where the three corners all lie on a straight line - the GPU will just ignore degenerate triangles. \$\endgroup\$
    – Will
    Commented Sep 20, 2011 at 16:39
1
\$\begingroup\$

Check out the open source Replica Island source code for a 2d grid to get ya started.

Do not modify vertices at runtime, build the entire level into a VBO when loading and draw using offsets based on camera position,

\$\endgroup\$
2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .