Нарисуйте простую пунктирную или пунктирную линию в OpenGL GLES20 android, используя фрагментный шейдер и GL_LINE_STRIP - PullRequest
1 голос
/ 19 февраля 2020

Я просмотрел разные источники и увидел, что мы можем нарисовать пунктирную линию, используя фрагментный шейдер. Поскольку я новичок в OpenGL, я не смог понять.

Может ли кто-нибудь поделиться примером кода, который отображает пунктирную или пунктирную линию, используя фрагментный шейдер и GL_LINE_STRIP в Android.

Список литературы:

1 Ответ

0 голосов
/ 20 февраля 2020

Пунктирная линия не поддерживается в OpenGL ES.

Если вы используете OpenGL ES 1.00, то вы можете использовать подход, представленный в ответах на OpenGL ES - Пунктирные линии .
Вы должны создать одномерную текстуру ( 2-мерная текстура Nx1), и оберните текстуру по линиям. Текстура имеет шаблон рисунка в виде альфа-канала. Пространство между тире отбрасывается альфа-тестом .

Если вы используете OpenGL ES 2.00 или выше (OpenGL ES 3.x), то вы не можете использовать альфа-тест, потому что это устарело. Вы должны использовать фрагментный шейдер и пропускать фрагменты по ключевому слову discard.

Создайте текстуру только с каналом красного цвета. Шаблон штриховки закодирован в канале красного цвета, но код очень похож на тот из OpenGL ES - пунктирные линии , за исключением того факта, что вы должны использовать 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);
}

Убедитесь, что координаты текстуры, которые связаны с вершинами, выравниваются по целым значениям при рисовании линии, что приводит к тому, что линии начинаются и заканчиваются с помощью da sh:

, например, четырехугольник с левым нижним краем (- 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:
glLineStipple устарел в OpenGL 3.1
Пунктирная линия в OpenGL3?

...