PDA

View Full Version : Reg Combiners ... Clueless



Shag
03-07-2002, 06:28 AM
OK - this is the first time I've used register combiners, and I'm stuck.

I want to take an RBG texture and occasionally convert it to gray scale. But I haven't got a clue how to do it quite frankly.

I know that I need to ...
input RGBA

and output
R = (R * 0.3) + (G * 0.59) + (B * 0.11)
G = (R * 0.3) + (G * 0.59) + (B * 0.11)
B = (R * 0.3) + (G * 0.59) + (B * 0.11)
A = A

But I'm looking at sample code which seems to bear no resmeblence to the spec. I think I've confused myself here. Or maybe getting up at 3am didn't help!!!

My code so far is ...

glEnable(GL_REGISTER_COMBINERS_NV);
glDisable(GL_REGISTER_COMBINERS_NV);


Impressive huh? All I need is the bits in the middle. Can anyone help? Please?

Regards

NitroGL
03-07-2002, 06:33 AM
Originally posted by Shag:
OK - this is the first time I've used register combiners, and I'm stuck.

I want to take an RBG texture and occasionally convert it to gray scale. But I haven't got a clue how to do it quite frankly.

I know that I need to ...
input RGBA

and output
R = (R * 0.3) + (G * 0.59) + (B * 0.11)
G = (R * 0.3) + (G * 0.59) + (B * 0.11)
B = (R * 0.3) + (G * 0.59) + (B * 0.11)
A = A

But I'm looking at sample code which seems to bear no resmeblence to the spec. I think I've confused myself here. Or maybe getting up at 3am didn't help!!!

My code so far is ...

glEnable(GL_REGISTER_COMBINERS_NV);
glDisable(GL_REGISTER_COMBINERS_NV);


Impressive huh? All I need is the bits in the middle. Can anyone help? Please?

Regards

Ok, I've never used the registry combiners before, but what you want is (using NVParse):

const0 = (0.3, 0.59, 0.11, 1);
out.rgb = tex0.const0

I think that's right...

NitroGL
03-07-2002, 06:36 AM
Nope, that's not right...




const0 = (0.3, 0.59, 0.11, 1);
{
rgb
{
spare0 = tex0.const0
}
}
out.rgb = spare0


That should work.


[This message has been edited by NitroGL (edited 03-07-2002).]

Shag
03-07-2002, 06:40 AM
And in terms of

glCombinerInputNV()
glCombinerOutputNV()
etc

Regards

PH
03-07-2002, 06:54 AM
Using the spec and sample code to understand RC's is probably not the easiest way. Have a look at the RC presentations on NVIDIA's site, these contain invaluable diagrams.

Eric
03-07-2002, 07:00 AM
Funny, that was actually the purpose of an Effect I submitted to the nVIDIA contest that took place some time ago (no wonder why I didn't win a thing...).

Actually, I did two versions: one with texture shaders (which was the aim !) and then one with the register combiners (after I realised that it was the most obvious and simple solution...).

Anyway, here is the snippet that sets the RC up:




// Texture 0 - Normal texture//
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,1);
glEnable(GL_TEXTURE_2D);
glEnable(GL_REGISTER_COMBINERS_NV);
glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV ,2);
float fGreyscale[4]={0.3,0.59,0.11,1};
glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV,fGre yscale);
float fAlpha[4]={0,0,0,fFade};
glCombinerParameterfvNV(GL_CONSTANT_COLOR1_NV,fAlp ha);
// Combiner 0 calculates the grey texture //
glCombinerInputNV(GL_COMBINER0_NV,GL_RGB,GL_VARIAB LE_A_NV,GL_TEXTURE0_ARB,GL_UNSIGNED_IDENTITY_NV,GL _RGB);
glCombinerInputNV(GL_COMBINER0_NV,GL_RGB,GL_VARIAB LE_B_NV,GL_CONSTANT_COLOR0_NV,GL_UNSIGNED_IDENTITY _NV,GL_RGB);
glCombinerOutputNV(GL_COMBINER0_NV,GL_RGB,GL_SPARE 0_NV,GL_DISCARD_NV,GL_DISCARD_NV,GL_NONE,GL_NONE,G L_TRUE,GL_FALSE,GL_FALSE);
// Combiner 1 interpolates between grey and color //
glCombinerInputNV(GL_COMBINER1_NV,GL_RGB,GL_VARIAB LE_A_NV,GL_TEXTURE0_ARB,GL_UNSIGNED_IDENTITY_NV,GL _RGB);
glCombinerInputNV(GL_COMBINER1_NV,GL_RGB,GL_VARIAB LE_B_NV,GL_CONSTANT_COLOR1_NV,GL_UNSIGNED_IDENTITY _NV,GL_ALPHA);
glCombinerInputNV(GL_COMBINER1_NV,GL_RGB,GL_VARIAB LE_C_NV,GL_SPARE0_NV,GL_UNSIGNED_IDENTITY_NV,GL_RG B);
glCombinerInputNV(GL_COMBINER1_NV,GL_RGB,GL_VARIAB LE_D_NV,GL_CONSTANT_COLOR1_NV,GL_UNSIGNED_INVERT_N V,GL_ALPHA);
glCombinerOutputNV(GL_COMBINER1_NV,GL_RGB,GL_DISCA RD_NV,GL_DISCARD_NV,GL_SPARE1_NV,GL_NONE,GL_NONE,G L_FALSE,GL_FALSE,GL_FALSE);
glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);


