PDA

View Full Version : Multitexturing->Mix two textures



dletozeun
01-15-2006, 07:58 AM
hello,

I try to mix two textures (grass and soil for example) but would setup the mix factor with a third texture that is a gray level texture...

these are the grass textures and soil texture:
http://www.rootage.org/GCNwiki/terre.jpg http://www.rootage.org/GCNwiki/herbe.jpg

I would mix the two textures above, using the color of this texture in order to setup the mix factor between them:
http://www.rootage.org/GCNwiki/exmasque.jpg

and I would obtain this:
http://www.rootage.org/GCNwiki/terre_eau.jpg

But, I don't how to do that with openg...
This is the code which I try to mix the textures but it doesn't work...because I obtain the product of textures and 2 and not the product of textures 0 and 1 with texture 2 as mix factor...

In this code: nom[0] is soil texture
nom[1] is grass texture
nom[2] is level gray texture

__________________________________________________ _______
glActiveTextureARB( GL_TEXTURE0_ARB );
glEnable( GL_TEXTURE_2D );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glBindTexture(GL_TEXTURE_2D,nom[0]);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);

glActiveTextureARB( GL_TEXTURE1_ARB );
glEnable( GL_TEXTURE_2D );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS );
glBindTexture(GL_TEXTURE_2D,nom[1]);
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
glBindTexture(GL_TEXTURE_2D,nom[2]);
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE );
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
glTexEnvi( GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_MODULATE );
__________________________________________________ ________

thank you very much.

CrazyButcher
01-15-2006, 08:57 AM
with tex_env_crossbar or nv_combine4:
tex0 = unit0 with grass
tex1 = unit1 with soil
tex2 = unit2 with greyscale (you should pack greyscale as 8bit alpha-texture)

combiner
tex0 =
color: decal between tex0 and tex1, using tex2 alpha
tex1 = replace prev
tex2 = replace prev

without those extensions
units
tex0 = mix texture
tex1 = grass
tex2 = soil

combiner
tex0 = replace
tex1 = colorop: replace tex , alphaop: replace prev
tex2 = decal: between prev and tex using prev.alpha

dorbie
01-16-2006, 08:53 AM
You can do it with vanilla ARB env combine and ARB crossbar and a single combiner unit. Simply set each texture as each of the three inputs and use an INTERPOLATE capability to interpolate between the two images using your ramp texture, the ramp would be the third input (arg2).

http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_env_combine.txt

This will be supported functionality on pretty much all modern cards and is even part of core OpenGL now so you can use it with confidence.

dletozeun
01-20-2006, 12:07 PM
Thank you for replying me and excuse me for this late answer...
But I'm only a beginner with multitexturing and I didn't understand all you have said...

In fact I don't know how I can adapt all you have said...

How can I integrate tex_env_crossbar or nv_combine4 or vanilla ARB env combine and ARB crossbar in my code??

Thank you.

dorbie
01-20-2006, 12:34 PM
ARB combiners and ARB crossbar are part of the core.

Vanilla just means 'nothing fancy', or unadulterated.

No need to integrate to integrate anything, do it my way and use a single texenv unit and 3 texture images.... hmmm you may need to use the last available texture unit instead of the first. It's all supported in teh shipping values. You need only make the OpenGL texparameter calls with the appropriate combiner and crossbar tokens, it's easy.

dletozeun
01-20-2006, 01:26 PM
Maybe i'm hopeless but I don't understand how I can do that!
Can you explain me with an example, please?

And I saw in a discussion this:

INTERPOLATE_ARB -- Interpolate (blend) between source0 and source1 using source2 as a t factor

It seems to be easy but when I set grass as source0 , soil as source1 and greyscale texture as source2 it doesn't work...

thans a lot for your patience!

ScottManDeath
01-21-2006, 01:28 AM
Just removed the dust from a tool I wrote a couple of years ago (yuck, am I doing this for that long time already :rolleyes: ). It lets one "click" everything together and generates proper code for it :)


Originally posted by CrazyButcher:
with tex_env_crossbar or nv_combine4:
tex0 = unit0 with grass
tex1 = unit1 with soil
tex2 = unit2 with greyscale (you should pack greyscale as 8bit alpha-texture)

combiner
tex0 =
color: decal between tex0 and tex1, using tex2 alpha
tex1 = replace prev
tex2 = replace prev

