In the process of trying to port my 2D shadow rendering technique from Directx to Opengl, I've run across a problem where I can't seem to get fine enough access to the opengl blender.
But first, so that the following makes sense, my algorithm:
I sort and render all sprites from back to front without using a depth buffer. Shadow sprites are drawn just before the objects that cast them and use the second blendstate below, gShadowBlendState. That makes them draw only their alpha values to the alpha channel on the framebuffer.
Sprites for regular objects use gBlendState specified first below, which is just a regular alpha blend to the backbuffer. However, they also remove alpha from the backbuffer alpha channel to the extent that they are opaque; this makes sure that shadows don't show through opaque objects that are in front of them.
The third thing that is drawn, and which is drawn after everything else, is a fullscreen quad that renders using the shadow colour and the final blend state below. It uses the backbuffer's alpha channel for opacity, effectively bringing out all the shadow information inscribed earlier.
The whole point of this exercise is to get shadows that don't get darker where they overlap.
gBlendState.SrcBlend = D3DBLEND_SRCALPHA;
gBlendState.BlendOp = D3DBLENDOP_ADD;
gBlendState.DestBlend = D3DBLEND_INVSRCALPHA;
gBlendState.SrcBlendAlpha = D3DBLEND_ZERO;
gBlendState.BlendOpAlpha = D3DBLENDOP_ADD;
gBlendState.DestBlendAlpha = D3DBLEND_INVSRCALPHA;
gShadowBlendState.SrcBlend = D3DBLEND_ZERO;
gShadowBlendState.BlendOp = D3DBLENDOP_ADD;
gShadowBlendState.DestBlend = D3DBLEND_ONE;
gShadowBlendState.SrcBlendAlpha = D3DBLEND_ONE;
gShadowBlendState.BlendOpAlpha = D3DBLENDOP_MAX;
gShadowBlendState.DestBlendAlpha = D3DBLEND_ONE;
gShadowFillBlendState.SrcBlend = D3DBLEND_DESTALPHA;
gShadowFillBlendState.BlendOp = D3DBLENDOP_ADD;
gShadowFillBlendState.DestBlend = D3DBLEND_INVDESTALPHA;
gShadowFillBlendState.SrcBlendAlpha = D3DBLEND_ONE;
gShadowFillBlendState.BlendOpAlpha = D3DBLENDOP_MAX;
gShadowFillBlendState.DestBlendAlpha = D3DBLEND_ONE;
Anyway. I'm trying to do this now in Opengl. Currently I have alpha blending enabled with
glEnable(GL_BLEND);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
but I'm not sure how to give it separate instructions for how to calculate the colour and alpha components. So my question is this: Is there a way to get finer control over the blender in OpenGL than just glBlendFunc() ?