Results 1 to 8 of 8

Thread: Masking

  1. #1
    Crunch
    Guest

    Masking

    How would I perform masking if my mask texture is separate from my color texture? In other words I have one texture with just alphas and another texture with just RGBs. For feasibility reasons it would not be practical for me to combine the mask and color bits into a single RGBA texture. ... and I've got lighting going too.

    The alpha stuff in the OpenGL guide always assumes the alphas are rolled in with the RGBs. Same with the blending and implementation of GL_DST_ALPHA in glBlendFunc is not universally supported.

    The stencil buffer seems to be the solution. Reducing the mask from 8bits to 1bit is still acceptable. My current stencil testing code causes the shape of the quad to be written to the stencil buffer when I'm really just looking for the white areas of my mask.

    Using version 1.1 and no extensions.

    Thanks

  2. #2
    Senior Member Regular Contributor
    Join Date
    Jul 2000
    Location
    Nice, France
    Posts
    201

    Re: Masking

    I've never done this, but I think you can texture w/ alpha values only. Combining this with multipass texturing and alpha test might do the job.

  3. #3
    Senior Member OpenGL Pro
    Join Date
    Jun 2000
    Location
    Shreveport, LA, USA
    Posts
    1,502

    Re: Masking

    When you draw the alpha texture into the stencil buffer, if you have alpha testing enabled and have the alpha test appropriately set, then it is possible just for the nonzero portion of the mask to be drawn. Then you can draw with the rgb texture using a stencil test. Instead of using a stencil buffer, you may use an alpha buffer. If you use an alpha buffer, then you will not need to use any alpha test. Either way, be sure you are using a 32 bpp mode.

  4. #4
    Crunch
    Guest

    Re: Masking

    Originally posted by Moz:
    I've never done this, but I think you can texture w/ alpha values only. Combining this with multipass texturing and alpha test might do the job.
    ---------------------------

    Hi Moz. I've gone and tested your suggestion first by texturing the alpha channel. No go. But here's what happened.

    I assume you ment to draw the alpha values first followed by the color texture. By alpha test I assume you ment glBlendFunc and not glAlphaFunc because glAlphaFunc only tests the alphas of incoming textures against a reference value and not the alphas in the framebuffer against a ref value. (Could I have been less wordy?)

    Anyways it seems the reason why whats below didn't work is because of line [8]. The glColor4f call of my quad sets the alpha in the framebuffer and not my mask. By varying the fourth parameter all, none or some of my color tex would appear. I thought of removing line [8] but then OpenGL would just use the alpha from what ever glColor call I did last. Bummer.

    I hope I interpreted your suggestion correctly.

    ------------------------------------------------------------------------

    // loaded mask as a one component with internal GL_ALPHA format
    glBindTexture( GL_TEXTURE_2D, maskName )
    glTexImage2D( GL_TEXTURE_2D, 0, 1, width, height, 0, GL_ALPHA,
    GL_UNSIGNED_BYTE, pMaskBits )

    // loaded color bmp as 3 component with internal format GL_BGR_EXT
    glBindTexture( GL_TEXTURE_2D, colorName )
    glTexImage2D( GL_TEXTURE_2D, 0, 3, _width, _height, 0, GL_BGR_EXT,
    GL_UNSIGNED_BYTE, pColorBits )

    // create plane for textures to sit on
    glNewList( listName, GL_COMPILE )
    glBegin( GL_QUADS )
    glNormal3f( 0.0f, 0.0f, 1.0f )
    [8] glColor4f( 0.5f, 0.0f, 0.0f, 0.5f )
    glTexCoord2fv( bottomRight ); glVertex2i( 40, -40 );
    glTexCoord2fv( topRight ); glVertex2i( 40, 40 );
    glTexCoord2fv( topLeft ); glVertex2i( -40, 40 );
    glTexCoord2fv( bottomLeft ); glVertex2i( -40, -40 );
    glEnd( )
    glEndList( )


    glClear( GL_COLOR_BUFFER_BIT );

    // no depth testing so mask does not fight with color tex
    glDisable( GL_DEPTH_TEST );

    // write to alpha layer only
    glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE );

    // Draw mask
    glEnable( GL_TEXTURE_2D );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
    glBindTexture( GL_TEXTURE_2D, maskName );
    glCallList( listName );

    glEnable( GL_LIGHTING );
    glEnable( GL_LIGHT0 );
    glLightfv( GL_LIGHT0, GL_POSITION, lightPos );

    // Write to RGB layers. Protect alphas.
    glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE );

    // Set to modulate because we got lights going for color tex.
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

    // Draw color texture
    glEnable( GL_BLEND );
    glBlendFunc( GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA );
    glBindTexture( GL_TEXTURE_2D, colorName );
    glCallList( listName );
    glDisable( GL_BLEND );

    glDisable( GL_LIGHT0 );
    glDisable( GL_LIGHTING );
    glDisable( GL_TEXTURE_2D );

    --------------------------------------------------

    I'm off to try DFrey's suggestions.

  5. #5
    Crunch
    Guest

    Re: Masking

    Originally posted by DFrey:
    When you draw the alpha texture into the stencil buffer, if you have alpha testing enabled and have the alpha test appropriately set, then it is possible just for the nonzero portion of the mask to be drawn. Then you can draw with the rgb texture using a stencil test
    Hi DFrey. I've tried your suggestion about using stencil and alpha testing prior to drawing the color texture. Unfortunately that didn't seem to work either.

    According to the guide if a fragment passes the alpha test then the fragment moves onto the stencil test. However if the fragment fails the alpha test then testing stops and OpenGL movies onto the next fragment. Fine.

    This is all very nice had OpenGL actually evaluated the alphas in my mask. Instead OpenGL chose to evaluate the alpha from glColor4f (line [8]) that was used to draw the quad my texture sits on. By changing glColor4f's alpha I saw everything or nothing. Removing the glColor4f call wouldn't have changed anything because OpenGL would then use what ever alpha was set from the most recent glColor call.

    Masking with the alpha mask split from the color texture is proving to be a royal pain.

    ----------------------------------------------------------
    // loaded mask as a one component with internal GL_ALPHA format
    glBindTexture( GL_TEXTURE_2D, maskName )
    glTexImage2D( GL_TEXTURE_2D, 0, 1, width, height, 0, GL_ALPHA,
    GL_UNSIGNED_BYTE, pMaskBits )

    // loaded color bmp as 3 component with internal format GL_BGR_EXT
    glBindTexture( GL_TEXTURE_2D, colorName )
    glTexImage2D( GL_TEXTURE_2D, 0, 3, _width, _height, 0, GL_BGR_EXT,
    GL_UNSIGNED_BYTE, pColorBits )

    // create plane for textures to sit on
    glNewList( listName, GL_COMPILE )
    glBegin( GL_QUADS )
    glNormal3f( 0.0f, 0.0f, 1.0f )
    [8] glColor4f( 0.5f, 0.0f, 0.0f, 0.0f )
    glTexCoord2fv( bottomRight ); glVertex2i( 40, -40 );
    glTexCoord2fv( topRight ); glVertex2i( 40, 40 );
    glTexCoord2fv( topLeft ); glVertex2i( -40, 40 );
    glTexCoord2fv( bottomLeft ); glVertex2i( -40, -40 );
    glEnd( )
    glEndList( )


    glClearStencil( 0 );
    glClear( GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );

    glDisable( GL_BLEND );

    // no depth testing so mask does not fight with color tex
    glDisable( GL_DEPTH_TEST );

    // Leave the color buffer alone
    glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );

    // any alpha other than 0 moves onto the stencil test
    glEnable( GL_ALPHA_TEST );
    glAlphaFunc( GL_GREATER, 0 );

    // any non-zero alpha becomes white in stencil buffer
    // alphas==zero don't make it this far and are discarded
    // before getting to the stencil test.
    glEnable( GL_STENCIL_TEST );
    glStencilMask( 1 );
    glStencilFunc( GL_ALWAYS, 1, 1 );
    glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );

    // Draw mask
    glEnable( GL_TEXTURE_2D );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
    glBindTexture( GL_TEXTURE_2D, maskName );
    glCallList( listName );
    glDisable( GL_ALPHA_TEST );

    // Update color buffer where stencil is white and
    // deny updates to stencil buffer.
    glStencilFunc( GL_EQUAL, 1, 1 );
    glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
    glEnable( GL_LIGHTING );
    glEnable( GL_LIGHT0 );
    glLightfv( GL_LIGHT0, GL_POSITION, lightPos );

    // Draw color texture
    glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
    glBindTexture( GL_TEXTURE_2D, colorName );
    glCallList( listName );

    glDisable( GL_LIGHT0 );
    glDisable( GL_LIGHTING );
    glDisable( GL_STENCIL_TEST );
    glDisable( GL_TEXTURE_2D );

  6. #6
    Senior Member OpenGL Pro
    Join Date
    Jun 2000
    Location
    Shreveport, LA, USA
    Posts
    1,502

    Re: Masking

    Well, that code looks like it should work. Indeed it looks very similar to some of my code that I know works. The only difference is you use a GL_ALPHA texture whereas I used a GL_RGBA texture. That was the only way I could get it to work if I didn't also enable a destination alpha buffer. If I did have an alpha buffer enabled, then I could get GL_LUMINANCE_ALPHA type textures to work even though I didn't use the destination alpha, but GL_ALPHA textures still failed.
    Starting to make me think that NVIDIA OpenGL implementation is not very robust when it comes to GL_ALPHA textures. Maybe Matt can clarify things.

  7. #7
    Crunch
    Guest

    Re: Masking

    Maybe Matt can clarify things.[/B]
    Who's Matt?


    I saw an odd thing at http://msdn.microsoft.com/library/default.asp
    You can find it by following these subsection titles in the table of contents:
    Platform SDK
    Graphics and Multimedia
    OpenGL
    Win32 Extensions to OpenGL
    OpenGL Reference
    GL functions
    glTexImage2D

    The description for parameter [format] when using GL_ALPHA is:
    "Each element is a single red component."
    and general comments
    "A texture image can have up to four components per texture element, depending on components. A one-component texture image uses only the red component of the RGBA color extracted from pixels."

    Intuitively I would have thought a one component GL_ALPHA texture uses the alpha component. Assuming this stuff about the red component is true that would mean I would have to:
    draw my mask to the red layer
    copy the red layer to the alpha layer
    clear the red layer
    finally draw my color texture?
    That's stupid.

  8. #8
    Senior Member OpenGL Pro
    Join Date
    Jun 2000
    Location
    Shreveport, LA, USA
    Posts
    1,502

    Re: Masking

    Matt is an NVIDIA OpenGL developer that frequents these forums. And I believe that MSDN article is just a copy and paste error.

    [This message has been edited by DFrey (edited 12-09-2000).]

Similar Threads

  1. masking
    By in forum OpenGL: Basic Coding
    Replies: 4
    Last Post: 04-11-2006, 03:58 AM
  2. Masking + Fog.....
    By PhotonMan in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 02-05-2004, 08:55 AM
  3. Masking + Fog
    By in forum OpenGL: Basic Coding
    Replies: 3
    Last Post: 01-30-2004, 10:06 AM
  4. Masking
    By xill in forum OpenGL: Basic Coding
    Replies: 7
    Last Post: 11-12-2002, 12:21 PM
  5. Masking?
    By imported_zedus in forum OpenGL: Basic Coding
    Replies: 4
    Last Post: 01-07-2002, 11:10 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean