I'm working on a small tile/sprite-based PC game with a team of people, and we're running into performance issues. The last time I used OpenGL was around 2004, so I've been teaching myself how to use the core profile, and I'm finding myself a little confused.
I need to draw in the neighborhood of 250-750 48x48 tiles to the screen every frame, as well as maybe around 50 sprites. The tiles only change when a new level is loaded, and the sprites are changing all the time. Some of the tiles are made up of four 24x24 pieces, and most (but not all) of the sprites are the same size as the tiles. A lot of the tiles and sprites use alpha blending.
Right now I'm doing all of this in immediate mode, which I know is a bad idea. All the same, when one of our team members tries to run it, he gets very bad frame rates (~20-30 fps), and it's much worse when there are more tiles, especially when a lot of those tiles are the kind that are cut into pieces. This all makes me think that the problem is the number of draw calls being made.
I've thought of a few possible solutions to this, but I wanted to run them by some people who know what they're talking about so I don't waste my time on something stupid:
TILES:
- When a level is loaded, draw all the tiles once into a frame buffer attached to a big honking texture, and just draw a big rectangle with that texture on it every frame.
- Put all the tiles into a static vertex buffer when the level is loaded, and draw them that way. I don't know if there's a way to draw objects with different textures with a single call to glDrawElements, or if this is even something I'd want to do. Maybe just put all the tiles into a big giant texture and use funny texture coordinates in the VBO?
SPRITES:
- Draw each sprite with a separate call to glDrawElements. This seems to involve a lot of texture switching, which I'm told is bad. Are texture arrays maybe useful here?
- Use a dynamic VBO somehow. Same texture question as number 2 above.
- Point sprites? This is probably silly.
Are any of these ideas sensible? Is there a good implementation somewhere I could look over?