CCTextureAtlas是一个大图绘制管理类。说白了,它本身保存一张大图的纹理和一个记录画大图某一区域的信息结构体的数组,通过操纵这个数组你可以绘制出一批四边形,这些四边形的纹理和绘制的坐标都存放在你操作的数组之中的(又把废话重复了一遍。)
由于CCTextureAtlas使用了opengl的VBO(顶点数组对象),所以用CCTextureAtlas所作的绘制在效率上比较高。
下面介绍一下该类的成员:
1.GLuint m_pBuffersVBO[2],这是两个opengl VBO的句柄。一个用来做顶点数组句柄,一个用来做顶点索引数组句柄。
2.GLushort *m_pIndices,这是一个顶点索引数组的类本地备份。
3 ccV3F_C4B_T2F_Quad * m_pQuads ,这是一个顶点数组的类本地备份。这应该是CCTextureAtlas类实现的核心,所有该类的功能都再围绕该结构体在做操纵。
4. CCTexture2D *m_pTexture,这是保存大图的纹理管理类。
5 int m_uCapacity,四边形的容量。
6 int m_uTotalQuads,实际上使用的四边形的数目。
7 m_bDirty ,当前opengl VBO中的数据是否是脏数据。为什么会存在这么一个类呢?实际上因为CCTextureAtlas容许你动态改变它管理的四边形数据,一旦你改变了该数据就需要一个标志位告诉该类在绘制四边形的时候把VBO中得数据更新掉。该成员就是起这个作用。
该类的主要功能和实现介绍
初始化。
该类的初始化需要提供的参数,除了需要加载的图片外还需要提供一个容量值。
初始化的流程:
1.如果提供一个文件名作为纹理参数,则调用纹理缓冲的加载该图片,如果提供纹理则接着到下一步。
2 根据提供的容量nCapaciity,malloc分配nCapaciity大小的ccV3F_C4B_T2F_Quad 数组,和6倍nCapaciity的容量的GLuint数组。
3 生成VBO。
4 初始化顶点索引数组。该操作在CCTextureAtlas::initIndices()中完成,特别注意索引初始化的顺序。
代码如下:
- /*这段代码取自CCTextureAtlas::initIndices()
- *四边形存储形式如图 : 0 — 2 opengl中绘图逆时针算正向绘制,所以正确顺序是0-1-2,3-2-1。
- *<span style="white-space:pre"> </span> | / |
- */<span style="white-space:pre"> </span> 1 — 3
- for( unsigned int i=0; i < m_uCapacity; i++)
- {
- #if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
- m_pIndices[i*6+0] = i*4+0;
- m_pIndices[i*6+1] = i*4+0;
- m_pIndices[i*6+2] = i*4+2;
- m_pIndices[i*6+3] = i*4+1;
- m_pIndices[i*6+4] = i*4+3;
- m_pIndices[i*6+5] = i*4+3;
- #else
- m_pIndices[i*6+0] = (GLushort)(i*4+0);
- m_pIndices[i*6+1] = (GLushort)(i*4+1);
- m_pIndices[i*6+2] = (GLushort)(i*4+2);
- // inverted index. issue #179
- m_pIndices[i*6+3] = (GLushort)(i*4+3);
- m_pIndices[i*6+4] = (GLushort)(i*4+2);
- m_pIndices[i*6+5] = (GLushort)(i*4+1);
- // m_pIndices[i*6+3] = i*4+2;
- // m_pIndices[i*6+4] = i*4+3;
- // m_pIndices[i*6+5] = i*4+1;
- #endif
- }
在这函数的结尾,将顶点数组和顶点索引数组导入到opengl中,下面这段代码就不解释了,如果你实在想知道,建议你看看opengl方面的书籍。
- #if CC_USES_VBO
- glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_pIndices[0]) * m_uCapacity * 6, m_pIndices, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- #endif // CC_USES_VBO
- if (m_bDirty)
- {
- glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * start, sizeof(m_pQuads[0]) * n, &m_pQuads[start]);
- m_bDirty = false;
- }
CCTextureAtlas提供了增删改查m_pQuads的函数。值得一提的是CCTextureAtlas::resizeCapacity这个函数。
resizeCapacity会根据重置数组大小重新生成数组,然后它要重新生成那两个VBO(你知道,不知道看前面吧),然后初始化索引。
好了,打多了眼疼。就到这里吧。
本文转载于zhidejll的专栏,地址http://blog.csdn.net/liuzhidejll/article/details/7298954