调整缓冲区大小通常是一个不存在的概念。您不知道缓冲区后面是否有空间需要增加,或者存储空间是否可用。所有看似有此选项的操作实际上都会检查这些异常并在需要时重新分配缓冲区。
但在您的情况下,GPU 上的缓冲区非常接近设备内存中的缓冲区。您甚至可以使用glMapBuffer 映射内存以接收void* 指针,但要检查整个过程。
结合这些事实,您可以独自管理缓冲区中的数据。如果缓冲区需要膨胀,您应该创建一个新缓冲区,然后将旧数据复制到其中。其中一个程序是在需要时将缓冲区膨胀 2 倍:
- 从一些固定的缓冲区大小开始,比如说
currentSize = sizof(GLfloat*3*1000)
- 继续填写数据并跟踪您有多少空间。当缓冲区已满时,将其充气
-
newSize = currentSize*2 膨胀 2
- 分配具有新大小的新缓冲区
- 映射两个缓冲区
- 将第一个
currentSize 字节复制到新缓冲区 (memcpy)
- 将
currentSize 设置为newSize
但现在这是最容易的部分。您的问题还包含缓冲区块可能被丢弃的情况。所以你需要追踪这些人。以下是我能想到的几种方法:
- 让他们的坐标离开屏幕
- 将它们标记为可丢弃
- 每次删除数据时都回推数据
问题是他们每个人都有一个缺点。我个人会选择可丢弃的:
假设您使用的是 ObjectiveC/C(如果您使用的是 Swift,请不要打扰)。你会有一个顶点结构:
struct MyVertex {
GLfloat x,y;
// Add additional values here like color or whatever
GLfloat discarded;
};
然后在您的对象中为单个段具有 s 结构:
struct Drop {
MyVertex vertices[6]; // or wahtever
}
现在您需要为属性设置指针,您需要添加另一个可丢弃的指针(在glAttributePointer 中)。对于您正在使用的位置NULL+offsetof(MyVertex, x),对于可丢弃的NULL+offsetof(MyVertex, discarded)。而对于大步sizeof(MyVertex)...
现在在片段着色器中检查丢弃的值,如果片段具有某些值,则丢弃片段(您可以选择任何表示任何值的值)。
所以现在,无论何时添加一个 drop,您都可以遍历内存中的数组并检查其中一个 drop 是否被丢弃并使用那个。因此,您为所有顶点设置drops[index].vertices[i].discarded = 0.0,并使用缓冲区子数据过程来更新这部分缓冲区。
当你想删除它时,你需要将丢弃的设置为1.0(或任何你想要的),但还要记住将顶点设置为相等的值(例如全为 0)。这样做的原因是您减少了生成的片段数量。最好只生成一些完全离屏的坐标。
如果可能,永远不要使用幻数,永远不要使用固定值。 sizeof、offsetof、struct 和 union 应该足以有效地管理原始数据。并且通过使用这种改变结构永远不会破坏你的逻辑。