<pre name="code" class="cpp">class ShaderNode : public Node
{
public:
static ShaderNode* shaderNodeWithVertex(const std::string &vert, const std::string &frag);
virtual void update(float dt);
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
protected:
ShaderNode();
~ShaderNode();
bool initWithVertex(const std::string &vert, const std::string &frag);
void loadShaderVertex(const std::string &vert, const std::string &frag);
void onDraw(const Mat4 &transform, uint32_t flags);
Vec2 _center;
Vec2 _resolution;
float _time;
std::string _vertFileName;
std::string _fragFileName;
CustomCommand _customCommand;
};
<pre name="code" class="cpp">enum
{
SIZE_X = 256,
SIZE_Y = 256,
};
ShaderNode::ShaderNode()
:_center(Vec2(0.0f, 0.0f))
,_resolution(Vec2(0.0f, 0.0f))
,_time(0.0f)
{
}
ShaderNode::~ShaderNode()
{
}
ShaderNode* ShaderNode::shaderNodeWithVertex(const std::string &vert, const std::string& frag)
{
auto node = new (std::nothrow) ShaderNode();
node->initWithVertex(vert, frag);
node->autorelease();
return node;
}
bool ShaderNode::initWithVertex(const std::string &vert, const std::string &frag)
{
#if CC_ENABLE_CACHE_TEXTURE_DATA
auto listener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom* event){
this->setGLProgramState(nullptr);
loadShaderVertex(_vertFileName, _fragFileName);
});
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
#endif
_vertFileName = vert;
_fragFileName = frag;
loadShaderVertex(vert, frag);
_time = 0;
_resolution = Vec2(SIZE_X, SIZE_Y)*2.5 ;
getGLProgramState()->setUniformVec2("resolution", _resolution);
scheduleUpdate();
setContentSize(Size(SIZE_X, SIZE_Y)*5 );
setAnchorPoint(Vec2(0.5f, 0.5f));
return true;
}
void ShaderNode::loadShaderVertex(const std::string &vert, const std::string &frag)
{
auto fileUtiles = FileUtils::getInstance();
// frag
auto fragmentFilePath = fileUtiles->fullPathForFilename(frag);
auto fragSource = fileUtiles->getStringFromFile(fragmentFilePath);
// vert
std::string vertSource;
if (vert.empty()) {
vertSource = ccPositionTextureColor_vert;
} else {
std::string vertexFilePath = fileUtiles->fullPathForFilename(vert);
vertSource = fileUtiles->getStringFromFile(vertexFilePath);
}
auto glprogram = GLProgram::createWithByteArrays(vertSource.c_str(), fragSource.c_str());
auto glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram);
setGLProgramState(glprogramstate);
}
void ShaderNode::update(float dt)
{
_time += dt;
}
void ShaderNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(ShaderNode::onDraw, this, transform, flags);
renderer->addCommand(&_customCommand);
}
void ShaderNode::onDraw(const Mat4 &transform, uint32_t flags)
{
float w = SIZE_X*5 , h = SIZE_Y*5;
GLfloat vertices[12] = {0,0, w,0, w,h, 0,0, 0,h, w,h};
auto glProgramState = getGLProgramState();
glProgramState->setVertexAttribPointer("a_position", 2, GL_FLOAT, GL_FALSE, 0, vertices);
glProgramState->apply(transform);
glDrawArrays(GL_TRIANGLES, 0, 6);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,6);
}
<pre name="code" class="cpp">auto s = Director::getInstance()->getWinSize()/2;
s.height = Director::getInstance()->getWinSize().height * 0.62;
sn->setPosition(Vec2(0, 0));
sn->getGLProgramState()->setUniformVec2("center", s);//设置的是世界坐标
m_effctNode->addChild(sn);