Originally posted by CrazyButcher:
without those extensions:
units
tex0 = mix texture
tex1 = grass
tex2 = soil

combiner
tex0 = replace
tex1 = colorop: replace tex , alphaop: replace prev
tex2 = decal: between prev and tex using prev.alpha[/qb]
// 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_TEXTURE_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_TEXTURE1);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);

// ALPHA combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_ALPHA,GL_REPLACE);
glTexEnvi (GL_TEXTURE_ENV,GL_ALPHA_SCALE,alpha_scale0);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_ALPHA,GL_TEXTURE);
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_TEXTURE_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_REPLACE);
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_TEXTURE_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_PREVIOUS);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);
// arg 1
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE1_RGB,GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND1_RGB,GL_SRC_COLOR);
// arg 2
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE2_RGB,GL_PREVIOUS);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND2_RGB,GL_SRC_ALPHA);

// ALPHA combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_ALPHA,GL_MODULATE);
glTexEnvi (GL_TEXTURE_ENV,GL_ALPHA_SCALE,alpha_scale2);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_ALPHA,GL_PREVIOUS);
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);

CrazyButcher
01-21-2006, 04:02 AM
this tool is quite old, but illustrates arb_tex_env_combine

http://www.ati.com/developer/sdk/rage128sdk/Multex/OGLMultex.html

nv_combine4 or arb_tex_env_crossbar let you pick different source textures (not just current/previous)

dletozeun
01-21-2006, 10:20 AM
ScottManDeath> Thank you for your reply, but your solution seems to be a little complicated...

I've try to integrate it in my code but it doesn't work...
Moreover, the textures that I use haven't an alpha layer...and severals lines in this code seems to be not useful ( for what i want to do), like these:

glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,env _color2);
or
glTexEnvi (GL_TEXTURE_ENV,GL_RGB_SCALE,rgb_scale2);

CrazyButcher> thank you but this tool illustrate only blending between two textures using their alpha layer and not a gray scale texture...

CrazyButcher
01-21-2006, 12:56 PM
interpolate operand can be set to COLOR as well, so you dont necessarily need to use alpha.

the sample actually lets you change many parameters

you dont need to use those 2 commands. in your original post you were already using tex_env_combine, you just didnt set all commands, like operands, and sources.

like for interpolate, source2 set to your texture that contains the greyscale, you would also need to set the operand to COLOR and not ALPHA with following

glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);

dletozeun
01-21-2006, 01:45 PM
In ARB_texture_env_combine specs I saw this :

COMBINE_RGB_ARB Texture Function
------------------ ----------------
REPLACE Arg0
MODULATE Arg0 * Arg1
ADD Arg0 + Arg1
ADD_SIGNED_ARB Arg0 + Arg1 - 0.5
INTERPOLATE_ARB Arg0 * (Arg2) + Arg1 * (1-Arg2)
SUBTRACT_ARB Arg0 - Arg1

So if I set grass as source0, soil as source2 and grayscale texture as source1 I would obtain what I want to do...
But there is something wrong because if I do that it doesn't work:

glActiveTextureARB( GL_TEXTURE0_ARB );
glEnable( GL_TEXTURE_2D );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glBindTexture(GL_TEXTURE_2D,nom[0]);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);

glActiveTextureARB( GL_TEXTURE1_ARB );
glEnable( GL_TEXTURE_2D );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);

glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS );
glTexEnvi( GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);

glBindTexture(GL_TEXTURE_2D,nom[2]);
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
glTexEnvi( GL_TEXTURE_ENV,GL_OPERAND1_RGB,GL_SRC_COLOR);

glBindTexture(GL_TEXTURE_2D,nom[1]);
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE );
glTexEnvi( GL_TEXTURE_ENV,GL_OPERAND2_RGB,GL_SRC_COLOR);

glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE );

where nom[0] is soil
nom[1] grass
nom[2] grayscale

Moreover it is really strange but if I invert the two last paragraphs It does'nt do the same thing!!
With the code above I obtain a the product between grass and soil only...and with tje code below I obtain the product between soil and greyscale only...where is interpolation here??

glActiveTextureARB( GL_TEXTURE0_ARB );
glEnable( GL_TEXTURE_2D );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glBindTexture(GL_TEXTURE_2D,nom[0]);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);

