在OpenGL GLES20 android中使用片段着色器和GL_LINE_STRIP绘制一条简单的点线或虚线[英] Draw a simple dotted line or dashed line in OpenGL GLES20 android using fragment shader and GL_LINE_STRIP

本文是小编为大家收集整理的关于在OpenGL GLES20 android中使用片段着色器和GL_LINE_STRIP绘制一条简单的点线或虚线的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我经历了不同的来源,发现我们可以使用片段着色器绘制虚线.因为我是OpenGL的新手,所以我无法理解.

任何人都可以共享一些使用Fragment着色器和Android中的GL_LINE_STRIP绘制或虚线的代码样本.

参考:

推荐答案

在OpenGL ES中不支持线点.

如果使用OpenGL ES 1.00,则可以使用 OpenGlgl中的答案中显示的方法ES-虚线.
您必须创建一个1维纹理(2维NX1纹理),并将纹理包裹在线上.该纹理具有在其Alpha通道中编码的点画图案.破折号之间的空间由

如果使用OpenGL ES 2.00或更高(OpenGL ES 3.X),则无法使用Alpha测试,因为它已弃用.您必须使用片段着色器并通过 discard discard discard 关键字.

仅使用红色通道创建纹理.点式图案在红色频道中编码,但是代码与 openggl es-s-1 https://stackoverflow非常相似虚线,除了您必须使用GL10.GL_RED的事实以进行内部纹理格式(而不是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);

绘制线条时,您必须使用着色器程序,以丢弃取决于纹理的红色通道的片段.一个非常简单的GLSL ES 1.00着色器(用于OpenGL ES 3.00)可能如下:

顶点着色器:

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

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

碎片着色器:

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);
}

确保与顶点相关的纹理坐标在绘制线路时与积分值对齐,这会导致行以仪表率启动和结尾:

例如.左下方(-0.5 -0.5)和(0.5,0.5)的左下四边形,纹理坐标为[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

由于包裹函数为GL_REPEAT,并且纹理坐标在范围内[0,5],因此,将点式图案的5个重复包裹在四边形的每个边缘.


您还可以在片段着色器中生成点贴,而不是使用纹理.请参阅桌面OpenGL Cor配置文件的解决方案:
Gllinestipple在OpenGl 3.1
中折磨了Gllinestipple
在OpenGl3中涂在stashed Line?

本文地址:https://www.itbaoku.cn/post/2091094.html

问题描述

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:

推荐答案

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?