Trouble with alpha when drawing into FBO

Sage
Posts: 1,199
Joined: 2004.10
Post: #1
Hi,

It's been a long time since I was here... I used to frequent this forum a lot.

I'm having an issue when drawing into an FBO. My game's UI is drawn into an FBO which is then composited atop the gameplay rendering. In my specific situation, I'm showing a 'modal' dialog box, so the FBO's filled to a translucent middle grey, and then a text box is composited atop that fill in the center. The text box has rounded cornders and a dropshadow, so it has a roughly 4px region around if of < 255 alpha.

(Note: The text box is rendered offscreen by webkit, and has premultiplied alpha)

I expected the text box's dropshadow to composite nicely atop the translucent grey grey fill.

What actually happens is that the non-opaque alpha of the text box's dropshadow knocks out the destination alpha of the FBO, causing a transparent border around the text box.

Here's a screenshot: https://dl.dropbox.com/u/363720/screensh...aError.png

Now, my immediate assumption was that I needed to set glBlendEquation to GL_FUNC_ADD. I figured this would cause the incoming alpha to be added to the destination alpha, instead of overwriting it.

This doesn't help, though.

Here's what my drawing code looks like. I'm using libCinder, btw, in case you're wondering about the gl calls.

Code:
void RichTextBox::draw( const core::render_state &state )
{
    if ( !dismissed() && _renderedText )
    {
        real alpha = _alpha * _alphaMultiplier;

        Vec2i position = _position;
        if ( _initializer.modal )
        {
            //
            //    Modal text box is centered, and drawn over a solid color
            //

            position.x = layer()->size().x / 2 - _renderedText.getWidth() / 2;
            position.y = layer()->size().y / 2 - _renderedText.getHeight() / 2;

            ci::ColorA blankingColor = _initializer.blankingColor;
            blankingColor.a *= alpha;

            gl::color( blankingColor );
            glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
            gl::drawSolidRect( Rectf(0,0,layer()->size().x,layer()->size().y));
        }

        //
        // webkit generated texture is premultiplied, so use premultiplied blending
        //

        gl::color( alpha,alpha,alpha,alpha );
        glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
        glBlendEquation( GL_FUNC_ADD );

        gl::draw( _renderedText, position );

        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    }
}
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #2
You need to use glBlendFuncSeparate() I think. Off the top of my head that sounds like the blending function you'd already want to use though... so maybe I'm wrong about that. Would need to think about it more than I have time for. :-\

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #3
I gave that a stab, too, before I posted.

Code:
glBlendFuncSeparate( GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE );
glBlendEquation( GL_FUNC_ADD );
gl::draw( _renderedText, position );

I've been sleuthing - it's apparent that I'm leaving the GL state in some bad way in earlier draw calls. I'm doing a sort of 'binary search' of disabling stuff in the pipeline to figure out what exactly is breaking rendering.

What bugs me is that the call to glBlendEquation and glBlendFuncSeparate SHOULD have fixed this.

For what it's worth, here's what my rendering stages look like, sort of.

1) Game -> FBO -> GLSL filters -> screen
2) Player's UI -> FBO -> GLSLS filters -> screen
3) Game UI -> FBO -> GLSLS filters -> screen

The problem here is in #3. If I completely disable #2 the alpha bug is fixed. If I have #2 render directly to screen, the alpha bug is fixed.

I'm narrowing this down, but I'm really baffled.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #4
The OpenGL Profiler can show you current state, delta state, and the current contents of your buffers and textures, when stopped at a breakpoint (eg glBindFramebuffer Wink )

These days, that's not included with Xcode, it's a separate download with a wonky install process.
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #5
Just wanted to bump in to say it's good to see you here again TomorrowPlusX! Best of luck with your project Grin
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #6
@OneSadCookie Would be nice if they did similar things for regular GL like they've done with ES on iOS. :-\

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #7
I don't know what you're talking about... the tools? or the programmable blending? The latter is not supportable by desktop hardware. The former would indeed be nice.
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #8
Err, yeah. All the ES GL debugging/profiling tools that they have in Xcode now. Like the frame capture and "performance detective" (Who came up with that name?).

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #9
I'd like both please. In addition to the tools, it would indeed be nice to have programmable blending come to desktop hardware at some point. Fixed pipeline blending is obviously inflexible and frustrating at times.

