Рисование пунктирных линий с помощью OpenGL-ES

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

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

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

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

2 ответов


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

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

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

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

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

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

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

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

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


Если все, что вы хотите, это рисовать пунктирные линии, просто измените с GL_LINE_STRIP на GL_LINES. Таким образом, open 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);

  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). Однако у меня нет примера, чтобы показать вам. :/