Jump to content
  • Advertisement
Sign in to follow this  
Majestik666

Display Red channel of a texture as luminance ?

This topic is 4961 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Quote:
Original post by Brother Bob
Now that you mentioned the 0.5 offset in the dot product equation, which I should have noticed myself, I doubt it's doable using the set of functions I mentioned in my post.

It's doable, it just involves a little biasing and range compression. The code below will simulate a non-biased standard dot product with the ARB_DOT3 extension.
It uses two texture units (first for prebiasing, second for the dot product), and will only operate on 7bit precision. On the other hand, you'll hardly notice the lacking bit in common operations (the code is used for on the fly greyscale conversion of colour images here). The texture to convert is expected to be bound to unit 0. The constant colour of unit 0 is fixed to (0.5, 0.5, 0.5). The constant colour of unit 1 contains your weights, biased into the 0.5 to 1 range (0.5 + weight * 0.5). Unit 1 needs to be activated, with some dummy texture bound to it.


void glColourArg0(int source, int operand)
{
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, source);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, operand);
}

void glColourArg1(int source, int operand)
{
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, source);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, operand);
}

void SetupDot3Combiners(void)
{
float c0[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
float c1[4];

c1[0] = 0.5f + 0.5f * red_weight;
c1[1] = 0.5f + 0.5f * green_weight;
c1[2] = 0.5f + 0.5f * blue_weight;
c1[3] = 1.0f;

glActiveTexture(GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glColourArg0(GL_TEXTURE, GL_ONE_MINUS_SRC_COLOR);
glColourArg1(GL_CONSTANT, GL_SRC_COLOR);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, c0);

glActiveTexture(GL_TEXTURE1);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
glColourArg0(GL_PREVIOUS, GL_ONE_MINUS_SRC_COLOR);
glColourArg1(GL_CONSTANT, GL_SRC_COLOR);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, c1);

glActiveTexture(GL_TEXTURE0);
}


Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Yann L
Quote:
Original post by Brother Bob
Now that you mentioned the 0.5 offset in the dot product equation, which I should have noticed myself, I doubt it's doable using the set of functions I mentioned in my post.

It's doable, it just involves a little biasing and range compression. The code below will simulate a non-biased standard dot product with the ARB_DOT3 extension.
It uses two texture units (first for prebiasing, second for the dot product), and will only operate on 7bit precision. On the other hand, you'll hardly notice the lacking bit in common operations (the code is used for on the fly greyscale conversion of colour images here). The texture to convert is expected to be bound to unit 0. The constant colour of unit 0 is fixed to (0.5, 0.5, 0.5). The constant colour of unit 1 contains your weights, biased into the 0.5 to 1 range (0.5 + weight * 0.5). Unit 1 needs to be activated, with some dummy texture bound to it.

*** Source Snippet Removed ***

Indeed. I never extended my thought to use a second dummy texture unit, thus I failed to find a solution. The problem I had was that I couldn't find a way to get the proper range on the texture color values (as in your first combiner).

Very clever use of operands and such to reach the final result, and a good demonstration that a fairly limited, but wisely choosen, set of functions (the extensions I mentioned) can be very versatile.

Share this post


Link to post
Share on other sites
I suppose you could also use the accumulator, you set it to GL_MULT and than use the luminance conversion constants to get RGB to luminance... but I never tried anything like that.

Share this post


Link to post
Share on other sites
Yann, are you sure you code works ?

can't get it to work on my texture :/
but I'm using a non square texture using the
texture_rectangle extension, could that be the problem ??

Thanks a lot anyway !!!
Francois

Share this post


Link to post
Share on other sites
Quote:
Original post by Majestik666
Yann, are you sure you code works ?

Yes.

Quote:

can't get it to work on my texture :/
but I'm using a non square texture using the
texture_rectangle extension, could that be the problem ??

No.

Post your entire combiner setup code.

Share this post


Link to post
Share on other sites
here it is ...
i stripped it down a bit (move texture loading etc) to make it more
readable, but no code change :

glActiveTexture(GL_TEXTURE0);
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, text_id);
glTexImage2D( GL_TEXTURE_RECTANGLE_ARB,
0,
GL_RGB,
w,h,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
(GLvoid *)pixels);

weights[0] = 1.00f; weights[1] = 0.00f; weights[2] = 0.00f;

float c0[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
float c1[4];

c1[0] = 0.5f + 0.5f * weights[0];
c1[1] = 0.5f + 0.5f * weights[1];
c1[2] = 0.5f + 0.5f * weights[2];
c1[3] = 1.0f;

glActiveTexture(GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, c0);

glActiveTexture(GL_TEXTURE1);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, c1);

glActiveTexture(GL_TEXTURE0);

am I doing something completly wrong ? :/

Thanks !

Share this post


Link to post
Share on other sites
Are you actually enabling the two texture units, and does the second unit have a valid dummy texture bound? If you don't have a valid texture bound to a unit, the unit is disabled, even thouhg you're actually using it for something.

So something like this, ignoring the actual combiner setup.

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, text_id);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
...

glActiveTexture(GL_TEXTURE1);
glBindTexture(some texture target, some dummy texture id);
glEnable(some texture target);
...

The dummy texture id in the second unit can, I believe, be the same as in the first unit. In any case, it must be an existing, and valid, texture. You can also create a 1x1 texture with arbitrary data just to have something valid to bind.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!