Blending in OpenGL
Hello everyone,
I am trying to use blending in OpenGL. I tried out a simple program, but it doesn't work. I render a quad at z = 4.0f(Green) and another quad at z = -2.0f(Red) and the two quads do not intersect. I have enabled blending using glEnable(GL_BLEND) and the depth test using glEnable(GL_DEPTH_TEST). The blending function I use is glBlendFunc(GL_SRC_ALPHA,GL_ONE). I use 1.0f for the alpha values. If my understanding is right, the quad at -2.0f should hide the quad at -4.0f. If I draw the quad at z=-2.0f first and then the quad at z=-4.0f, the hidden surfaces are removed. But if I draw them in the reverse order (z = -4.0f first and then z = -2.0f) there is a blending of colors. Can someone explain why this happens? Have I understood the blend function wrong?
Here's what I expect the program to do. The two quads should be drawn according to their depths, ie. the hidden surfaces should not be drawn and this should be done in the same way irrespective of the order in which they are drawn. When they intersect, blending should occur in the region of intersection. If I have gone wrong in coding this, what should I do to achieve the above result.
Here is a section of the code.
draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 50.0f, 0.0f, 0.0f, 0.0f, 0, 1, 0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glColor4f(0.0f,1.0f,0.0f,1.0f); //Green Quad
glBlendFunc(GL_ONE,GL_ONE);
glBegin(GL_QUADS);
glVertex3f(-5.0f,-5.0f,-4.0f);
glVertex3f(-5.0f,5.0f,-4.0f);
glVertex3f(5.0f,5.0f,-4.0f);
glVertex3f(5.0f,-5.0f,-4.0f);
glEnd();
glColor4f(1.0f,0.0f,0.0f,1.0f); //Red Quad
glBegin(GL_QUADS);
glVertex3f(-2.5f,-2.5f,-2.0f);
glVertex3f(-2.5f,2.5f,-2.0f);
glVertex3f(7.5f,2.5f,-2.0f);
glVertex3f(7.5f,-2.5f,-2.0f);
glEnd();
glflush();
}
Thank you,
Sriram.
P.S: I have tried using accumulation buffer to achieve the same result, but in vain. Is there a way, I can get through the accumulation buffer method?
Quote: Original post by absriram
Here's what I expect the program to do. The two quads should be drawn according to their depths, ie. the hidden surfaces should not be drawn and this should be done in the same way irrespective of the order in which they are drawn.
No. When you draw a quad it gets processed right then, so it depends on whats gone before it.
When you start you've got an empty depth buffer. Drawing an object tests its pixels against the *current* depth buffer and writes the pixels that pass (updating the depth buffer accordingly). Thats why if you draw the near then the far it looks normal.
Buf you draw the far then the near then the far actually gets written to the framebuffer. If you were using solid objects then the near object would then overwrite it correctly and you've get proper depth sorting.
However 'cos you're using blending you're not just replacing pixels but merging them with whats already present. Ideally for proper blending & depth sorting you 1. draw all solid objects. 2. disable depth writing (but leave enabled depth testing) and draw all transparent objects back to front.
[size="1"][[size="1"]TriangularPixels.com[size="1"]] [[size="1"]Rescue Squad[size="1"]] [[size="1"]Snowman Village[size="1"]] [[size="1"]Growth Spurt[size="1"]]
Just some quick advice after looking at your code: perhaps you should be changing the alpha value of glColor4f() to something less than 1.0f?
glColor4f(1.0f,0.0f,0.0f,0.5f);
glColor4f(1.0f,0.0f,0.0f,0.5f);
If I'm understanding correctly what you want to do then the way to do it is:
This first runs a depth-only pass to fill the depth buffer. The second pass renders the actual scene, providing occlusion because of the previous depth pass and blending where surfaces overlap (but only where they exactly overlap).
Enigma
glClear(GL_COLOUR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ANY_OTHER_BUFFER_BITS);setUpCamera();glDepthFunc(GL_LESS);glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);glDisable(GL_BLEND);renderScene();glDepthFunc(GL_EQUAL);glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);glEnable(GL_BLEND);renderScene();
This first runs a depth-only pass to fill the depth buffer. The second pass renders the actual scene, providing occlusion because of the previous depth pass and blending where surfaces overlap (but only where they exactly overlap).
Enigma
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement