gpt4 book ai didi

c++ - OpenGL更新部分VBO(点云)

转载 作者:行者123 更新时间:2023-11-30 04:02:13 25 4
gpt4 key购买 nike

我有一个 udp 客户端,用于从在 4 毫秒内生成点的服务器读取点,每个数据包有近 3000 个点。我阅读了这些点并将它们映射到具有 100 万个坐标元素的矩阵。 (我用固定键从流点创建一个哈希表。我的意思是你可以想到 1000 个键,每个键最多有 1000 个点,但它会有所不同。完成此表后,我从服务器获得的任何新值,映射到我的键一种排序的方式,我的意思是,我首先更新较小键中的点,然后......:D

我真的很惭愧我不能这样做,我的 1990x1080 像素的 LCD 做这件事比我快!! :-((

我想把它插入到一个 VBO 中,然后在 30 毫秒内升级每个关键部分。

所以我想创建 1000 个用于绘图的 vbo 和 1000 个用于缓冲的 vbo,并且在每 33 毫秒迭代后我将 50 个绘图 vbo 更改为缓冲 vbo。每个vbo最多有0f 1000个点和颜色,一个VBO的点数从10变为1000;

我的问题从这里开始我不明白 VBO 的工作原理和实现这个问题的最佳解决方案? :D

1- 我的第一个问题:为什么我创建一个 VAO 以及它如何与新一代缓冲区相关联?它看起来像是与下一个 glGenBuffer() 相关联,对吗?但是在我阅读的任何示例中,我都没有看到这个指针的任何使用(仅用于绘制)?这是我从某处下载的用于创建 vbo 的代码

glGenVertexArrays(1, &vertexArrayObject);
glBindVertexArray(vertexArrayObject);

// First see if the vertex array buffer has been created...
if(uiVertexArray == 0) { // Nope, we need to create it
glGenBuffers(1, &uiVertexArray);
glBindBuffer(GL_ARRAY_BUFFER, uiVertexArray);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * nNumVerts, NULL, GL_DYNAMIC_DRAW);
}

// Now see if it's already mapped, if not, map it
if(pVerts == NULL) {
glBindBuffer(GL_ARRAY_BUFFER, uiVertexArray);
pVerts = (M3DVector3f *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
}

// Ignore if we go past the end, keeps things from blowing up
if(nVertsBuilding >= nNumVerts)
return;

// Copy it in...
pVerts[nVertsBuilding][0] = x;
pVerts[nVertsBuilding][1] = y;
pVerts[nVertsBuilding][2] = z;
nVertsBuilding++;

用于颜色和纹理映射的外观。哪个性能更好(GL_DYNAMIC_DRAW,GL_STREAM_DRAW)

2- 这是绘图函数?为什么使用最后一行?用于创建下一个 VBO 和 VAO?

// Set up the vertex array object
glBindVertexArray(vertexArrayObject);
glDrawArrays(primitiveType, 0, nNumVerts);
glBindVertexArray(0);

3-下次我想用新点更改缓冲的 VBO 内容时,我必须为不同数量的点再次执行此操作,如果我这样做,我是否必须删除 VBO 的最后一个缓冲区?

// Vertex buffer objects
if(uiVertexArray != 0)
glDeleteBuffers(1, &uiVertexArray);

4- 我可以调整我的 VBO 的大小并且不使用重新创建缓冲区 VBO 吗?

5- 如何从缓冲区 VBO 复制数据以绘制 VBO?

这是我在主绘图函数中使用绘图 VBO 的交换缓冲区,我在交换函数中从第一个开始重新创建 VBO 数据

for(int i=0; i<1000; i++)
if(must_show_buffer(i))
{
bufferVBO[i].draw();
drawedVBO[i].swap(bufferVBO[i]);
}
else drawedVBO[i].draw();

更新:

我将此函数用于交换数据: 如果(批处理->cVerts != NULL) { CopyVertexData3f(batch->cVerts); CopyColorData4f(batch->cColors); } 结束();

void GLBatch::CopyColorData4f(M3DVector4f *vColors)
{
// First time, create the buffer object, allocate the space
if(uiColorArray == 0) {
glGenBuffers(1, &uiColorArray);
glBindBuffer(GL_ARRAY_BUFFER, uiColorArray);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4 * nNumVerts, vColors, GL_DYNAMIC_DRAW);
}
else { // Just bind to existing object
glBindBuffer(GL_ARRAY_BUFFER, uiColorArray);

// Copy the data in
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * 4 * nNumVerts, vColors);
pColors = NULL;
}
}

这种方法是正确的,但是 glBufferSubData 增加内存使用的速度如此之快,我得到了一个内存不足的异常

和这种方法

    if(batch->uiVertexArray != NULL)
{
// First time, create the buffer object, allocate the space
if(uiVertexArray == 0) {
glGenBuffers(1, &uiVertexArray);
glBindBuffer(GL_ARRAY_BUFFER, uiVertexArray);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * nNumVerts, NULL, GL_DYNAMIC_DRAW);
}

// Fast copy data
glBindBuffer(GL_COPY_READ_BUFFER, batch->uiVertexArray);
glBindBuffer(GL_COPY_WRITE_BUFFER, uiVertexArray);
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, nNumVerts);
glBindBuffer(GL_COPY_READ_BUFFER, 0);
glBindBuffer(GL_COPY_WRITE_BUFFER, 0);

//copy color data
if(uiColorArray == 0) {
glGenBuffers(1, &uiColorArray);
glBindBuffer(GL_ARRAY_BUFFER, uiColorArray);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4 * nNumVerts, NULL, GL_DYNAMIC_DRAW);
}

glBindBuffer(GL_COPY_READ_BUFFER, batch->uiColorArray);
glBindBuffer(GL_COPY_WRITE_BUFFER, uiColorArray);
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, nNumVerts);
glBindBuffer(GL_COPY_READ_BUFFER, 0);
glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
}

没有内存分配问题但点前不清除

我在每次实现中错过了什么?

最佳答案

  1. VBO 在 glVertexAttribPointer 期间与当前绑定(bind)的 VAO 相关联

  2. 解除绑定(bind)缓冲区是一个好习惯,记住绑定(bind)状态是全局的,你依赖的全局状态越少越好

  3. 无需删除 VBO,您可以跳过 glGenBuffers(1, &uiVertexArray); 调用

  4. 是的,使用新的 nNumVerts 对 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * nNumVerts, NULL, GL_DYNAMIC_DRAW); 的新调用将调整缓冲区大小(并破坏任何现有数据)

  5. 您可以执行以下操作:

    glBindBuffer(GL_COPY_READ_BUFFER, bufferVBO);
    glBindBuffer(GL_COPY_WRITE_BUFFER, drawVBO);
    glCopyBufferSubData(GL_COPY_READ_BUFFER​, GL_COPY_WRITE_BUFFER​, 0​, 0, size​);
    glBindBuffer(GL_COPY_READ_BUFFER, 0);
    glBindBuffer(GL_COPY_WRITE_BUFFER, 0);

我已经在屏幕上写出了 700k 点/秒,只要将它们全部上传到一个 VBO 中并绘制它就没问题。

关于c++ - OpenGL更新部分VBO(点云),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25286738/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com