在模拟中使用 GL_ARRAY_BUFFER 时屏幕锁定

Posted

技术标签:

【中文标题】在模拟中使用 GL_ARRAY_BUFFER 时屏幕锁定【英文标题】:Screen locking up, when using GL_ARRAY_BUFFER within a simulation 【发布时间】:2011-11-30 22:55:34 【问题描述】:

我实现了一个小型粒子模拟查看器,用于显示粒子模拟。类似于 VMD。 由于我得到了大量粒子(> 80000),我使用 GL_ARRAY_BUFFER 和 GL_POINTS 来显示它们。这适用于小型数据集。

在每个时间步,我使用以下代码填充新的粒子位置:

void displayPoints(Timestep t) 
    int elements = t.elements;
    unsigned int glbuffersize = elements*sizeof(float4);
    glBindBuffer(GL_ARRAY_BUFFER,positionsVBO);
    glBufferData(GL_ARRAY_BUFFER,glbuffersize,t.pos,GL_DYNAMIC_DRAW);
    glVertexAttribPointer(shaderAtribute,4,GL_FLOAT,GL_FALSE,0,0);
    glEnableVertexAttribArray(shaderAtribute);
    glBindBuffer(GL_ARRAY_BUFFER,positionsVBO);
    glUseProgram(shaderProgram);
    glDrawArrays(GL_POINTS, 0, elements);

t.pos 只是一个简单的 float4 结构数组。

如果我现在使用我的 600MB 测试集以每个时间步长 >80000 个点运行此程序,则显示会在前 20-50 帧后锁定。我必须等待 2 分钟,直到我看到程序再次运行 10 帧,直到它再次冻结。

我怀疑上面的代码可能会填满图形内存。有没有更好的方法来制作这个动画?

如果你想看看完整的代码,这里提供:https://github.com/moeeeep/opengl_dataviewer (着色器目前被硬编码到我的机器上,因为我还没有时间修复我的 CMake 文件)。

【问题讨论】:

【参考方案1】:

glBufferData(重新)初始化一个全新的缓冲区对象——就像glTexImage重新初始化一个全新的纹理一样。

使用glBufferSubData 更新内容,无需进行完整的对象分配。

【讨论】:

以上是关于在模拟中使用 GL_ARRAY_BUFFER 时屏幕锁定的主要内容,如果未能解决你的问题,请参考以下文章

我可以在更新同一个“GL_ARRAY_BUFFER”时多次调用“glDrawArrays”吗?

OpenGL 如何知道它应该根据 GL_ARRAY_BUFFER 将顶点绘制到啥位置?

在 OpenGL ES 2 中更新 VBO 的顶点

每帧多次调用 glBufferSubData

使用类型类使OpenGL的int常量类型安全

关于opengl的绑定和解绑的时机