How can we make selected edges to stay ALWAYS in front of blue ones during 3D rotation (picture A) instead of flickering all the time (picture B) ?
Please don’t suggest disabling depth test during edge drawing because in a more complex part they won’t be hidden from polygons. Clearly to get this result we are already using polygon offset to make edges always to stand out.
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glEnable(GL_POLYGON_OFFSET_LINE);
glPolygonOffset(1.0f,1.0f) //or higher
//draw some polygons as wires with offset
You should if that’s what you need. I normally use GL_LEQUAL all the time as “default” to enable multiple passes.
The caveat with PolygonOffset is that units and factor is driver dependant, and you may have problems with too far or too near objects.
GL_LEQUAL solution guarantees that fragments with same depth values pass the depth test on any hardware unless the implementation really sucks. Draw your selected edges with exactly the same coordinates and order as the non-selected otherwise it may not work.
You have GL_POLYGON_OFFSET_FILL, GL_POLYGON_OFFSET_LINE, or GL_POLYGON_OFFSET_POINT, so you can offset polygons, lines or points.
Sadly lines and polygons don’t make good bedfellows. No amount of depth offset is going to save you in the pathological cases. Check out NV’s solid wireframe demo for a great way to skirt the depth buffer business.
Wow, I completely forgot the other two ones. By the way I guess that the offsetting polygons away from the viewer or edges closer to the viewer is the same right?
I was wondering if these two approachs differs when I rotate the box and the selected face is behind the others…
Not more driver-dependent than any other OpenGL feature. The amount of offset is strictly defined in the specification and depends only on the depth buffer resolution (that can be specified manually by you).
If ‘bad’ edges fragments had the same depth values - there would be no flickering during rotation. I doubt LEQUAL will help here.
For what I can see in the video, you may be suffering because of those “T” vertices. Are you sure edges in the unselected polygon are exactly the same the as the ones in the selected polygon?. Do you have the same z-fighting with a simpler shape, such as a cube?
In other words, do the polygons really share the edges?
If they don’t and this is a requirement in your application, then do as dmitry says. Use PolygonOffset with GL_POLYGON_OFFSET_LINE to offset selected edges towards the camera. But I would suggest you to avoid “T” vertices.
They aren’t ‘T’ vertices, planar faces are triangulated without splitting edges. I don’t understand by the way a ‘T’ vertes should affect in some way the depth buffer.
The sad news is that depending on the object we are drawing, edges are drawn either using GL_POLYGON_OFFSET_LINE or GL_LINE_STRIP :(. This is the reason why we can only push triangles away from the viewer.
I am sure that another trick that works in our scenario exists.
either using GL_POLYGON_OFFSET_LINE or GL_LINE_STRIP
I don’t understand: the GL_POLYGON_OFFSET_LINE is a OpenGL state, while GL_LINE_STRIP is a drawing mode.
Moreover, AFAIK, you can pass negative values into the PolygonOffset() making the triangles/edges closer to the viewer.
In some cases we draw edges simply redrawing the polygons with the glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) in some others we draw edges with glBegin(GL_LINE_STRIP).
This is the reason why we cannot used different negative offset values into the glPolygonOffset() function. They would affect only the edges drawed using glPolygonMode(GL_FRONT_AND_BACK, GL_LINE), not the others. Is this correct?
I believe you could do what you want by using the stencil buffer.
Enable depth test.
Draw the non-selected sides (and any other geometry).
Enable the stencil test.
Draw the selected side, and set the stencil buffer to 1 where the selected side “wins” the z-buffer test.
Disable the stencil test.
Draw the edges (lines) that surround the non-selected sides.
Disable depth test.
Enable the stencil test.
Draw the edges (lines) that surround the selected side, but only where the stencil buffer is set to 1.
This technique requires that your line width be larger than 1. In your screen shot, it looks like your lines have thickness. Not sure if you mind, but the selected lines will only draw where they overlap the selected side, i.e., the lines will not bleed outward beyond the selected side.
The stencil is set to 1 only where the selected side “won” the z-buffer test. So, the selected lines will draw only where they are visible. Since the selected lines are drawn without depth testing, you won’t have z-buffer fighting with the other lines.
You could use this idea to correct z-buffer fighting between the non-selected faces and edges if you chose not to use a polygon offset.