glDrawArrays不会渲染整个点云

时间:2017-01-26 16:55:09

标签: opengl point-clouds

我试图渲染巨大的点云(~150M),但OpenGL只渲染它的一部分(~52M)。渲染较小的数据集(< 40M)时,一切正常。我使用单个VBO。当使用多个VBO时,会渲染点,但渲染速度非常慢,这是预期的。我的元素大小为44bytes,GPU有3GB内存可用。这应该足够接近~70M点,但我可以用多个VBO渲染多达100M点。 每个VBO是否有任何OpenGL特定限制我不知道?

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, cloud.size() * sizeof(Point), cloud.data(), GL_STATIC_DRAW);
// lot of other code
glDrawArrays(GL_POINTS, 0, cloud.size());

2 个答案:

答案 0 :(得分:6)

看起来系统的某些部分使用32位无符号整数来存储缓冲区的大小,从而传递148M*44bytes溢出并转换为大约54.9M50.4M,具体取决于你的兆字节是二进制还是十进制。我首先检查你的OpenGL绑定库,看看它声明的原型是否正确使用了64位类型。如果确实如此,那么bug必须在OpenGL驱动程序中。

要将超过4GB的数据传输到缓冲区,您可以尝试使用其他可用功能之一:glBufferSubDataglBufferStorage,或使用glMapBufferRange对缓冲区进行内存映射,解决了4GB的限制。

要考虑的另一件事是使用一个VAO但在多个缓冲区之间拆分数据。大概你的Point由不同的属性组成,比如位置,颜色等......你可以将它们中的每一个放在一个单独的缓冲区中,并且仍然使用一个VAO和一个绘制调用。您还可以优化所使用属性的类型(例如,不要使用短路或字节可以使用的浮点数)和结构的布局(检查字段之间没有不必要的填充)。 / p>

答案 1 :(得分:0)

我不认为记忆是一个问题,事实上我说你的程序会进行太多的绘图调用。你应该尝试使用glDrawArraysInstanced()。为此,您需要为顶点着色器中的每个实例提供新位置......这可能会解决您的问题:D。 对不起,如果我无法向你提供详细信息,我的OpenGL技能有点沉闷,但我打算尽快恢复:D。我希望它有所帮助。