Эффективно нарисовать большое количество точек облака точек в OpenGL? - PullRequest
1 голос
/ 23 октября 2019

Моя программа продолжает получать большое количество точек в формате облака точек PCL, то есть pcl::PointCloud<pcl::PointXYZI>::Ptr, что на самом деле std::vector< pcl::PointXYZI, Eigen::aligned_allocator< pcl::PointXYZI > >.

Я хочу рисовать точки в OpenGL в режиме реального времени, как толькокак я их получил. Я умею рисовать традиционным способом. Каждый раз, когда я получаю новый набор точек, я копирую их один за другим в свой вектор вершин (я использую Qt, поэтому он равен QVector<QVector3D>) и в то же время создаю цветовой вектор, который также равен QVector<QVector3D>. После копирования двух векторов в VBO, я могу нарисовать их все за один вызов. Однако количество точек, как правило, слишком велико (около 100 тыс. Точек на кадр с частотой 10 Гц), и копирование из необработанного формата PCL в мой вектор Qt и построение цветового вектора представляются большой тратой времени и вычислительной мощности.

Есть ли способ обойти копирование и напрямую нарисовать точки? Решение, о котором я могу подумать, может заключаться в том, что формат облака точек PCL - std :: vector, возможно, можно напрямую использовать его для вызова отрисовки, например, я получаю указатель вектора и напрямую копирую в VBO. Но таким образом, как я могу построить цветовой вектор? Если все точки имеют одинаковый цвет, есть ли способ, которым я могу назначить цвет для всех точек, не создавая цветовой вектор для каждой вершины? Наверное, через фрагментный шейдер, наверное?

Ответы [ 2 ]

1 голос
/ 23 октября 2019

Если точки не перемещаются, вы можете загрузить только те точки, которые добавлены с помощью glBufferSubData (в отличие от glBufferData , которая создает новый буфер и инициализирует его).

Идея была бы такова:

  • Вы создаете большой буфер, который может вместить все точки, которые мы можем иметь (glBufferData).
  • По мере приближения точекмы добавляем их в конец буфера, используя glBufferSubData.
  • Когда вы собираетесь рисовать glDrawArrays , убедитесь, что передали параметру count количество точек, которые вы в данный момент используете. have.

Если все точки имеют одинаковый цвет, есть ли способ, которым я могу назначить цвет для всех точек, не создавая цветовой вектор для каждой вершины? Наверное, через фрагментный шейдер?

Да, вы можете использовать для этого униформу.

В вашем коде шейдера вы объявляете:

uniform vec4 u_color;

Затем в C ++Вы можете присвоить значение с помощью glUniform4f :

glUniform4f(1.f, 0.f, 0.f, 1.f); // all points are red
0 голосов
/ 23 октября 2019

Почему прокси копирует в QVector? Вы можете скопировать pcl::PointCloud в VBO напрямую, без этого промежуточного промежутка времени и пропускной способности памяти. Кроме того, 100 тыс. Точек при 16 байтах на точку составляют менее 2 МБ, что в современных условиях почти ничто.

...