Multitexturing->Mix two textures

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.

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

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:

…and now try that with lighting enabled. :wink:

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

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.

@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.

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.

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 ??

@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. :stuck_out_tongue:

@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 :wink: )
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.

:smiley: 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

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);

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.

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.

@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.

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.

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.

:(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!

just use GL_TEXTUREn_ARB as source, it will work just fine if you have either crossbar or combine4 extension.

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.