Вопрос

Моя программа использует Pyopengl (так что это Python) с psyco.

У меня есть около 21 000 сегментов линий, которые мне нужно рендеринг в каждом кадре моего рендеринга (если пользователь не увеличивает, в этом случае сегменты линий отключены и вообще не отправляются на карту). В настоящее время это занимает около 1,5 секунды каждый кадр. Этого недостаточно, поэтому я ищу способы уменьшить количество отдельных линейных сегментов.

Я полагаю, что будут случаи, когда несколько сегментов линий могут быть объединены в одну большую линию, но я, честно говоря, даже не знаю, с чего начать с этого. У меня есть начальная точка и конечная точка каждой линии, хранящейся, так что это может помочь. Обратите внимание, что я могу взять столько времени, сколько мне нужно в стартапе, и использование памяти не слишком озабочен.

Любые идеи были бы очень оценены.

Это было полезно?

Решение

Это почти наверняка накладные расходы всех непосредственных вызовов функции режима, которые убивают вашу производительность. Я бы сделал следующее.

Не используйте GL_LINE_STRIPS, используйте один список GL_LINES Вместо этого они могут быть сделаны за один раз.

Использовать glDrawArrays Вместо немедленного рендеринга режима:

float* coordinates = {....}; //x and y coordinate pairs for all line segments
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 2 * sizeof(float), coordinates);
glDrawArrays(GL_LINES, 0, 2 * linecount);
glDisableClientState(GL_VERTEX_ARRAY);

(Для еще лучшей производительности вы можете хранить буфер вершины в том, что называется буферным объектом вершины, но с самого начала это должно быть хорошо)

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

Другие советы

Сегменты 20K не так уж и много. Кроме того, вам повезет, когда вы сможете объединить 10-100 линий на кадр, поэтому ускорение этой оптимизацией будет пренебрежным. Процесс рендеринга, вероятно, медленный, потому что вы создаете модель снова и снова. Использовать glNewList() Чтобы сохранить все команды рендеринга в списке рендеринга GL на карте, а затем просто выпустите glCallList() Чтобы сделать это с помощью одной команды.

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

Одним из примеров является этот алгоритм:

  1. Построить новый сегмент линии x из двух точек, которые далеки друг от друга в двух сегментах линии A и B.
  2. Найдите минимальное расстояние до x для всех точек в A и B.
  3. Назначьте ошибку как максимум этих минимальных расстояний.
  4. Замените A и B на X, если ошибка ниже вашего порога.

Это не лучший алгоритм, но его легко реализовать.

Редактировать 1

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top