转载自:http://blog.youkuaiyun.com/zhuyingqingfen/article/details/19238651
顶点数组对象(Vertex Array Object 即VAO)是一个包含一个或数个顶点缓冲区对象(Vertex Buffer Object, 即 VBO)的对象,一般存储一个可渲染物体的所有信息。VAO的编号最多在0 to GL_MAX_VERTEX_ATTRIBS - 1.之间。
顶点缓冲区对象(Vertex Buffer Object VBO)是你显卡内存中的一块高速内存缓冲区,用来存储顶点的所有信息。
There is always a VAO bound to the context. The default VAO has the name 0 and is created along with the context, similar to textures 0 and framebuffer 0. When you bind a VAO, all the state stored in it will become active. Calls to glVertexAttribPointer, or glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ...), modify the currently bound VAO.
一个VAO通常绑定到一个上下文中,默认的VAO编号是0,这个是随着上下文创建时而创建的,还有textures 0、framebuffer 0 。当你绑定一个VAO 它的所有的状态将会激活,调用glvertexAttribPointer 或者glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...),将会改变当前的绑定的VAO
VAO 对象
- struct VertexAttributeState
- {
- bool bIsEnabled = false;
- int iSize = 4; //This is the number of elements in each attrib, 1-4.
- unsigned int iStride = 0;
- VertexAttribType eType = GL_FLOAT;
- bool bIsNormalized = false;
- bool bIsIntegral = false;
- void * pPtrOrBufferObjectOffset = 0;
- BufferObject * pBufferObj = 0;
- };
- struct VertexArrayObjectState
- {
- BufferObject *pElementArrayBufferObject = NULL;
- VertexAttributeState attributes[MAX_VERTEX_ATTRIB];
- }
- static VertexArrayObjectState *pContextVAOState = new VertexArrayObjectState();
- static BufferObject *pCurrentArrayBuffer = NULL;
VertexArrayObjectState 中存储的就是一个VAO存储的所有状态。
- void glBindBuffer(enum target, uint buffer)
- {
- BufferObject *pBuffer = ConvNameToBufferObj(buffer);
- switch(target)
- {
- case GL_ARRAY_BUFFER:
- pCurrentArrayBuffer = pBuffer;
- break;
- case GL_ELEMENT_ARRAY_BUFFER:
- pContextVAOState->pElementArrayBufferObject = pBuffer;
- break;
- ...
- }
- }
- void glEnableVertexAttribArray(uint index)
- {
- pContextVAOState->attributes[index].bIsEnabled = true;
- }
- void glDisableVertexAttribArray(uint index)
- {
- pContextVAOState->attributes[index].bIsEnabled = false;
- }
- void glVertexAttribPointer(uint index, int size, enum type, boolean normalized, sizei stride, const void *pointer)
- {
- VertexAttributeState &currAttrib = pContextVAOState->attributes[index];
- currAttrib.iSize = size;
- currAttrib.eType = type;
- currAttrib.iStride = stride;
- currAttrib.bIsNormalized = normalized;
- currAttrib.bIsIntegral = true;
- currAttrib.pPtrOrBufferObjectOffset = pointer;
- currAttrib.pBufferObj = pCurrentArrayBuffer;
- }
从上面可以看出(glBindBuffer函数),GL_ARRAY_BUFFER 不是VAO的状态!,事实上连接属性索引和一个缓冲区的是glVertexAttribPointer.
This works just like any other state object. Allocated Vertex Array Objects will have their state set by these functions
上面这些工作原理和其他状态对象一样,分配的VAO将通过这些函数来用他们的状态集。
glDrawElements将会用你所设置的当前OpenGL的状态上下文来渲染你的物体。