glDisable(GL_BLEND) doesn't seem to work

Started by avm1979, March 12, 2008, 17:29:18

Previous topic - Next topic

avm1979

I've noticed that GL11.glDisable(GL_BLEND) doesn't seem to work in the way I'd expect it to.

Consider the following code:

begin render loop
   GL11.glEnable(GL_BLEND)
   GL11.glBlendFunc(...)
   // render sprite one
   GL11.glDisable(GL_BLEND)
   // render sprite two
end render loop

The problem is that sprite two is still rendered using the blend function specified earlier in the loop.

Am I misunderstanding how glDisable is supposed to work in this case, or is this a bug in my video card drivers, or something else?  If this is the "normal" behavior, what's the standard way of turning off blending?  I can work around this pretty easily by setting the blend function to (GL_ONE, GL_ZERO), but I imagine that has some performance overhead.  From reading gl docs, it seems like disabling blending in this way should work...

Thank you in advance for any insight.

My graphics card is an nvidia GeForce 7900, btw.

bobjob

not sure if it will help, but what is in your init GL code.

is aplha testing also enabled?

avm1979

Thanks for the reply.

Alpha testing is not enabled.  The following is the init code:
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glEnable (GL11.GL_BLEND);  // not sure if that's actually necessary? seems like it's not


In the main render loop, I'm entering/exiting ortho mode w/ the following code:


enter:
GL11.glPushAttrib(GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_ENABLE_BIT);
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();   
      
// now enter orthographic projection
GL11.glLoadIdentity();      
GL11.glOrtho(0, width, height, 0, -distance, distance);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_LIGHTING);

exit:
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPopMatrix();
GL11.glPopAttrib();

It all seems very basic, I'm not doing anything very involved as far as gl capabilities...

Fool Running

Are you trying to disable/enable the blending in between glBegin() and glEnd() calls?
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

avm1979

Nope, it's definitely not between begin and end calls.  I have a feeling that things would explode if that was the case.

It just seems that wherever I turn blending on (I've tried various places), I can't turn it off w/ GL11.glDisable.

From what you're saying, it sounds like what I'm doing should work, is that right?  Any thoughts on something I can try to diagnose this any further?

bobjob

yeah, from what your saying alone, it should be working fine.

Are you sure that GL11.glEnabled(GL11.GL_BLEND). is not getting called in your sprite render code?

avm1979

Quote from: bobjob on March 13, 2008, 06:37:24
Are you sure that GL11.glEnabled(GL11.GL_BLEND). is not getting called in your sprite render code?

Great idea, but unfortunately doesn't look like it  :)

Tried it on a different machine, btw, running Vista no less, and same got the same behavior, so it's really looking like something in my code.  I'll put together a primitive example that'll reproduce this, if you'd be kind enough to look at it.

avm1979

Figured it out.  Thanks for the help.

Turns out my original understanding of the problem was incorrect.  The sprites rendered before the one that was blended were showing up blended, not the ones after.  The code roughly looked like this:

render loop
  enterOrtho
  drawUnblendedSprite // shows up blended
  drawBlendedSprite // shows up blended
  drawUnblendedSprite // shows up unblended
  leaveOrtho
end render loop


The problem was that
1) GL_BLEND was enabled prior to entering ortho mode, but with the blend function being GL_ONE, GL_ZERO, so it didn't seem like blending was enabled.
2) in enterOrtho, the blend function was NOT being saved with the call to
GL11.glPushAttrib(GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_ENABLE_BIT),
but the GL_BLEND enable bit was.

So, when at the end of the loop, the attribute stack was popped (in leaveOrtho), it restored the blend enable bit (on) but left whatever blend function was being used by the blended sprite inside the ortho rendering part.  Consequently, the sprite rendered at the beginning of the ortho part was drawn using the re-enabled blend and the blend function from the previous iteration of the loop.

The solution was to store the blend function in enter ortho:
GL11.glPushAttrib(GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
and to disable blending in enter ortho, as well.