Vertex Buffer Objects
A while back I posted on how I had been trying to use Vertex Buffer Objects with the tile map in Sir Lamorak’s Quest. Until recently everything was going really well and then I hit a snag.
Performance on the real device had been great but then all of a sudden dropped to 6fps. I spent ages trying to work out what I had changed and then realised that I had just populated the entire tile map with images. All tiles now had a image. On running some checks in instruments it was obvious that I was now maxing out the tile renderer :(
I ended up going back to my original tile map implementation which works fine again.
Having almost done that the VBO approach it was stuck in my head and I’m determined to get it working. What I’m working on now is implementing a mix of the two methods.
I am creating a single VBO for each layer in the tile map which is loaded with all the geometry and texture info for each tile. I was doing this before, but rather than just rendering the entire tile map layer as I was before, I am now using glDrawElements and creating a small array that points to the tiles that are actually visible on screen.
This looks to be working really really well. The performance is up on the original approach and I’ve not seen the slow down I had before.
Mike
Update 29/11/09: Whilst I am seeing some improvement by using VBOs for my tile map, VBOs don’t really work that well on anything pre 3Gs. The OpenGL ES driver still performs a copy when using them, rather than having them loaded into fast memory near the GPU where it stays without getting copied each frame. The 3Gs uses VBOs as you would expect. I like the idea of the VBOs automatically providing benefits on hardware that can use them correctly and I’ve not noticed any issues using them on pre-3Gs devices either.
P.S. The screenshot below shows Instruments running the OpenGL ES Instrument. When I talk about seeing if the Tile Renderer or Renderer in OpenGL ES are maxed out, it is this instrument that tells me. The shot below was taken whilst running Sir Lamorak’s Quest on an iPhone 3G, mid game with entities, particle emitters, tile map etc all rendering. You can see the two columns that show the Renderer and Tile Renderer usage. Tile Renderer is nice and low and I’m only pushing the renderer to around 70%. If this was always up near 100% then the renderer could be your bottle neck. Same with the Tile Renderer.
5 Comments
Flexicoder on November 29th, 2009
I’d be interested in knowing how you got your draw elements working with multiple textures. I draw a map with tiles, each tile has a different texture but I couldn’t get my head around draw elements as each point needs a unique texture reference? Although I feel that I just not understanding it!
mike on November 29th, 2009
Hi Chaps
I will be doing a post shortly on my final design for the tile map in Sir Lamorak’s Quest. I’m not going to have a chance to put it into a tutorial as it relies on many other elements in my game engine such as the Image class, SpriteSheet class etc, but I will be able to post about the design I’m using.
At a high level i am using basically the same tile map class that are in the tutorials. This creates a tile map for the tile images that are used. Once I have parsed the tile map and I know what tiles I have, I then create a VBO that contains an entry for every tile in a map layer. I have a separate VBO for each layer.
When I render, I then pass in the start tile position and how wide and high I want to render. This creates an array of indexes that represent the tiles I want to render in the VBO. I pass this list of indexes into glDrawElements and it just renders the tiles I am after.
This means I can calculate the VBO once at game load. This includes the geometry of each tile and the texture coordinates. Rather than ever changing the tilemap coordinates I simply perform a glTranslate after rendering the tilemap tiles. This then places the entities and player over the tile map I have rendered.
It’s hard to explain this quickly, but the blog entry will have more details.
Watch this space.
Mike
MrGando on November 29th, 2009
It would be awesome if you could show how did you noticed that the renderer was the bottle neck and not another part, using instruments. A screenshot may suffice :)
mike on November 29th, 2009
Hi MrGando
No problem at all. If you check the posting above I have edited it to include info on the Instrument I am using and a screen shot. Hope it helps.
Mike




Eugene on November 28th, 2009
Hi, Mike.
I hope you will show us your solution sooner or later. ;-)
I’m using a lot of code from your tutorials. So thanks for the tutorials, they are awesome.
In my game, at first, rendering was really straightforward. I was just creating every tile as an image and rendering it. It was not very efficient, so I’ve rolled my own Tile Map solution, based on .plist files. And gave my tiles some additional properties, CopyQty and CopyDirection. This step made my .plist file very small. Plus now I can use texture tiling by multiplying appropriate texture coordinate by CopyQty.
It gave me a 50 % fps boost on a really small two screen scene, with parallax scrolling, and 7 layers.
I wanted to try Texture Atlases, but then decided, not to waste time as now I’m satisfied with my game performance. The game is smooth and gives me 30-45 fps.
P.S.: Pardon me my english. =) I’m not a native speaker.