This is a short tutorial about how to make 2D destructible terrain similar to old Worms games. This technique uses Box2D and Clipper libraries. I wont explain the code, just the general idea.
1. Make Box2D bodies with chain fixtures that would match "collidable" areas on the background image:
2. During the game when a bullet hits the destructible terrain I just make a circular polygon(explosion), then take the vertices that define the terrain and do polygon clipping using Clipper. In Clipper Execute method I use ctDifference as clipType to get vertices outside the circle. Each path in the solution holds vertices that I use to define new Box2D chain fixtures, while the previous ones are destroyed. And that is basically it.
There are several reasons why I use chains instead of polygons:
a) Box2D only supports convex polygons and chains can have any (non intersecting) shape.
b) By default Box2D polygons can have up to 8 vertices. Even though that can be increased, there is still an issue with a).
c) You could use polygon triangulation(Poly2Tri or Polypartition library) on non-convex(concave) polygons, but then every time you do it the number of fixtures in the scene will increase and you will end up with hundreds of tiny fixtures. Another problem with polygon triangulation is that it can make polygons with sharp edges and the player could get stuck on those, just like he can get stuck on tiny fixtures.
But there is a problem with chains too, they are hollow. If the player is right next to the terrain and his weapon barrel is inside it you can fire a bullet inside the terrain and it will collide only when it reaches the other side of the chain fixture. A solution for that is that when generating new terrain, you create both chains and polygons using triangulation, but you set the collision filters so that the player only collides with the chains(so he doesn't get stuck) and bullets collide with the polygons(so they don't pass trough).
a) The "collidable" area/texture is rendered on a FBO which supports alpha channel.
b) When bullet hits the terrain I draw a circular polygon with an alpha value of 0 to that FBO on the location of the bullet. Using glBlendFunc(GL_SRC_ALPHA,GL_SRC_ALPHA) this makes holes in the texture.
c) I also render another, a bit bigger, circle on another FBO of the same size to make those explosion outlines.
d) Then, using multitexturing and a shader, I combine the collision FBO with the explosion outline FBO, to render those outlines only there where is visible pixels on the collison texture and outline texture, else I render pixels from collision FBO.
a) b) c) d)
uniform sampler2D img;
uniform sampler2D img2;
varying vec2 texcoord;
vec4 texcolor = texture2D(img,texcoord);
vec4 texcolor2 = texture2D(img2,texcoord);
if(texcolor.a!=0 && texcolor2.a!=0) gl_FragColor = texcolor2;
else gl_FragColor = texcolor;
The end result is rendered on screen:
How to run an example?ReplyDelete
Error inicialized FMOD audio system!
windows 7 x64
BMUG engine started.
Engine object created.
Game preload finished.
SDL video mode initialized.
OpenGL version: 3.3.0
Window handle found.
Audio manager deleted.
Input manager deleted.
Texture manager deleted.
Font manager deleted.
GUI manager deleted.
Skeleton manager deleted.
Animation manager deleted.
Particle manager deleted.
BMUG engine shut down.
Hi, for some reason the audio system fails to initialize and the game shuts down. Unfortunately I don't know why, you are the first one who actually tried to run this and reported back. Could you try downloading the newest version of the engine http://antonior-software.blogspot.com/2014/12/broken-mug-engine-2d-ragdoll-physics.html If this one fails too, I will try to see if I could get FMOD write down a more detailed error message.Delete
I have that error too, in my computer is not have audio device out put. It seems that the problem is causing the errorDelete
Very interesting work that you've done there. Would it be possible to get hold of source for this solely for my own educational purpose?ReplyDelete
Thanks. The problem is that this was only a proof of concept, and was hacked in to my existing code, so I can make a video showing it. I don't have the working code anymore.Delete
Hi, I'm having problems with Rendering. Do I get it right that the FBO "only" works as a data storage and is not cleared every frame?ReplyDelete
That is correct.Delete
what does FBO mean? could you give me any information about this?Delete
FBO stands for "framebuffer object". It enables you to render things on a texture, instead of rendering directly on the screen.Delete
Thanks for your fast reply!ReplyDelete
By "FBO which supports alpha channel" do you mean that the texture in COLOR_ATTACHMENT_0 has to be created with format GL_RGBA ?
I use GL_RGBA when I create a texture using glTexImage2D()then I attach that texture to a framebuffer object using glFramebufferTexture2D(). Here is my code: https://pastebin.com/d8Q6VkPTDelete
Awesome, thank you!Delete
Now lets see if I can get it to render..
unfortunately I am not able to render the content of my texture buffer. I was just thinking to ask a question on StackOverflow, but before that I wanted to ask if there is any chance to look into some of your rendering code?
Thanks for your help!
I don't have a clean piece of code that I could send you, so you could understand it. I think it would be best you make that topic on StackOverflow, show your own code and explain what you are doing, then I can look it up there. You could send me an email when you do it instead of posting here, you can find the address on top of the blog under Contact.Delete