javaopenglimmediate-mode

OpenGL blending: Remove pixels being drawn over (immediate mode)


What I'd like to achieve is a blend where I draw two quads over eachother, both transparent, and the quad drawn last will cancel the colour of the previous quad completely, as if it was never there. However, it may not affect anything behind it besides that single other quad. Because I'm horrible at explaining, I made the following image:

enter image description here

I'm using very basic openGL immediate mode functions. Currently I have something along the lines of:

glEnable(GL_BLEND)
glColor4f(0,0,1,0.3f);
glBegin(GL_QUADS);
{
    glVertex2d(100, -100);
    glVertex2d(-100, -100);
    glVertex2d(-100, 100);
    glVertex2d(100, 100);
}
glEnd();
glColor4f(0,1,0,0.3f);
glBegin(GL_QUADS);
{
    glVertex2d(150, -50);
    glVertex2d(-50, -50);
    glVertex2d(-50, 150);
    glVertex2d(150, 150);
}
glEnd();

Solution

  • This isn't really a blending problem per se. One way to solve this would be to change the depth buffer comparison function. Use GL_LESS for the green square, while drawing the blue square first. This way the pixels of the green square overlapping the blue square, simply wouldn't be drawn at all to begin with.

    glDepthFunc(GL_LEQUAL);
    // Draw the blue square
    
    glDepthFunc(GL_LESS);
    // Draw the green square
    

    If you want to have elements visible under both the blue and green square. You could draw the first and then clear the depth buffer and then it's the same.

    glDepthFunc(GL_LEQUAL);
    // Draw the red squares
    
    glClear(GL_DEPTH_BUFFER_BIT);
    
    glDepthFunc(GL_LEQUAL);
    // Draw the blue square
    
    glDepthFunc(GL_LESS);
    // Draw the green square
    

    Whether there's a simpler way to do it, depends on what the overall goal is.