Skip to main content
spelling (frustum)
Source Link
sam hocevar
  • 24k
  • 2
  • 65
  • 95

For a 2D grid game, you can keep things pretty low key and still get very good performance.

There are a few ways you can go about things.

  1. Create a VBO and index buffer for each world piece. When you draw, draw all visible world pieces. Finding which ones are in your view rectangle should be easy, and if you have a lot loaded at once, using a quad-tree to organize the world pieces will help.

  2. Create a single streaming VBO, and fill it with cells each frame. Find the world pieces in the view frustrumfrustum, then clip their cells to the visible region, and copy the translated position and texture coordinates to the VBO and index buffer for rendering. This will probably be slower than option 1, but gives you some added flexibility.

  3. Same as 2, but use different VBOs and index buffers for different textures and shaders. You should minimize the number of each (ideally one shader and one texture), but if you need to use different materials to pull off the look you're going for, this is the way to go.

  4. Do the same as option 2 or 3, but use GPU instancing. This will let you get a bit closer to the efficiency of option 1 while retaining the added flexibility.

Of the four, option 1 is both the simplest and (in general) most efficient.

Also keep in mind that the size of your WorldPiece grids can have a big effect. You don't want them to be overly large. In a game I'm working on right now we have a similar setup to you. We found that using chunks that are approximately 1/2 the size of the visible screen worked fairly well. (32x32 tiles, in our case.)

When rendering, atlas your textures. As I mentioned above, you want as few draw calls as possible. That means as few state changes. A single WorldPiece should ideally require only a single texture that has all the tile data on it, and a single shader. Even if you strictly need more than one texture or shader, you want to keep the number small. If you have more than one, you want to use batch all the individual tiles that use the same texture and shader into a single draw call, so use option 2, 3, or 4.

For a 2D grid game, you can keep things pretty low key and still get very good performance.

There are a few ways you can go about things.

  1. Create a VBO and index buffer for each world piece. When you draw, draw all visible world pieces. Finding which ones are in your view rectangle should be easy, and if you have a lot loaded at once, using a quad-tree to organize the world pieces will help.

  2. Create a single streaming VBO, and fill it with cells each frame. Find the world pieces in the view frustrum, then clip their cells to the visible region, and copy the translated position and texture coordinates to the VBO and index buffer for rendering. This will probably be slower than option 1, but gives you some added flexibility.

  3. Same as 2, but use different VBOs and index buffers for different textures and shaders. You should minimize the number of each (ideally one shader and one texture), but if you need to use different materials to pull off the look you're going for, this is the way to go.

  4. Do the same as option 2 or 3, but use GPU instancing. This will let you get a bit closer to the efficiency of option 1 while retaining the added flexibility.

Of the four, option 1 is both the simplest and (in general) most efficient.

Also keep in mind that the size of your WorldPiece grids can have a big effect. You don't want them to be overly large. In a game I'm working on right now we have a similar setup to you. We found that using chunks that are approximately 1/2 the size of the visible screen worked fairly well. (32x32 tiles, in our case.)

When rendering, atlas your textures. As I mentioned above, you want as few draw calls as possible. That means as few state changes. A single WorldPiece should ideally require only a single texture that has all the tile data on it, and a single shader. Even if you strictly need more than one texture or shader, you want to keep the number small. If you have more than one, you want to use batch all the individual tiles that use the same texture and shader into a single draw call, so use option 2, 3, or 4.

For a 2D grid game, you can keep things pretty low key and still get very good performance.

There are a few ways you can go about things.

  1. Create a VBO and index buffer for each world piece. When you draw, draw all visible world pieces. Finding which ones are in your view rectangle should be easy, and if you have a lot loaded at once, using a quad-tree to organize the world pieces will help.

  2. Create a single streaming VBO, and fill it with cells each frame. Find the world pieces in the view frustum, then clip their cells to the visible region, and copy the translated position and texture coordinates to the VBO and index buffer for rendering. This will probably be slower than option 1, but gives you some added flexibility.

  3. Same as 2, but use different VBOs and index buffers for different textures and shaders. You should minimize the number of each (ideally one shader and one texture), but if you need to use different materials to pull off the look you're going for, this is the way to go.

  4. Do the same as option 2 or 3, but use GPU instancing. This will let you get a bit closer to the efficiency of option 1 while retaining the added flexibility.

Of the four, option 1 is both the simplest and (in general) most efficient.

Also keep in mind that the size of your WorldPiece grids can have a big effect. You don't want them to be overly large. In a game I'm working on right now we have a similar setup to you. We found that using chunks that are approximately 1/2 the size of the visible screen worked fairly well. (32x32 tiles, in our case.)

When rendering, atlas your textures. As I mentioned above, you want as few draw calls as possible. That means as few state changes. A single WorldPiece should ideally require only a single texture that has all the tile data on it, and a single shader. Even if you strictly need more than one texture or shader, you want to keep the number small. If you have more than one, you want to use batch all the individual tiles that use the same texture and shader into a single draw call, so use option 2, 3, or 4.

Source Link
Sean Middleditch
  • 42k
  • 4
  • 91
  • 133

For a 2D grid game, you can keep things pretty low key and still get very good performance.

There are a few ways you can go about things.

  1. Create a VBO and index buffer for each world piece. When you draw, draw all visible world pieces. Finding which ones are in your view rectangle should be easy, and if you have a lot loaded at once, using a quad-tree to organize the world pieces will help.

  2. Create a single streaming VBO, and fill it with cells each frame. Find the world pieces in the view frustrum, then clip their cells to the visible region, and copy the translated position and texture coordinates to the VBO and index buffer for rendering. This will probably be slower than option 1, but gives you some added flexibility.

  3. Same as 2, but use different VBOs and index buffers for different textures and shaders. You should minimize the number of each (ideally one shader and one texture), but if you need to use different materials to pull off the look you're going for, this is the way to go.

  4. Do the same as option 2 or 3, but use GPU instancing. This will let you get a bit closer to the efficiency of option 1 while retaining the added flexibility.

Of the four, option 1 is both the simplest and (in general) most efficient.

Also keep in mind that the size of your WorldPiece grids can have a big effect. You don't want them to be overly large. In a game I'm working on right now we have a similar setup to you. We found that using chunks that are approximately 1/2 the size of the visible screen worked fairly well. (32x32 tiles, in our case.)

When rendering, atlas your textures. As I mentioned above, you want as few draw calls as possible. That means as few state changes. A single WorldPiece should ideally require only a single texture that has all the tile data on it, and a single shader. Even if you strictly need more than one texture or shader, you want to keep the number small. If you have more than one, you want to use batch all the individual tiles that use the same texture and shader into a single draw call, so use option 2, 3, or 4.