glBufferStorage 不允许你取消分配它[注意 glBufferData 中的 0 参数,但它保留了 Persistent-mapped Buffer 的内存,通常你会看到用法如下所示: glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferStorage(GL_ARRAY_BUFFER, size, data, GL_MAP_PRESISTENT_BIT|GL_MAP_COHERENT_BIT); GLubyte* ptr = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_PRESISTENT_BIT|GL_MAP_COHERENT_BIT); Foo(ptr, size); 注意,ptr只是保持在同一缓冲区's address, that means the buffer is persistented in the memory, and you don't需要取消映射,直到你真的不需要它为止
2 回答
你知道,这是
glTexStorage* (...)
背后的原理 . 实际上,您与API签订 Contract ,该 Contract 规定您永远不会被允许更改对象的某些属性,并且作为交换,这将赋予对象不可变状态,并允许您执行通常无法使用它的操作 .纹理视图是一个有趣的例子,其中不可变纹理的内部图像数据可以在多个纹理对象之间共享,甚至可以重新解释其格式/维度(例如,可以共享和使用1个2D数组纹理切片,就好像它是普通的2D纹理) .
对于顶点缓冲区,不可变存储会打开一类性能优化(例如,持久映射内存),如果您可以随时更改缓冲区的大小,则无法实现 . 您创建一个永远不会更改其大小的缓冲区,但您仍然可以使用
glBufferSubData* (...)
命令随时向其发送新数据,或者在内存映射时写入缓冲区 .使用
glBufferData (...)
,您可以在同一对象上多次调用该命令,它将孤立旧内存并分配新存储 . 使用glBufferStorage (...)
时,缓冲区的大小设置为对象的生命周期(不可变),并且一旦分配不可变,再次调用glBufferStorage (...)
是错误(GL_INVALID_OPERATION
) .简而言之,数据存储(存储特性)是不可变的,而不是实际的数据 .
我相信这句话来自[https://www.opengl.org/registry/specs/ARB/buffer_storage.txt]显示关键:
这些提到可变缓冲区可能被解除分配或调整大小,并且来自
glBufferData
,它带来了可变缓冲区 . 但glBufferStorage
将向您展示创建不可变缓冲区的能力 .这里的关键是“不可变”意味着您将来无法调整大小或取消分配它,但并不意味着您无法在其中写入/读取数据 .
[编辑]我认为附加一些样本也很好,这可以使规范中的单词更容易理解,:)
glBufferData
有时你可能会遇到单词'buffer orphan',通常你会看到类似的调用(还有其他一些方法可以像_1658013那样做缓冲孤儿等):glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, size, 0, GL_STREAM_DRAW); GLubyte* ptr = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_WRITE_BIT); Foo(ptr, size); glUnmapBuffer(GL_ARRAY_BUFFER);
glBufferStorage
不允许你取消分配它[注意glBufferData
中的0
参数,但它保留了Persistent-mapped Buffer
的内存,通常你会看到用法如下所示:glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferStorage(GL_ARRAY_BUFFER, size, data, GL_MAP_PRESISTENT_BIT|GL_MAP_COHERENT_BIT); GLubyte* ptr = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_PRESISTENT_BIT|GL_MAP_COHERENT_BIT); Foo(ptr, size);
注意,ptr只是保持在同一缓冲区's address, that means the buffer is persistented in the memory, and you don't需要取消映射,直到你真的不需要它为止
谢谢