2-stage multitexturing with 2-colors?

ok, so i’m layering 2 textures using multitex and combine_ext, but i only seem to be able to add them, and then apply a color to them as a whole.
I need to be able to apply 1 color PER LAYER… specifically, one alpha component so the blending of the textures is not really an addition.
The idea is that i was doing two steps like:

glDisable(GL_BLEND);
// here i draw first layer

glEnable(GL_BLEND);
glBlendFunc
(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// here i draw second

My idea was to do something like:

glMultiTexCoord2f(0,u,v)
glMultiTexColor3f(0,r,g,b)

glMultiTexCoord2f(1,u,v)
glMultiTexColor3f(1,r,g,b)

get the idea? can it be done? how? if it can’t is there a clever way to blend two textures in one pass using varying alphas per vertex?

thankx

dani

im not really understanding. (normal for me)

but glColor…(…) affects whatever the current texture stage is set.
eg
glActiveTex…(TEX0)
glColor(red)
glActiveTex…(TEX1)
glColor(blue)

note u might wanna put both units to modulate (depending on what u want to do)

aphex to do what you describe, you need to set the first texture enviroment to GL_MODULATE or GL_REPLACE, not GL_COMBINE_EXT. Set the second texture environment to GL_COMBINE_EXT, and set GL_COMBINE_RGB_EXT to GL_INTERPOLATE_EXT. Then set rgb operand0 to GL_SRC_COLOR and rgb source0 to GL_PREVIOUS_EXT, set rgb operand1 to GL_SRC_COLOR, rgb source1 to GL_TEXTURE, set rgb operand2 to GL_SRC_ALPHA, and rgb source2 to GL_TEXTURE. The alpha component of the second texture will encode the amount of blending for the textures. Look at the EXT_texture_env_combine thread in the beginner’s forum for more details.

[This message has been edited by DFrey (edited 05-03-2001).]

You can’t send a single color value per vertex per texture. If you have EXT_secondary_color, you can send two colors.

However, if you do have an alpha value you wish to interpolate between, you might be able to do it with texture_env_combine, but you’ll probably need something more like register combiners.

DFrey, gotcha, but still…: what I am layering is a large texture (in the first stage) AND a detail texture (in the second), and I use the blending as calculated with a complex expression with partial derivatives, perlin noise, etc. so the alpha is not in the texture really, but calculated real-time per vertex.

What about the secondary color thing? would that work? if so, how?

Originally posted by DFrey:
[b]aphex to do what you describe, you need to set the first texture enviroment to GL_MODULATE or GL_REPLACE, not GL_COMBINE_EXT. Set the second texture environment to GL_COMBINE_EXT, and set GL_COMBINE_RGB_EXT to GL_INTERPOLATE_EXT. Then set rgb oprehand0 to GL_SRC_COLOR and rgb source0 to GL_PREVIOUS_EXT, and set rgb oprehand1 to GL_SRC_ALPHA, and rgb source1 to GL_TEXTURE. The alpha component of the second texture will encode the amount of blending for the textures. Look at the EXT_texture_env_combine thread in the beginner’s forum for more details.

[This message has been edited by DFrey (edited 05-02-2001).][/b]

In the normal GL pipeline, secondary color would not do what you want since its alpha is fixed at 0. However, you can still configure the combine extension to do what you want. The only change is to set rgb source2 to GL_PRIMARY_COLOR_EXT, and set the alpha component of the primary color of each vertex to the first texture’s blending weight at that vertex.

[This message has been edited by DFrey (edited 05-03-2001).]

Doesnt’ seem to work… in fact, only appears the first texture, and not the second.

Let’s see: my initial, 2-pass blending code is:

//first texture pass
tm.usetexture(12);
for(int i…)
{
glBegin(GL_TRIANGLE_STRIP);
for(int j…)
{
glColor3ub(grayscale color for shading);
glTexCoord2f(…);
glVertex3f(…);

  glColor3ub(grayscale...);
  glTexCoord2f(....);
  glVertex3f(......);
  }

glEnd();
}
//end first pass

//second texture pass
glEnable(GL_BLEND);
glDepthFunc(GL_LEQUAL);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
tm.usetexture(11);
for(i…)
{
glBegin(GL_TRIANGLE_STRIP);
for(int j…)
{
// here comes the blending
glColor4ub(…);
glTexCoord2f(…);
glVertex3f(…);

  glColor4ub(.........);
  glTexCoord2f(........);
  glVertex3f(........);
  }

glEnd();
}
glDisable(GL_BLEND);

Keep in mind:

  • the texcoords,colors are different for both passes
  • the blend factor is calculated, does not come from a texture

Ok, so the setup code i use now is:

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
tm.usetexture(12);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
tm.usetexture(11);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PRIMARY_COLOR_EXT);

And the paint loop is:

for(int i…)
{
glBegin(GL_TRIANGLE_STRIP);
for(int j…)
{
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,…);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,…);

  glColor4ub(.......);
  glVertex3f(.......);

  glMultiTexCoord2fARB(GL_TEXTURE0_ARB,.........);
  glMultiTexCoord2fARB(GL_TEXTURE1_ARB,........);
  glColor4ub(.......);
  glVertex3f(.......);
  }

glEnd();
}

Now, I don’t get it: if we put a color in the loop, it will affect BOTH texturing stages, right?

thankx in advance for looking at this whole mess

[This message has been edited by aphex (edited 05-03-2001).]

You have an error in the combine setup, it should be:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PRIMARY_COLOR_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);

And the alpha component of the primary color of each vertex would set the blending factor.

But as you now indicate that the primary color of each vertex was different for each pass in the multipass approach, then this combine setup will not work obviously.

The only way I can see to do that is with register combiners. However I’m no expert with that extension as I have yet to lay my hands on a Geforce of any variety.

how about using the secondary color? you say it’s alpha’d to 0… ok, could the following be done?

  • use the secondary color for the first “layer”, which has alpha=0
  • use the normal color for the second, alpha-blended layer?

maybe this is just sci-fi, but sounds ok to me.

thanks anyway…

Originally posted by DFrey:
[b]You have an error in the combine setup, it should be:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PRIMARY_COLOR_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);

And the alpha component of the primary color of each vertex would set the blending factor.

But as you now indicate that the primary color of each vertex was different for each pass in the multipass approach, then this combine setup will not work obviously.

The only way I can see to do that is with register combiners. However I’m no expert with that extension as I have yet to lay my hands on a Geforce of any variety. [/b]

Right, that’s what you could do. But only the register combiners extension will let you do that. And I have no idea how to setup the register combiners to do that though. Also remember that using register combiners would limit your program to Geforce cards unless you kept the multipass approach to fall back onto.

ok, so it seems we are stuck… too bad, as multitex raised our framerate like a 15%…

thanks!

Originally posted by DFrey:
Right, that’s what you could do. But only the register combiners extension will let you do that. And I have no idea how to setup the register combiners to do that though. Also remember that using register combiners would limit your program to Geforce cards unless you kept the multipass approach to fall back onto.