rendering a solid with hidden line feature

Hi there,
I have some solid objects that would like to display as follows:
the visible polygons (faces) with solid lines, and the non visible as dashed lines, and be able to see the background… I was serching the formus here, and there are basically the two solutions that come in the red book, (polygon offset and stencil), none of them do exaclty what I need, any help or or suggestions would be appreciated, thanks!

If the background has already been drawn then there is a way.

  1. Render the object as a solid, but mask out all colors using glColorMask(0, 0, 0, 0);

  2. invert the depth func, if it’s glDepthFunc(GL_LEQUAL); then make it glDepthFunc(GL_GREATER);

  3. draw the wireframe(dashed lines, pink whatever), if your drawing polygons then make sure you reverse the vertic order.
    Don’t forget to reactivate the color mask beforehand.

  4. revert the depth func, as you did in step 2 but in reverse.

  5. draw the wireframe again with whatever settings you like for the non hidden mesh

I think this will work.

I tried it and works, but has an issue: it leaves a few parts of the visble lines on the hidden ones, and a few more on the visible ones from the hidden (how can I attach a picture ?)

this is the code I did:

glDepthFunc(GL_LESS);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLineWidth(1.0);
<render background>

glColorMask(0.0, 0.0, 0.0, 0.0);
<render geometry>

glDepthFunc(GL_GREATER);
glColor4d(0.0, 0.0, 1.0, 1.0); // hidden
glColorMask(1.0, 1.0, 1.0, 1.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
<render geometry>

glColor4d(1.0, 1.0, 1.0, 1.0); // solid
glLineWidth(3.0);
glDepthFunc(GL_LESS);
<render geometry>

Try GL_LEQUAL instead of GL_LESS, it might clear up the visible lines problem.

To attach an image you can use a site like imageshack to store the image, then enter the url into an image tag found in the reply form.

thanks for the tip!, here is the result of the previous code:

imageshack

I tried GL_LEQUAL but draws everything with white color…

hey, I added the dashed lines and works if using GL_LEQUAL, but still everything is white…

glDepthFunc(GL_LEQUAL);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLineWidth(1.0);
<render background>

glColorMask(0.0, 0.0, 0.0, 0.0);
<render geometry>

glDepthFunc(GL_GREATER);
glColor4d(0.0, 0.0, 1.0, 1.0); // hidden, blue not showed…
glColorMask(1.0, 1.0, 1.0, 1.0);
glLineStipple(4, 0xAAAA); // added
glEnable(GL_LINE_STIPPLE); // added
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
<render geometry>

glDisable(GL_LINE_STIPPLE); // added
glColor4d(1.0, 1.0, 1.0, 1.0); // solid
glLineWidth(3.0);
glDepthFunc(GL_LEQUAL);
<render geometry>

ok my bad, try this.
add glDepthMask(GL_FALSE); before you render the hidden lines stage, but after the solid stage.
(don’t forget to reverse this after the visible line stage or your rendering will be messed up)

hey, it works !!

honestly, I don’t know how it works, but I would like to know, can you please explain me ??, I read the docs but don’t understand what exactly do glColorMask and glDepthMask, also on the glDepthFunc switching…

Thanks !

this is the final result:

working hidden line

(changed blue dashed lines to yellow)

It’s simple, the first pass is to get the shape into the z-buffer so that we can test if the lines are in front or behind the front surface, but we don’t want to render into the colorbuffer.
For that you use glColorMask to enable or disable writing the individual colors to the color buffer so that they will or will not be rendered in the first stage, glDepthMask does the same for the z-buffer.
So in the first stage we set all colormask values are set to 0 and depthmask to GL_TRUE

in the second stage we want to

  1. render the color and not the z
  2. render everything behind the x buffer
    the glDepthFunc(GL_GREATER); line makes that last thing possible, it makes it so that everything behind this shape is rendered, but to preserve the z we need to turn off the depthMask with GL_FALSE.
    And lastly we re enable all the color buffer writing with colorMask.

in the final step we want to do is everything we did in the previous step but only render those lines that are in the front, setting glDepthFunc to GL_LEQUAL does just that.

thanks for the explanation!!, I’m not so lost now…

I found one more issue… as the code is now, there is no problem if the hidden line geometry is drawn only after the background is drawn and if there is nothing in front of it, but if there is something on the front drawn first and/or something else after it there is a problem… check this code:

// draw a cyan quad on the front
glColor4d(0.0, 1.0, 1.0, 1.0);
glBegin(GL_QUADS);
glVertex3d(-0.5, 0.5, 2.0);
glVertex3d(-1.5, 0.5, 2.0);
glVertex3d(-1.5, 1.5, 2.0);
glVertex3d(-0.5, 1.5, 2.0);
glEnd();

// start of hidden line cylinder geometry located at 0,0,0

glColorMask(0.0, 0.0, 0.0, 0.0);
<render geometry>

glDepthFunc(GL_GREATER);
glDepthMask(GL_FALSE);
glColorMask(1.0, 1.0, 1.0, 1.0);
glColor4d(0.5, 0.5, 0.0, 1.0);
glLineStipple(4, 0xAAAA);
glEnable(GL_LINE_STIPPLE);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
<render geometry>

glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
glDisable(GL_LINE_STIPPLE);
glColor4d(1.0, 1.0, 1.0, 1.0);
glLineWidth(4.0);
<render geometry>

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLineWidth(1.0);

// draw a magenta quad on the back
glColor4d(1.0, 0.0, 1.0, 1.0);
glBegin(GL_QUADS);
glVertex3d(0.5, 0.5, -2.0);
glVertex3d(1.5, 0.5, -2.0);
glVertex3d(1.5, 1.5, -2.0);
glVertex3d(0.5, 1.5, -2.0);
glEnd();

here are some snapshots of what I mean:

top-iso-view-like

front-iso-view-like

I think it would be better to use polygon offset instead of reverse depth test.

can you be more specific with polygon offset ?

if you mean something like the solution on chapter 14 on redbook, it is not what I need.

thanks

I’ll try to detail what I am thinking :
(normal depth-testing is always used)

  • pass 1 : render all backfacing-only filled polys, offset so that to be a bit farther
  • pass 2 : render all backfacing-only dotted lines
  • pass 3 : render all frontfacing-only filled polys, offset so that to be a bit farther
  • pass 4 : render all frontfacing-only lines

I hope it makes sense, it is late out there …

EDIT : why do you think the screenshots you posted are wrong ? It seems already completely correct to me. The blue square is nearer than part of the cylinder, so this part is considered hidden, right ?

if you could tell me the commands needed for those steps (perhaps some code) will help me much more, anyway many thanks for the reply.
Check the “front-iso-view-like” in my last post, the cyan quad is in front of the cylinder, so it should be seen all cyan, not mixed with the cylinder lines, and the magenta quad is at the back of the cylinder, you should be able to see the part of the quad behind the cylinder lines…