glActiveTextureARB( GL_TEXTURE1_ARB );
glEnable( GL_TEXTURE_2D );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);

glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS );
glTexEnvi( GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);

glBindTexture(GL_TEXTURE_2D,nom[1]);
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE );
glTexEnvi( GL_TEXTURE_ENV,GL_OPERAND2_RGB,GL_SRC_COLOR);

glBindTexture(GL_TEXTURE_2D,nom[2]);
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
glTexEnvi( GL_TEXTURE_ENV,GL_OPERAND1_RGB,GL_SRC_COLOR);

glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE );

CrazyButcher
01-22-2006, 03:31 AM
you are not using arb_combine correctly
it works per-stage, not as total effect

the ati sample actually illustrates this, too

e.g. you want to interpolate between 2 textures
you would bind texture 0 and set it to replace
then you would bind texture 1 and set combiner_rgb to interpolate.
now you need to specify all operands/sources for this stage.
which results into something what ScottManDeath has posted.
each combiner runs independent of the ones bound to other texture units.

another mistake is that you bind 2 textures to the same textureunit (nom1 and nom2) so only the last one nom2 will be really used.

you can only bind 1 texture per texture unit.

dletozeun
01-22-2006, 06:51 AM
So what can I do to solve this problem?

I don't know how I can do this without two glBindTexture...

CrazyButcher
01-22-2006, 08:54 AM
you cant do this effect if your card supports just 2 texture units.

if you have more, use activetexture to activate the third texture unit and bind the proper texture to it.

the thread should contain enough info, after all scottman already posted large portions of code. you have to work yourself thru understanding arb_tex_env_combine and how multi-texturing works in general...

dletozeun
01-27-2006, 11:53 AM
My graphic card support more than 2 textures...
But I'm a beginner with multitexturing in opengl and I swear that I tried to use scottManDeath's code but in my opinion it is really difficult to obtain the effect that I want! Moreover scottManDeath in his code set alpha layer for all texture unit...and what I want to do is just mix grass texture and soil texture with grayscale as mix factor...
Perhaps I could multiply grass texture with grayscale and on a other side multiply soil texture with grayscale inverted and finally adding the two textures obtained...but I think it is not possible to do this with opengl and it is not fast...

I have another question: what is the difference between GL_TEXTURE and GL_TEXTURE1 ?? When I replace GL_TEXTURE in scottManDeath's code by GL_TEXTURE it don't work at all!

thank you

dletozeun
01-27-2006, 02:36 PM
this what I do now to set up the textures, but I don't understand why it doesn't work....

nom[0] is soil
nom[1] grass
nom[2] grayscale (now it is a TGA texture were the gray scale is the alpha layer)

//|texture unit 0|
//----------------
GLint alpha_scale0 = 1;

glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,nom[2]);

glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);

// RGB combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULATE);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_TEXTURE1);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);

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

//----------------
//|texture unit 1|
//----------------
GLint alpha_scale1 = 1;

glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,nom[1]);

glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);

// RGB combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_REPLACE);

// 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_REPLACE);
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|
//----------------
GLint alpha_scale2 = 1;

glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,nom[0]);

glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);

// RGB combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_ADD);

// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_PREVIOUS);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE1_RGB,GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND1_RGB,GL_SRC_COLOR);

// 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_SOURCE1_ALPHA,GL_PREVIOUS);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND1_ALPHA,GL_ONE_MINUS_SRC
_ALPHA);

tamlin
01-27-2006, 04:19 PM
The comment says "texture unit 2" but the code i still using TU 1.

dorbie
01-27-2006, 04:22 PM
It doesn't work because you've not done what some posters have written here.

Use interpolate and crossbar, 3 texture images into one texenv unit with interpolate. Use the last unit.

Unless your next post begins "It's working!" or "I've tried to use interpolate on the third texenv unit with 3 active textures as the inputs in the few combinations available" then don't post until you've done some more work on the problem.

It is simple to use crossbar, you just specify a texture unit token (numbered unit) as the input to a combiner argument.

dorbie
01-27-2006, 04:34 PM
Set up the textures on 3 enabled units and on unit 3 (i.e. GL_TEXTURE2) the one with the ramp image do this:

