GL Texture Animation/Modification (aka destructible terrain)

Nibbie
Posts: 2
Joined: 2008.12
Post: #1
Hi,

I'm working with a few others on a game where we want to have destructible terrain. The "easy" way to do this in OGL ES is to modify the texture data, and call glTexSubImage2d every frame. However, this is slow.

We've tried various things:
1. Modify the data directly and recreate the texture. This is very slow (10-15 FPS)
2. Create explicit 32x32 tiles of textures, modifying the tile data and recreating it. With some smart selective drawing, we can achieve > 60 FPS.
3. Modify the data directly and blit it using glTexSubImage2d and give it only the modified parts. This is just as slow as (1).

The problem with 2 is that it becomes very difficult (and possibly slow) to just draw something onto the screen, because you'd have to draw on every tile the corresponding part, and the arrays are not laid out in a way that is conducive to doing this quickly and easily.

So overall, I have a couple of questions:
1. Is there a technique we didn't think about?
2. How would you do destructible terrain if the terrain was not uniform in shape or color (say the terrain was composed of a non-uniform image)?
3. If you had to implement a side scrolling game where the background was procedurally generated and you couldn't put it all into one texture, how would you do that?

Details are of course appreciated, but any answers are appreciated even more.

Thanks!
Quote this message in a reply
Sage
Posts: 1,234
Joined: 2002.10
Post: #2
There's no fast Tex(Sub)Image path on the phone, so you really just need to avoid submitting texture data per frame from the CPU.

On the other hand, if you can modify the data by rendering into the texture via FBO, that will be much faster, as you avoid the CPU upload path completely. That assumes you can modify the texture by rendering primitives into it, and not manipulating pixels directly, so it depends on the type of modifications you want to make.

For a side scrolling game, one way to do it is treat the playfield as a wraparound (torodial) quad:
Each frame, you render the newly exposed strip (or strips, if you can scroll diagonally) to the playfield via FBO. Then draw the entire playfield as two (or four, for diagonal scrolling) quads to the real view.

It's a little hard to explain this without a picture-- so, see my old TileScroller for an example.
Leopard has unfortunately broken the assumptions I made about NSImage, so the tileset is scrambled now. But if you press 'q' you can see the diagonals of the quads being drawn to the view. Press 'v' to see the offscreen playfield updating its strips each frame, at upper right.
Quote this message in a reply
Nibbie
Posts: 2
Joined: 2008.12
Post: #3
Thanks for the reply.

I think the FBO idea is a valid one, though I fear that you will lose a lot of dexterity in the types of animations you could make to the terrain. For example, to get "falling terrain" would not be easy, though not impossible, and you wouldn't be able to operate on a small pixel level anymore.

Let me give you a high level view of how I see your idea working:
1. You'd load your original terrain into a texture (say, for now, that it is completely flat).
2. You draw it onto the FBO.
3. You draw the FBO.
4. You have some event which causes some of the terrain to disappear.
5. You issue drawing commands that only draw part of the original texture onto the FBO. For example, render this 2d flat terrain with a semi-circular crater.
6. Go to (3).

Is this what you had in mind, or did I misunderstand?

Itay
Quote this message in a reply
Sage
Posts: 1,234
Joined: 2002.10
Post: #4
Yes, that's the general outline. Step 6 is the important one-- you want to optimize the drawing to only touch the newly exposed strip, or other parts of the terrain which are animating that frame (like exploding terrain.) And you need to draw everything in step 6 with primitives using textures already in VRAM.
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2008.10
Post: #5
Wouldn't a simple solution be to just load all the animation frames as seperate textures and then just use the texture you want? (Or less simpler - load the frames as one large texture and use a text pointer to pic what part to show)
Quote this message in a reply
Sage
Posts: 1,234
Joined: 2002.10
Post: #6
Simple <---> flexible.

The best way to implement this really depends on the type of procedural generation you want to do. For a scrolling terrain which is gradually destroyed (craters, cracks, fire, etc), updating an offscreen copy of the playfield using a tile atlas is fairly flexible, and fits within the hardware limitations.
Quote this message in a reply
Post Reply