transitioning from 1 texture to another
I recently have been working with multi texturing and I decided that a quick way to get GL Golf to look way better would be to blend the edges of surfaces together like this
![[Image: transition.jpg]](http://nuclearnova.com/temp/transition.jpg)
If I know each of the two textures and weight values as a percent, how would I do this?
![[Image: transition.jpg]](http://nuclearnova.com/temp/transition.jpg)
If I know each of the two textures and weight values as a percent, how would I do this?
In general what you want to do is draw the underlying texture (let's call that "grass") with alpha=1.0 everywhere. And the overlying texture ("water") with alpha interpolating across the quad from 0.0 to 1.0.
There are a few different ways to achieve this: you could draw all your grass in one pass, then the water as separate meshes. Or you could draw them both over the same geometry with multitexturing. To fade the water out, you could use either the interpolated vertex alpha, or you could make a separate landscape mask texture, like a light map.
Which way you go depends on how much control you want of the blending edge. But let's say you want to do it in one pass with multitexturing, and don't care so much about pixel-level control:
Set "grass" to texture unit 0 and set up the texture environment to COMBINE mode-- if you want to be able to colorize the grass with the vertex color (for brown/green/yellow colorization of the same texturemap) then you can use MODULATE for the RGB component; otherwise REPLACE. For the alpha, use a CONSTANT 1.0.
Set "water" to texture unit 1 and use COMBINE mode again. Use INTERPOLATE mode for both RGB and A to blend between the PREVIOUS (unit0) result and the TEXTURE ("water") fragment, using PRIMARY_COLOR (the vertex alpha) as source2, use SRC_ALPHA for operand2.
There are a few different ways to achieve this: you could draw all your grass in one pass, then the water as separate meshes. Or you could draw them both over the same geometry with multitexturing. To fade the water out, you could use either the interpolated vertex alpha, or you could make a separate landscape mask texture, like a light map.
Which way you go depends on how much control you want of the blending edge. But let's say you want to do it in one pass with multitexturing, and don't care so much about pixel-level control:
Set "grass" to texture unit 0 and set up the texture environment to COMBINE mode-- if you want to be able to colorize the grass with the vertex color (for brown/green/yellow colorization of the same texturemap) then you can use MODULATE for the RGB component; otherwise REPLACE. For the alpha, use a CONSTANT 1.0.
Set "water" to texture unit 1 and use COMBINE mode again. Use INTERPOLATE mode for both RGB and A to blend between the PREVIOUS (unit0) result and the TEXTURE ("water") fragment, using PRIMARY_COLOR (the vertex alpha) as source2, use SRC_ALPHA for operand2.
arekkusu Wrote:Set "grass" to texture unit 0 and set up the texture environment to COMBINE mode-- if you want to be able to colorize the grass with the vertex color (for brown/green/yellow colorization of the same texturemap) then you can use MODULATE for the RGB component; otherwise REPLACE. For the alpha, use a CONSTANT 1.0.
Set "water" to texture unit 1 and use COMBINE mode again. Use INTERPOLATE mode for both RGB and A to blend between the PREVIOUS (unit0) result and the TEXTURE ("water") fragment, using PRIMARY_COLOR (the vertex alpha) as source2, use SRC_ALPHA for operand2.
Thanks, I will test that tonight!
I had a start to the code, but I am sure I am doing some stuff wrong. Can somone please fix this?
Also, how do I send two alpha values with glColor4f?
PHP Code:
glActiveTexture(GL_TEXTURE0);
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, gv->texture[k] );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glActiveTexture(GL_TEXTURE1);
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, gv->texture[m] );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
Also, how do I send two alpha values with glColor4f?
PHP Code:
glNormal3f(vertexCount[whichTriangle].x, vertexCount[whichTriangle].y, vertexCount[whichTriangle].z );
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,i,j);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,i,j);
glColor4f(0.0,0.0,0.0,mPer[0][i][j]);
glVertex3f(-(i+offsetx)*levelScale, mPer[2][i][j]*levelScale, (j+offsetz)*levelScale );
This setup works as I described. I made a sample project, if you want I'll mail it to you.
Note that this relies on some of the COMBINE default values-- see the spec to understand what they are. You can always set everything explicitly to be safe.
You don't need to set two alpha values. There's one primary alpha value per vertex, which is interpolated along the quad. It serves as the % of water texture to blend in.
Code:
void RenderMap() {
// set up the first texture unit for grass
glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); // example grass tinting
GLfloat constant[4] = {1, 1, 1, 1};
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_CONSTANT);
// set up the second texture unit for water
glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[WATER]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
// draw a mesh (just one quad for now)
glBegin(GL_QUAD_STRIP);
glColor4f(1, 0, 1, 0); // tint one grass corner purple as example
glMultiTexCoord2f(GL_TEXTURE0, 0, 0);
glMultiTexCoord2f(GL_TEXTURE1, 0, 0);
glVertex2f(0, 0);
glColor4f(1, 1, 1, 0); // normal grass color
glMultiTexCoord2f(GL_TEXTURE0, 0, 1);
glMultiTexCoord2f(GL_TEXTURE1, 0, 1);
glVertex2f(0, 1);
glColor4f(1, 1, 1, 1); // normal water color
glMultiTexCoord2f(GL_TEXTURE0, 1, 0);
glMultiTexCoord2f(GL_TEXTURE1, 1, 0);
glVertex2f(1, 0);
glMultiTexCoord2f(GL_TEXTURE0, 1, 1);
glMultiTexCoord2f(GL_TEXTURE1, 1, 1);
glVertex2f(1, 1);
glEnd();
}Note that this relies on some of the COMBINE default values-- see the spec to understand what they are. You can always set everything explicitly to be safe.
You don't need to set two alpha values. There's one primary alpha value per vertex, which is interpolated along the quad. It serves as the % of water texture to blend in.
it always uses 100% water here
EDIT : It turned out that enabling lighting is what was screwing everything up, how do I light stuff and blend it together?
EDIT : It turned out that enabling lighting is what was screwing everything up, how do I light stuff and blend it together?
PHP Code:
glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, gv->texture[1] );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); // example grass tinting
GLfloat constant[4] = {1, 1, 1, 1};
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_CONSTANT);
// set up the second texture unit for water
glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, gv->texture[4]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
glBegin(GL_QUADS);
for( i = 1; i < (levelx-1); i++ )
{
for( j = 1; j < (levely-1); j++ )
{
if ((mTex[0][i][j] == k && mTex[1][i][j] == m) && (mPer[0][i][j] != 1.0)) {
whichTriangle = [self whichTria:i z:j];
glColor4f(1.0,1.0,1.0,0.0);
glMultiTexCoord2f(GL_TEXTURE0, 0, 0);
glMultiTexCoord2f(GL_TEXTURE1, 0, 0);
glVertex3f(-(i+offsetx)*levelScale, mPer[2][i][j]*levelScale, (j+offsetz)*levelScale );
whichTriangle = [self whichTria:i+1 z:j];
glColor4f(1.0,1.0,1.0,1.0);
glMultiTexCoord2f(GL_TEXTURE0, 0, 1);
glMultiTexCoord2f(GL_TEXTURE1, 0, 1);
glVertex3f(-((i+offsetx)+1)*levelScale, mPer[2][i+1][j]*levelScale, ((j+offsetz))*levelScale );
whichTriangle = [self whichTria:i z:j+1];
glMultiTexCoord2f(GL_TEXTURE0, 1, 0);
glMultiTexCoord2f(GL_TEXTURE1, 1, 0);
glColor4f(1.0,1.0,1.0,mPer[0][i][j+1]);
glVertex3f(-((i+offsetx)+1)*levelScale, mPer[2][i+1][j+1]*levelScale, ((j+offsetz)+1)*levelScale );
whichTriangle = [self whichTria:i+1 z:j+1];
glMultiTexCoord2f(GL_TEXTURE0, 1, 1);
glMultiTexCoord2f(GL_TEXTURE1, 1, 1);
glColor4f(1.0,1.0,1.0,mPer[0][i+1][j+1]);
glVertex3f(-((i+offsetx))*levelScale, mPer[2][i][j+1]*levelScale, ((j+offsetz)+1)*levelScale );
}
}
(mailed reply:)
man glColorMaterial
man glColorMaterial
Revisiting this, Jake has lighting enabled. In that case, what you want is the lit vertex color modulated with the two textures which have been interpolated according to the vertex alpha. Or:
LIT_PRIMARY_RGB * (TEXTURE0*PRIMARY_A + TEXTURE1*(1-PRIMARY_A))
This is equivalent to the problem I had with interpolating two alpha textures modulated by the polygon color.
As OSC described there, you can do this with three texture units: REPLACE, INTERPOLATE, MODULATE. But then it won't work on older GPUs.
Henry pointed out that it might be possible with two units if the vertex alpha is always one. Well, Jake doesn't care about the resulting vertex alpha (the terrain will always be opaque), he only uses the vertex alpha as an interpolator.
Can anyone see a clever way to do lit two-texture terrain in one pass with two texture units?
LIT_PRIMARY_RGB * (TEXTURE0*PRIMARY_A + TEXTURE1*(1-PRIMARY_A))
This is equivalent to the problem I had with interpolating two alpha textures modulated by the polygon color.
As OSC described there, you can do this with three texture units: REPLACE, INTERPOLATE, MODULATE. But then it won't work on older GPUs.
Henry pointed out that it might be possible with two units if the vertex alpha is always one. Well, Jake doesn't care about the resulting vertex alpha (the terrain will always be opaque), he only uses the vertex alpha as an interpolator.
Can anyone see a clever way to do lit two-texture terrain in one pass with two texture units?
Thanks Alex for posting, I was actually just getting on to restate the question, but you already did for me!
I have friday off of school so I am going to spend some time getting this finished out, and I will have a big of enough update to make GL Golf 1.4.
I have friday off of school so I am going to spend some time getting this finished out, and I will have a big of enough update to make GL Golf 1.4.
Here is an update - I tried to add the third texture unit but I am getting the same results - Here is a snippet of the relevant code.
But first, in this thread someone said that it is possible to use two texture units if the alpha is only going to be a 0 or 1, how can I do that because that is true for me?
http://www.idevgames.com/forum/showthread.php?t=1232
Thanks
But first, in this thread someone said that it is possible to use two texture units if the alpha is only going to be a 0 or 1, how can I do that because that is true for me?
http://www.idevgames.com/forum/showthread.php?t=1232
Thanks
Code:
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
for(k=0; k<5; k++)
{
for(m=0; m<5; m++)
{
if (m != k) {
// set up the first texture unit for the main textre
glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, gv->texture[m] );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); // example grass tinting
GLfloat constant[4] = {1, 1, 1, 1};
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_CONSTANT);
// set up the second texture unit for blended texture
glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, gv->texture[k]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
// set up the third texture unit for light modulation
glActiveTextureARB(GL_TEXTURE2);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
glBegin(GL_QUADS);
for( i = 1; i < (levelx-1); i++ )
{
for( j = 1; j < (levely-1); j++ )
{
whichTriangle = [self whichTria:i z:j];
if (mPer[3][i][j] == m && (mTex[0][i][j] == k || mTex[1][i][j] == k) && mPer[0][i][j] != 1) {
glNormal3f(vertexCount[whichTriangle].x, vertexCount[whichTriangle].y, vertexCount[whichTriangle].z );
glMultiTexCoord2f(GL_TEXTURE0, (i)*levelScale/textureSizes[m], (j)*levelScale/textureSizes[m]);
glMultiTexCoord2f(GL_TEXTURE1, (i)*levelScale/textureSizes[k], (j)*levelScale/textureSizes[k]);
glColor4f(1.0,1.0,1.0,0.0);
glVertex3f(-(i+offsetx)*levelScale, mPer[2][i][j]*levelScale, (j+offsetz)*levelScale );
What is wrong with this piece of code - it doesn't seam to be correctly modulating the color with the second texture (unit #1)?
Code:
// set up the third texture unit for light modulation
glActiveTextureARB(GL_TEXTURE2);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR)
Is unit2 enabled?
[Edit: it looks like you have to actually have a texture bound to the active unit, even if you don't sample the texture data in the combine stage for that unit. Blah. Here's code using three units:]
[Edit: it looks like you have to actually have a texture bound to the active unit, even if you don't sample the texture data in the combine stage for that unit. Blah. Here's code using three units:]
Code:
void RenderMap() {
// set up the first texture unit for grass
glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// set up the second texture unit for water
glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[WATER]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
// set up the third texture unit for primary color tinting
glActiveTextureARB(GL_TEXTURE2);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[WATER]); // dummy texture, not sampled
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
GLfloat constant[4] = {1, 1, 1, 1}; // force final output alpha to 1, doesn't matter if not blending
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_CONSTANT);
// draw a mesh (just one quad for now)
glBegin(GL_QUAD_STRIP);
glColor4f(1, 0, 0, 0); // tint top edge red as example
glMultiTexCoord2f(GL_TEXTURE0, 0, 0);
glMultiTexCoord2f(GL_TEXTURE1, 0, 0);
glVertex2f(0, 0);
glColor4f(1, 1, 1, 0); // normal grass color
glMultiTexCoord2f(GL_TEXTURE0, 0, 1);
glMultiTexCoord2f(GL_TEXTURE1, 0, 1);
glVertex2f(0, 1);
glColor4f(1, 0, 0, 1); // tint top edge red as example
glMultiTexCoord2f(GL_TEXTURE0, 1, 0);
glMultiTexCoord2f(GL_TEXTURE1, 1, 0);
glVertex2f(1, 0);
glColor4f(1, 1, 1, 1); // normal water color
glMultiTexCoord2f(GL_TEXTURE0, 1, 1);
glMultiTexCoord2f(GL_TEXTURE1, 1, 1);
glVertex2f(1, 1);
glEnd();
}
And here's another approach, which does the interpolation and color tinting using only two texture units:
However this uses ARB_texture_env_crossbar functionality, which is only exported on Radeon7000+ under 10.3 (or Radeon9600 under 10.2.) It won't work on Rage128 due to hardware limitations. It *might* work on the nvidia cards even though the extension isn't exported, I haven't tested. So this might be a way to get your effect to work on GF2MX and GF4MX cards in only one pass. But you'll still need two passes for Rage128.
Code:
void RenderMap() {
// set up the first texture unit to interpolate between grass and water using crossbar extension
glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
// set up the second texture unit for primary color tinting
glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[WATER]); // sampled only by first unit
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
GLfloat constant[4] = {1, 1, 1, 1}; // force final output alpha to 1, doesn't matter if not blending
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_CONSTANT);
// draw a mesh (just one quad for now)
glBegin(GL_QUAD_STRIP);
glColor4f(1, 0, 0, 0); // tint top edge red as example
glMultiTexCoord2f(GL_TEXTURE0, 0, 0);
glMultiTexCoord2f(GL_TEXTURE1, 0, 0);
glVertex2f(0, 0);
glColor4f(1, 1, 1, 0); // normal grass color
glMultiTexCoord2f(GL_TEXTURE0, 0, 1);
glMultiTexCoord2f(GL_TEXTURE1, 0, 1);
glVertex2f(0, 1);
glColor4f(1, 0, 0, 1); // tint top edge red as example
glMultiTexCoord2f(GL_TEXTURE0, 1, 0);
glMultiTexCoord2f(GL_TEXTURE1, 1, 0);
glVertex2f(1, 0);
glColor4f(1, 1, 1, 1); // normal water color
glMultiTexCoord2f(GL_TEXTURE0, 1, 1);
glMultiTexCoord2f(GL_TEXTURE1, 1, 1);
glVertex2f(1, 1);
glEnd();
}However this uses ARB_texture_env_crossbar functionality, which is only exported on Radeon7000+ under 10.3 (or Radeon9600 under 10.2.) It won't work on Rage128 due to hardware limitations. It *might* work on the nvidia cards even though the extension isn't exported, I haven't tested. So this might be a way to get your effect to work on GF2MX and GF4MX cards in only one pass. But you'll still need two passes for Rage128.
Thanks for the help, that cleaned up my code and got it working!
But It has 3 side effects...
1. There is a red tint to everything, mostly in the distance
2. Anything with blending is now messed up (tree transparencies are now black)
Is there a way to revert back to the normal texture mode after I am done?
2. Here is how I normally go back to 1 texture unit when I am done
Even if I do that AFTER I am done drawing my multitextures it screws the multitextured quads...
I can get some screenshots if needed, but my internet is sketching out now so I will only get them if you need them.
Thanks!
But It has 3 side effects...
1. There is a red tint to everything, mostly in the distance
2. Anything with blending is now messed up (tree transparencies are now black)
Is there a way to revert back to the normal texture mode after I am done?
2. Here is how I normally go back to 1 texture unit when I am done
Code:
glActiveTexture(GL_TEXTURE2);
glDisable( GL_TEXTURE_2D );
glActiveTexture(GL_TEXTURE1);
glDisable( GL_TEXTURE_2D );
glActiveTexture(GL_TEXTURE0);Even if I do that AFTER I am done drawing my multitextures it screws the multitextured quads...
I can get some screenshots if needed, but my internet is sketching out now so I will only get them if you need them.
Thanks!

