register combiners

Is it possible, using 3 texture units, to have the first and second textures units be set up with normal textures and have the 3rd be set as an alpha map. And using the alpha map determine how much of the second texture to be laid on top of the first?

I know you can control the alpha values using glColor4f() for each individual vertex passed in, but with an alpha map you could basically simulate a pixel shader, right?

Yes, you can do this fairly easily using a single general combiner. Here’s the Cg code to do that:

float4 main(in float2 texcoords[3] : TEXCOORD0, uniform sampler2D maps[3] : TEXUNIT0) : COLOR
{
    float3 a = tex2D(maps[0], texcoords[0]).rgb;
    float3 b = tex2D(maps[1], texcoords[1]).rgb;
    float alpha = tex2D(maps[2], texcoords[2]).a;

    return float4(lerp(a, b, alpha), 1.0);
}

which produces the following nvparse code:

!!RC1.0
{
  rgb
  {
    discard = unsigned_invert(tex2.a) * tex0.rgb;
    discard = tex1.rgb * tex2.a;
    col0 = sum();
  }
}
out.rgb = unsigned(col0.rgb);
out.a = unsigned_invert(zero.a);

[This message has been edited by jra101 (edited 09-09-2003).]

But does CG work on ATI cards? Also, isn’t there a way to do it using Texture Combiners? Thanks for the code though, I’ll look into CG.

Check ARB_texture_env_combine
This should do the trick

CG will work on ATI as long as you choose a compatible target profile.

I’ve found the coolest txt file at sgi’s site. http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_env_combine.txt

This thing lists all the arb extensions for register combiners. So far from what I’ve gathered, this is how I’m approaching to solve my problem. Having the 3 textures I discussed above, here’s what I have

glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);

glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, texture2);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE_ARB);

Now the documentation says for interpolate_arb, it uses the equation Arg0 * (Arg2) + Arg1 * (1-Arg2), where Arg0, Arg1, and Arg2 are SOURCE<n>_RGB_ARB, SOURCE<n>_ALPHA_ARB, OPERAND<n>_RGB_ARB and
OPERAND<n>_ALPHA_ARB.
Now i’m trying to figure out, do I setup arg0,arg1, and arg2 as SOURCE0_RGB_ARB,SOURCE1_RGB_ARB,and SOURCE2_RGB_ARB? My alpha texture doesn’t actually have an alpha channell, I’m just using the r,g,b components are the alpha components. So anyone have any ideas on how to setup this up so the 3rd texture defines the alpha map used to determine how much of texture2 to blend ontop of texture1?

I really hope somebody will help me with this issue and not consider me a newbie :slight_smile:

Here’s the code I’ve gotten for the problem.

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_RGB_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture2);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE_ARB);

// Operand0 is the color of the previous stage (Tex1).
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);

// Operand1 is the color of the current stage (Tex2).
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);

// Operand2 is the alpha of the current stage (Tex2).
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);

Here’s a link for the output http://cs.selu.edu/~soconnell/example.jpg

The top left pic is the actual render, and the bottom left pic is texture1, then the bottom right is texture2. And the top pic is the alphamap which is mapped onto texture2’s alpha channel. So this SHOULD smoothly interpolate between both textures based on the alpha map, but as you can see from the example render, it is not. Is there something wrong with the GL calls? Please any help is much appreciated.

This thing lists all the arb extensions for register combiners.

There are no such things as “ARB register combiners”. The ARB functionality is called “texture env combine”; the nVidia functionality is called “register combiners”. That could be why you got responses with things like Cg; you were asking for NV-specific functionality when you really wanted texture_env_combine.

For your particular problem, I don’t think texture_env_combine can fully solve it, unless you have the cross-bar extension (and maybe not even then.

with the ARB_texture_env_combine extension and the crossbar functionalit yit ids possible

// OpenGL texture environment
// file generated by gl_tut texture environment

//----------------
//|texture unit 0|
//----------------
GLuint tex_id0;
GLfloat env_color0[4] = {0.808740f,0.193304f,0.563585f,0.001251f};
GLint rgb_scale0 = 1;
GLint alpha_scale0 = 1;

glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTUE_2D,tex_id0);

glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,env_color0);
glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);

// RGB combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_REPLACE);
glTexEnvi (GL_TEXTURE_ENV,GL_RGB_SCALE,rgb_scale0);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);

// ALPHA combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_ALPHA,GL_MODULATE);
glTexEnvi (GL_TEXTURE_ENV,GL_ALPHA_SCALE,alpha_scale0);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_ALPHA,GL_PREVIOUS);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_ALPHA,GL_SRC_ALPHA);

//----------------
//|texture unit 1|
//----------------
GLuint tex_id1;
GLfloat env_color1[4] = {0.895962f,0.350291f,0.479873f,0.585009f};
GLint rgb_scale1 = 1;
GLint alpha_scale1 = 1;

glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTUE_2D,tex_id1);

glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,env_color1);
glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);

// RGB combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_REPLACE);
glTexEnvi (GL_TEXTURE_ENV,GL_RGB_SCALE,rgb_scale1);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);

// ALPHA combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_ALPHA,GL_MODULATE);
glTexEnvi (GL_TEXTURE_ENV,GL_ALPHA_SCALE,alpha_scale1);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_ALPHA,GL_PREVIOUS);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_ALPHA,GL_SRC_ALPHA);

//----------------
//|texture unit 2|
//----------------
GLuint tex_id2;
GLfloat env_color2[4] = {0.858943f,0.174108f,0.746605f,0.822840f};
GLint rgb_scale2 = 1;
GLint alpha_scale2 = 1;

glActiveTexture(GL_TEXTURE2);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTUE_2D,tex_id2);

glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,env_color2);
glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);

// RGB combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_INTERPOLATE);
glTexEnvi (GL_TEXTURE_ENV,GL_RGB_SCALE,rgb_scale2);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_TEXTURE0);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);
// arg 1
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE1_RGB,GL_TEXTURE1);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND1_RGB,GL_SRC_COLOR);
// arg 2
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE2_RGB,GL_TEXTURE2);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND2_RGB,GL_SRC_ALPHA);

// ALPHA combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_ALPHA,GL_REPLACE);
glTexEnvi (GL_TEXTURE_ENV,GL_ALPHA_SCALE,alpha_scale2);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_ALPHA,GL_TEXTURE2);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_ALPHA,GL_SRC_ALPHA);
// arg 1
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE1_ALPHA,GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND1_ALPHA,GL_SRC_ALPHA);
// arg 2
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE2_ALPHA,GL_CONSTANT);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND2_ALPHA,GL_SRC_ALPHA);

Thanks to everyone who helped me out with this topic. I’m not going to CG, cause this way is a pain in the butt. But I finally got it working. Basically I had my grass texture, rock texture, and alpha map. I set the grass as texure0, alpha as texture1, and rock as texture2. I then make the calls below and rock fades through, where at 0 it’s transparent, and 1 is opaque. Anyway, here’s what I ended up with.

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_RGB_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, alphamap);

glActiveTextureARB(GL_TEXTURE2_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture2);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); 
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB); 

glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB,GL_TEXTURE0/*GL_PREVIOUS_ARB*/); 
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB,GL_SRC_COLOR); 

glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB,GL_TEXTURE2); 
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_ARB,GL_SRC_COLOR); 

glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB,GL_TEXTURE1);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_ALPHA);

Hope this helps somebody else out. Also, I found this great utility in the process called GLView http://www.realtech-vr.com/glview/

I meant to say, “I’m NOW going to CG”. Not I’m “not”.