2010-12-28 11:09:40 +08:00
|
|
|
/****************************************************************************
|
2011-03-19 14:45:51 +08:00
|
|
|
Copyright (c) 2010-2011 cocos2d-x.org
|
|
|
|
Copyright (c) 2008-2010 Ricardo Quesada
|
2011-07-04 19:20:16 +08:00
|
|
|
Copyright (c) 2011 Zynga Inc.
|
2010-12-28 11:09:40 +08:00
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
#include "CCParticleSystemPoint.h"
|
|
|
|
#include "platform/CCGL.h"
|
|
|
|
|
|
|
|
namespace cocos2d {
|
|
|
|
|
|
|
|
//implementation CCParticleSystemPoint
|
2011-07-04 19:20:16 +08:00
|
|
|
bool CCParticleSystemPoint::initWithTotalParticles(unsigned int numberOfParticles)
|
2010-12-28 11:09:40 +08:00
|
|
|
{
|
|
|
|
if( CCParticleSystem::initWithTotalParticles(numberOfParticles) )
|
|
|
|
{
|
2011-07-06 18:16:19 +08:00
|
|
|
m_pVertices = new ccPointSprite[m_uTotalParticles];
|
2010-12-28 11:09:40 +08:00
|
|
|
|
|
|
|
if( ! m_pVertices )
|
|
|
|
{
|
|
|
|
CCLOG("cocos2d: Particle system: not enough memory");
|
|
|
|
this->release();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if CC_USES_VBO
|
|
|
|
glGenBuffers(1, &m_uVerticesID);
|
|
|
|
|
|
|
|
// initial binding
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_uVerticesID);
|
2011-07-06 18:16:19 +08:00
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(ccPointSprite)*m_uTotalParticles, m_pVertices, GL_DYNAMIC_DRAW);
|
2010-12-28 11:09:40 +08:00
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
#endif
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
CCParticleSystemPoint::~CCParticleSystemPoint()
|
|
|
|
{
|
2011-03-07 17:11:57 +08:00
|
|
|
CC_SAFE_DELETE(m_pVertices);
|
2010-12-28 11:09:40 +08:00
|
|
|
#if CC_USES_VBO
|
|
|
|
glDeleteBuffers(1, &m_uVerticesID);
|
|
|
|
#endif
|
|
|
|
}
|
2011-06-14 16:27:47 +08:00
|
|
|
|
|
|
|
// implementation CCParticleSystemPoint
|
|
|
|
CCParticleSystemPoint * CCParticleSystemPoint::particleWithFile(const char *plistFile)
|
|
|
|
{
|
|
|
|
CCParticleSystemPoint *pRet = new CCParticleSystemPoint();
|
|
|
|
if (pRet && pRet->initWithFile(plistFile))
|
|
|
|
{
|
|
|
|
pRet->autorelease();
|
|
|
|
return pRet;
|
|
|
|
}
|
|
|
|
CC_SAFE_DELETE(pRet)
|
|
|
|
return pRet;
|
|
|
|
}
|
|
|
|
|
2011-08-17 21:19:57 +08:00
|
|
|
void CCParticleSystemPoint::updateQuadWithParticle(tCCParticle* particle, const CCPoint& newPosition)
|
2010-12-28 11:09:40 +08:00
|
|
|
{
|
|
|
|
// place vertices and colos in array
|
2011-07-07 11:27:45 +08:00
|
|
|
m_pVertices[m_uParticleIdx].pos = vertex2(newPosition.x, newPosition.y);
|
|
|
|
m_pVertices[m_uParticleIdx].size = particle->size;
|
|
|
|
ccColor4B color = {(GLubyte)(particle->color.r * 255), (GLubyte)(particle->color.g * 255), (GLubyte)(particle->color.b * 255),
|
|
|
|
(GLubyte)(particle->color.a * 255)};
|
|
|
|
m_pVertices[m_uParticleIdx].color = color;
|
2010-12-28 11:09:40 +08:00
|
|
|
}
|
|
|
|
void CCParticleSystemPoint::postStep()
|
|
|
|
{
|
|
|
|
#if CC_USES_VBO
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_uVerticesID);
|
2011-07-06 18:16:19 +08:00
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(ccPointSprite)*m_uParticleCount, m_pVertices);
|
2010-12-28 11:09:40 +08:00
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
void CCParticleSystemPoint::draw()
|
|
|
|
{
|
2011-07-12 11:20:41 +08:00
|
|
|
CCParticleSystem::draw();
|
|
|
|
|
2011-07-07 11:27:45 +08:00
|
|
|
if (m_uParticleIdx==0)
|
2010-12-28 11:09:40 +08:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
|
|
|
|
// Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY
|
|
|
|
// Unneeded states: GL_TEXTURE_COORD_ARRAY
|
|
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, m_pTexture->getName());
|
|
|
|
|
|
|
|
glEnable(GL_POINT_SPRITE_OES);
|
|
|
|
glTexEnvi( GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE );
|
|
|
|
|
|
|
|
#define kPointSize sizeof(m_pVertices[0])
|
|
|
|
|
|
|
|
#if CC_USES_VBO
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_uVerticesID);
|
|
|
|
|
2011-01-10 17:54:44 +08:00
|
|
|
#if CC_ENABLE_CACHE_TEXTTURE_DATA
|
2011-07-06 18:16:19 +08:00
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(ccPointSprite)*m_uTotalParticles, m_pVertices, GL_DYNAMIC_DRAW);
|
2011-01-10 17:54:44 +08:00
|
|
|
#endif
|
|
|
|
|
2010-12-28 11:09:40 +08:00
|
|
|
glVertexPointer(2,GL_FLOAT,kPointSize,0);
|
|
|
|
|
2011-07-04 19:20:16 +08:00
|
|
|
glColorPointer(4, GL_UNSIGNED_BYTE, kPointSize,(GLvoid*)offsetof(ccPointSprite,color) );
|
2010-12-28 11:09:40 +08:00
|
|
|
|
|
|
|
glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
|
|
|
|
glPointSizePointerOES(GL_FLOAT,kPointSize,(GLvoid*) offsetof(ccPointSprite,size) );
|
|
|
|
#else // Uses Vertex Array List
|
|
|
|
int offset = (int)m_pVertices;
|
|
|
|
glVertexPointer(2,GL_FLOAT, kPointSize, (GLvoid*) offset);
|
|
|
|
|
2011-07-04 19:20:16 +08:00
|
|
|
int diff = offsetof(ccPointSprite, color);
|
|
|
|
glColorPointer(4, GL_UNSIGNED_BYTE, kPointSize, (GLvoid*) (offset+diff));
|
2010-12-28 11:09:40 +08:00
|
|
|
|
|
|
|
glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
|
|
|
|
diff = offsetof(ccPointSprite, size);
|
|
|
|
glPointSizePointerOES(GL_FLOAT, kPointSize, (GLvoid*) (offset+diff));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bool newBlend = (m_tBlendFunc.src != CC_BLEND_SRC || m_tBlendFunc.dst != CC_BLEND_DST) ? true : false;
|
|
|
|
if( newBlend )
|
|
|
|
{
|
|
|
|
glBlendFunc( m_tBlendFunc.src, m_tBlendFunc.dst );
|
|
|
|
}
|
|
|
|
|
2011-07-07 11:27:45 +08:00
|
|
|
glDrawArrays(GL_POINTS, 0, m_uParticleIdx);
|
2010-12-28 11:09:40 +08:00
|
|
|
|
|
|
|
// restore blend state
|
|
|
|
if( newBlend )
|
|
|
|
glBlendFunc( CC_BLEND_SRC, CC_BLEND_DST);
|
|
|
|
|
|
|
|
#if CC_USES_VBO
|
|
|
|
// unbind VBO buffer
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
glDisableClientState(GL_POINT_SIZE_ARRAY_OES);
|
|
|
|
glDisable(GL_POINT_SPRITE_OES);
|
|
|
|
|
|
|
|
// restore GL default state
|
|
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Non supported properties
|
|
|
|
|
|
|
|
//
|
|
|
|
// SPIN IS NOT SUPPORTED
|
|
|
|
//
|
|
|
|
void CCParticleSystemPoint::setStartSpin(float var)
|
|
|
|
{
|
2011-03-07 17:11:57 +08:00
|
|
|
CCAssert(var == 0, "PointParticleSystem doesn't support spinning");
|
2010-12-28 11:09:40 +08:00
|
|
|
CCParticleSystem::setStartSpin(var);
|
|
|
|
}
|
|
|
|
void CCParticleSystemPoint::setStartSpinVar(float var)
|
|
|
|
{
|
2011-03-07 17:11:57 +08:00
|
|
|
CCAssert(var == 0, "PointParticleSystem doesn't support spinning");
|
2010-12-28 11:09:40 +08:00
|
|
|
CCParticleSystem::setStartSpinVar(var);
|
|
|
|
}
|
|
|
|
void CCParticleSystemPoint::setEndSpin(float var)
|
|
|
|
{
|
2011-03-07 17:11:57 +08:00
|
|
|
CCAssert(var == 0, "PointParticleSystem doesn't support spinning");
|
2010-12-28 11:09:40 +08:00
|
|
|
CCParticleSystem::setEndSpin(var);
|
|
|
|
}
|
|
|
|
void CCParticleSystemPoint::setEndSpinVar(float var)
|
|
|
|
{
|
2011-03-07 17:11:57 +08:00
|
|
|
CCAssert(var == 0, "PointParticleSystem doesn't support spinning");
|
2010-12-28 11:09:40 +08:00
|
|
|
CCParticleSystem::setEndSpinVar(var);
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// SIZE > 64 IS NOT SUPPORTED
|
|
|
|
//
|
|
|
|
void CCParticleSystemPoint::setStartSize(float size)
|
|
|
|
{
|
2011-03-07 17:11:57 +08:00
|
|
|
CCAssert(size >= 0 && size <= CC_MAX_PARTICLE_SIZE, "PointParticleSystem only supports 0 <= size <= 64");
|
2010-12-28 11:09:40 +08:00
|
|
|
CCParticleSystem::setStartSize(size);
|
|
|
|
}
|
|
|
|
void CCParticleSystemPoint::setEndSize(float size)
|
|
|
|
{
|
2011-03-07 17:11:57 +08:00
|
|
|
CCAssert( (size == kCCParticleStartSizeEqualToEndSize) ||
|
2010-12-28 11:09:40 +08:00
|
|
|
( size >= 0 && size <= CC_MAX_PARTICLE_SIZE), "PointParticleSystem only supports 0 <= size <= 64");
|
|
|
|
CCParticleSystem::setEndSize(size);
|
|
|
|
}
|
|
|
|
|
|
|
|
}// namespace cocos2d
|