glActiveTextureARB(GL_TEXTURE2);

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_TEXTURE0);
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE1_RGB,GL_TEXTURE1);
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE2_RGB,GL_TEXTURE2);

No need for alpha if your ramp is grey in color. See how simple it could have been ;-)
(You are invited to go back & read my first post in this thread now.)

Butcher tried to help too (gj) but this thread went to hell fast. Butcher's DECAL (P.S. decal isn't but blend would be(P.P.S. BLEND equivalency isn't a biggie since there's a dependency of crossbar on combine)) on the first unit with passthrough on later units is equivalent. All this got lost in the noise. Just because someone posts code doesn't mean you should ignore other posters, you were told the simplest way to do this at least twice from two sources in this thread.

dletozeun
01-28-2006, 11:58 AM
I have really work on this part of code, I have spent hours on this , modifying it, trying to find the way to do the mix that I want, searching on the net documentations...on extensions but they are always not explicit!
So, please, don't tell me that I have not work on it! I don't understand how I could guess the way to do multitexturing with opengl without some piece of code who show me the way to use GL_ARB_texture_env_crossbar...
I try to do this, enablig UNIT0 and 1 to use the color of grass and soil texture and enabling finally Unit2 and do what you show me in your last post.But it still don't work...

tamlin> thank you! it was a careless mistake!

thank you.

andras
01-29-2006, 07:16 AM
Originally posted by dletozeun:
I don't understand how I could guess the way to do multitexturing with opengl without some piece of code who show me the way to use GL_ARB_texture_env_crossbar...First of all, you don't guess. OpenGL is not a guessing game. And you don't just blindy paste code, and hope that it works. You have to understand how it works.
The documentation is good. If you read the documentation carefully, you wouldn't need any sample code at all.
Ok, so here's the plan. Go and read section 3.8.13 in the OpenGL specification (Texture Environments and Texture Functions). It's only four pages and a couple of tables. It's dense though. So you read it slowly, and you make sure that you _understand_ every sentence. If you don't, then ask yourself what is it that you do not understand, and try to figure out that first.
Then, go through the sources posted here, one line at a time, look it up in the documentation, and see what it does.
If you do all this, you'll understand what these snippets do, and you can make them work in your program.
And please, next time you post, don't just say that "it doesn't work". And especially do _not_ simply ask "how do I make it work?"! You have to find out _what_ is it exactly, that you do not understand, and then ask for an explanation.

dletozeun
01-29-2006, 07:49 AM
Thank you I will try to read this next week...
Excuse me, i didn't think that what I said was not clear...I've explain a lot of time what I wan't to do...
But I have difficulties to make it work because I can't spent a lot of time on this...

thank you

dorbie
02-02-2006, 11:58 PM
My posted code works if you add:

glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND2_RGB, GL_SRC_COLOR);

This is because the default operand for GL_SOURCE2_RGB is actually the alpha component ?!! Yea go figure.

I think this is a horribly asymmetric API design decision that implies a preference for GL_DECAL as opposed say GL_BLEND using the INTERPOLATE mode, although both are trivially possible.

Anyhoo, this should get you going, make sure you have at least 3 texture units supported on your card.

Here is a screenshot of it working, I changed your ramp texture, click on the image for a higher resolution version:

http://www.freeimagehosting.net/uploads/th.b8caaf6bf0.jpg (http://www.freeimagehosting.net/b8caaf6bf0.jpg)

knackered
02-03-2006, 01:00 AM
...and now try that with lighting enabled. ;)

dletozeun
02-03-2006, 01:09 PM
hello,

Dorbie-> your picture is great but How did you set the textures units 0 and 1 ? Because I've set texture unit 2 like you have said and I did not obtain this result...
All I have is the grayscale texture's color on terrain instead of grass and soil...
I set the texture unit 0 and 1 in this way for grass and soil. It seems to be correct...

//|texture unit 0|
//----------------
glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,nom[0]);
glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
//RGB combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULATE);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_TEXTURE0);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);

//----------------
//|texture unit 1|
//----------------
glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,nom[1]);
glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
// RGB combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULATE);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_TEXTURE1);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);

Moreover I have read opengl specifications about texture mapping and multitexturing. I have not learnt much more that I known about glTexEnv* and multitexturing...
My graphic card is a geforce4 MMX 440, I saw on the web that it support three texture units and games like GTA san andreas Half life2 battlefield...work with this so I supposed that what I want could work...