Hopefully this is enough for you to go on (I don't remember the effect itself very well but I can have a look if something is missing).

If you want the full source code, I can e-mail it to you.

Regards.

Eric

EDIT: Just remembered that this actually more than you need ! This piece of code also interpolates between the greyscale version and the colored one according to the alpha value of GL_CONSTANT_COLOR1_NV... Anyway, you should be able to remove the useless part !

[This message has been edited by Eric (edited 03-07-2002).]

Shag
03-07-2002, 07:06 AM
Cheers Eric/Opla, much appreciated.

The spec implies

glCombinerInputNV(GL_COMBINER0_NV, GL_RGB
should be ...
glCombinerInputNV(GL_RGB, GL_COMBINER0_NV

or am I just reading this wrong?

*Head spinning* lol

Thanks again

[This message has been edited by Shag (edited 03-07-2002).]

Eric
03-07-2002, 07:18 AM
The specs says:




GLvoid glCombinerInputNV(GLenum stage,GLenum portion,GLenum variable,GLenum input,GLenum mapping,GLenum componentUsage);


Stage is GL_COMBINERi_NV and portion is GL_RGB or GL_ALPHA.

Why do you say that the specs imply the opposite ?

Regards.

Eric

opla
03-07-2002, 07:19 AM
it's glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, ...

opla
03-07-2002, 07:21 AM
Arghh, Eric was faster ...

Eric, je n'ai toujours pas reussi a t'envoyer d'email. a chaque fois j'ai un message d'erreur. peut-etre un filtre anti-spam ...

Shag
03-07-2002, 07:25 AM
sacre bleu!

I wrote down the params to each of the function - and for some reason swapped PORTION and STAGE around.

Some people are beyond help ... no clues as to who!

Shag
03-07-2002, 07:41 AM
If it's of any use to anyone else, this works. But obviously there's no lighting ... yet http://www.opengl.org/discussion_boards/ubb/smile.gif




float Grey[4] = {0.3f, 0.59f, 0.11f, 1.0f};

glEnable(GL_REGISTER_COMBINERS_NV);
glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV ,1);
glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, Grey);

glCombinerInputNV(GL_COMBINER0_NV,GL_RGB,GL_VARIAB LE_A_NV,GL_TEXTURE0_ARB,GL_UNSIGNED_IDENTITY_NV,GL _RGB);
glCombinerInputNV(GL_COMBINER0_NV,GL_RGB,GL_VARIAB LE_B_NV,GL_CONSTANT_COLOR0_NV,GL_UNSIGNED_IDENTITY _NV,GL_RGB);
glCombinerOutputNV(GL_COMBINER0_NV,GL_RGB,GL_SPARE 0_NV,GL_DISCARD_NV,GL_DISCARD_NV,GL_NONE,GL_NONE,G L_TRUE,GL_FALSE,GL_FALSE);

glPushMatrix();
glRotated(yrot,0,0,1);
glCallList(2);
glPopMatrix();

glDisable(GL_REGISTER_COMBINERS_NV);


Regards

[This message has been edited by Shag (edited 03-07-2002).]

Nutty
03-07-2002, 08:06 AM
Where does 0.3, 0.59, and 0.11 come from?

Is this some magical gray-scale conversion numbers that some genius devised one day or something?

NitroGL
03-07-2002, 08:13 AM
Originally posted by Nutty:
Where does 0.3, 0.59, and 0.11 come from?

Is this some magical gray-scale conversion numbers that some genius devised one day or something?

Pretty much...

Shag
03-07-2002, 08:17 AM
Yeah - it's magic. I spent the last few weeks devising a method to accurately describe the luminunce value from an RGB input.

OK, I lied. I saw it in a post in here http://www.opengl.org/discussion_boards/ubb/smile.gif

Apparently it's used to convert colour TV signals etc to B&W.

[This message has been edited by Shag (edited 03-07-2002).]

Eric
03-07-2002, 11:51 PM
I don't think you can find a method that would actually prove that these values are correct: they just reflect how each component (R,G,B) is seen in terms of luminance by the human eye.

Basically, green is the brightest, then comes red, and then blue.

I have searched the web for a scientific explanation but I suppose the guy who defined those values did a good old "trial'n'error" experiment !

Regards.

Eric

Relic
03-08-2002, 01:30 AM
Aren't these constants derived from the behaviour of an NTSC (Never The Same Color) scheme. (A happy PAL user http://www.opengl.org/discussion_boards/ubb/wink.gif)

Well, Roy Hall "Illumination And Color In Computer Generated Imagery" names a few other constants too, but in Section 5.2 "NTSC and RGB Video" footnote 15 you'll find
Y = 0.299 * R + 0.587 * G + 0.114 * B.
which is one of the three components YIQ (cite) "used in some broadcast components and recording formats such as Betacam".
For people interested in the two other components they are
I = 0.877 * (R-Y)
Q = 0.493 * (B-Y)

[This message has been edited by Relic (edited 03-08-2002).]

Humus
03-08-2002, 02:57 AM
A sidenote .. you don't need register combiners to do this, the GL_ARB_texture_env_dot3 extension is sufficient and allows it to work on many cards, including the Radeon/GeForce/Kyro series.

glColor3f(0.3f, 0.59f, 0.11f);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGBA_EXT);

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_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);

