Рисование пунктирных линий с помощью OpenGL-ES
У меня есть приложение, которое рисует 3 - d вид карты, отмеченные линии, которые показывают различные функции. Я переношу карту на архитектуру OpenGL-ES, но у меня возникли проблемы с отображением пунктирных линий.
делая много googling, я нашел много ссылок на идею о том, что рисование пунктирных линий и полигонов было удалено из OpenGL-ES, поскольку их можно легко эмулировать с помощью треугольников текстур. Это здорово, но я не могу найти никого, кто действительно делает это эмуляция и / или имеет описание соответствующих шагов.
пример одной проблемы, с которой я столкнулся, пытаясь прототипировать эту концепцию, - перспектива сжимает мои линии до невидимого, когда они идут к горизонту. Используя LINE_STRIP, этого не происходит, и линии остаются постоянной шириной на карте.
любые советы о том, как достичь пунктирных линий постоянной ширины в перспективе, будут высоко оценены.
2 ответов
Я считаю, что вы можете применить текстуру к линии, а не только треугольник. Вам нужно будет установить координаты текстуры для каждого конца линии; текстура будет интерполироваться линейно вдоль линии.
эффективность этого решения должна быть инвариантной от того, используете ли вы линии или линейные полосы-линейные полосы-это просто способ создания линий с меньшим количеством вершин.
есть еще одна проблема: тенденция текстуры шаблона, чтобы стать компактным, как линия уходит с камеры. Это происходит потому, что интерполяция координат текстуры является перспективной даже для линий (см. раздел 3.5 спецификации GL).
есть два способа обойти это:
Если вы можете вычислить координату " q " для своей текстуры, которая отменяет перспективу, вы можете восстановить текстурирование экрана. Эта техника, вероятно, слишком дорого стоит.
вы можете проецировать текстуру в пространстве глаз (например 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).
вот как это выглядит, когда я это сделал:
линия не 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). Однако у меня нет примера, чтобы показать вам. :/