cocos2d-x 之 CCTextureAtlas 简介
2012-02-27 18:09
274 查看
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()
在这函数的结尾,将顶点数组和顶点索引数组导入到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
CCTextureAtlas绘制功能的实现是在这个函数中CCTextureAtlas::drawNumberOfQuads,里面大部分都是opengl的命令,比较令我感兴趣的是这句话:
if (m_bDirty)
{
glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * start, sizeof(m_pQuads[0]) * n, &m_pQuads[start]);
m_bDirty = false;
}这句话的作用就是之前说的。如果该类所管理的四边形信息结构体数组被外界改了,需要置位m_bDirty为true,这样在画的时候,就把相关的数据更新到opengl中。
CCTextureAtlas提供了增删改查m_pQuads的函数。值得一提的是CCTextureAtlas::resizeCapacity这个函数。
resizeCapacity会根据重置数组大小重新生成数组,然后它要重新生成那两个VBO(你知道,不知道看前面吧),然后初始化索引。
好了,打多了眼疼。就到这里吧
由于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。
* | / |
*/ 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
CCTextureAtlas绘制功能的实现是在这个函数中CCTextureAtlas::drawNumberOfQuads,里面大部分都是opengl的命令,比较令我感兴趣的是这句话:
if (m_bDirty)
{
glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * start, sizeof(m_pQuads[0]) * n, &m_pQuads[start]);
m_bDirty = false;
}这句话的作用就是之前说的。如果该类所管理的四边形信息结构体数组被外界改了,需要置位m_bDirty为true,这样在画的时候,就把相关的数据更新到opengl中。
CCTextureAtlas提供了增删改查m_pQuads的函数。值得一提的是CCTextureAtlas::resizeCapacity这个函数。
resizeCapacity会根据重置数组大小重新生成数组,然后它要重新生成那两个VBO(你知道,不知道看前面吧),然后初始化索引。
好了,打多了眼疼。就到这里吧
相关文章推荐
- cocos2d-x 学习: CCTextureAtlas 简介
- cocos2d-x 动画详解之零 基础CCTexture2D,CCTextureAtlas,CCTextureCache
- CCSpriteBatchNode和CCTextureAtlas 详解-沈大海cocos2d-x教程21
- cocos2d-x节点(CCTextureAtlas.h)API
- Cocos2D-x , CCTextureCache的多线程加载原理和使用方法
- [cocos2d-js]cc.RenderTexture几种用法(数字图片、刮刮乐效果)
- cocos2d-x中CCTextureCache图片资源的异步加载<转>
- cocos2d-x 2.2.3 CCTextureCache的addImage简单分析
- cocos2d-x中CCLabelAtlas的小图片拼接
- cocos2d-x 字体描边CCRenderTexture glBlendFunc
- cocos2d-x之CCTextureCache 用法总结
- CCTextureAtlas(Atlas地图集图册-表示将小纹理组成一张纹理集以达到批量渲染目的 方法->TextureAtlas维护了一个ccV3F_C4B_T2F_Quad数组)
- Cocos2d-JS中的cc.LabelAtlas
- cocos2dx2.1版本中使用CCTextureAtlas drawQuads绘制问题
- Cocos2d-x中的 CCSpriteFrameCache , CCTextureCache的使用
- cocos2d-x学习笔记(14)--CCTextureCache
- cocos2d-x中的缓存CCTextureCache、CCSPriteFrameCache、CCAnimationCache
- cocos2d-x CCTextureCache使用
- Cocos2d-JS中的cc.LabelAtlas
- 更改 cocos2d-x CCRenderTexture 的使用方式