0

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();
genpfault
  • 51,148
  • 11
  • 85
  • 139
086
  • 197
  • 13
  • "*both transparent*" ... if they overwrite each other, then they're *not transparent*. So don't you just want opaque rendering? – Nicol Bolas Aug 08 '17 at 16:19
  • Not at all. In the project I want this rendered in, there's also stuff rendered behind these two quads (altough they're more complicated shapes in practice). I'd like to see what's behind those shapes, without the shapes themselves overlapping like they do. See the black line in the image. – 086 Aug 08 '17 at 16:22
  • Just disable the blending? – HolyBlackCat Aug 08 '17 at 18:04
  • That would again, just defeat the purpose of what I'm trying to do. There is already a whole scene rendered, with this ontop. The quads need to be transparent; so you can see the part of the scene they're covering behind it, too. The line in the image is BEHIND the quads, not infront! – 086 Aug 08 '17 at 18:07

1 Answers1

3

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.

vallentin
  • 23,478
  • 6
  • 59
  • 81
  • Looks like I was completely overthinking it. Thanks alot! Any way to restore the depth buffer back to what it was before clearing it after rendering though? – 086 Aug 10 '17 at 17:13
  • One way would be to [disable color writing](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glColorMask.xhtml) and just draw everything again. – vallentin Aug 10 '17 at 17:23
  • That seems incredibly performance heavy / inefficient though. Any other way? – 086 Aug 10 '17 at 17:33
  • There's other ways, but it really depends on what the overall goal is, for me to suggest an overall better way. – vallentin Aug 10 '17 at 17:36
  • What I'm doing is adding (modding) a game. I'm drawing a GUI, which has multiple outlined, rounded rectangles (the outline is just a larger rounded rectangle). I'd like for the GUI to be transparent, which is why I asked this question for the outlines to work correctly. However, clearing the depth buffer mid-way of drawing the GUI breaks some graphical elements. That's why I'd like to restore it after rendering the rectangles. – 086 Aug 10 '17 at 17:39
  • In that case (unless I'm mistaking something) another alternative could be to write all the GUI into a framebuffer and then lastly draw that onto the actual screen. If needed you could even disable depth rendering for when you're drawing the GUI onto the screen. (*However I don't see why that would be needed.*) – vallentin Aug 10 '17 at 17:42
  • I'll look into it. Thanks again. – 086 Aug 10 '17 at 17:43