Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Using Texture combiners to create a grayscale tex

  1. #1
    Intern Contributor
    Join Date
    Mar 2008
    Location
    Singapore
    Posts
    67

    Using Texture combiners to create a grayscale tex

    Hi guys,

    I'm been struggling to use texture combiners for a while now. If anyone could help me, that'd be nice. I cannot use shaders because we have to cater for low end graphics cards. So my only option is texture combiners.

    What I want to is this:

    1. Add the color (0.5,0.5,0.5,1.0) to texture0
    2. Perform a dot3 operation with texture1 and the result of Step1.

    Texture0 is a nice picture of a girl.
    Texture1 is a flat color with values (0.58, 0.58, 0.58 );

    If all goes well, I should get the grayscale texture as my final result. That's because the dot3 operation performs the following operation:

    4 * ( ( ( r0 - 0.5 ) * (r1 - 0.5 ) ) +
    ( ( g0 - 0.5 ) * (g1 - 0.5 ) ) +
    ( ( b0 - 0.5 ) * (b1 - 0.5 ) ) );

    So if I add r0,g0,b0 with 0.5 (thus canceling the -0.5 that occurs during the dot3 operation) and perform a dot3 operation with a texture having a color of (0.58 0.58, 0.58 ), i should end up with a result of

    ( ( r0 * 0.33 ) + ( g0 * 0.33 ) + ( b0 * 0.33 ) )


    I tried it out and I get a greyscale image for sure. But it's heavily contrasted. And I mean heavily! I did some debugging and it looks that the first operation is not being taken into account. i.e the GL_ADD operation

    Can someone please tell me what I'm doing wrong.

    thx.


    Below is my code:

    glActiveTextureARB( GL_TEXTURE0 );
    glEnable(GL_TEXTURE_2D );
    glBindTexture( GL_TEXTURE_2D, m_textureID0 );

    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );

    //Color Operation
    glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD );

    //source 0
    GLfloat rgba[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, rgba );
    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT );
    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );
    //Source 1
    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE0 );
    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR );



    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
    //Color Operation
    glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB );
    //Source 0
    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS );
    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );


    glActiveTextureARB( GL_TEXTURE1 );
    glEnable(GL_TEXTURE_2D );
    glBindTexture( GL_TEXTURE_2D, m_textureID1 );

    //Source 1
    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1 );
    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR );

    glActiveTextureARB( GL_TEXTURE1 );
    glDisable(GL_TEXTURE_2D );


    glBegin( GL_QUADS );

    glMultiTexCoord2fARB( GL_TEXTURE0, 0, 0 );
    glVertex3d( -1, -1, -2.0 );

    glMultiTexCoord2fARB( GL_TEXTURE0, 1, 0 );
    glVertex3d( 1, -1, -2.0 );

    glMultiTexCoord2fARB( GL_TEXTURE0, 1, 1 );
    glVertex3d( 1, 1, -2.0 );

    glMultiTexCoord2fARB( GL_TEXTURE0, 0, 1 );
    glVertex3d( -1, 1, -2.0 );

    glEnd();


    glActiveTextureARB( GL_TEXTURE0 );
    glDisable(GL_TEXTURE_2D );

  2. #2
    Senior Member OpenGL Pro Zengar's Avatar
    Join Date
    Sep 2001
    Location
    Germany
    Posts
    1,932

    Re: Using Texture combiners to create a grayscale tex

    Quote Originally Posted by matchStickMan
    I cannot use shaders because we have to cater for low end graphics cards. So my only option is texture combiners.
    Allow me to note that any low-level card manufactured during last five years support fragment shaders. Or do you have to support stuff like Geforce 4 too?

  3. #3
    Intern Contributor
    Join Date
    Mar 2008
    Location
    Singapore
    Posts
    67

    Re: Using Texture combiners to create a grayscale

    Hi Zengar,

    We have to support intel GMA 900 cards or something like that. And it's a card that we know for sure (we emailed intel ) does not support shaders.

  4. #4
    Senior Member OpenGL Guru Relic's Avatar
    Join Date
    Apr 2000
    Posts
    2,453

    Re: Using Texture combiners to create a grayscale

    First, you assume that the DOT3_RGB formula works on unclamped color values.
    As the spec says the DOT3 uses pseudo-signed math (alas the -0.5 bias) I don't expect it to work with values outside the range [0,1].
    If that's the case your algorithm is doomed.

    Adding 0.5 to a color value above 0.5 might saturate at 1.0 BEFORE the -0.5 bias is done inside the DOT3 operation.

    Your code looks bugged.

    OpenGL is a state machine. You have a
    glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD );
    ...
    glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB );
    after each other, which cancels out the GL_ADD.

    You actually disabled texture unit 1 before rendering and don't send texture coordinates for it which makes the GL_SOURCE1_RGB, GL_TEXTURE1 setup futile.
    The fixed function pipeline has a one-to-one relationship between units and MultiTextCoord slots.

    BTW, a nicer greyscale conversion from RGB uses the factors (0.3, 0.59, 0.11) in the dot product because green is percieved brightest, then red, then blue. Means you could even distinguish differently colored parts in the final greyscale image.

    Performance tip: Avoid double typed OpenGL API entry functions.

    Try if this works a little better. Untested!
    Mind, it'll never work this way if I'm right with the clamping at 1.0.
    (Combiners are outdated functionality. Get over it.)


    Code :
     glActiveTextureARB( GL_TEXTURE0 );
    glEnable(GL_TEXTURE_2D );
    glBindTexture( GL_TEXTURE_2D, m_textureID0 ); 
     
     
    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); 
    glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD );
     
    //source 0
    GLfloat rgba[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, rgba );
     
    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT );
    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );
     
    //Source 1
    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE0 );
    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR );
     
     
    glActiveTextureARB( GL_TEXTURE1 );
    glEnable(GL_TEXTURE_2D );
    glBindTexture( GL_TEXTURE_2D, m_textureID1 );
     
     
    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); 
    glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB );
     
    //Source 0
    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS );
    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );
     
    //Source 1
    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1 );
    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR );
     
     
    glBegin( GL_QUADS );
     
    glMultiTexCoord2fARB( GL_TEXTURE0, 0.0f, 0.0f );
    glMultiTexCoord2fARB( GL_TEXTURE1, 0.0f, 0.0f );
    glVertex3f( -1.0f, -1.0f, -2.0f );
     
    glMultiTexCoord2fARB( GL_TEXTURE0, 1.0f, 0.0f );
    glMultiTexCoord2fARB( GL_TEXTURE1, 1.0f, 0.0f );
    glVertex3f( 1.0f, -1.0f, -2.0f );
     
    glMultiTexCoord2fARB( GL_TEXTURE0, 1.0f, 1.0f );
    glMultiTexCoord2fARB( GL_TEXTURE1, 1.0f, 1.0f );
    glVertex3f( 1.0f, 1.0f, -2.0f );
     
    glMultiTexCoord2fARB( GL_TEXTURE0, 0.0f, 1.0f );
    glMultiTexCoord2fARB( GL_TEXTURE0, 0.0f, 1.0f );
    glVertex3f( -1.0f, 1.0f, -2.0f );
     
    glEnd();
     
    glDisable(GL_TEXTURE_2D );  // Unit 1
     
    glActiveTextureARB( GL_TEXTURE0 );
    glDisable(GL_TEXTURE_2D );

  5. #5
    Member Regular Contributor
    Join Date
    Apr 2007
    Location
    Fairfax, VA
    Posts
    252

    Re: Using Texture combiners to create a grayscale

    Quote Originally Posted by Zengar
    Quote Originally Posted by matchStickMan
    I cannot use shaders because we have to cater for low end graphics cards. So my only option is texture combiners.
    Allow me to note that any low-level card manufactured during last five years support fragment shaders. Or do you have to support stuff like Geforce 4 too?
    My TiBook is from 2002. While it's approaching time to replace the thing, it's still good enough for most purposes. I wouldn't assume "low-end" doesn't include it and similarly aged machines.

  6. #6
    Senior Member OpenGL Guru knackered's Avatar
    Join Date
    Aug 2001
    Location
    UK
    Posts
    2,833

    Re: Using Texture combiners to create a grayscale

    Ah, texture combiners, register combiners, it's all coming back to me now. What a living nightmare they were. I reallocated that part of my brain for other things a long time ago, like for tax returns. Good luck.

  7. #7
    Intern Contributor
    Join Date
    Mar 2008
    Location
    Singapore
    Posts
    67

    Re: Using Texture combiners to create a grayscale

    Hi guys,

    Tnx for all your responses.

    Relic, I tried what you suggested, ie disable texture unit 1 after drawing the quad. That doesnt seem to work cos I get a black screen.

    I was told that clamping only occured at the last step. So that's why I attempted the algorithm.

    Anyways I think it's time to give up those texture combiners. I've tried as much as possible to make it work.


    Tnx again for all your responses.

  8. #8
    Junior Member Newbie recipe for disaster's Avatar
    Join Date
    Apr 2008
    Posts
    5

    Re: Using Texture combiners to create a grayscale

    Quote Originally Posted by knackered
    Ah, texture combiners, register combiners, it's all coming back to me now. What a living nightmare they were. I reallocated that part of my brain for other things a long time ago, like for tax returns. Good luck.
    Don't combiners give better control over the displayed image then shaders? I would be interested in some links to working examples for shaders, preferably if they were for xcode. Thanks.

  9. #9
    Junior Member Regular Contributor
    Join Date
    Aug 2007
    Location
    USA
    Posts
    243

    Re: Using Texture combiners to create a grayscale

    No, they don't. Shaders are much, much more flexible and general. Take a look here for shaders.

  10. #10
    Member Regular Contributor
    Join Date
    Mar 2001
    Posts
    468

    Re: Using Texture combiners to create a grayscale

    If you have to deal with low end cards, you can always multi pass ( and don't care about the performance anyways) and accumulate the gray scale image in the frame buffer using blending (with all the precision issues). So you would render the texture three times, each time computing 0.33 times the respective color channel and using GL_ONE, GL_ONE as the blend function.

    According to http://en.wikipedia.org/wiki/Intel_G..._and_chipsets, the GMA 9XX chips are DX shader model 2.0 cards, so they should have basic GLSL support. But given intels driver policy, you might be screwed

    What OS do you have to support?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •