Ethan
Ethan

Reputation: 25

Efficiently draw large number of point cloud points in OpenGL?

My program keeps receiving a large amount of points in PCL point cloud format, i.e., pcl::PointCloud<pcl::PointXYZI>::Ptr which is actually std::vector< pcl::PointXYZI, Eigen::aligned_allocator< pcl::PointXYZI > >.

I want to draw the points in OpenGL in real-time as soon as I received them. I know how to draw in the traditional way. Every time I receive new set of points, I copy them one-by-one into my vertex vector (I'm using Qt so it is QVector<QVector3D>) and at the same time construct color vector which is also QVector<QVector3D>. After copying the two vectors into VBOs, I can draw them all in one draw call. However, the amount of points is normally too big (around 100k points per frame coming at 10Hz) and the copying from raw PCL format into my Qt vector and constructing color vector seem a big waste of time and computing power.

Is there any way to bypass the copying and directly draw the points? The solution that I can think of might be since the PCL point cloud format is std::vector, it maybe possible to directly use it for the draw call, like I get the vector pointer and directly copy into VBO. But in this way, how do I construct the color vector? If all the points are the same color, is there a way that I can assign a color to all the points without constructing the color vector for each vertex? Probably through fragment shader I guess?

Upvotes: 1

Views: 1965

Answers (2)

tuket
tuket

Reputation: 3951

If the points don't move, you can upload only the points that are added using glBufferSubData (unlike glBufferData that creates a new buffer and initialized it).

The idea would be:

  • You create a large buffer that is able to fit all the points we can potentially have (glBufferData).
  • As points are coming, we add them to the end of the buffer using glBufferSubData.
  • When you are going to draw glDrawArrays make sure to pass to the parameter count the number of points you currently have.

If all the points are the same color, is there a way that I can assign a color to all the points without constructing the color vector for each vertex? Probably through fragment shader I guess?

Yes, you can use uniforms for that.

In your shader code you declare:

uniform vec4 u_color;

Then in C++ you can assign the value with glUniform4f:

glUniform4f(1.f, 0.f, 0.f, 1.f); // all points are red

Upvotes: 1

datenwolf
datenwolf

Reputation: 162317

Why the proxy copies into QVector? You can copy the pcl::PointCloud into VBOs directly, without this time and memory bandwidth consuming step in between. Also 100k points at 16 bytes per point amounts to less than 2MB, which in today's terms is almost nothing.

Upvotes: 0

Related Questions