gpt4 book ai didi

c++ - 如何在不丢失以前数据的情况下只向 opengl 发送新数据?

转载 作者:搜寻专家 更新时间:2023-10-31 00:51:57 50 4
gpt4 key购买 nike

我正在处理需要使用 opengl 渲染的 PointCloud 数据。我每帧都会得到一个新的数据点 vector 。我希望我能够缓存之前发送到 opengl 的数据,并且只将最新的帧数据发送给它。我该怎么做?

我做了一些搜索,发现了这个想法 here :

// Bind the old buffer to `GL_COPY_READ_BUFFER`
glBindBuffer (GL_COPY_READ_BUFFER, old_buffer);

// Allocate data for a new buffer
glGenBuffers (1, &new_buffer);
glBindBuffer (GL_COPY_WRITE_BUFFER, new_buffer);
glBufferData (GL_COPY_WRITE_BUFFER, ...);

// Copy `old_buffer_size`-bytes of data from `GL_COPY_READ_BUFFER`
// to `GL_COPY_WRITE_BUFFER` beginning at 0.
glCopyBufferSubData (GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, old_buffer_size);

但看起来它终于在新缓冲区中发送了以前的数据和新数据,而不是缓存并仅发送最新数据。所以我不确定这是否是最好的方法。如果我错了或建议替代方案,请纠正我。

最佳答案

因此,您将一些数据存储在 CPU 内存中,并将更多数据附加到该存储空间。然后您只想将附加数据发送到 GPU,而不是整个缓冲区。

您的代码示例与此任务无关,因为 glCopyBufferSubData 将数据从 GPU 内存中的一个位置再次复制到 GPU 内存中的另一个位置。

您需要 glBufferDataglBufferSubData 的组合。 glBufferData 在 GPU 中分配内存并选择初始化它。 glBufferSubData 将一些数据写入已分配的 GPU 缓冲区。你可以把 glBufferData 当作 C 的 malloc 或 C++ new,而 glBufferSubData 就像一个特殊版本的 C 的 memcpy 或 C++ 标准::复制。更准确地说,glBufferSubData是从CPU到GPU的memcpyglCopyBufferSubData是从GPU到GPU的memcpy

如何一起煮?与C中的方法相同。在初始化时(程序启动时)调用一次glBufferData,并在需要追加数据时调用glBufferSubData。一定要分配足够的空间!由 glBufferData 分配的缓冲区不会增长,以及 malloced 缓冲区。使用 glBufferSubData 溢出缓冲区会导致未定义的行为,并可能使您的应用程序崩溃。

尝试预测缓冲区的空间需求,并仅在数据不适合缓冲区时才调用 glBufferData

请记住,使用已分配的缓冲区绑定(bind)调用 glBufferData 将释放现有缓冲区并创建一个新缓冲区。

glBufferSubData 不会重新分配您的缓冲区,但会覆盖已经存在的数据。

让我用C翻译来说明:

glGenBuffers(..., buf); // float* buf;
glBindBuffer(buf); // Tell opengl that we will use buf pointer, no analog in C.
glBufferData(/*non-null pointer*/); // buf = malloc(/*..*/); memcpy(to_gpu, from_cpu);
glBufferData(/*another non-null pointer*/); // free(buf); buf = malloc(/*..*/); memcpy(to_gpu, from_cpu);
glBufferSubData(...); // memcpy(to_gpu, from_cpu);

思想方法

你需要的是:

glGenBuffers(..., buf); // float* buf;
glBindBuffer(buf); // Tell opengl that we will use buf pointer, no analog in C.

// Initialization
glBufferData(/*non-null pointer*/); // buf = malloc(/*..*/); memcpy(to_gpu, from_cpu);

// Hot loop
while (needToRender) {
if(needToAppend) {
if (dataDoesNotFit) glBufferData(...); // Reallocate, same buffer name
else glBufferSubData(...); // memcpy(to_gpu, from_cpu);
}
}

这里我们只是偶尔重新分配内存,当我们需要追加一些东西并且缓冲区太小时。

其他方法

我建议使用 glBufferData 重新分配,因为您已经将所有数据放在 CPU 的单个缓冲区中。如果不是(即您在 GPU 上有一 block 数据,在 CPU 上有另一 block 数据,但不是在一起),您可以使用 glCopyBufferSubData 进行重新分配:

glBufferData(/*alloc new_gpu_buffer*/);
glCopyBufferSubData(/*from old_gpu_buffer to new_gpu_buffer*/);
glDeleteBuffers(/*old_gpu_buffer*/);
glBufferSubData(/*from_cpu_buffer to new_cpu_buffer*/)p; // Add some new data from CPU.

另一种更新 GPU 数据的方法是 mapping它到 CPU,所以你只需通过指针访问 GPU 内存。它可能很慢(阻塞缓冲区,使管道停止),并且仅在特殊情况下有用。如果您知道自己在做什么,请使用它。

关于c++ - 如何在不丢失以前数据的情况下只向 opengl 发送新数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53577821/

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