I gave up trying "understand" blending or "guess" what works long ago and made a little routine to cycle through all permutations with a click or tap, and log the permutation each click/tap so I know what I'm looking at. It's a brute force approach but it has worked well for me when I get stuck. The results of the test tell me one of two things, either A) the blending I wanted for a particular purpose is not possible and I need a different approach, which is often the case, or B) I find the blending effect I was looking for.
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #10
Heh. Aren't there a bajillion possible blending modes though?

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #11
Yep, it can take a lot of clicking. How many clicks vs. how much time thinking it through and punching in more code? As it often turns out, I am really good at clicking compared to thinking. Plus, I sometimes stumble across some interesting blending effects, so it is instructive too.
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #12
(Oct 18, 2012 05:47 PM)OneSadCookie Wrote:  The OpenGL Profiler can show you current state, delta state, and the current contents of your buffers and textures, when stopped at a breakpoint (eg glBindFramebuffer Wink )

These days, that's not included with Xcode, it's a separate download with a wonky install process.

I've been away for a long weekend, back to work and debugging.

OneSadCookie: I live and die by the OpenGL profiler - it's been in my dock since 2004 or so. Trouble is, I've never really learned to use it to its full capabilities. I use it to verify texture objects, catch gl errors, simple stuff. I've never used it to figure out the overall GL state at a breakpoint. I think it's time I did.

Regarding the discussion of programmable blending: YES PLEASE.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #13
AnotherJake: I'm pretty sure there are too many blend modes these days for "click through them all" to be possible Wink
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #14
980 of them by my maths. 14 src/dest blend factors and 5 equations. Must be a well built mouse. Wink

Also... 980 of them, yet still often not the one I want. Heh. Programmable blending couldn't come to the desktop soon enough. Grin Does really no hardware support it other than Power VR?

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #15
(Oct 21, 2012 06:31 PM)AnotherJake Wrote:  I gave up trying "understand" blending ... I sometimes stumble across some interesting blending effects

Experimentation is great, and you will certainly stumble across new uses for SRC_ALPHA_SATURATE that way.

But there is no substitute for knowing what you want to accomplish, and then translating that into a series of math operators. Math is your friend.



(Oct 22, 2012 05:26 AM)TomorrowPlusX Wrote:  I've never really learned to use [OpenGL profiler] to its full capabilities.

The OpenGL Profiler User Guide in the Help menu isn't super helpful, is it.

Profiler Gems:

1) Breakpoint window > Actions > Break After Draws. Add or disable breakpoints as needed.
2) Breakpoint window > State > filter state changes by Since Last Breakpoint / From Default State. Any colored state here was set by your app (potentially a bug, when your rendering is wrong.)
3) Views > Buffers > Current Draw * Buffer. Now hit "Continue" a bunch and watch your app execute, one draw call at a time. (a.k.a. "live frame capture".)
4) when your shader doesn't work, live-edit it in the Resources window and Continue. I.e. simplify to pass-through, or output varyings or temp variables to narrow down bad execution.
5) Breakpoint window > Break on GL Error / VAR error / thread conflict. Leave these on, any hit is a (sometimes very difficult to find otherwise) bug in your app.

Quote:Regarding the discussion of programmable blending: YES PLEASE.

Desktop hardware can't do it like iOS. The closest we could get is NV_texture_barrier. If that sounds appealing, please file feature requests to Apple. A description of how you intend to use to make amazing, otherwise-impossible apps wouldn't hurt. Wink




(Oct 22, 2012 08:58 AM)Skorche Wrote:  980 of them by my maths. 14 src/dest blend factors and 5 equations.

That number is close (a bit high, because some of the factors weren't orthogonal) for OpenGL ten years ago, but you're way, way off now.

In recent GL versions, you have 19 blend factors (fully orthogonal) and 5 equations. And separate factors and equations for RGB and Alpha. And separate enables, factors, and equations for up to eight draw buffers. That's lots of combinations.

And if that isn't enough (from a white-box testing perspective) consider that some hardware has dedicated raster back-ends for different framebuffer formats (i.e. 8-bit blend, 16-bit blend, float blend), so you can't assume everything works if RGBA8 works. So multiply the whole number by the number of internalformats. And what about multisampling (blend-per-sample)? The number of possible combinations is really, really big.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  png without alpha fine, png with alpha, nothing dave05 6 6,500 Jun 11, 2005 10:31 AM
Last Post: dave05
  Premultiplied alpha trouble Fenris 21 10,788 Nov 8, 2004 12:47 AM
Last Post: aaronsullivan