Search code examples
c++opengldepth-bufferstencil-buffer

Mixing GL_ALWAYS with GL_LESS in OpenGl


I have:

  1. a set of dots
  2. a set of meshes

I need

  1. the meshes to be drawn in the correct z order, based on depth. For this I used glDepthFunc(GL_LESS) or glDepthFunc(GL_LEQUAL), or glEnable(GL_DEPTH_TEST)
  2. the dots to be rendered in the order of drawing, ignoring the depth. For this I used glDepthFunc(GL_ALWAYS), or glDisable(GL_DEPTH_TEST). They are drawn using GL_POINTS and glVertex3d
  3. the meshes to be rendered as if the dots are in the correct depth.

Fig. 1 shows the dots, as squared, vs the meshes, when the depth is considered. Fig. 2 shows how it looks when the dots are rendered ignoring the depth (so the red dots appear on top of the blue dots regardless their depth), but the meshes are always behind the dots, regardless the depths. I would like the meshes to be in the same relation with the dots as in Fig. 1, but the dots be in the same relation with each other as in Fig. 2.

enter image description here

I realize that I will get into something like a mesh being between two dots, but the dot with greater depth rendered on top of the dot with lower depth, but in this case it would be fine if for the dot which is closer is rendered on top.

Whatever I tried it made the meshes be either behind all dots, or in front of all dots, regardless the depth of each object. What I tried was to draw the dots, and it works as needed, draw the meshes and it works as needed, but when combined, it doesn't work, whether I draw first the dots or the meshes.

Q: Is it possible, and if yes, how can I do this?


Solution

  • As Michael Nastenko said in the comments, the effect you want to achieve requires drawing the meshes, then turn depth writing off, then draw the "points" (with the depth test still on). Obviously, you'll have to turn the depth writes back on before drawing the next frame.

    By turning off depth writes (with glDepthMask(GL_FALSE)), you ensure that the "points" don't write their depth to the depth buffer. So each "point" is only being tested against the depth of the scene before you started drawing the "points". If two "points" overlap, then they will be drawn in render-order.