There are two ways to approach this problem in general.
- Paste-on decals. You project a rectangular or cone shaped volume onto the model and generate vertices where the volume clips against the polys of the model. In theory this is the "best" way to do it since you're generating the smallest possible polys for the decals. But it suffers from the venetian blind problem. That is, because the vertices of the decal poly aren't the same as the vertices of the poly its being drawn on top of, inaccuracies in the 3d rotation/projection code will cause them to have slightly inconsistent Z values. So the two of them will end up "fighting" for the zbuffer in a view-dependant manner. There are 2 fixes for this. First is to use the "z bias" setting available in D3D. The squad logos use this to work properly. Alternately, you can multiply 1/z value of each of the projected verts by some slightly-greater-than-1 value to fake their depth "out" of the wbuffer. For small decals (where "small" means small onscreen) this is the preferred method. But if you do this for blast decals which could be applied to, say, the side of a capital ship, they could potentially end up very large onscreen. In this case, you'd need to use a larger value to mess with the 1/z depth and that's going to result in really ugle view-dependant warping of the decal. Which brings us to method 2 :
- Multi-pass decals. As with the paste-ons you're projecting a 3d volume onto the model and "clipping" it against each relevant face. But the difference here is that instead of calculating vertex points, you just calculate texture UV's to map the decal texture onto the existing model verts. Kind of like a lightmap. As long as you draw the decal face with clamping enabled, you're all good. The main advantage is that you'll never have zbuffer fighting. The main disadvantage is that you're going to end up drawing more pixels per decal. In theory this could eat away framerate. But on newer 3d cards, maybe that's not an issue.
I'm not sure which I'd use in this particular case. If I were going to implement this for a "real" game in this circumstance, I'd probably go with method 2 and impose some hard limits on the # of decals per ship or something like that, to make sure fillrate doesn't skyrocket.