Selected edges always in front

Hi Everybody,

New post old problem:

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.

Thanks,

Alberto

Use GL_LEQUAL and draw selected edges after the non-selected ones.

glDepthFunc(GL_LEQUAL)

// draw non selected edges

// draw selected edges

Maybe I’m missing something, but why not just draw the yellow polygon’s edges with a bigger offset?

I really wish you were right DandyYuyo, I will try ASAP your solution.

Shall I restore a standard depth func after these calls, right?

Thanks,

Alberto

Dimitry,

The polygon offset only offset poligons, not wires.

Alberto


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…

Thanks again,

Alberto

Brolingstanz,

I tried to google for Nvidia Solid Wireframe demo without success, can you provide a link?

Will this approach work also on legacy GPUs?

Thanks,

Alberto

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.

Hi Dmitry,

¿Did I get it wrong or he’s asking how to overdraw edges?

I assumed that he has a list of edges, and not that is doing glPolygonMode(xxx, GL_LINE).

Then if we wants selected edges to be drawn over all edges already drawn in blue, GL_LEQUAL (or even GL_EQUAL) will suffice for that.

He can also NOT DRAW non-selected edges in blue in the first place!

OR he can do GL_POLYGON_OFFSET_LINE and suffer from z-fighting in some “pathological cases” as Brolingstanz pointed out.

Finally yes, he can do wireframe with shaders and in a single-pass but it won’t work with legacy hardware:

http://orbit.dtu.dk/getResource?recordId=219956&objectId=1&versionId=1

Hi DandyYuyo,

Here is the result: no improvement.

Quick movie

I added the glDepthFunc(GL_LEQUAL) before I draw edges (first non selected then selected) and glDepthFunc(GL_LESS) at the end to restore defaults.

In this case we are not using glPolygonMode(xxx, GL_LINE) to draw edges but it happens in other situations.

What I am doing wrong?

Thanks,

Alberto

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.

I will also try Dimitry solution.

Thanks,

Alberto

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.

Any other idea?

Thanks,

Alberto

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.

Dimitry,

You are right I wrote the wrong GL_ code, sorry.

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?

Thanks,

Alberto

Maybe it’s too late, but here is a short FAQ:
http://www.opengl.org/resources/faq/technical/polygonoffset.htm

So, you have 3 kind of primitives drawn:
-polygons
-lines drawn as edges using PolygonMode()
-lines drawn simply via GL_LINE_STRIP

You can vary 2 of these depth offsets, so you have a full control over all(3) their relative offsets.

I believe you could do what you want by using the stencil buffer.

  1. Enable depth test.
  2. Draw the non-selected sides (and any other geometry).
  3. Enable the stencil test.
  4. Draw the selected side, and set the stencil buffer to 1 where the selected side “wins” the z-buffer test.
  5. Disable the stencil test.
  6. Draw the edges (lines) that surround the non-selected sides.
  7. Disable depth test.
  8. Enable the stencil test.
  9. 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.