8

In my Android app I need to display a 3D object (that's no problem), but the front edges should be solid and the back edges should be dotted. I need to have something like on the picture. How can I achieve it using OpenGL ES 1 or 2?

I have tried the Tim's idea(using Depth buffer). It works but there are some artefacts like on the pictures, dotted(purple) lines overlap solid(red) lines:

enter image description here enter image description here

It happens because dotted lines(purple colour(GL_GREATER)) are drawn AFTER red lines(GL_LEQUAL). It there any ideas how to prevent it?

Thank you everyone for helping. Now it looks great!! enter image description here

agent-10
  • 361
  • 2
  • 9
  • That's my first experience with OpenGL at all. I have no idea. – agent-10 Oct 18 '12 at 17:56
  • 1
    I can not give you a full answer but what you would need to do in my opinion is use gles2.0 and having culling off for the objects so it renders all sides, then using a shader you can perform a method similar to this (found it in a Google search) that lets you draw dotted lines. With this information, maybe someone can help piece it together for you. if (step(sin(scale * input.param), 0.5f)) discard; – ian.shaun.thomas Oct 18 '12 at 18:07

1 Answers1

2

Here's a rough outline of what I would do. You'll need one mesh for the object itself, and another mesh of GL_LINES for the 'edge lines' that you want to draw.

  1. Draw the solid mesh into the depth buffer.
  2. Draw your 'edge mesh' with a standard shader, such that you get solid lines, but set the depth test to GL_LEQUAL (only draw objects nearer than the depth value.
  3. Draw your edge mesh a second time with a depth test of GL_GREATER. In this pass use a stipple shader to get the dotted line effect (explained further below).

This might have problems depending on what other objects are in the scene, as you might get dotted lines drawn in the case where the cube is obscured by something else, but maybe that's not a problem for you or you can somehow cull the mesh if it is obscured.

For the stipple shader, you can set a texcoord of one vertex of the line to be zero, and another endpoint of the line to be one. Then in your shader you can use a step function similar to suggested by tencent, to reject fragments to create a stipple pattern.

You can also skip the messing with the depth buffer if you want to calculate yourself which lines are behind the object, though it could be a lot of work with anything more than a cube.

If you want to use OpenGLES 1 instead of OpenGLES 2, replace the stipple shader with a 1D texture of a stipple pattern, and texture the back lines with that. However I'm not 100% sure you can texture a line in OpenGL, so maybe this won't work.

Tim
  • 35,413
  • 11
  • 95
  • 121
  • Thank you, that's very clear. The only one question: how to draw into the depth buffer? – agent-10 Oct 21 '12 at 06:05
  • Everything you draw goes into the depth buffer. If you want to draw **only** into the depth buffer and not draw any colors on the screen, then mask the color writes with `glColorMask`. – Tim Oct 21 '12 at 06:06
  • Tim, do you have any ideas about problem I described above? – agent-10 Oct 26 '12 at 18:17
  • @agent-10 Maybe just draw the back lines first, then draw the front lines? It should work the same way, and then the front lines will draw overtop the back ones. – Tim Oct 26 '12 at 18:42