mcraighead
03-08-2002, 03:47 AM
Not true, the dot3 extension doesn't allow you to disable the implicit scale and bias of [0,1] to [-1,1].

- Matt

Humus
03-08-2002, 10:06 AM
Heh, reminds me I've done the same mistake once before on this forum proposing the same nonworking solution to the very same problem. http://www.opengl.org/discussion_boards/ubb/smile.gif You can make it work though with the dot3 extension, but you'll burn another texture unit and loose some precision.

Can't wait to get 64bit rendering so we can just store stuff and their real values instead of squeezing it into [0,1].

davepermen
03-08-2002, 11:06 AM
can't wait for floatingpoint textures and pixelshaders.. (even if they would only be 16bit floats.. is there an IEEE standart for 16bit floats around?!)

as far as i can see, no.. only 4 standarts, single (ext single), double (ext double)
double is 64bits and ext-double 80bits as far as i know.. single 32bits, and what about single-ext?40?

[This message has been edited by davepermen (edited 03-08-2002).]

henrikd
03-11-2002, 12:32 PM
Poynton's Color FAQ (item #10) has another explanation of this: http://www.inforamp.net~poynton/ColorFAQ.html.

[QUOTE]Originally posted by Relic:
Well, Roy Hall "Illumination And Color In Computer Generated Imagery" names a few other constants too, but in Section 5.2 "NTSC and RGB Video" footnote 15 you'll find
Y = 0.299 * R + 0.587 * G + 0.114 * B.
which is one of the three components YIQ (cite) "used in some broadcast components and recording formats such as Betacam".