PDA

View Full Version : Tricky Blending



Lehm
05-17-2005, 10:14 PM
I originally asked this in the beginners group awhile back, but the responses, while helpful, didn't solve my problem so I decided to bump it up here.

Basically I'm working with two texture units and polygon color. What I would like to do is have both texture units be modulated with the polygon color but not with each other. I have no idea if it's possible, I hope it is.

There are two methods that come close but don't quite do it.

Polygon
Texture1: Modulated
Texture2: Decal.

or

Polygon
Texture1: Decal
Texture2: Modulated,
...Source0 Polygon
...Source1 Texture2

The second one comes the closest but it causes the first texture to be masked out. I've tried hundreds of ways, changing everything from the blendmodes to rgbsources. I've gotten close, but can't seem to do it.

Any help would be greatly appreciated.

CrazyButcher
05-17-2005, 11:22 PM
use crossbar functionality:
ARB_texture_env_crossbar or NV_texture_env_combine4 extensions will help you.

using ARB_texture_env_combine you can do

tex0: interpolate tex0 and tex1
tex1: modulate prev with primary color

T101
05-17-2005, 11:31 PM
I'm still trying to get to grips with texture combiners myself (especially since I'm not sure if all texenv calls are local to the active texture stage), but how about something like this:


glActiveTexture(GL_TEXTURE0);
glBindTexture(walltextureID);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_CO MBINE);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_REPLACE );
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_TEXTURE );
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_CO LOR);

glActiveTexture(GL_TEXTURE1);
glBindTexture(decaltextureID);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_CO MBINE);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_INTERPO LATE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_TEXTURE );
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_CO LOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB,GL_PREVIOU S);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB,GL_SRC_CO LOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB,GL_TEXTURE );
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB,GL_SRC_AL PHA);

glActiveTexture(GL_TEXTURE2);
glBindTexture(walltextureID); // used as dummy texture
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_CO MBINE);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULAT E);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_PRIMARY _COLOR);

Using _three_ combiners, and ignoring the polygon color in the first stage. The decal would have to have an alpha channel (I presume it does).

The third stage modulates the combined "texture" with the primary color.

Lehm
05-18-2005, 12:43 AM
Originally posted by CrazyButcher:
use crossbar functionality:
ARB_texture_env_crossbar or NV_texture_env_combine4 extensions will help you.

using ARB_texture_env_combine you can do

tex0: interpolate tex0 and tex1
tex1: modulate prev with primary colorWhere can I find more on crossbar functionality? Well I found the Spec on it. Example source code would probably be more helpful.

Overmind
05-18-2005, 05:08 AM
It's a really simple extension that extends the combiners.

It just allows you to use GL_TEXTURE?_ARB (with ? being the number of a texture unit) as argument for GL_SOURCE?_RGB (or ALPHA), just like you would use GL_TEXTURE when you want the current texture unit.

CrazyButcher
05-18-2005, 05:21 AM
crossbar/combine4 allow you to use new targets in tex_combine functions as sources to the operation.

glTexEnvi(GL_TEXTURE_ENV,GL_SOURCEx_RGB,_TARGET_);

_TARGET_ can be GL_TEXTURE, GL_TEXTURE0_ARB, GL_TEXTURE1_ARB... GL_PRIMARY_COLOR, GL_CONSTANT, GL_PREVIOUS

you could also like T101 said use 3 stages, but likely if your hardware has more than 2 texture stages it will have crossbar or combine4

if you want to know more about ARB_texture_env_combine just use it as search keyword on the advanced forum you will find plenty threads

also this little app helps to play with the extension

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

Lehm
05-19-2005, 09:42 PM
I think I'm a little over my head here. I'm a little confused about how these two extensions are used. It'd be helpful to see an example. All I can find is documentation. I can't find any example code.

T101
05-19-2005, 10:33 PM
Well, judging from the descriptions, you should be able to do this:


glActiveTexture(GL_TEXTURE0_ARB);
glBindTexture(walltextureID);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_CO MBINE);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_INTERPO LATE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_TEXTURE 0_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_CO LOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB,GL_TEXTURE 1_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB,GL_SRC_CO LOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB,GL_TEXTURE 1_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB,GL_SRC_AL PHA);

glActiveTexture(GL_TEXTURE1_ARB);
glBindTexture(decaltextureID);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_CO MBINE);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULAT E);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB,GL_PRIMARY _COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB,GL_PREVIOU S);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB,GL_SRC_CO LOR);Although it will only work if the extension is supported.
And you should check your header file if it's GL_TEXTUREn or GL_TEXTUREn_ARB.

Obviously on combiner stage 0, GL_TEXTURE is equivalent to GL_TEXTURE0 etc.

Lehm
05-20-2005, 04:47 AM
So I don't have to do anything to enable it in code, if it's supported it will just work?

T101
05-20-2005, 05:30 AM
Judging by the extension spec (new state: none), you don't need to enable it.

So for a quick and dirty version, you should be able to just use it.
But if you want to be robust, you should check at runtime if the extension is supported on the card, and use a different method (3 units or multipass) if it's not.