Fouf
Fouf

Reputation: 591

Deformable terrain in OpenGL 2D [Worms like]

I've searched for a while and I've heard of different ways to do this, so I thought I'd come here and see what I should do,

From what I've gathered I should use.. glBitmap and 0s and 0xFF values in the array to make the terrain. Any input on this? I tried switching it to quads, but I'm not sure that is efficient and the way its meant to be done.

I want the terrain to be able to have tunnels, such as worms. 2 Dimensional.

Here is what I've tried so far,

I've tried to make a glBitmap, so..

pixels = pow(2 * radius, 2);
ras = new GLubyte[pixels];

and then set them all to 0xFF, and drew it using glBitmap(x, y, 0, 0, ras); This could be then checked for explosions and what not and whatever pixels could be set to zero. Is this a plausible approach? I'm not too good with opengl, can I put a texture on a glBitmap? From what I've seen it I don't think you can.

Upvotes: 4

Views: 1410

Answers (2)

rgngl
rgngl

Reputation: 5423

I would suggest you to use the stencil buffer. You mark destroyed parts of the terrain in the stencil buffer and then draw your terrain with stencil testing enabled with a simple quad without manually testing each pixel.

Upvotes: 3

Wyzard
Wyzard

Reputation: 34581

OK, this is a high-level overview, and I'm assuming you're familiar with OpenGL basics like buffer objects already. Let me know if something doesn't make sense or if you'd like more details.


The most common way to represent terrain in computer graphics is a heightfield: a grid of points that are spaced regularly on the X and Y axes, but whose Z (height) can vary. A heightfield can only have one Z value per (X,Y) grid point, so you can't have "overhangs" in the terrain, but it's usually sufficient anyway.

A simple way to draw a heightfield terrain is with a triangle strip (or quads, but they're deprecated). For simplicity, start in one corner and issue vertices in a zig-zag order down the column, then go back to the top and do the next column, and so on. There are optimizations that can be done for better performance, and more sophisticated ways of constructing the geometry for better appearance, but that'll get you started.

(I'm assuming a rectangular terrain here since that's how it's commonly done; if you really want a circle, you can substitute 𝑟 and 𝛩 for X and Y so you have a polar grid.)

The coordinates for each vertex will need to be stored in a buffer object, as usual. When you call glBufferData() to load the vertex data into the GPU, specify a usage parameter of either GL_STREAM_DRAW if the terrain will usually change from one frame to the next, or GL_DYNAMIC_DRAW if it will change often but not (close to) every frame. To change the terrain, call glBufferData() again to copy a different set of vertex data to the GPU.

For the vertex data itself, you can specify all three coordinates (X, Y, and Z) for each vertex; that's the simplest thing to do. Or, if you're using a recent enough GL version and you want to be sophisticated, you should be able to calculate the X and Y coordinates in the vertex shader using gl_VertexID and the dimensions of the grid (passed to the shader as a uniform value). That way, you only have to store the Z values in the buffer, which means less GPU memory and bandwidth consumed.

Upvotes: 3

Related Questions