加速IO绑定的OpenGL应用程序

时间:2010-08-02 22:05:31

标签: performance opengl optimization 3d lidar

我最近一直在研究一个点云播放器,它应该能够理想化激光雷达捕获中的地形数据点并以大约30fps的顺序显示它们。然而,我似乎已经因PCI-e IO而陷入困境。

我需要为每一帧做的是加载存储在内存中的大点云,然后根据高度计算颜色图(我使用的东西类似于matlab的喷射图),然后将数据传输到GPU。这适用于带有点<云捕获的云捕获。一百万。然而,在大约200万点时,这开始减慢到每秒30帧以下。我意识到这是很多数据(每点200万帧* [每点3个浮点数+每个颜色点3个浮点数] *每个浮点数4个字节*每秒30帧= 每秒1.34千兆字节

我的呈现代码现在看起来像这样:

glPointSize(ptSize);
glEnableClientState(GL_VERTEX_ARRAY);
if(colorflag) {
    glEnableClientState(GL_COLOR_ARRAY);
} else {
    glDisableClientState(GL_COLOR_ARRAY);
    glColor3f(1,1,1);
}
glBindBuffer(GL_ARRAY_BUFFER, vbobj[VERT_OBJ]);
glBufferData(GL_ARRAY_BUFFER, cloudSize, vertData, GL_STREAM_DRAW);
glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vbobj[COLOR_OBJ]);
glBufferData(GL_ARRAY_BUFFER, cloudSize, colorData, GL_STREAM_DRAW);
glColorPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_POINTS, 0, numPoints);
glDisableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

每帧都会更改vertData和colorData的指针。

我希望能够以每秒至少30帧的速度播放,即使以后使用每帧可能达到700万点的大点云也是如此。这甚至可能吗?或者也许更容易网格化并构建高度图并以某种方式显示它?我对3D编程还很陌生,所以任何建议都会受到赞赏。

5 个答案:

答案 0 :(得分:7)

如果可以,使用一维纹理实现颜色贴图。您只需要1个纹理坐标而不是3个颜色,它也会使顶点128位对齐。

编辑:你只需要从你的色彩图创建纹理并使用glTexCoordPointer而不是glColorPointer(当然在[0,1]范围内改变纹理坐标的顶点颜色值)。这是线性插值的6纹素色图:

// Create texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_1D, texture);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

// Load textureData
GLubyte colorData[] = {
    0xff, 0x00, 0x00,
    0xff, 0xff, 0x00,
    0x00, 0xff, 0x00,
    0x00, 0xff, 0xff,
    0x00, 0x00, 0xff,
    0xff, 0x00, 0xff
};
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 6, 0, GL_RGB, GL_UNSIGNED_BYTE, colorData);
glEnable(GL_TEXTURE_1D);

答案 1 :(得分:4)

我对opengl一无所知,但数据压缩不是一个自然的解决方法吗? 是不是支持整数类型或16位浮点数? 还有其他颜色表示,每点3浮点数?

答案 2 :(得分:3)

如果你愿意处理延迟,你可以加倍(或更多!)缓冲你的VBO,将几何体转移到一个缓冲区,同时从另一个缓冲区渲染:

while(true)
{
    draw_vbo( cur_vbo_id );
    generate_new_geometry();
    load_vbo( nxt_vbo_id );
    swap( cur_vbo_id, nxt_vbo_id );
}

编辑:您也可以尝试interleaving您的顶点而不是每个组件使用一个VBO。

答案 3 :(得分:1)

你说它是I / O绑定的。这意味着你已经对它进行了分析,并看到它花费50%或更多的时间等待I / O.

如果是这样,那就是你必须专注的,而不是图形。

如果没有,那么其他一些答案对我来说听起来不错。无论如何,个人资料,不要猜测This is the method I use.

答案 4 :(得分:0)

一些指示:

  • 在显卡上存储尽可能多的数据,并仅加载真正需要的内容(非常明显)
  • 在树木中使用lod水平(kd-或octtrees)并尽可能预先计算
  • 光盘上的压缩也很有用,以克服任何瓶颈