此系列学习笔记来自OpenGL超级宝典第七版英文版自己翻译而来,此书使用的OpenGL核心的版本是4.5.
2017-3-22缓冲区(buffers)
1、 缓冲区是线性分配存储的。
2、 缓冲区是由名字表示的,OpenGL本质上是使用名字来辨识缓冲区的。
3、 在你使用一个缓冲区前,你需要向OpenGL请求一些名字,然后使用这些名字来申请内存,最后向内存中存储数据。这些内存称之为缓冲区的数据仓库。
4、 一旦你获得了一个缓冲区的名字,就可以通过绑定点把缓冲区附着到OpenGL上下文中去。绑定点(binding points)一般也可以指目标(targets),这些属于一般可以替换使用(虽然从技术上讲把绑定点与目标看成一个东西是不正确的,因为一个单独的目标可能会有很多绑定点。但在大多数场合,混淆使用这两者应该会被正确的理解)
5、 OpenGL中有很多绑定点,他们各有不同的用处。
6、 OpenGL中的的大多数对象(Object)都是用GLuint类型的变量代表的,这个变量即称之为名字。
7、 创建缓冲区对象:
void glCreateBuffers(GLsizei n , GLuint * buffers);
第一个参数表示要创建的缓冲区对象的数量,第二个参数表示要创建的缓冲区对象的名字的地址,如果要创建大于1个(n),那么参数buffers应该是一个至少有n个元素的GLuint数组的首地址。OpenGL默认相信这个数组的元素数是大于你要创建的缓冲区对象的数目的。
8、 把缓冲区对象绑定到OpenGL上下文中去:
void glBindBuffers(GLenum target, GLuint buffer);
9、 为缓冲区对象分配内存:
void glBufferStorage(GLenum target ,GLsizeiptrsize,const void* data,GLbitfieldflags);
void glNamedBufferStorage(GLuintbuffer ,GLsizeiptrsize,const void* data,GLbitfieldflags);
第一个函数将为所有的绑定到target指定的绑定点的缓冲区对象分配内存,第二个则只为buffer这一个缓冲区对象分配内存。size表示要分配的内存的大小,单位为字节,data则是要用来初始化内存内容的数据的地址,为Null则不初始化,flags则指定了如何使用这个缓冲区对象。
一旦缓冲区对象的存储已经使用上面的函数分配了,那么他的存储(地址)、存储内存大小和使用目的flag将不能重新分配或指定,但是数据仓库内的内容是可以改变的。
10、为缓冲区分配对象函数中的参数flag可能的值有:
GL_DYNAMIC_STORAGE_BIT,告诉OpenGL缓冲区的内容是可以改变的,如果不指定这个位,那么OpenGL将会给这个缓冲区对象分配一些不容易被更改的内存上去,而且glBufferSubData()这个函数将不能改变这个缓冲区对象的值(有其他的OpenGL函数可以);
GL_MAP_READ_BIT,GL_MAP_WRITE_BIT,GL_MAP_PERSISTENT_BIT,GL_MAT_COHERENT_BIT这几个flag标志位,告诉OpenGL是否以及怎样去映射数据仓库。映射操作(mapping)是指从主程序中获得一个的一个指针,而这个指针代表某一个缓冲区的潜在的数据仓库。前两个顾名思意,不在详述,第三个告诉系统当你在使用其他绘制指令时,你希望映射某缓冲区后保持其映射状态。否则意味着当你因为调用绘制指令时而使用某缓冲区时,系统不要求映射这个缓冲区。支持永久映射会造成大量的额外开销,除非你必须使用它,否则尽量不要使用它。最后一个标志位告诉系统你想要能够与GPU紧凑的共享数据。如果不设置此位,你需要告诉系统什么时候往该缓冲区写入数据,即使你不解除映射它。