Original Post
I am going to explain the problem I have:
[1] The Blending Operation
----------------------------
Let (Cf,Af) be the RGB color and alpha value stored
in the frame buffer (fragment)
Let (Ct,At) be the RGB color and alpha value stored
in the texture image (source)
The blending operation glBlendFunc(GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA); (without multitexturing)
works like this:
(Cf,Af) = (Ct,At)*At + (Cf,Af) * (1-At)
GL_SRC_ALPHA (i.e. At) multiplies the source RGBA (Ct,Af)
and GL_ONE_MINUS_SRC_ALPHA (i.e. 1-At) multiplies (Cf,Af)
If I want to blend N textures for volume rendering, this
way works wonderful.
I just blend a textured polygons in back to front order,
with the blending operator.
[2] The blending operator with multitexturing
---------------------------------------------
I was reading the opengl1 1.3 specification. To simulate
the blending operator in each texture unit (and improve
the speed about 4x) I wrote the following instructions
to set the texture units (pseudocode):
For each texture unit i=0..3
glActiveTextureARB(GL_TEXTUREi_ARB);
glBindTexture(GL_TEXTURE_2D, TextNames);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP); glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT, GL_INTERPOLATE_EXT);
glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SRC_COLOR);
glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT,(i==0) ?
GL_PRIMARY_COLOR_EXT:GL_PREVIOUS_EXT);
glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SRC_COLOR);
glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE2_RGB_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND2_RGB_EXT,GL_SRC_ALPHA);
glTexEnvf(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_EXT, GL_INTERPOLATE_EXT);
glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_EXT,GL_SRC_ALPHA);
glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_EXT,(i==0) ?
PRIMARY_COLOR_EXT:GL_PREVIOUS_EXT);
glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND1_ALPHA_EXT,GL_SRC_ALPHA);
glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE2_ALPHA_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND2_ALPHA_EXT,GL_SRC_ALPHA);
After that, for these 4 textures:
glBegin(GL_QUADS);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0, 0);
glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0, 0);
glMultiTexCoord2fARB(GL_TEXTURE3_ARB, 0, 0);
glVertex3f(-1, -1, -1.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0, 1);
glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 0, 1);
glMultiTexCoord2fARB(GL_TEXTURE3_ARB, 0, 1);
glVertex3f(-1, 1, -1.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1, 1);
glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1, 1);
glMultiTexCoord2fARB(GL_TEXTURE3_ARB, 1, 1);
glVertex3f(1, 1, -1.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1, 0);
glMultiTexCoord2fARB(GL_TEXTURE2_ARB, 1, 0);
glMultiTexCoord2fARB(GL_TEXTURE3_ARB, 1, 0);
glVertex3f(1, -1, -1.0f);
glEnd();
This algorithm is applied for each 4 consecutives textures
of the volume.
Before anything (as usual) I activated the texture units
glActiveTextureARB =(PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");
if (!glActiveTextureARB)
{
printf("glActiveTextureARB not supported\n");
exit(1);
}
glMultiTexCoord2fARB =
(PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress("glMultiTexCoord2fARB");
if (!glMultiTexCoord2fARB)
{
printf("glMultiTexCoord2fARB not supported\n");
exit(1);
}
glActiveTextureARB(GL_TEXTURE0_ARB);
glActiveTextureARB(GL_TEXTURE1_ARB);
glActiveTextureARB(GL_TEXTURE2_ARB);
glActiveTextureARB(GL_TEXTURE3_ARB);
I don''t know why these codes [1] & [2] are not equivalents.
Each texture unit does just the blending operator.
(Cout,Aout) = (Ct,At)*At + (Cprevious,Aprevious) * (1-At)
Where
(Cprevious,Aprevious) if the ouput of the previous texture unit. For the first unit (unit0) these are equivaelnt to (Cf,Af),
i.e. values in frame buffer
(Cout,Aout) is the output of the texture unit (and will be
the input for the next texture unit). For the las texture
unit, these are the result of 4 blendings.
It works like this due the GL_INTERPOLATE_EXT extension:
GL_INTERPOLATE_EXT Arg0 * (Arg2) + Arg1 * (1-Arg2)
where
for RGB
Arg0 = Ct
Arg1 = Cprevious
Arg2 = At
for Alpha
Arg0 = At
Arg1 = Aprevious
Arg2 = At
I don''t know what I am doing wrong. If you can help me, I
would appreciate you.
Bye