Opengl glDrawArrays不会渲染整个点云

Opengl glDrawArrays不会渲染整个点云,opengl,point-clouds,Opengl,Point Clouds,我试图渲染巨大的点云(~150M),但OpenGL只渲染其中的一部分(~52M)。在呈现较小的数据集时(系统的某些部分似乎使用32位无符号整数来存储缓冲区的大小,因此通过148M*44字节溢出并转换为大约54.9M或50.4M,具体取决于兆字节是二进制还是十进制。我首先检查OpenGL绑定库以查看他正确地使用了64位类型,如果是这样的话,那么这个bug肯定在OpenGL驱动程序中 要将超过4GB的数据传输到缓冲区,您可以尝试使用其他可用功能之一:glBufferSubData和glBufferS

我试图渲染巨大的点云(~150M),但OpenGL只渲染其中的一部分(~52M)。在呈现较小的数据集时(系统的某些部分似乎使用32位无符号整数来存储缓冲区的大小,因此通过
148M*44字节
溢出并转换为大约
54.9M
50.4M
,具体取决于兆字节是二进制还是十进制。我首先检查OpenGL绑定库以查看他正确地使用了64位类型,如果是这样的话,那么这个bug肯定在OpenGL驱动程序中

要将超过4GB的数据传输到缓冲区,您可以尝试使用其他可用功能之一:
glBufferSubData
glBufferStorage
,或者使用
glMapBufferRange
对缓冲区进行内存映射,这可能会绕过4GB的限制


另一个要考虑的是使用一个VAO,但是在多个缓冲区之间拆分数据。大概你的<代码>点由不同的属性组成,比如位置、颜色等。你可以把它们放在一个单独的缓冲区中,仍然使用一个VAO和一个绘制调用。你也可以优化你使用的属性的类型。(例如,不要在短字符或字节可以使用的地方使用浮点数)和结构布局(检查字段之间是否没有不必要的填充)。

我不认为内存是一个问题,事实上,我会说您的程序进行了太多的绘图调用。您应该尝试使用glDrawArraysInstanced().为此,您需要为顶点着色器中的每个实例提供新位置…也许这将解决您的问题:D。
很抱歉,如果我不能向您提供详细信息,我在OpenGL中的技能有点枯燥,但我正计划尽快恢复:D。我希望这会有所帮助。

您不是每帧都调用glBufferData,是吗?您是否正在验证
glBufferData()
没有将错误状态设置为
GL\u OUT\u OF\u MEMORY
?我没有。这只是伪代码。事实上,我只在数据更改时使用脏标志更新缓冲区。我测试了glGetError,它返回0。为了使用
glBufferSubData
我认为您首先需要调用
glBuff,您需要使用多少VBO?100、1000、10000erData
具有所需大小(即
GLsizei
)和用法,然后使用
glBufferSubData
更新它的一部分。我明白了吗?至于
glBufferStorage
。我想这会解决我的问题,但我没有OpenGL 4.4可用。我想我必须每2^32字节的数据使用一个VBO。谢谢!嗯,
glBufferSubData
确实需要内存y表示已分配的缓冲区,这就是
glBufferStorage
的用途。从它们使用的类型可以看出,它们确实是较新的函数。您可能仍然会检查是否支持引入
glBufferStorage
GL\u ARB\u buffer\u storage
扩展。这个答案不正确。
glBufferData
使用类型
GLsizeiptr
作为
size
参数,该参数被明确指定为
ptrbits
宽,其中
ptrbits
是客户端地址空间中用于地址的位数。@ybungalobill:我确实阅读了4.5规范。如果使用了di,我还检查了2.0规范之前有所不同。
BufferData
在两个变体中都使用了
sizeiptr
,而且
sizeiptr
在这两个变体中也有很好的规定。不过有一点不同:在2.0中,带的位是保证的最小值,在4.5中,它们是完全必需的。不过这并不会改变情况。@derhass:你说得对,我的大脑在玩游戏ks在我身上。我肯定也读过规范,但是已经看到
GLsizei
写在那里:X。我修正了答案。
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());