Sign in to follow this  
long_xz

How to use Multitexture like this?

Recommended Posts

I want to use multitexture like this Cv = Cf*C0+Cf+C1 Cf: the fragment color C0: texture0 C1: texture1 Cv is the final color how should I configure my texutre environment

Share this post


Link to post
Share on other sites
Hello,

Basicly, you could write your equation like this: Cv = Cf(C0+C1)
That way, you can do the following:

// Setup the color on TEXUNIT0
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); // try GL_MODULATE also I'm not sure
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
//Setup texture unit 1
...
//Setup texture unit 2
...
// Activate TEXUNIT1 again
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE1);
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);

Hope I've been able to help,
Jeroen

[Edited by - godmodder on April 7, 2007 6:27:41 AM]

Share this post


Link to post
Share on other sites
Sorry, I've made a mistake. Here's the correct sequence, however I haven't verified the code because I'm currently not on my home pc:

// Setup the color using glColor
...
// Setup texture unit 2
...
// Setup combining for texture unit 2 --> (Cf*C0)
glActiveTextureARB(GL_TEXTURE2_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE2); // or GL_TEXTURE?
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);

// Setup texture unit 1
...
// Activate TEXUNIT1 again --> (Cf+C1)
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE1); // or GL_TEXTURE?
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);

// Activate TEXUNIT0
glActiveTextureARB(GL_TEXTURE0_ARB); --> (Cf*C0)+(Cf+C1)
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE1);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);

I think you have to disable TEXUNIT 1/2 after the combining to prevent them from being modulated with the final result in TEXUNIT0.

Jeroen

Share this post


Link to post
Share on other sites
thank you for your help,but i still have some question
Is that means that if i want to map two textures,then i need to use 3 texture units?
can you use just 2 units to achieve this?Because the number of the textures used to map is dynamic.

Share this post


Link to post
Share on other sites
Hello,

unless there's some clever trick I don't yet know about, I don't think you can do it without a third texunit because you have to store 2 intermediate results and use them in another texture unit. If you are working with lightmaps or greyscale images, you could save some texture units by storing grayscale images in the alpha channels of the other textures, but for the rest I don't know. There's some further reading in the GL_ARB_tex_env_combine extension specification about the behavior if some texture units aren't intialized correctly. Maybe you can find the answer to your last question there...

Good luck,
Jeroen

Share this post


Link to post
Share on other sites
Thank you again.
But i have another question.
Given i use GL_TEXTURE0 and GL_TEXTURE1 to store 2 intermediate results.
and combine them in GL_TEXTURE2,
how shoule i set the texture coordinate in GL_TEXTURE2,while using glMultiTexCoord2f

Share this post


Link to post
Share on other sites
Hello,

I understand your problem: you want to blend three things: a color value that hasn't got any coordinates associated with it, a texture "1" that has it's own coordinates and a texture "2" that has it's own coordinates. You store (Cf*C0) in TEXUNIT2 and (Cf + C1) in TEXUNIT1. Then you want to add the two together and use the result in TEXUNIT0. I honestly don't know if this is even possible in this way, and which coordinates you should use then. But I find this problem quite interesting, so I will devote some research to it. I'll get back to you when I find a solution.

EDIT: maybe you should just use a glDisableClientState(GL_TEXTURE0_ARB); because you supply the other texcoords when doing the combining already.

Jeroen

[Edited by - godmodder on April 9, 2007 7:12:38 AM]

Share this post


Link to post
Share on other sites
Wait, do you want Cv = CfC0 + Cf + C1 like you originally posted or Cv = CfC0 + CfC1 = Cf(C0+C1) like what was assumed in the rest of the thread? If the second equation is what you want I think something like this should work...
//Assuming tex0 and tex1 are already bound to GL_TEXTURE0 and GL_TEXTURE1

//Setup texunit 0's environment to output C0+C1
glActiveTexture(GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

//Combine function (Arg0 + Arg1)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);

//Arg0 RGB and alpha come from tex0
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);

//Arg1 RGB and alpha come from tex1
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE1);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE1);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);


//Setup texunit 1's environment to output Cf*previous
glActiveTexture(GL_TEXTURE1);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

//Combine function (Arg0 * Arg1)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);

//Arg0 comes from the incoming fragment
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);

//Arg1 comes from the previous texture environment
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
You will need at least OpenGL v1.4 or support for GL_ARB_texture_env_crossbar (with the approriate ARB suffixes) in order to access different texture units than the current one as a source in the combine functions. This is also untested but I think it should work.

If you don't mind requiring support for fragment shaders, this simply becomes
vec4 c0 = texture2D(tex0, uv0);
vec4 c1 = texture2D(tex1, uv1);
gl_FragColor = gl_Color * (c0 + c1);

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this