Рисование пунктирных линий с использованием OpenGL-ES - PullRequest
8 голосов
/ 21 декабря 2009

У меня есть приложение, которое рисует трехмерные карты, размеченные линии, которые показывают различные функции. Я портирую карту на архитектуру OpenGL-ES, но у меня возникли некоторые затруднения с выбором способа отображения пунктирных линий.

Много занимаясь поиском, я нашел много ссылок на идею о том, что рисование пунктирных линий и многоугольников было удалено из OpenGL-ES, поскольку их можно легко эмулировать, используя треугольники текстур. Это здорово, но я не могу найти никого, кто бы на самом деле делал эту эмуляцию и / или имел описание необходимых шагов.

Примером одной проблемы, с которой я столкнулся, пытаясь создать прототип этой концепции, является перспектива, сжимающая мои линии до невидимого, когда они движутся к горизонту. При использовании LINE_STRIP этого не происходит, и линии остаются на карте постоянной ширины.

Любой совет о том, как добиться пунктирных линий постоянной ширины на виде в перспективе, будет весьма полезен.

Ответы [ 2 ]

5 голосов
/ 29 января 2010

Я считаю, что вы можете применить текстуру к линии, а не просто к треугольнику. Вам нужно будет установить координаты текстуры для каждого конца линии; текстура будет линейно интерполирована вдоль линии.

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

Есть еще одна проблема: склонность текстуры к уменьшению линии по мере удаления от камеры. Это происходит потому, что интерполяция координат текстуры корректна в перспективе даже для линий (см. Раздел 3.5 спецификации GL).

Есть два способа обойти это:

  1. Если вы можете рассчитать координату "q" для вашей текстуры, которая отменяет перспективу, вы можете восстановить текстурирование пространства экрана. Этот метод, вероятно, слишком дорогой по производительности.

  2. Вы можете проецировать текстуру в пространстве глаза (например, glTexGen).

Генерация координат текстуры, конечно, недоступна в GLES 1.1, но если вы используете вершины по массиву, вы можете подделать их:

  • Установка массива координат текстуры в качестве массива координат вершины и
  • Использование матрицы текстур для "преобразования" вершин.

Недостатком этого метода является то, что текстура будет находиться в фиксированном пространстве экрана, то есть текстура не будет пересекать линии.

3 голосов
/ 20 февраля 2014

Если все, что вам нужно, это рисовать пунктирные линии, просто измените с GL_LINE_STRIP на GL_LINES. Таким образом, открытый GL соединит вершины 1 и 2, 3 и 4, 5 и 6, но не 3 & 4 или 4 & 5, оставляя там пробелы. По сути, это будет пунктирная линия с половинным соотношением - грубый эквивалент glLineStipple (1, 0101);

IE: в массиве вершин

[0,0,1,1,2,2,3,3,4,4,5,5,6,6]

OpenGL соединит (0,0) с (1,1), но не соединит (1,1) с (2,2) [тогда как с GL_LINE_STRIP]. Затем он соединит (3,3) с (4,4), но НЕ (4,4) с (5,5). Окончательное соединение будет (5,5) - (6,6).

Вот как это выглядит, когда я это сделал:

Пунктирные линии на Android

Линия не является 50/50 пунктирной / пустой, потому что в моем случае она представляет позицию игрового объекта в каждом игровом кадре - и игровые кадры не обязательно имеют одинаковую длину, следовательно, несовместимое соотношение линия: пространство.

Код выглядит следующим образом:

публичная ничья (GL10 gl) { gl.glDisable (GL10.GL_TEXTURE_2D); * +1022 *

  gl.glColor4f(color[0], color[1], color[2], color[3] / fade);
          //pointsBuffer holds the points on the line
  gl.glVertexPointer(2, GL10.GL_FLOAT, 0, pointsBuffer); 

  gl.glDrawArrays(GL10.GL_LINES, 0, points.length/2);

  gl.glEnable(GL10.GL_TEXTURE_2D);

}

Альтернативной идеей создания более намеренно заданного шаблона является пропуск определенных вершин вместо рисования с помощью массива индексов (glDrawElements). Тем не менее, у меня нет примера того, чтобы показать вам. : /

...