前端之家收集整理的这篇文章主要介绍了
Cocos2d-x2.0 粒子系统深入分析三部曲(二),
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
红孩儿Cocos2d-X学习园地QQ2群:44208467加群写:Cocos2d-x
红孩儿Cocos2d-X学习园地QQ群:249941957加群写:Cocos2d-x
Cocos2d-x2.0 粒子系统深入分析三部曲(二)
上一节我们了解了粒子系统的原理,也学习了Cocos2d-x中的两个有关粒子系统的类:
(1)CCParticleSystem :粒子系统的基类,提供对粒子的创建和更新管理。
(2)CCParticleBatchNode:粒子系统的批次结点,用于将使用相同纹理的粒子系统进行同批次渲染优化处理。
在学习CCParticleSystem时,我们留下了一些疑问,什么时候调用setBatchNode?以及做为基类,CCParticleSystem提供了两个供子类重载的纯虚函数postStep()和updateQuadWithParticle,它们的具体用法是什么?我们仍然有一些迷茫。
我们今天来了解一下CCParticleSystemQuad,这个类是CCParticleSystem的子类。它将解开我们的这些疑惑。
打开CCParticleSystemQuad.h:
- classCC_DLLCCParticleSystemQuad:publicCCParticleSystem
- {
- protected:
-
- ccV3F_C4B_T2F_Quad*m_pQuads;
- GLushort*m_pIndices;
-
- #ifCC_TEXTURE_ATLAS_USE_VAO
- GLuintm_uVAOname;
- #endif
- GLuintm_pBuffersVBO[2];
- public:
- //构造函数。
- CCParticleSystemQuad();
- //析构函数。
- virtual~CCParticleSystemQuad();
-
- //创建函数,参为为PLIST,内部调用create实现。
- CC_DEPRECATED_ATTRIBUTEstaticCCParticleSystemQuad*particleWithFile(constchar*plistFile);
-
- //上面函数的create实现。
- staticCCParticleSystemQuad*create(char*plistFile);
- //初始化索引缓冲。
- voidsetupIndices();
- //初始化方理坐标。
- voidinitTexCoordsWithRect(constCCRect&rect);
- //设置显示一个精灵帧。
- voidsetDisplayFrame(CCSpriteFrame*spriteFrame);
- //设置使用纹理对象上指定的矩形图像区域做为粒子系统的贴图。
- voidsetTextureWithRect(CCTexture2D*texture,//重载基类粒子系统的相应函数。
- //初始化粒子数量。
- virtualboolinitWithTotalParticles(unsignedintnumberOfParticles);
- //设置所用的纹理对象指针
- virtualvoidsetTexture(CCTexture2D*texture);
- //上一篇留下的疑问,虽然明显是更新粒子顶点缓冲中的位置数据。但上一篇为什么没有实现?
- voidupdateQuadWithParticle(tCCParticle*particle,153); font-weight:bold; background-color:inherit">constCCPoint&newPosition);
- //上一篇留下的疑问,不知道是做什么,咱们到CPP中看吧。
- voidpostStep();
- //渲染处理。
- voiddraw();
- //设置批次结点。
- voidsetBatchNode(CCParticleBatchNode*batchNode);
- //设置总的粒子数量。
- voidsetTotalParticles(unsignedinttp);
- //监听响应当前结点的EVNET_COME_TO_FOREGROUND事件的回调函数。
- voidlistenBackToForeground(CCObject*obj);
- //创建一个当前实例结点,内部调用create实现。
- CC_DEPRECATED_ATTRIBUTEstaticCCParticleSystemQuad*node();
- //上面的create实现。
- staticCCParticleSystemQuad*create();
- private:
- //如果使用VAO
- #ifCC_TEXTURE_ATLAS_USE_VAO
- //初始化VAO和VBO
- voidsetupVBOandVAO();
- #else
- //初始化VBO
- voidsetupVBO();
- #endif
- //申请内存。
- boolallocMemory();
- };
对应的实现:
@H_
404_580@//重载粒子系统基类的初始化
函数,创建相应
数量的粒子。
boolCCParticleSystemQuad::initWithTotalParticles(unsignedintnumberOfParticles)
{
//调用基类的相应函数。
if(CCParticleSystem::initWithTotalParticles(numberOfParticles))
//创建顶点和索引缓冲,如果失败释放并返回。
if(!this->allocMemory()){
this->release();
returnfalse;
}
//填充索引缓冲。
setupIndices();
//如果当前OPENGL版本支持VAO,就创建VAO,如果不支持,只创建VBO。
setupVBOandVAO();
#else
setupVBO();
//设置使用顶点格式为“位置+纹理+顶点色”的顶点格式组合。
setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));
//告诉通知中心,注册函数listenBackToForeground用来响应当前结点的EVNET_COME_TO_FOREGROUND事件。这个事件的意义是程序将由后面返回到前台。这个事件响应时可做资源的重新载入。
CCNotificationCenter::sharedNotificationCenter()->addObserver(this,
callfuncO_selector(CCParticleSystemQuad::listenBackToForeground),
EVNET_COME_TO_FOREGROUND,
NULL);
true;
//构造函数。
CCParticleSystemQuad::CCParticleSystemQuad()
:m_pQuads(NULL)
,m_pIndices(NULL)
memset(m_pBuffersVBO,sizeof(m_pBuffersVBO));
//析构函数。
CCParticleSystemQuad::~CCParticleSystemQuad()
//对所创建的顶点缓冲,索引缓冲,以及VBO,VA0进行释放。
if(NULL==m_pBatchNode)
CC_SAFE_FREE(m_pQuads);
CC_SAFE_FREE(m_pIndices);
glDeleteBuffers(2,&m_pBuffersVBO[0]);
glDeleteVertexArrays(1,&m_uVAOname);
}
//注销对通知管理器注册的相应事件的响应处理函数。
CCNotificationCenter::sharedNotificationCenter()->removeObserver(//静态创建函数。由PLIST文件创建相应的当前实例对象,内部调用create实现。
CCParticleSystemQuad*CCParticleSystemQuad::particleWithFile(char*plistFile)
returnCCParticleSystemQuad::create(plistFile);
CCParticleSystemQuad*CCParticleSystemQuad::create(char*plistFile)
//创建一个CCParticleSystemQuad实例对象,进行初始化后交由内存管理器进行引用计数器的管理。
CCParticleSystemQuad*pRet=newCCParticleSystemQuad();
if(pRet&&pRet->initWithFile(plistFile))
pRet->autorelease();
returnpRet;
//如果失败,删除并置空,返回NULL。
CC_SAFE_DELETE(pRet);
//初始化纹理坐标。
voidCCParticleSystemQuad::initTexCoordsWithRect(constCCRect&pointRect)
//创建出相应的矩形。
CCRectrect=CCRectMake(
pointRect.origin.x*CC_CONTENT_SCALE_FACTOR(),248)"> pointRect.origin.y*CC_CONTENT_SCALE_FACTOR(),108); list-style:decimal-leading-zero outside; color:inherit; line-height:18.9473686218262px; margin:0px!important; padding:0px 3px 0px 10px!important"> pointRect.size.width*CC_CONTENT_SCALE_FACTOR(),248)"> pointRect.size.height*CC_CONTENT_SCALE_FACTOR());
//默认使用的是批次结点,以批次结点的纹理对设置所用的图像区域矩形宽高。
GLfloatwide=(GLfloat)pointRect.size.width;
GLfloathigh=(GLfloat)pointRect.size.height;
//如果使用单纹理对象,取得纹理的宽高。
if(m_pTexture)
wide=(GLfloat)m_pTexture->getPixelsWide();
high=(GLfloat)m_pTexture->getPixelsHigh();
//此宏是为了解决精灵边缘黑线而做的纹理坐标的微调。
#ifCC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
GLfloatleft=(rect.origin.x*2+1)/(wide*2);
GLfloatbottom=(rect.origin.y*2+1)/(high*2);
GLfloatright=left+(rect.size.width*2-2)/(wide*2);
GLfloattop=bottom+(rect.size.height*2-2)/(high*2);
GLfloatleft=rect.origin.x/wide;
GLfloatbottom=rect.origin.y/high;
GLfloatright=left+rect.size.width/wide;
GLfloattop=bottom+rect.size.height/high;
//将top与bottom交换一下,因为在Cococs2d-x中坐标系Y轴是向上为正,这里处理一下后面可以做为顶点位置数据。
CC_SWAP(top,bottom,float);
//根据是否使用批次结点来取得相应的矩形顶点缓冲数组。
ccV3F_C4B_T2F_Quad*quads=NULL;
unsignedintstart=0,end=0;
if(m_pBatchNode)
{
quads=m_pBatchNode->getTextureAtlas()->getQuads();
//取得起始和结束的粒子所对应的矩形索引。
start=m_uAtlasIndex;
end=m_uAtlasIndex+m_uTotalParticles;
else
{
quads=m_pQuads;
start=0;
end=m_uTotalParticles;
//遍历所有的矩形顶点。
for(unsignedinti=start;i<end;i++)
//设置四个顶点的纹理坐标。
quads[i].bl.texCoords.u=left;
quads[i].bl.texCoords.v=bottom;
quads[i].br.texCoords.u=right;
quads[i].br.texCoords.v=bottom;
quads[i].tl.texCoords.u=left;
quads[i].tl.texCoords.v=top;
quads[i].tr.texCoords.u=right;
quads[i].tr.texCoords.v=top;
voidCCParticleSystemQuad::setTextureWithRect(CCTexture2D*texture,153); font-weight:bold; background-color:inherit">constCCRect&rect)
//如果当前尚无纹理对或者使用的纹理与参数指定的纹理不同。则设置使用参数指定的纹理。
if(!m_pTexture||texture->getName()!=m_pTexture->getName())
CCParticleSystem::setTexture(texture);
//设置指定的矩形图像区域做为贴图计算粒子系统的纹理坐标.
this->initTexCoordsWithRect(rect);
//设置使用的纹理对象。
voidCCParticleSystemQuad::setTexture(CCTexture2D*texture)
//取得纹理的大小。
constCCSize&s=texture->getContentSize();
this->setTextureWithRect(texture,CCRectMake(0,s.width,s.height));
//设置使用精灵帧中的纹理。
voidCCParticleSystemQuad::setDisplayFrame(CCSpriteFrame*spriteFrame)
//有效性判断。
CCAssert(spriteFrame->getOffsetInPixels().equals(CCPointZero),108); list-style:decimal-leading-zero outside; color:inherit; line-height:18.9473686218262px; margin:0px!important; padding:0px 3px 0px 10px!important"> "QuadParticleonlysupportsSpriteFrameswithnooffsets");
//如果当前尚无纹理对或者使用的纹理与参数指定的纹理不同。则设置使用参数指定的纹理。
if(!m_pTexture||spriteFrame->getTexture()->getName()!=m_pTexture->getName())
//设置使用精灵帧中的纹理.
this->setTexture(spriteFrame->getTexture());
voidCCParticleSystemQuad::setupIndices()
//遍历粒子数目计算索引缓冲值。
inti=0;i<m_uTotalParticles;++i)
constunsignedinti6=i*6;
inti4=i*4;
m_pIndices[i6+0]=(GLushort)i4+0;
m_pIndices[i6+1]=(GLushort)i4+1;
m_pIndices[i6+2]=(GLushort)i4+2;
m_pIndices[i6+5]=(GLushort)i4+1;
m_pIndices[i6+4]=(GLushort)i4+2;
m_pIndices[i6+3]=(GLushort)i4+3;
//更新指定粒子的顶点缓冲中的位置数据。
voidCCParticleSystemQuad::updateQuadWithParticle(tCCParticle*particle,153); font-weight:bold; background-color:inherit">constCCPoint&newPosition)
//定义临时指针变量用于取得相应的粒子所对应的矩形顶点缓冲。
ccV3F_C4B_T2F_Quad*quad;
//如果使用了批次结点。
if(m_pBatchNode)
//取得批次结点中对应的矩形顶点缓冲数组指针。
ccV3F_C4B_T2F_Quad*batchQuads=m_pBatchNode->getTextureAtlas()->getQuads();
//通过索引取得相应的矩形顶点缓冲。
quad=&(batchQuads[m_uAtlasIndex+particle->atlasIndex]);
else
//如果没有使用批次结点,直接取得相应的粒子的矩形顶点缓冲。
quad=&(m_pQuads[m_uParticleIdx]);
//根据是否由ALPHA值来设定RGB取得相应的颜色值。
ccColor4Bcolor=(m_bOpacityModifyRGB)
?ccc4(particle->color.r*particle->color.a*255,particle->color.g*particle->color.a*255,particle->color.b*particle->color.a*255,particle->color.a*255)
:ccc4(particle->color.r*255,particle->color.g*255,particle->color.b*255,particle->color.a*255);
//填真顶点缓冲中的颜色信息。
quad->bl.colors=color;
quad->br.colors=color;
quad->tl.colors=color;
quad->tr.colors=color;
//设置顶点的位置信息
GLfloatsize_2=particle->size/2;
//判断是否进行旋转。
if(particle->rotation)
//定义临时变量来存放以size_2为半径的矩形外圆上的四个顶点。
GLfloatx1=-size_2;
GLfloaty1=-size_2;
GLfloatx2=size_2;
GLfloaty2=size_2;
//定义临时变量来存放圆心。
GLfloatx=newPosition.x;
GLfloaty=newPosition.y;
//求得旋转角度。
GLfloatr=(GLfloat)-CC_DEGREES_TO_RADIANS(particle->rotation);
//通过sin,cos来计算旋转后的矩形外圆上的四个角的顶点位置。
GLfloatcr=cosf(r);
GLfloatsr=sinf(r);
GLfloatax=x1*cr-y1*sr+x;
GLfloatay=x1*sr+y1*cr+y;
GLfloatbx=x2*cr-y1*sr+x;
GLfloatby=x2*sr+y1*cr+y;
GLfloatcx=x2*cr-y2*sr+x;
GLfloatcy=x2*sr+y2*cr+y;
GLfloatdx=x1*cr-y2*sr+x;
GLfloatdy=x1*sr+y2*cr+y;
//填充计算旋转后的顶点位置信息。
quad->bl.vertices.x=ax;
quad->bl.vertices.y=ay;
quad->br.vertices.x=bx;
quad->br.vertices.y=by;
quad->tl.vertices.x=dx;
quad->tl.vertices.y=dy;
quad->tr.vertices.x=cx;
quad->tr.vertices.y=cy;
//如果不旋转,直接填充位置信息。
quad->bl.vertices.x=newPosition.x-size_2;
quad->bl.vertices.y=newPosition.y-size_2;
quad->br.vertices.x=newPosition.x+size_2;
quad->br.vertices.y=newPosition.y-size_2;
quad->tl.vertices.x=newPosition.x-size_2;
quad->tl.vertices.y=newPosition.y+size_2;
quad->tr.vertices.x=newPosition.x+size_2;
quad->tr.vertices.y=newPosition.y+size_2;
//我们一直想知道在CCParticleSystem中每次update时,如果粒子批次结点为空时为什么要调用postStep?它倒底是干什么的,看完下面的代码,就很清楚了。
voidCCParticleSystemQuad::postStep()
//绑定顶点缓冲区对象。
glBindBuffer(GL_ARRAY_BUFFER,m_pBuffersVBO[0]);
//用m_pQuads中数据更新绑定的缓冲区数据。
glBufferSubData(GL_ARRAY_BUFFER,153); font-weight:bold; background-color:inherit">sizeof(m_pQuads[0])*m_uParticleCount,m_pQuads);
//取消绑定缓冲区对象。
CHECK_GL_ERROR_DEBUG();
//清楚了,原来这个函数是针对不使用批次结点时的VBO顶点缓冲的更新。
//绘制粒子系统。
voidCCParticleSystemQuad::draw()
//如果当前在粒子的批次结点有值,则draw()不应该被调用!为什么呢?因为有批次结点的话,渲染交给批次结点的draw()函数而不是当前粒子系统的draw()函数来处理。
CCAssert(!m_pBatchNode,"drawshouldnotbecalledwhenaddedtoaparticleBatchNode");
//使用相应的Shader
CC_NODE_DRAW_SETUP();
//绑定所用的纹理对象。
ccGLBindTexture2D(m_pTexture->getName());
//设定所用的ALPHA混合方案。
ccGLBlendFunc(m_tBlendFunc.src,m_tBlendFunc.dst);
//判断当前粒子索引是否为粒子总数,也就是判断是否已经update完成未出错。
CCAssert(m_uParticleIdx==m_uParticleCount,"Abnormalerrorinparticlequad");
//如果使用VAO。
//使用VAO绑定的顶点数组
glBindVertexArray(m_uVAOname);
//绑定索引数组
#ifCC_REBIND_INDICES_BUFFER
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_pBuffersVBO[1]);
//渲染调用
glDrawElements(GL_TRIANGLES,(GLsizei)m_uParticleIdx*6,GL_UNSIGNED_SHORT,0);
//渲染完取消绑定索引数组
//取消绑定顶点数组
glBindVertexArray(0);
//
//UsingVBOwithoutVAO
//
#definekQuadSizesizeof(m_pQuads[0].bl)
//设置使用相应的顶点格式为:位置+颜色+纹理坐标
ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex);
//绑定顶点缓冲
//设置顶点缓冲中位置数据的描述
glVertexAttribPointer(kCCVertexAttrib_Position,3,GL_FLOAT,GL_FALSE,kQuadSize,(GLvoid*)offsetof(ccV3F_C4B_T2F,vertices));
//设置顶点缓冲中颜色数据的描述
glVertexAttribPointer(kCCVertexAttrib_Color,4,GL_UNSIGNED_BYTE,GL_TRUE,colors));
//设置顶点缓冲中纹理坐标数据的描述
glVertexAttribPointer(kCCVertexAttrib_TexCoords,2,texCoords));
//绑定索引缓冲
//渲染调用
glDrawElements(GL_TRIANGLES,0); background-color:inherit">//取消绑定
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); background-color:inherit">//渲染调用计数器加一
CC_INCREMENT_GL_DRAWS(1);
CHECK_GL_ERROR_DEBUG();
//设置粒子数量
voidCCParticleSystemQuad::setTotalParticles(unsignedinttp)
//如果要申请内存的粒子数量大于之前已经申请内存的粒子数量。
if(tp>m_uAllocatedParticles)
//计算要申请的内存大小。
//粒子信息结构数组大小。
size_tparticlesSize=tp*sizeof(tCCParticle);
//顶点缓冲的大小
size_tquadsSize=sizeof(m_pQuads[0])*tp*1;
//索引缓冲的大小
size_tindicesSize=sizeof(m_pIndices[0])*tp*6*1;
//在m_pParticles指定的内存位置申请相应大小的内存用于存储粒子信息结构数组。
tCCParticle*particlesNew=(tCCParticle*)realloc(m_pParticles,particlesSize);
//在m_pQuads指定的内存位置申请相应大小的内存用于填充顶点缓冲。
ccV3F_C4B_T2F_Quad*quadsNew=(ccV3F_C4B_T2F_Quad*)realloc(m_pQuads,quadsSize);
//在m_pIndices指定的内存位置申请相应大小的内存用于填充索引缓冲。
GLushort*indicesNew=(GLushort*)realloc(m_pIndices,indicesSize);
//如果申请都成功。
if(particlesNew&&quadsNew&&indicesNew)
//将内存地址传值给成员指针。
m_pParticles=particlesNew;
m_pQuads=quadsNew;
m_pIndices=indicesNew;
//内存清零
memset(m_pParticles,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18.9473686218262px; margin:0px!important; padding:0px 3px 0px 10px!important"> memset(m_pQuads,quadsSize);
memset(m_pIndices,0); background-color:inherit">//记录申请内存的粒子数量。
m_uAllocatedParticles=tp;
//如果失败,记录成功申请的内存地址打印出错LOG。
if(particlesNew)m_pParticles=particlesNew;
if(quadsNew)m_pQuads=quadsNew;
if(indicesNew)m_pIndices=indicesNew;
CCLOG("Particlesystem:outofmemory");
return;
//更新粒子数量。
m_uTotalParticles=tp;
//根据是否使用批次结点来设定每个粒子对应的矩形顶点块的索引。
inti=0;i<m_uTotalParticles;i++)
m_pParticles[i].atlasIndex=i;
//填充索引缓冲。
setupIndices();
//初始化VAO
setupVBOandVAO();
//如果要申请内存的粒子数量小于原来申请的粒子数量,直接修改一下最大粒子数量就OK。
m_uTotalParticles=tp;
//如果当前OPENGL版本支持VAO。
//初始化VBO与VAO
voidCCParticleSystemQuad::setupVBOandVAO()
//初始化1个顶点数组对象,产生VAO对象的句柄
glGenVertexArrays(1,0); background-color:inherit">//绑定VAO。
glBindVertexArray(m_uVAOname);
//创建2个VBO缓冲区对象,产生两个句柄填充到句柄数组中。
glGenBuffers(2,0); background-color:inherit">//绑定第一个VBO缓冲区对象。
//将顶点数据拷贝到绑定的缓冲区。
glBufferData(GL_ARRAY_BUFFER,153); font-weight:bold; background-color:inherit">sizeof(m_pQuads[0])*m_uTotalParticles,m_pQuads,GL_DYNAMIC_DRAW);
//设置使用位置数据
glEnableVertexAttribArray(kCCVertexAttrib_Position);
//设置位置数据在顶点缓冲中的描述
glVertexAttribPointer(kCCVertexAttrib_Position,vertices));
//设置使用颜色数据
glEnableVertexAttribArray(kCCVertexAttrib_Color);
//设置颜色数据在顶点缓冲中的描述
//设置使用纹理坐标数据
glEnableVertexAttribArray(kCCVertexAttrib_TexCoords);
//设置纹理坐标数据在顶点缓冲中的描述
glVertexAttribPointer(kCCVertexAttrib_TexCoords,texCoords));
//绑定VBO的第二个缓冲区
//将索引缓冲区数据拷贝到绑定的缓冲区
glBufferData(GL_ELEMENT_ARRAY_BUFFER,153); font-weight:bold; background-color:inherit">sizeof(m_pIndices[0])*m_uTotalParticles*6,m_pIndices,GL_STATIC_DRAW);
glBindVertexArray(0);
//否则只使用VBO
voidCCParticleSystemQuad::setupVBO()
//创建2个VBO缓冲区对象,产生两个句柄填充到句柄数组中。
glGenBuffers(2,&m_pBuffersVBO[0]);
//绑定第一个VBO缓冲区对象并填充数据。
glBindBuffer(GL_ARRAY_BUFFER,m_pBuffersVBO[0]);
//绑定第二个VBO缓冲区对象并填充数据。
//响应当前结点的EVNET_COME_TO_FOREGROUND事件。这个事件的意义是程序将由后面返回到前台。这个事件响应时可做资源的重新载入。
voidCCParticleSystemQuad::listenBackToForeground(CCObject*obj)
//重新初始化VBO和VAO。
//创建顶点缓冲和索引缓冲区。
boolCCParticleSystemQuad::allocMemory()
//如果已经申请则中断。
CCAssert((!m_pQuads&&!m_pIndices),"Memoryalreadyalloced");
CCAssert(!m_pBatchNode,"MemoryshouldnotbeallocedwhennotusingbatchNode");
//释放顶点与索引缓冲
//为顶点与索引缓冲申请内存。
m_pQuads=(ccV3F_C4B_T2F_Quad*)malloc(m_uTotalParticles*sizeof(ccV3F_C4B_T2F_Quad));
m_pIndices=(GLushort*)malloc(m_uTotalParticles*6*sizeof(GLushort));
//如果出现失败,则提示LOG并释放置空返回。
if(!m_pQuads||!m_pIndices)
CCLOG("cocos2d:Particlesystem:notenoughmemory");
CC_SAFE_FREE(m_pQuads);
CC_SAFE_FREE(m_pIndices);
//如果成功,置零操作返回true.
//设置CCParticleSystemQuad使用的粒子批次结点。
voidCCParticleSystemQuad::setBatchNode(CCParticleBatchNode*batchNode)
//如果当前使用的粒子批次结点与参数不同,则进行更换处理。
if(m_pBatchNode!=batchNode)
//先记录一下当前使用的。
CCParticleBatchNode*oldBatch=m_pBatchNode;
//将后调用基类相应函数,设置当前使用的粒子批次结点。
CCParticleSystem::setBatchNode(batchNode);
//如果参数值为空,代表不使用批次结点。则进行顶点缓冲的相关初始化。
if(!batchNode)
//创建顶点缓冲,填充索引,并根据是否可用VAO设置顶点缓冲,设置纹理。
allocMemory();
setTexture(oldBatch->getTexture());
setupVBO();
//如果批次结点有效,且更换前没有使用粒子批次结点。
elseif(!oldBatch)
//取得相应粒子批次结点的矩形数组,取出相应索引位置的矩形数据,将相应的顶点缓冲数据拷到矩形数组中。
ccV3F_C4B_T2F_Quad*quad=&(batchQuads[m_uAtlasIndex]);
memcpy(quad,153); font-weight:bold; background-color:inherit">sizeof(m_pQuads[0]));
//释放当前用的顶点缓冲
//释放所用的VBO顶点对象与AVO名称
glDeleteBuffers(2,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18.9473686218262px; margin:0px!important; padding:0px 3px 0px 10px!important"> glDeleteVertexArrays(1,&m_uVAOname);
//创建一个CCParticleSystemQuad,内部调用create实现。
CCParticleSystemQuad*CCParticleSystemQuad::node()
returnCCParticleSystemQuad::create();
CCParticleSystemQuad*CCParticleSystemQuad::create(){
//创建一个CCParticleSystemQuad的实例对象。
CCParticleSystemQuad*pParticleSystemQuad=newCCParticleSystemQuad();
//如果创建成功,进行初始化。成功后交由内存管理器进行引用计数器的管理。
if(pParticleSystemQuad&&pParticleSystemQuad->init())
pParticleSystemQuad->autorelease();
returnpParticleSystemQuad;
//如果失败,释放置空并返回NULL。
CC_SAFE_DELETE(pParticleSystemQuad);
returnNULL;
}