Thanks

dorbie
02-03-2006, 02:53 PM
It doesn't matter how you set texenv on 0 and 1 you just need the texture image on there and enabled correctly.

It only matters what the combiner mode is set to on unit 2, and I've posted that code.

It works.

For multitexture your card supports only 2 full texture units (and even image units alone in ARB shader is still 2), see the table at the bottom of this page under "Extension specifics":

http://www.delphi3d.net/hardware/viewreport.php?report=753

Download glinfo2 from this site if you want your own personal report, it is a great utility.

You'll have to upgrade to another graphics card or use 2 passes if you really need texture to apply the ramp. You could alternatively use per vertex color to do the ramp, just apply primary color as the source2 and set up the interpolate with inputs on the second unit (unit 1).

Time to stick a fork in this one since you don't even have the texture units, quite the waste of time & effort.

dorbie
02-03-2006, 08:17 PM
@knackered

You could take the 3 textures into the second texenv set to INTERPOLATE and use PREVIOUS and PRIMARY_COLOR into the third texenv set to MODULATE and voila, lighting, no big deal.

knackered
02-04-2006, 02:47 AM
Yes, I know Dorbie, but you didn't consider lighting in your original post - your solution would have lit the first texture and interpolated with the other unlit texture. In fact, even if lighting was disabled, your solution would have been incorrect if the primary colour was anything other than white (eg. if the lighting and shadows were pre-baked into the vertex colours).
I'm not trying to be facetious, just pre-empting his next post.

dletozeun
02-04-2006, 10:23 AM
thank you very much for all these details.
glinfo is very useful! Now I'm sure that my graphic card suuport only 2 texture units...

But there is no mean to do this without two passes rendering?

otherwise...you said that I could use a color with the constant GL_PRIMARY_COLOR...
yes it is possible in my program to do that ( even if it could be less beautiful...)
But knackered said that it is not possible...is there an other constant that could set opengl to use a color that I define ??

dorbie
02-04-2006, 06:32 PM
@knackered,

sigh, my first post uses 3 texture inputs on one unit and works as requested, lighting is intentionally ingored because lighting was never asked for. Enabled or not it works. I don't use PREVIOUS etc, I use direct texture taps, lighting would not have affected anything.

PRIMARY_COLOR was only suggested as a means to apply a color ramp on a system where you only have 2 texture units, lighting is clearly not viable. This suggestion was made AFTER your remark.

Thanks for help with his 'next question' but anticipating that one is probably impossible and you're wrong not me. :p

dorbie
02-04-2006, 06:42 PM
@dletozeum,

knackered is wrong, or just causing trouble with a nit pick or more likely he's trying to make fun of you, (see the trouble you cause knackered ;) )
With 2 units you take PRIMARY_COLOR into source 2 and the textures into source 0 and source 1 on the second unit.

If you also need lighting you could move all this to the first unit and set the operand to alpha for the ramp and modulate PREVIOUS with primary_color on the second unit. To drive this you set RGB to the lighting result and alpha to the ramp blend. Disable blending to avoid alpha fragment issues of course, but this was not part of the earlier discussion.

You have what you need. I'm done here.

dletozeun
02-05-2006, 05:12 AM
:D Thank you dorbie! You give me a glimmer of hope!

I don't if it is me but I don't understand the last paragraph of your post...
You speak about alpha and color at the same time...and finally I don't see what I have to do...

I need lighting in my program and now I obtain that
http://www.freeimagehosting.net/uploads/th.a702765586.jpg (http://www.freeimagehosting.net/a702765586.jpg)

It is very strange: in fact, more the terrain is drak ( less it is lighted ) more the grass and soil textures are mixed!

this what I am doing to obtain this :

//|texture unit 0|
//----------------
glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,nom[0]);
glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
//RGB combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULATE);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);

//----------------
//|texture unit 1|
//----------------
glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,nom[1]);
glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
// RGB combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_INTERPOLATE);
// arg 0
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_PREVIOUS);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE1_RGB,GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND1_RGB,GL_SRC_COLOR);
glColor3f(0.8,0.8,0.8);// I hope this line could change the color set by primary_color, vut nothing change...
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE2_RGB,GL_PRIMARY_COLOR);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND2_RGB,GL_SRC_COLOR);

