1

I went through different sources and seen that we could draw a dotted line using a fragment shader. Because I am new to OpenGL I couldn't able to understand.

Can anyone share some code sample that plot dotted or dashed line using fragment shader and GL_LINE_STRIP in Android.

References:

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Subhash Kumar
  • 43
  • 1
  • 6
  • If you use `GL_LINE_STRIP` then you don't need a fragment shader. But line stipple is not supported in OpenGL ES. See [OpenGL ES - Dashed Lines](https://stackoverflow.com/questions/37975618/opengl-es-dashed-lines) – Rabbid76 Feb 19 '20 at 07:58
  • Thanks for the comment, I will check the code and let you know – Subhash Kumar Feb 19 '20 at 09:25
  • Does this answer your question? [OpenGL ES - Dashed Lines](https://stackoverflow.com/questions/37975618/opengl-es-dashed-lines) – Rabbid76 Feb 19 '20 at 15:47
  • Can you give me some clarity how to use below code: gl.glGenTextures(1, texture_id_, stippleTexObj); gl.glBindTexture(GL10.GL_TEXTURE_2D, stippleTexObj); here what is the texture_id_, stippleTexObj need to pass – Subhash Kumar Feb 20 '20 at 06:06
  • GLES20.glAlphaFunc is not working it was deprecated in GLES20 – Subhash Kumar Feb 20 '20 at 06:08

1 Answers1

1

Line stipple is not supported in OpenGL ES.

If you use OpenGL ES 1.00, then you can use the approach which is presented in the answers to OpenGL ES - Dashed Lines.
You have to create a 1 dimensional texture (2 dimensional Nx1 texture), and wrap the texture on the lines. The texture has a stipple pattern encoded in its alpha channel. The space between the dashes is discarded by the Alpha test.

If you use OpenGL ES 2.00 or higher (OpenGL ES 3.x), then you can't use the alpha test, because it is deprecated. You have to use a fragment shader and to skip fragments by the discard keyword.

Create a texture with a red color channel only. The stipple pattern is encoded in the red color channel, but the code is very similar to that one from OpenGL ES - Dashed Lines, beside the fact that you have to use GL10.GL_RED for the internal texture format (instead of GL10.GL_ALPHA):

byte arr[] = new byte[] { 255, 0, 0, 255 };
ByteBuffer textureBuffer = ByteBuffer.wrap(arr);

gl.glGenTextures(1, texture_id_, stippleTexObj);
gl.glBindTexture(GLES20.GL_TEXTURE_2D, stippleTexObj);
gl.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
gl.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
gl.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
gl.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
gl.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RED, 4, 1, 0,
                GLES20.GL_RED, GLES20.GL_UNSIGNED_BYTE, textureBuffer);

When you draw the lines, the you have to use a shader program, that discard the fragments dependent on the red color channel of the texture. A very simple GLSL ES 1.00 shader (for OpenGL ES 3.00) may look as follows:

Vertex shader:

attribute vec2  inPos;
attribute float inU;
varying   float vU;

void main()
{
    outU        = inU;
    gl_Position = vec4( inPos.xy, 0.0, 1.0 );
}

Fragment shader:

precision mediump float;

varying float     vU;
uniform sampler2D u_stippleTexture;

void main()
{
    float stipple = texture2D(u_stippleTexture, vec2(vU, 0.0)).r;
    if (stipple < 0.5)
        discard;
    gl_FragColor = vec4(1.0);
}

Ensure that the texture coordinates which are associated to the vertices are aligned to integral values when you draw the line, that causes the the lines start and end with a dash:

e.g. a quad with bottom left of (-0.5 -0.5) and to right of (0.5, 0.5) and the texture coordinates in range [0, 5]:

 x     y       u   
-0.5f -0.5f    0.0f
 0.5f -0.5f    5.0f
 0.5f  0.5f    0.0f
-0.5f  0.5f    5.0f

Since the wrap function is GL_REPEAT and the texture coordinates are in range [0, 5], 5 repetitions of the stipple pattern are wrapped to each edge of the quad.


Instead of using a texture, you can also generate the stippling in the fragment shader. See the solutions for desktop OpenGL cor profile:
glLineStipple deprecated in OpenGL 3.1
Dashed line in OpenGL3?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Here what is inU? what have I to give input for this parameter? It will be helpful if you give some example – Subhash Kumar Feb 21 '20 at 05:12
  • @SubhashKumar `inU` is the 1 dimensional texture coordinate. See the table in the answer. Your question in the comment suggest me that you are missing some basics (in OpenGL and unsing Shaders) – Rabbid76 Feb 21 '20 at 07:19