tags:

views:

137

answers:

7

I want to make a game with Worms-like destructible terrain in 2D, using OpenGL.

  • What is the best approach for this?
    • Draw pixel per pixel? (Uh, not good?)
    • Have the world as a texture and manipulate it (is that possible?)

Thanks in advance

A: 

I think, but this is just a quick idea, that a good way might be to draw a Very Large Number of Lines.

I'm thinking that you represent the landscape as a bunch of line segments, for each column of the screen you have 0..n vertical lines, that make up the ground:

 12    789
0123  6789
0123456789
0123456789

In the above awesomeness, the column of "0":s makes up a single line, and so on. I didn't try to illustrate the case where a single pixel column has more than one line, since it's a bit hard in this coarse format.

I'm not sure this will be efficient, but it at least makes some sense since lines are an OpenGL primitive.

You can color and texture the lines by enabling texture-mapping and specifying the desired texture coordinates for each line segment.

unwind
But how would I add color/texture the terrain then?
Mrfrank
A: 

Typically the way I have seen it done is to have each entity be a textured quad, then update the texture for animation. For a destructible terrain it might be best to break the train into tiles then you only have to update the ones that have changed. Don't use GLdrawpixels it is probably the slowest approach possible (outside of reloading textures from disk every frame though it would be close.)

stonemetal
+2  A: 

I guess you'd better use texture-filled polygons with the correct mapping (a linear one that doesn't stretch the texture to use all the texels, but leaves the cropped areas out), and then reshape them as they get destroyed.

fortran
I have thought about this, altough it is crucial for me to be able to access and manipulate every pixel, that wouldn't be possible with the polygon approach
Mrfrank
It is, if you manipulate the edges with enough precission (nothing prevents you from putting as many vertices as pixel boundaries)... And if you do it well, you can even get your shapes drawn with anti-alias with little effort.
fortran
A: 

I'm assuming your problem will be to implement the collision between characters/weapons/terrain. As long as you aren't doing this on opengl es, you might be able to get away with using the stencil buffer to do per-pixel collision detection and have your terrain be a single modifyable texture.

This page will give an idea: http://kometbomb.net/2007/07/11/hardware-accelerated-2d-collision-detection-in-opengl/

Marc
Sorry but I'm not looking for help with collision detection, I didn't even mention it :o Thanks for your answer anyways though
Mrfrank
Hokay - sorry - I thought you were looking for a way to handle the terrain that you could easily use for the rest of the game too.You might want to look at this tutorial for writing to textures (so adding transparency sections for where the land gets taken away):http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=29
Marc
A: 

The way I imagine it is this:

  • a plane with the texture applied
  • a path( a vector of points/segments ) used for ground collisions.

When something explodes, you do a boolean operation (rectangle-circle) for the texture(revealing the background) and for the 'walkable' path.

What I'm trying to say is you do a geometric boolean operation and you use the result to update the texture(with an alpha mask or something) and update the data structure you use to keep track of the walkable area(which ever that might be).

Split things up, instead of relying only on gl draw methods

George Profenza
+7  A: 

Thinking about the way Worms terrain looked, I came up with this idea. But I'm not sure how you would implement it in OpenGL. It's more of a layered 2D drawing approach. I'm posting the idea anyway. I've emulated the approach using Paint.NET.

First, you have a background sky layer.

alt text

And you have a terrain layer.

alt text

The terrain layer is masked so the top portion isn't drawn. Draw the terrain layer on top of the sky layer to form the scene.

alt text

Now for the main idea. Any time there is an explosion or other terrain-deforming event, you draw a circle or other shape on the terrain layer, using the terrain layer itself as a drawing mask (so only the part of the circle that overlaps existing terrain is drawn), to wipe out part of the terrain. Use a transparent/mask-color brush for the fill and some color similar to the terrain for the thick pen.

alt text

You can repeat this process to add more deformations. You could keep this layer in memory and add deformations as they occur or you could even render them in memory each frame if there aren't too many deformations to render.

alt text

FogleBird
Very nice illustrations, helped me understand what you meant :) Thanks for the answer
Mrfrank
FogleBird
A: 

I think I would start by drawing the foreground into the stencil buffer so the stencil buffer is set to 1 bits anywhere there's foreground, and 0 elsewhere (where you want your sky to show).

Then to draw a frame, you draw your sky, enable the stencil buffer, and draw the foreground. For the initial frame (before any explosion has destroyed part of the foreground) the stencil buffer won't really be doing anything.

When you do have an explosion, however, you draw it to the stencil buffer (clearing the stencil buffer for that circle). Then you re-draw your data as before: draw the sky, enable the stencil buffer, and draw the foreground.

This lets you get the effect you want (the foreground disappears where desired) without having to modify the foreground texture at all. If you prefer not to use the stencil buffer, the alternative that seems obvious to me would be to enable blending, and just manipulate the alpha channel of your foreground texture -- set the alpha to 0 (transparent) where it's been affected by an explosion. IMO, the stencil buffer is a bit cleaner approach, but manipulating the alpha channel is pretty simple as well.

Jerry Coffin