上一篇文章介绍了cocos2d-x的基本渲染结构,这篇顺着之前的渲染结构介绍渲染命令QUAD_COMMAND命令的部分,通过这部分的函数,学习opengl处理图片渲染的方法,首先介绍这节需要涉及到的基本概念VAO和VBO。
VAO和VBO:
顶点数组对象(Vertex Array Object 即VAO)是一个包含一个或数个顶点缓冲区对象(Vertex Buffer Object, 即 VBO)的对象,一般存储一个可渲染物体的所有信息。顶点缓冲区对象(VertexBuffer Object VBO)是你显卡内存中的一块高速内存缓冲区,用来存储顶点的所有信息。
这些概念显得很晦涩,简而言之,一般我们绘制一些图形需要将所有顶点的信息存储在一个数组里,但是经常会出现一些点是被重复使用的,这样就会出现一个点的信息的存储空间被重复使用的问题,这样第一会造成存储控件的浪费,第二就是如果我们要修改这个点的信息,需要改多次。所以我们采用索引的方式来描述图形,这样可以用一个数组存储点的信息,另外一个数组存储点的索引,这样所有的点都是不同的,另外把顶点信息存储在显卡的内存中,减少了cpu向gpu传输数据的时间,提高了程序的渲染效率,这就是VBO,在OpenGL3.0中,出现了更进一步的VAO,VBO通过绘制上下文获得绘制状态,VAO可以拥有多个VBO,它记录所有绘制状态,它的代码更简洁,效率更高,在cocos2d-x的绘制中,我们会判断底层是否支持VAO,如果支持VAO,那么优先采用VAO绘制。二者的区别可以从初始化就可以看出来:
- voidRenderer::setupBuffer()
- {
- if(Configuration::getInstance()->supportsShareableVAO())
- //初始化VBO和VAO
- setupVBOAndVAO();
- }
- else
- {
- //不支持VAO,只初始化VBO
- setupVBO();
- }
- voidRenderer::setupVBOAndVAO()
- //一个VAO
- glGenVertexArrays(1,&_quadVAO);
- //绑定VAO
- GL::bindVAO(_quadVAO);
- //创建生成两个VBO
- glGenBuffers(2,&_buffersVBO[0]);
- //顶点Buffer
- glBindBuffer(GL_ARRAY_BUFFER,_buffersVBO[0]);
- glBufferData(GL_ARRAY_BUFFER,sizeof(_quads[0])*VBO_SIZE,_quads,GL_DYNAMIC_DRAW);
- //这里就是VAO和VBO的区别,VAO把这些放到初始化中,无论后面绘制多少次,只要他不被改变,这段代码只会被调用一次,而VBO中,这个功能的代码会在每次被绘制时调用,这样就节约了效率
- //位置
- glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
- glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION,3,GL_FLOAT,GL_FALSE,153); background-color:inherit; font-weight:bold">sizeof(V3F_C4B_T2F),(GLvoid*)offsetof(V3F_C4B_T2F,vertices));
- //颜色
- glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR);
- glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR,4,GL_UNSIGNED_BYTE,GL_TRUE,colors));
- //纹理坐标数据
- glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORDS);
- glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS,2,texCoords));
- //索引Buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,_buffersVBO[1]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER,153); background-color:inherit; font-weight:bold">sizeof(_indices[0])*VBO_SIZE*6,_indices,GL_STATIC_DRAW);
- //取消VAO
- GL::bindVAO(0);
- CHECK_GL_ERROR_DEBUG();
- voidRenderer::setupVBO()
- //创建生成两个VBO
- glGenBuffers(2,&_buffersVBO[0]);
- //调用函数绑定buffer
- mapBuffers();
- voidRenderer::mapBuffers()
- //GL_ARRAY_BUFFER表示顶点数据
- //GL_ELEMENT_ARRAY_BUFFER表示索引数据
- //避免改变buffer元素
- //绑定id顶点数据
- //为改id制定一段内存区域
- glBufferData(GL_ARRAY_BUFFER,GL_DYNAMIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER,0); background-color:inherit">//第二个VBO索引数据
- CHECK_GL_ERROR_DEBUG();
- }