CrazyButcher
02-05-2006, 06:35 AM
tex0: interpolate texture0/texture1 with primary_color.alpha as value2
tex1: modulate previous with primary_color.rgb

that will mix textures and do lighting, but requires arb_crossbar/nv_combine4.

Without those two extensions you cannot mix and modulate with light in a single pass.

dorbie
02-05-2006, 04:43 PM
You have some reading comprehension problems.

I'm getting annoyed because you just breeze over responses ignoring what has been written and post your next problem which has already been addressed.

READ your own thread, specifically my previous post!

Interpolate on the first unit and modulate on the second.

dorbie
02-05-2006, 07:44 PM
@crazybutcher, that's what I described but you don't need nv_combine4 you can select separate alpha and rgb operands just fine with ARB combine tex env.

knackered
02-06-2006, 12:53 AM
Ah, bugger, yes you're right dorbie - I misread your posts. Sorry.
dletozeun, I wasn't trying to make fun of you, it was just a misunderstanding on my part.

CrazyButcher
02-06-2006, 02:00 AM
but to interpolate between tex0 and tex1 in the first texunit, you need crossbar or combine4, else you dont have access to GL_TEXTUREn...
you dont need to use the combine4 function, but the extension is needed to allow access to all textures.. in regular arb_combine you only have current texture.

