Ответ 1
Вы можете использовать геометрический шейдер, который будет принимать в качестве входа сегмент вашей линии и выводить квад (треугольную полосу, состоящую из двух треугольников), чтобы ширина квадрата была постоянной в пространстве экрана и соответствовала линии желания толщина. Он отлично работает (для его внедрения в CAD-движке CAD).
Если геометрический шейдер не является вариантом, обходным решением может быть использование вершинного шейдера, но для этого потребуется повторная работа вашего VB. Имейте в виду, что VS должен тогда знать весь сегмент линии, чтобы вы в конечном итоге сохранили p и p + 1 для каждого из ваших элементов VB, плюс стоимость дублирования индексов/вершин (в зависимости от используемой топологии и если вы визуализируете свою линию как индексированный примитив или нет).
Если производительность не является проблемой, выполнение расширения на процессоре - это, возможно, путь.
EDIT:
О шаблонах тире: вы можете использовать геометрический шейдер, чтобы эмулировать поведение glLineStipple
.
Если у вас есть топология GL_LINES
, то есть изолированные линии, шаблон перезапускается в каждом новом сегменте линии. Поэтому вам просто нужно вычислить в геометрическом шейдере горизонтальный старт экрана (или вертикальный старт, в зависимости от ориентации) вашего сегмента линии и передать эту дополнительную информацию в пиксельный шейдер. Затем пиксельный шейдер будет отвечать за отбрасывание фрагментов в соответствии с коэффициентами и значениями шаблона (DirectX 10/11 Integer и Bitwise упрощают).
Снова это хорошо работает, и вы можете комбинировать его с эмулированными линиями ширины (с первым описанным выше методом).
Теперь, если у вас есть топология GL_LINE_STRIP
, шаблон перезапускается в каждом новом примитиве (поэтому для каждого нового вызова рисования). Ситуация становится немного более сложной, так как вам нужно знать количество пикселей, которые были ранее отображены, и это для каждого сегмента линии.
Вы можете добиться этого с помощью рендеринга своей линейной полосы во временном VB, использующем функциональность Stream-out DirectX 10 (каждый элемент этого VB соответствует длине экрана каждого сегмента). Затем вам необходимо выполнить Параллельный префикс Sum (aka Scan) этого VB (для накопления значений длины каждого сегмента линии).
Наконец, вы делаете свою линейную полосу как для GL_LINES
, но используйте эту дополнительную информацию о сканировании VB в PS.