问题描述
我经历了不同的来源,发现我们可以使用片段着色器绘制虚线.因为我是OpenGL的新手,所以我无法理解.
任何人都可以共享一些使用Fragment着色器和Android中的GL_LINE_STRIP绘制或虚线的代码样本.
参考:
- OpenGl3中的涂鸦线?
- dock 的点缀后边缘
推荐答案
在OpenGL ES中不支持线点.
如果使用OpenGL ES 1.00,则可以使用 OpenGlgl中的答案中显示的方法ES-虚线. 如果使用OpenGL ES 2.00或更高(OpenGL ES 3.X),则无法使用Alpha测试,因为它已弃用.您必须使用片段着色器并通过 discard discard discard 关键字. 仅使用红色通道创建纹理.点式图案在红色频道中编码,但是代码与 openggl es-s-1 https://stackoverflow非常相似虚线
您必须创建一个1维纹理(2维NX1纹理),并将纹理包裹在线上.该纹理具有在其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个重复包裹在四边形的每个边缘.
Gllinestipple在OpenGl 3.1
中折磨了Gllinestipple
在OpenGl3中涂在stashed Line?
问题描述
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?