How can I support scrolling when using batched rendering for my tiles?

I have tiled map 100*75 and tiles are 32*32 pixel.I want to use batching for performance .I don't figure it out , because of my game needs scrolling and every frame i draw 22*16 tiles (my screen is 20*16 tile) .I thought that batching tiles for every frame .Is it good or any suggestion?

edit :to more clarify I want to use occlusion culling and batching at the same time.I thought that drawing only visible areas and batching them together .But there is a something i couldn't figure out .When scrolling screen with translate matrix , if one row become invisible , I bind new row and batch them again.Every batched objects needs to buffer again.So I batch tiles and buffer to VBO every time when one row become invisible .I don't know these way is efficient or not .This is my question .And i am open to any suggestions.

• This depends entirely on the hardware and software you're using (and has almost nothing to do with game design). Please give more details of the platform you are working with. – Kylotan Aug 16 '11 at 16:42
• I assume he is using libgdx, it seems to be the standerd for android game devolpment. – Derek Nov 16 '11 at 15:00

4 Answers

to more clarify I want to use occlusion culling and batching at the same time.

Occlusion culling? You are drawing tiles, not 3D polygonal meshes. They're axis-aligned. It takes very simple math to know exactly which tiles are on-screen.

Plus, even for Android hardware, drawing a few things off-screen will do nothing to your performance. As long as you're using proper texture atlasing (no texture changes between tiles), you could probably just draw the entire 100x75 map every frame with no problems.

Batching means bundling stuff into a single draw call. And batching is at its most efficient when the batches are static: they don't change from frame to frame. If you have to rebuild your index list or add new vertices, you're batching wrong.

You didn't say what screen size you're rendering to, so I'll assume it's around 1024x768. If, and only if, you profile your application and detect that simply drawing the 100x75 map is too slow, you can break the map up into 32x32 segments. If one of these segments is on the screen, you draw it. Even if it's just one tile. That's the best way to avoid non-static batching.

Again, only bother to do this if you actually have a performance deficiency. As in, you ran it on the hardware of choice and it wasn't performing the way you wanted it to.

In my experience this is best solved by simply transforming the co-ordinates that you are about to draw by a scrolling amount (deviation from the starting point).

You mentioned in a reply to another answer that you are using OpenGl. You can use glTranslate to move objects in your scene.

glTranslate(x, y, z)


http://www.opengl.org/sdk/docs/man/xhtml/glTranslate.xml

I imagine you're drawing your tiles in a loop over a 2D array. So the code might look something like this:

glPushMatrix();
glTranslate(scrollX, scrollY, 0);

for (int i=0; i < array.size(); i++)
for (int j=0; i <array[i].size(); j++)
array[i][j].Draw();

glPopMatrix()


You can calculate the scroll value using the player/cursor position from the edges of the viewport. Note that this draws tiles that are off screen and might have a performance impact. You can perform culling by calculating the tile values that are visible and use those as bounds in your loop.

for (int i = leftValue; i <= rightValue; i++)


See this page on MSDN for some further information. It is the technique I described but for C# and XNA.

What tools are you using, what platforms do you intend to release for? Most probably it doesn't really matter how you do the drawing, unless you use some really obscure technique a modern computer should be plenty fast.

Try out your options, flicking together a benchmark to find out how fast the different options are shouldn't be too hard.

• I use opengl es 2.0 on Android platform . – dardanel Aug 16 '11 at 17:10

There are several solutions to this:

1. simplest solution: put all tiles into one big image. All drawing calls will reference this image and draw different parts of it. This can be executed in one batch. The image might get too big for the phone to handle or contain tiles which are only used in one level and waste memory.

2. defer the drawing to a renderer class: the renderer will sort all sprites by drawOrder then image. This will batch all draw calls using the same source image per drawing layer. Your scrolling algorithm just marks which sprites are visible.

3. Combine 1. and 2.: put tiles of the same drawing layer into one image file and then let the renderer draw per layer.