顶点数组对象
使用glGenVertexArrays()分配顶点数组对象。
void glGenVertexArrays(GLsizei n,GLuint* arrays);
返回n个未使用的对象到数组arrays中,用作顶点数组对象,它们负责分配不同类型的OpenGL对象名称。这里的名称类似C语言中的一个指针比那辆,我们必须分配内存并且用名称引用它之后,名称才有意义,
使用glBindVertexArray()函数创建并且绑定一个顶点数组对象。
void glBindVertexArray(GLuint array);
glBindVertexArray()完成了三项工作:
如果输入的变量array非0,并且是glGenVertexArrays()所返回的,那么它将创建一个新的顶点数组对象并且与其名称关联起来;
如果绑定到一个已经创建的顶点数组中,那么会激活这个顶点数组对象,并且直接影响对象中所保存的顶点数组状态;
如果输入的变量array为0,那么OpenGL将不再使用程序所分配的任何顶点数组对象,并且将渲染状态重设为顶点数组的默认状态。
如果array不是glGenVertexArrays()所返回的数值,或者它已经被glDeleteVertexArrays()函数释放了,那么这里将产生一个GL_INVALID_OPERATION错误。
在较大的程序里当我们完成对顶点数组对象的操作之后,可以调用glDeleteVertexArrays()将它释放。
void glDeleteVertexArrays(GLsizei n,GLuint* arrays);
删除n个在arrays中定义的顶点数组对象,这样所有的名称可以再次用作顶点数组。
如果绑定的顶点数组已经被删除,那么当前绑定的顶点数组对象被重设为0(类似执行glBindBuffer()函数,并且输入参数为0),而默认的顶点数组会编程当前对象。在arrays当中未使用的名称都会被释放,但是当前顶点数组的状态不会发生任何变化。
调用glisVertexArray()检查某个名称是否已经被保留为一个顶点数组对象。
GLboolean glisVertexArray(GLuint array);
如果array是一个已经用glGenVertexArrays()创建且没有被删除的顶点数组对象的名称,那么返回GL_TRUE。如果array为0或者不是任何顶点数组对象的名称,那么返回GL_FALSE。
分配顶点缓存对象
顶点数组对象负责保存一系列顶点的数据。这些数据保存到缓存对象当中,并且由当前绑定的顶点数组对象管理。我们只有一种顶点数组对象类型,但是却有很多种类型的对象,并且其中一部分对象并不负责处理顶点数据。
a.创建顶点缓存对象的名称。
void glGenBuffers(GLsizei n,GLuint* buffer);
返回n个当前未使用的缓存对象名称,并保存到buffers数组中。返回到buffers中的名称不一定是连续的整型数据。
这里返回的名称只用于分配其他缓存对象,它们在绑定后只会记录一个可用的状态。
0是一个保留的缓存对象名称,glGenBuffers()永远都不会返回这个值的缓存对象。
b.调用glBindBuffer()来绑定,并且要指定所对应的类型。
void glBindBuffer(GLenum target,GLuint buffer);
指定当前激活的缓存对象。target必须设置为以下类型中的一个:GL_ARRAY_BUFFER、GL_ELEMENT_ARRAY_BUFFER、GL_PIXEL_PACK_BUFFER、GL_PIXEL_UNPACK_BUFFER、GL_COPY_READ_BUFFER、GL_COPY_WRITE_BUFFER、GL_TRANSFORM_FEEDBACK_BUFFER和GL_UNIFORM_BUFFER
glBindBuffer()完成了三项工作:1)如果是第一次绑定buffer,且它是一个非零的无符号整型,那么将创建一个与该名称相对应的新缓存对象。
2)如果绑定到一个已经创建的缓存对象,那么它将成为激活的缓存对象。
3)如果绑定的buffer值为0,那么OpenGL将不再对当前target应用任何缓存对象
释放缓存对象
void glDeleteBuffer(GLsizei n,const GLuint* buffers);
删除n个保存在buffers数组中的缓存对象。被释放的缓存对象可以收纳柜用。如果删除的缓存对象已经被绑定,那么该对象的所有绑定将会重置为默认的缓存对象,即相当于用0作为参数执行glBindBuffer()的结果。如果试图删除不存在的缓存对象,或者缓存对象为0,那么将忽略该操作。
将数据载入缓存
使用glBufferData()把顶点数据从对象传输到缓存对象当中。它有两个任务:分配顶点数据所需的存储空间,然后将数据从应用程序的数组中拷贝到OpenGL服务端的内存中。
void glBuffer(GLenu target,GLsizeiptr size,const GLvoid* data,GLenum usage);
在OpenGL服务端内存中分配size个存储单元,用于存储数据或者索引。如果当前绑定的对象已经存在了关联的数据,那么会首先删除这些数据。
对于顶点属性数据,target设置为GL_ARRAY_BUFFER;索引数据为GL_ELEMENT_ARRAY_BUFFER;OpenGL的像素数据为GL_PIXEL_PACK_BUFFER;对于缓存之间的复制数据为GL_COPY_READ_BUFFER和GL_COPY_WRITE_BUFFER;对于纹理缓存中存储的纹理数据为GL_TEXTURE_BUFFER;对于通过transform feedback着色器获得的结果设置为GL_TRANSFORM_FEEDBACK_BUFFER;而一致变量要设置为GL_UNIFORM_BUFFER。
size表示存储数据的总数量。这个数值等于data中存储的元素的总数乘以单位元素存储空间的结果。
data要么是一个客户内存的指针,以便初始化缓存对象,要么是NULL,如果传入的指针合法,那么将会有size大小的数据从客户端拷贝到服务端。如果传入NULL,那么将保留size大小的未初始化的数据,以备后用。
usage用于设置分配数据之后的读取和写入方式。可用的方式包括GL_STREAM_DRAW、GL_STREAM_READ、GL_STREAM_COPY、GL_STATIC_DRAW、GL_STATIC_READ、GL_STATIC_COPY、GL_DYNAMIC_DRAW、GL_DYNAMIC_COPY。
如果所需的size大小超过了服务端能够分配的额度,那么glBufferData()将产生一个GL_OUT_OF_MEMORY错误。如果usage设置的不是可用的模式值,那么将产生GL_INVALID_VALUE错误。