2D layering in OpenGL

Any ideas on how to manage this system?

I triad incrementing a global z value by 0.0001 so that every time i rendered on object it would be put slightly in front all of the other objects but this doesn’t really work as the VBOs are generated once and then have to be fully recompiled to change their z value

So use a shader.
One that cuts off what you do not want to see.
Sorry, very hard to help you until you finally tell what kind of project you are working on.

The project that I’m working on is a tile based RPG game.

I’m not very confident using a shader at the moment, mainly cause i suck at GLSL, but also I would like to emulate some sort of layering system that’s reminiscent of the whole ‘last rendered is on top’ feature.

Effectively I guess what I’m asking is, whats the fastest way to render out a 16 * 16 area of tiles without rendering them all in the same VBO

If there are only 256 of them immediate mode is still fast enough…

Immediate mode is more than enough to render only 256 tiles. Sure, immediate mode is not great performance wise, but don’t let that fool you. It can still handle thousands of vertices. I don’t recommend using it, but it isn’t going to give you a weird disease or something if you do, so don’t be scared to use it for basic tasks. As for your issue, maybe use a vertex array? A batcher would be the best solution.

By some vague calculations i reckon i need to render around 4096 at once though :-.

This is really gonna bug me. I will think while I sleep tonight and see if I come up with anything.

Certainly and interesting problem though

16 x 16 = 256?
16 x 16 x 16 = 4096

Either way, it won’t be an issue. You are seriously underestimating the power of a modern day GPU. You can throw literally millions of vertices at a decent GPU, and it will perform fine. It all depends on how the developer optimizes the program, but that isn’t the point.

I imagine that each tile in your game has 4 vertices.

4 * 256 = 1024 vertices

That’s nothing.

I am passing 20k values each frame to the gpu and it works fine. Just code as simple as possible and ONLY care about faster ways AFTER you have performace-issues.
Prorgammers tend to write “perfectly-efficient” code but in most cases it doesn’t help. No one will care if he has 2000 or 500 fps. Even 60-100 are fast enough ;D
So for example in 2D:
Tile: 4 edges -> (8 position-coords + 8 uv-coords) + (6 indices) ->22 values.
500 Tiles -> 11k values to pass to the gpu. On modern computers it shouldn’t be a problem. Of course if the tilemap is static you could use some vertex-buffer.

Surely generating a vbo for each individually tile is still quicker though?

The advantage of VBOs and ArrayLists is that there are less direct calls of the vertex function but every vertex position is already stored.
If there are not very much vertices, you could also use these vertex function, immediate mode.
Using so many VBOs might be even much slower since all the buffers have to be called separate.

Ok thanks :smiley:

I will try implementing this now and will report back on how I get on

Having switched to immediate mode, I’ve dropped from around 150fps to 100fps. It would seem in this case an individual VBO for each tile is the most viable option here.

I think, as layering only takes place on the y axis, I will give each row of tiles its own VBO to be rendered on as this seems the most efficient

EDIT

Upon reflection, a depth based management system does seems like a lot of work here but after a bit of thinking, I reckon i might give this a go, giving gui elements and world elements there own individual depth layers

I haven’t been tagging along this thread, but VBO for each tile is nonsense… VBOs are made to contain huge amount of info…

You might as well use immediate mode if you create VBO for each tile.

The way to use VBO is to do something like render certain part of the map into VBO (I don’t really mean render, put it into VBO) and render(really render it now) VBO at an offset. Reload VBO after half a second or something like that, or if you need force edit it if something like high distance TP happens.
This method has some draw backs: while it should be really fast, you need additional handling of when you might want to re-put stuff into VBO (player changes tile, player teleports to other location on the map). It also is lot harder to implement :stuck_out_tongue: Didn’t try it yet, but seems to work in theory for me and I think it should work in practice.

Hi appreciate your response and I do realize how absurd it really is to use one VBO for each tile ;D

I appreciate you said you weren’t following this thread but the main issue I’m having, is in a large VBO there is no easy way of layering it with other objects outside the VBO.

For example, usually I would write the code like this without VBOs


		for (int y = chunkH - 1; y >= 0; y--) {
			for (int x = chunkW - 1; x >= 0; x--) {
				//render tiles at coordinate
			}
			for (int x = chunkW - 1; x >= 0; x--) {
				//render entites in tiles at coordinate
			}
		}

This meant that all entities were rendered on top of the necessary tiles and behind the tiles that they shouldn’t be in front of.

The issue with a big VBO for each chunk of tiles, is that I can’t correctly render the entities layered with the tiles.

By my reckoning the only real way to make this work properly is to enable depth testing and use z values the layer things but this is difficult due to a number of issues:

  • Each tile needs to be rendered on a different z value
  • Each entity needs to rendered on a different z value
  • Each entity is made up of multiple body parts so those body parts will also need to be layered correctly and rendered on different z values
  • I also need to have GUI objects rendered on certain layers, but on top of the main world

Ahhh I see :slight_smile:

But I don’t really think that would be really hard to implement… Why would that be hard ? :stuck_out_tongue:

You could have a system something like 10 layers. Layer 10 would be furthest away from the screen. It would contain tiles for example.
Layer 9 could be for all entities.
Layer 8 could be for tiles that need to be rendered on top of entities.

Each layer could have like 10 sub-layers. So in all, you would have 100 layers, but would be dealing with 10 at a time! :smiley:

I probably don’t understand the issue, since I cannot see the thing you want to make. Could you show some game that your game reminds?

I appreciate creating 10 layers would be easy but…

As I mentioned, I need to render each individual body part of each entity on the correct layer which means with a large amounts of entities i need a more dynamic range of layers so instead of having layers 1, 2, 3, 4 etc. I have an each individual z value for each object

Using immediate mode you can completely ignore depth testing.
Just draw lower sprites first and higher ones later exactly like in Java2D.

I think however, although 100 fps is manageable at the moment, in future, the efficiency of that rendering won’t be good enough

Even 50 fps are still not really perceptible. Or 30.
You gave still no very useful information what you are doing.

Realistically speaking, 50 - 30 fps is not really anywhere near good enough for a 2d game :-\