The problem with having specific “additive” and “modulate” modes is that you cannot blend between them… eg an additive fire particle that turns into an opaque smoke particle…
If you use glsl you can get around this by modifying the alpha value in a fragment shader.
First look at the 2 functions
Key:
cs = src color
as = src alpha
cd = dst color
Additive:
cd = cs * as + cd
Modulate:
cd = cs * as + cd * (1 - as)
note there is very little difference between these modes …
So in your program set this blendmode:
cd = cs + cd * (1 - as) … which in gl is:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Then when you draw a particle you need to pass a blend ratio value to your shader (send it as an extra texcoord or whatever)
Now in your shader you have:
cs = incoming color
as = incoming alpha
br = incoming blend ratio … 0(modulate) -> 1(additive)
so your fragment program sets the color output to …
cs = cs * as;
as = lerp(as, 1 - as, br)
Remember the blend operation happens after the shader, so this output goes into the blendfunc as [cs] and [as].
So when we get to our blend func:
cd = cs + cd * (1 - as)
We have already handled the blending of cs by the original alpha value, and we have modified that alpha value (by the blend ratio) so that the contribution of cd is variable (ie can be modulate or additive)
Now you can control the blendmode without having to change state all the time, and you can have a smooth transition betweem additive and modulate modes.