transitioning from 1 texture to another

Member
Posts: 509
Joined: 2002.05
Post: #1
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]

If I know each of the two textures and weight values as a percent, how would I do this?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #2
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.
Quote this message in a reply
Member
Posts: 509
Joined: 2002.05
Post: #3
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!
Quote this message in a reply
Member
Posts: 509
Joined: 2002.05
Post: #4
I had a start to the code, but I am sure I am doing some stuff wrong. Can somone please fix this?

PHP Code:
glActiveTexture(GL_TEXTURE0);
                    
glEnableGL_TEXTURE_2D );
                    
glBindTextureGL_TEXTURE_2Dgv->texture[k] );
                    
                    
glTexEnvi(GL_TEXTURE_ENVGL_TEXTURE_ENV_MODEGL_COMBINE);
                    
glTexEnvi(GL_TEXTURE_ENVGL_COMBINE_RGBGL_REPLACE);
                    
                    
glActiveTexture(GL_TEXTURE1);
                    
glEnableGL_TEXTURE_2D );
                    
glBindTextureGL_TEXTURE_2Dgv->texture[m] );
                    
                    
glTexEnvi(GL_TEXTURE_ENVGL_TEXTURE_ENV_MODEGL_COMBINE);
                    
glTexEnvi(GL_TEXTURE_ENVGL_SOURCE0_RGBGL_TEXTURE0);
                    
glTexEnvi(GL_TEXTURE_ENVGL_COMBINE_RGBGL_INTERPOLATE);
                    
glTexEnvi(GL_TEXTURE_ENVGL_COMBINE_ALPHAGL_INTERPOLATE);
                    
glTexEnvi(GL_TEXTURE_ENVGL_SOURCE1_RGBGL_TEXTURE1);
                    
glTexEnvi(GL_TEXTURE_ENVGL_SOURCE1_ALPHAGL_PRIMARY_COLOR);
                    
glTexEnvi(GL_TEXTURE_ENVGL_OPERAND2_RGBGL_SRC_ALPHA);
                    
glTexEnvi(GL_TEXTURE_ENVGL_COMBINE_RGBGL_INTERPOLATE); 

Also, how do I send two alpha values with glColor4f?

PHP Code:
glNormal3f(vertexCount[whichTriangle].xvertexCount[whichTriangle].yvertexCount[whichTriangle].);
                            
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)*levelScalemPer[2][i][j]*levelScale, (j+offsetz)*levelScale ); 
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #5
This setup works as I described. I made a sample project, if you want I'll mail it to you.

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.
Quote this message in a reply
Member
Posts: 509
Joined: 2002.05
Post: #6
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?



PHP Code:
glActiveTextureARB(GL_TEXTURE0);
                
glEnable(GL_TEXTURE_2D);
                
glBindTexture(GL_TEXTURE_2Dgv->texture[1] );
                
glTexEnvi(GL_TEXTURE_ENVGL_TEXTURE_ENV_MODEGL_COMBINE);
                
glTexEnvi(GL_TEXTURE_ENVGL_COMBINE_RGBGL_MODULATE);                 // example grass tinting
                
GLfloat constant[4] = {1111};
                
glTexEnvfv(GL_TEXTURE_ENVGL_TEXTURE_ENV_COLORconstant);
                
glTexEnvi(GL_TEXTURE_ENVGL_COMBINE_ALPHAGL_CONSTANT);
                
                
// set up the second texture unit for water
                
glActiveTextureARB(GL_TEXTURE1);
                
glEnable(GL_TEXTURE_2D);
                
glBindTexture(GL_TEXTURE_2Dgv->texture[4]);   
                
glTexEnvi(GL_TEXTURE_ENVGL_TEXTURE_ENV_MODEGL_COMBINE);
                
glTexEnvi(GL_TEXTURE_ENVGL_COMBINE_RGBGL_INTERPOLATE);
                
glTexEnvi(GL_TEXTURE_ENVGL_SOURCE2_RGBGL_PRIMARY_COLOR);
                
glTexEnvi(GL_TEXTURE_ENVGL_OPERAND2_RGBGL_SRC_ALPHA);
                
glTexEnvi(GL_TEXTURE_ENVGL_COMBINE_ALPHAGL_INTERPOLATE);
                
glTexEnvi(GL_TEXTURE_ENVGL_SOURCE2_ALPHAGL_PRIMARY_COLOR);
                
glTexEnvi(GL_TEXTURE_ENVGL_OPERAND2_ALPHAGL_SRC_ALPHA);
                
                
glBegin(GL_QUADS);
                for( 
1< (levelx-1); i++ )
                {
                    for( 
1< (levely-1); j++ )
                    {
                        if ((
mTex[0][i][j] == && 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_TEXTURE000);
                            
glMultiTexCoord2f(GL_TEXTURE100);
                            
glVertex3f(-(i+offsetx)*levelScalemPer[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_TEXTURE001);
                            
glMultiTexCoord2f(GL_TEXTURE101);
                            
glVertex3f(-((i+offsetx)+1)*levelScalemPer[2][i+1][j]*levelScale, ((j+offsetz))*levelScale );
                            
                            
whichTriangle = [self whichTria:i z:j+1];
                            
glMultiTexCoord2f(GL_TEXTURE010);
                            
glMultiTexCoord2f(GL_TEXTURE110);   
                            
glColor4f(1.0,1.0,1.0,mPer[0][i][j+1]);
                            
glVertex3f(-((i+offsetx)+1)*levelScalemPer[2][i+1][j+1]*levelScale, ((j+offsetz)+1)*levelScale );
                            
                            
whichTriangle = [self whichTria:i+1 z:j+1];
                            
glMultiTexCoord2f(GL_TEXTURE011);
                            
glMultiTexCoord2f(GL_TEXTURE111);   
                            
glColor4f(1.0,1.0,1.0,mPer[0][i+1][j+1]);
                            
glVertex3f(-((i+offsetx))*levelScalemPer[2][i][j+1]*levelScale, ((j+offsetz)+1)*levelScale );
                            
                        }
                    } 
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #7
(mailed reply:)
man glColorMaterial
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #8
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?
Quote this message in a reply
Member
Posts: 509
Joined: 2002.05
Post: #9
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.
Quote this message in a reply
Member
Posts: 509
Joined: 2002.05
Post: #10
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

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 );
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #11
No solutions, but just for reference these threads discuss the same problem:
one
two
Quote this message in a reply
Member
Posts: 509
Joined: 2002.05
Post: #12
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)
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #13
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:]

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();    
}
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #14
And here's another approach, which does the interpolation and color tinting using only two texture units:

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.
Quote this message in a reply
Member
Posts: 509
Joined: 2002.05
Post: #15
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

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!
Quote this message in a reply
Post Reply