Ideal use of SpriteBatches for tiles?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Dattorz
Citizen
Posts: 66
Joined: Sat Oct 27, 2012 12:32 am
Contact:

Ideal use of SpriteBatches for tiles?

Post by Dattorz »

So after roughly a year of working on other projects, I've decided to come back to my game engine project. Right now I'm doing code cleanup, API refactoring, and performance improvements, among other things. Currently I'm looking at what my system refers to as "Tilegrids". I wrote a simple test scene and noticed that, with an 800x600 window filled with 16x16px tiles (roughly 1800 tiles on-screen), I was getting draw timings around 5-6ms. This seemed... wrong to me. This sort of thing would limit the use of Tilegrids across multiple layers. I knew it wasn't fillrate-related since this GPU is pretty fast. I then realized that I wasn't using bind() and unbind() on my tilegrid SpriteBatch! Oops! Just by fixing that I was able to shave off a couple milliseconds. Nice.

I then started making other optimizations. I would only try to update the SpriteBatch when the tiles were "dirty" (when setTileValue() had been used before the current draw frame), or when the screen had scrolled enough that it needed to show different tiles. Next, if the number of rows and columns of visible tiles didn't change between frames, I would use SpriteBatch:set() instead of doing a clear() and add(). Now when you're sitting idle, the draw timings sit around 1ms, though as you scroll it pops up 1-2ms every several frames, depending on your movement. My concern is that this might create an unstable framerate on less powerful systems.

This is what the scene currently looks like:
Tilegrid test scene
Tilegrid test scene
klua_screenshot17.png (128.1 KiB) Viewed 1493 times
Now, my next idea is to use a grid of SpriteBatches (each batch having, say, a 20x20 array of tiles), covering the entire layer, pre-filled during initialization. This way, unless actual changes were being made to the tilegrid, there would be no need to constantly refill the SpriteBatches during scrolling. Instead, the system would just have to decide which SpriteBatches to draw.

My current (and somewhat extreme) test case is a 1000x1000 layer of tiles: 1 million tiles in all, spread out over 2500 SpriteBatches. Now my question is whether this would be too many SpriteBatches? Are there VRAM or driver performance issues with having this many batches stored? Is there some other way I should go about handling this? The more I look at existing engines, the more I realize that they use multiple static batches of geometry data to draw the levels.

For reference, here is my renderer info:
OpenGL | 3.3.0 NVIDIA 340.46 | NVIDIA Corporation | GeForce GTX 275/PCIe/SSE2
Post Reply

Who is online

Users browsing this forum: No registered users and 208 guests