dletozeun
02-06-2006, 03:47 AM
:(Excuse me, you are right Dorbie, I have not read properly your post...maybe i was too quick...
Now I have understand what i have to do but like I have already said I will able to to that next week-end...

But there is something I still don't understand...because Dorbie said that I don't need crossbar or combine4 and CrazyButcher said that I need this!?
I need or not TEXTUREn ? :confused:
And how can I set two different textures as source0 and source1 in the same unit?

Thanks a lot!

CrazyButcher
02-06-2006, 05:01 AM
just use GL_TEXTUREn_ARB as source, it will work just fine if you have either crossbar or combine4 extension.

dorbie
02-06-2006, 10:50 AM
I never said you don't need crossbar, I said you don't need the the nvidia specific combiner extension, the ARB combine texenv does the job just fine. This means your software will work correctly on a broader range of platforms.

You still need crossbar to specify the sources, but the operand controls on each source are actually part of ARB texture env combine.

P.S. @ Crazybutcher, I see what happened, I read your post as meaning crossbar+combine4 not either or. We're obviously in violent agreement.

dletozeun
02-08-2006, 09:25 AM
ok thank you but I think that I don't have GL_ARB_texture_env_combine extension on my geforce4 MMX 440 ! according to delphi3D hardware registry...I will verify but I am almost sure...
So is there another mean to do the mix or I have to change my graphic card? :(

CrazyButcher
02-08-2006, 01:08 PM
you surely have it, else you hadn't gotten so far...
there is also an EXT_ version, which is really old.

dletozeun
02-09-2006, 07:03 AM
I have not GL_ARB_texture_env_combine on my graphic card but I have GL_NV_texture_env_combine4 ( I did see it) so I can keep my graphic card!
But what is the equivalent with ATI graphic cards?

thank you.

dorbie
02-09-2006, 12:31 PM
That graphics card supports env combine reporting both ARB and EXT strings (the right thing to do for compatability).

http://delphi3d.net/hardware/viewreport.php?report=943

More speed less haste, you need to slow down be a heck of a lot more careful before disagreeing with people who're trying to help you.

This has dragged on for weeks and now this.

You may want to check the gl release version incase combiners are in the core (this advice is platform dependent since the Windows ABI is locked in the past and technically should report all this stuff, other platforms can spin the major rev and drop the string [although it can cause issues exactly like this one so I'm not sure if they do]). Since you ran glinfo2 I suspect you're on windows and therefore you're just not looking carefully enough.

Update your drivers, and if you still think it doesn't support combiners then take up bowling instead.

dletozeun
02-10-2006, 12:25 PM
Thank you! sorry I am confused but I made a big mistake when I said that I have not GL_ARB_texture_env_combine extension! In fact I wanted to say that I have not GL_ARB_texture_env_crossbar ! But I have the equivalent with GL_NV_texture_env_combine4...
That's why I would like to know what is the equivalent on ATI graphic cards when GL_ARB_texture_env_combine extension is not there..

I thought that I can't set more than one texture ( with GL_TEXTURE ) on the same unit...so I don't understand how I could set the grass and soil textures as source0 and 1 on the first unit...
And why I have to set the operand to alpha for the ramp? And with this operand alpha I take the color of ramp with GL_SRC_COLOR? In short, this passage is not clear...

Yes my OS in windows and now I am at home and I am sure that I have not crossbar extension.

thank you

dorbie
02-10-2006, 03:04 PM
It should probably report crossbar, you'll find it works, heck you're already feeding multile textures into a single unit.

Crossbar is trivial from an API point of view and it is working for you. It's the ability to specify other texture taps into a texenv, and yes NV combine4 does add this.

dletozeun
02-11-2006, 08:39 AM
ok but I am sure! I don't have crossbar and I am only trying to set multiple texture in the same texture unit and it doesn't work because I don't know the good way to do this form the beginnig of this thread...
Otherwise have you got some piece of code that could give me some examples in order to I know how I have to use this extension...

for example if I can use two textures in the same unit I could modulate two textures in this way (without lighting):

glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE4_NV );
//RGB combiner setup
glTexEnvi (GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULATE);

glBindTexture(GL_TEXTURE_2D,nom[0]);
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR);
glBindTexture(GL_TEXTURE_2D,nom[1]);
glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE1_RGB,GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND1_RGB,GL_SRC_COLOR);

But i see only the second texture ( nom[1] ) on the terrain...

CrazyButcher
02-11-2006, 08:50 AM
bloody hell, you cant bind 2 textures to the same unit... as frequently stated

crossbar/combine4 allow you to code the combiner of the texunit in a fashion you can access from other bound texunits. that's all...

stop guessing around, and start reading the spec + experimenting on your own. it's pure a + b = c math going on in the texunit combiners... make sure you set ALL operands/sources that are needed for the function.

you dont need to use combine4, just regular combiners will do.
the combine4 extensions just also allows to use GL_TEXTUREn_ARB as sources in regular combine, and has that special combine4 mode,which you dont need.



// texunit 0
vidSelectTexture(GL_TEXTURE0_ARB);
// bind whatever texture here
vidBindTexture(blubb);
// we do lerp(tex0,tex1,vertex.alpha)
vidTexEnvf ( GL_COMBINE );
vidComb_COMB_RGB ( GL_INTERPOLATE );
vidComb_SRC_RGB (0 , GL_TEXTURE1_ARB );
vidComb_OP_RGB (0 , GL_SRC_COLOR );
vidComb_SRC_RGB (1 , GL_TEXTURE);
vidComb_OP_RGB (1 , GL_SRC_COLOR );
vidComb_SRC_RGB (2 , GL_PRIMARY_COLOR );
vidComb_OP_RGB (2 , GL_SRC_ALPHA );


// texunit 1
vidSelectTexture(GL_TEXTURE1_ARB);
// bind the other texture here
vidBindTexture(blah);
// the combiner is set to just modulate with vertex.color as that contains the lighting
// we do modulate(previous,vertex.color)
vidTexEnvf ( GL_COMBINE );
vidComb_COMB_RGB (GL_MODULATE );
vidComb_SRC_RGB (0 , GL_PREVIOUS );
vidComb_OP_RGB (0, GL_SRC_COLOR);
vidComb_SRC_RGB (1 , GL_PRIMARY_COLOR );
vidComb_OP_RGB (1, GL_SRC_COLOR);

// the total thing
// lerp(tex0,tex1,vertex.alpha)*(vertex.color)

dorbie
02-11-2006, 10:16 AM
dletozeun,

the information you need has already been presented very clearly in this thread, you need to read it carefully and apply the techniques presented.

If you want advice on multitexture basics I suggest you start another thread in the beginners forum, I'm closing this thread.

Please don't be discouraged, you're close and already have a pretty decent screenshot. You need to slightly modify that code to use different units as explained earlier.

P.S. don't get distracted by the vid*() code crazybutcher just posted, dunno why he did that it's probably some framework/wrapper he's used to using, it isn't OpenGL, but it's clearly similar in structure. Read his code and deduce what the equivalent OpenGL texture environment call parameters should be, it's pretty easy.