着色器片段
RedTwinkle.fsh
#ifdef GL_ES
precision lowp float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform int addRed;
void main()
{
vec4 texColor = texture2D(CC_Texture0, v_texCoord);
if(texColor.a>0.5)
{
if(addRed==1)
{
texColor.r+=0.3;
}
gl_FragColor =texColor;
}
else
{
gl_FragColor=texColor;
}
}
封装的接口:
TKRedTwinkleNode.h文件
#include "cocos2d.h"
#ifndef __TKRedTwinkleNode__
#define __TKRedTwinkleNode__
class TKRedTwinkleNode:public cocos2d::Node
{
public:
TKRedTwinkleNode();
~TKRedTwinkleNode();
static TKRedTwinkleNode* create(cocos2d::Node* ownNode);
void start();
protected:
bool init(cocos2d::Node* ownNode);
void findSprites(cocos2d::Node* node);
void redTwink(bool v);
void twinkUpdate(float dt);
private:
float m_dt;
std::vector<Node*> m_spVec;
public:
static void loadRedTwinkleNode(cocos2d::Node* ownNode,bool v);
};
#endif// !__TKRedTwinkleNode__
TKRedTwinkleNode.cpp
#include "TKRedTwinkleNode.h"
USING_NS_CC;
const std::string redTwinkleShaderKey = "RedTwinkle";
TKRedTwinkleNode::TKRedTwinkleNode()
:m_dt(0)
{
}
TKRedTwinkleNode::~TKRedTwinkleNode()
{
}
TKRedTwinkleNode* TKRedTwinkleNode::create(cocos2d::Node* ownNode)
{
auto pRet = new TKRedTwinkleNode;
if (pRet&& pRet->init(ownNode))
{
pRet->autorelease();
return pRet;
}
delete pRet;
return nullptr;
}
bool TKRedTwinkleNode::init(cocos2d::Node* ownNode)
{
if (!Node::init()){
return false;
}
auto cache = GLProgramCache::getInstance()->getGLProgram(redTwinkleShaderKey);
if (!cache)
{
auto loadFx = [=](const char* vArr, const char* fArr, const char* key) {
GLProgram* program = GLProgramCache::getInstance()->getGLProgram(key);
if (!program)
{
program = GLProgram::createWithByteArrays(vArr, fArr);
if (program != nullptr)
program->link();
GLProgramCache::getInstance()->addGLProgram(program, key);
}
else
{
program->reset();
program->initWithByteArrays(vArr, fArr);
program->link();
}
};
auto str = FileUtils::getInstance()->getStringFromFile("RedTwinkle.fsh");
loadFx(ccPositionTextureColor_noMVP_vert, str.c_str(), redTwinkleShaderKey.c_str());
}
this->findSprites(ownNode);
return true;
}
void TKRedTwinkleNode::findSprites(cocos2d::Node* node)
{
if (node)
{
auto sp = dynamic_cast<Sprite*>(node);
if (sp)
{
m_spVec.push_back(sp);
}
auto childs = node->getChildren();
for (auto aa : childs)
{
findSprites(aa);
}
}
}
void TKRedTwinkleNode::start()
{
this->redTwink(true);
m_dt = 0;
unschedule(CC_SCHEDULE_SELECTOR(TKRedTwinkleNode::twinkUpdate));
this->schedule(CC_SCHEDULE_SELECTOR(TKRedTwinkleNode::twinkUpdate), 1.0 / 60);
}
void TKRedTwinkleNode::redTwink(bool v)
{
for (auto sp : m_spVec)
{
if (sp)
{
if (v)
{
sp->setGLProgram(GLProgramCache::getInstance()->getGLProgram(redTwinkleShaderKey));
}
else
{
sp->setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP));
}
}
}
}
void TKRedTwinkleNode::twinkUpdate(float dt)
{
m_dt += dt;
int add = 0;
if ((m_dt > 0.1&& m_dt<0.2)
|| (m_dt > 0.3 && m_dt < 0.4)
|| (m_dt > 0.5 && m_dt < 0.6))
{
add = 1;
}
for (auto node : m_spVec)
{
if (node)
{
node->getGLProgramState()->setUniformInt("addRed", add);
}
}
if (m_dt>0.6)
{
this->redTwink(false);
unschedule(CC_SCHEDULE_SELECTOR(TKRedTwinkleNode::twinkUpdate));
}
}
void TKRedTwinkleNode::loadRedTwinkleNode(cocos2d::Node* ownNode, bool v)
{
if (ownNode)
{
auto node =static_cast<TKRedTwinkleNode *>(ownNode->getChildByName("TKRedTwinkleNode"));
if (!node)
{
node = TKRedTwinkleNode::create(ownNode);
node->setName("TKRedTwinkleNode");
ownNode->addChild(node);
}
if (v&&node)
{
node->start();
}
}
}
调用接口:
TKRedTwinkleNode::loadRedTwinkleNode(m_sp,true);
效果图: