Adds effectNode in ShaderTest2

This commit is contained in:
Ricardo Quesada 2014-05-13 18:12:58 -07:00
parent 0171e27747
commit 723938e292
10 changed files with 253 additions and 59 deletions

View File

@ -647,7 +647,7 @@ void Node::setGLProgram(GLProgram *glProgram)
if (_glProgramState == nullptr || (_glProgramState && _glProgramState->getGLProgram() != glProgram))
{
CC_SAFE_RELEASE(_glProgramState);
_glProgramState = GLProgramState::getOrCreate(glProgram);
_glProgramState = GLProgramState::getOrCreateWithGLProgram(glProgram);
_glProgramState->retain();
}
}

View File

@ -72,7 +72,7 @@ const char* kCCUniformTime_s = GLProgram::UNIFORM_NAME_TIME;
const char* kCCUniformSinTime_s = GLProgram::UNIFORM_NAME_SIN_TIME;
const char* kCCUniformCosTime_s = GLProgram::UNIFORM_NAME_COS_TIME;
const char* kCCUniformRandom01_s = GLProgram::UNIFORM_NAME_RANDOM01;
const char* kCCUniformSampler_s = GLProgram::UNIFORM_NAME_SAMPLER;
const char* kCCUniformSampler_s = GLProgram::UNIFORM_NAME_SAMPLER0;
const char* kCCUniformAlphaTestValue = GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE;
// Attribute names

View File

@ -817,7 +817,7 @@ CC_DEPRECATED_ATTRIBUTE const int kCCUniformTime = GLProgram::UNIFORM_TIME;
CC_DEPRECATED_ATTRIBUTE const int kCCUniformSinTime = GLProgram::UNIFORM_SIN_TIME;
CC_DEPRECATED_ATTRIBUTE const int kCCUniformCosTime = GLProgram::UNIFORM_COS_TIME;
CC_DEPRECATED_ATTRIBUTE const int kCCUniformRandom01 = GLProgram::UNIFORM_RANDOM01;
CC_DEPRECATED_ATTRIBUTE const int kCCUniformSampler = GLProgram::UNIFORM_SAMPLER;
CC_DEPRECATED_ATTRIBUTE const int kCCUniformSampler = GLProgram::UNIFORM_SAMPLER0;
CC_DEPRECATED_ATTRIBUTE const int kCCUniform_MAX = GLProgram::UNIFORM_MAX;
CC_DEPRECATED_ATTRIBUTE extern const char* kCCShader_PositionTextureColor;

View File

@ -78,7 +78,10 @@ const char* GLProgram::UNIFORM_NAME_TIME = "CC_Time";
const char* GLProgram::UNIFORM_NAME_SIN_TIME = "CC_SinTime";
const char* GLProgram::UNIFORM_NAME_COS_TIME = "CC_CosTime";
const char* GLProgram::UNIFORM_NAME_RANDOM01 = "CC_Random01";
const char* GLProgram::UNIFORM_NAME_SAMPLER = "CC_Texture0";
const char* GLProgram::UNIFORM_NAME_SAMPLER0 = "CC_Texture0";
const char* GLProgram::UNIFORM_NAME_SAMPLER1 = "CC_Texture1";
const char* GLProgram::UNIFORM_NAME_SAMPLER2 = "CC_Texture2";
const char* GLProgram::UNIFORM_NAME_SAMPLER3 = "CC_Texture3";
const char* GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE = "CC_alpha_value";
// Attribute names
@ -123,7 +126,7 @@ GLProgram::GLProgram()
, _hashForUniforms(nullptr)
, _flags()
{
memset(_uniforms, 0, sizeof(_uniforms));
memset(_builtInUniforms, 0, sizeof(_builtInUniforms));
}
GLProgram::~GLProgram()
@ -275,7 +278,7 @@ void GLProgram::bindPredefinedVertexAttribs()
void GLProgram::parseVertexAttribs()
{
_attributesDictionary.clear();
_vertexAttribs.clear();
// Query and store vertex attribute meta-data from the program.
GLint activeAttributes;
@ -299,7 +302,7 @@ void GLProgram::parseVertexAttribs()
// Query the pre-assigned attribute location
attribute.index = glGetAttribLocation(_program, attribName);
_attributesDictionary[attribute.name] = attribute;
_vertexAttribs[attribute.name] = attribute;
}
}
}
@ -307,7 +310,7 @@ void GLProgram::parseVertexAttribs()
void GLProgram::parseUniforms()
{
_uniformsDictionary.clear();
_userUniforms.clear();
// Query and store uniforms from the program.
GLint activeUniforms;
@ -344,7 +347,7 @@ void GLProgram::parseUniforms()
uniform.name = std::string(uniformName);
uniform.location = glGetUniformLocation(_program, uniformName);
_uniformsDictionary[uniform.name] = uniform;
_userUniforms[uniform.name] = uniform;
}
}
}
@ -353,16 +356,16 @@ void GLProgram::parseUniforms()
Uniform* GLProgram::getUniform(const std::string &name)
{
const auto itr = _uniformsDictionary.find(name);
if( itr != _uniformsDictionary.end())
const auto itr = _userUniforms.find(name);
if( itr != _userUniforms.end())
return &itr->second;
return nullptr;
}
VertexAttrib* GLProgram::getVertexAttrib(const std::string &name)
{
const auto itr = _attributesDictionary.find(name);
if( itr != _attributesDictionary.end())
const auto itr = _vertexAttribs.find(name);
if( itr != _vertexAttribs.end())
return &itr->second;
return nullptr;
}
@ -446,32 +449,42 @@ void GLProgram::bindAttribLocation(const std::string &attributeName, GLuint inde
void GLProgram::updateUniforms()
{
_uniforms[UNIFORM_P_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_P_MATRIX);
_uniforms[UNIFORM_MV_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MV_MATRIX);
_uniforms[UNIFORM_MVP_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MVP_MATRIX);
_builtInUniforms[UNIFORM_P_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_P_MATRIX);
_builtInUniforms[UNIFORM_MV_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MV_MATRIX);
_builtInUniforms[UNIFORM_MVP_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MVP_MATRIX);
_uniforms[UNIFORM_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_TIME);
_uniforms[UNIFORM_SIN_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_SIN_TIME);
_uniforms[UNIFORM_COS_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_COS_TIME);
_builtInUniforms[UNIFORM_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_TIME);
_builtInUniforms[UNIFORM_SIN_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_SIN_TIME);
_builtInUniforms[UNIFORM_COS_TIME] = glGetUniformLocation(_program, UNIFORM_NAME_COS_TIME);
_uniforms[UNIFORM_RANDOM01] = glGetUniformLocation(_program, UNIFORM_NAME_RANDOM01);
_builtInUniforms[UNIFORM_RANDOM01] = glGetUniformLocation(_program, UNIFORM_NAME_RANDOM01);
_uniforms[UNIFORM_SAMPLER] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER);
_builtInUniforms[UNIFORM_SAMPLER0] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER0);
_builtInUniforms[UNIFORM_SAMPLER1] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER1);
_builtInUniforms[UNIFORM_SAMPLER2] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER2);
_builtInUniforms[UNIFORM_SAMPLER3] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER3);
_flags.usesP = _uniforms[UNIFORM_P_MATRIX] != -1;
_flags.usesMV = _uniforms[UNIFORM_MV_MATRIX] != -1;
_flags.usesMVP = _uniforms[UNIFORM_MVP_MATRIX] != -1;
_flags.usesP = _builtInUniforms[UNIFORM_P_MATRIX] != -1;
_flags.usesMV = _builtInUniforms[UNIFORM_MV_MATRIX] != -1;
_flags.usesMVP = _builtInUniforms[UNIFORM_MVP_MATRIX] != -1;
_flags.usesTime = (
_uniforms[UNIFORM_TIME] != -1 ||
_uniforms[UNIFORM_SIN_TIME] != -1 ||
_uniforms[UNIFORM_COS_TIME] != -1
_builtInUniforms[UNIFORM_TIME] != -1 ||
_builtInUniforms[UNIFORM_SIN_TIME] != -1 ||
_builtInUniforms[UNIFORM_COS_TIME] != -1
);
_flags.usesRandom = _uniforms[UNIFORM_RANDOM01] != -1;
_flags.usesRandom = _builtInUniforms[UNIFORM_RANDOM01] != -1;
this->use();
// Since sample most probably won't change, set it to 0 now.
this->setUniformLocationWith1i(_uniforms[UNIFORM_SAMPLER], 0);
// Since sample most probably won't change, set it to 0,1,2,3 now.
if(_builtInUniforms[UNIFORM_SAMPLER0] != -1)
setUniformLocationWith1i(_builtInUniforms[UNIFORM_SAMPLER0], 0);
if(_builtInUniforms[UNIFORM_SAMPLER1] != -1)
setUniformLocationWith1i(_builtInUniforms[UNIFORM_SAMPLER1], 1);
if(_builtInUniforms[UNIFORM_SAMPLER2] != -1)
setUniformLocationWith1i(_builtInUniforms[UNIFORM_SAMPLER2], 2);
if(_builtInUniforms[UNIFORM_SAMPLER3] != -1)
setUniformLocationWith1i(_builtInUniforms[UNIFORM_SAMPLER3], 3);
}
bool GLProgram::link()
@ -806,14 +819,14 @@ void GLProgram::setUniformsForBuiltins(const Matrix &matrixMV)
Matrix matrixP = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
if(_flags.usesP)
setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_P_MATRIX], matrixP.m, 1);
setUniformLocationWithMatrix4fv(_builtInUniforms[UNIFORM_P_MATRIX], matrixP.m, 1);
if(_flags.usesMV)
setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MV_MATRIX], matrixMV.m, 1);
setUniformLocationWithMatrix4fv(_builtInUniforms[UNIFORM_MV_MATRIX], matrixMV.m, 1);
if(_flags.usesMVP) {
Matrix matrixMVP = matrixP * matrixMV;
setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MVP_MATRIX], matrixMVP.m, 1);
setUniformLocationWithMatrix4fv(_builtInUniforms[UNIFORM_MVP_MATRIX], matrixMVP.m, 1);
}
if(_flags.usesTime) {
@ -823,19 +836,19 @@ void GLProgram::setUniformsForBuiltins(const Matrix &matrixMV)
// Getting Mach time per frame per shader using time could be extremely expensive.
float time = director->getTotalFrames() * director->getAnimationInterval();
setUniformLocationWith4f(_uniforms[GLProgram::UNIFORM_TIME], time/10.0, time, time*2, time*4);
setUniformLocationWith4f(_uniforms[GLProgram::UNIFORM_SIN_TIME], time/8.0, time/4.0, time/2.0, sinf(time));
setUniformLocationWith4f(_uniforms[GLProgram::UNIFORM_COS_TIME], time/8.0, time/4.0, time/2.0, cosf(time));
setUniformLocationWith4f(_builtInUniforms[GLProgram::UNIFORM_TIME], time/10.0, time, time*2, time*4);
setUniformLocationWith4f(_builtInUniforms[GLProgram::UNIFORM_SIN_TIME], time/8.0, time/4.0, time/2.0, sinf(time));
setUniformLocationWith4f(_builtInUniforms[GLProgram::UNIFORM_COS_TIME], time/8.0, time/4.0, time/2.0, cosf(time));
}
if(_flags.usesRandom)
setUniformLocationWith4f(_uniforms[GLProgram::UNIFORM_RANDOM01], CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1());
setUniformLocationWith4f(_builtInUniforms[GLProgram::UNIFORM_RANDOM01], CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1(), CCRANDOM_0_1());
}
void GLProgram::reset()
{
_vertShader = _fragShader = 0;
memset(_uniforms, 0, sizeof(_uniforms));
memset(_builtInUniforms, 0, sizeof(_builtInUniforms));
// it is already deallocated by android

View File

@ -100,8 +100,11 @@ public:
UNIFORM_SIN_TIME,
UNIFORM_COS_TIME,
UNIFORM_RANDOM01,
UNIFORM_SAMPLER,
UNIFORM_SAMPLER0,
UNIFORM_SAMPLER1,
UNIFORM_SAMPLER2,
UNIFORM_SAMPLER3,
UNIFORM_MAX,
};
@ -132,7 +135,10 @@ public:
static const char* UNIFORM_NAME_SIN_TIME;
static const char* UNIFORM_NAME_COS_TIME;
static const char* UNIFORM_NAME_RANDOM01;
static const char* UNIFORM_NAME_SAMPLER;
static const char* UNIFORM_NAME_SAMPLER0;
static const char* UNIFORM_NAME_SAMPLER1;
static const char* UNIFORM_NAME_SAMPLER2;
static const char* UNIFORM_NAME_SAMPLER3;
static const char* UNIFORM_NAME_ALPHA_TEST_VALUE;
// Attribute names
@ -288,11 +294,11 @@ public:
inline const GLuint getProgram() const { return _program; }
// DEPRECATED
CC_DEPRECATED_ATTRIBUTE bool initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{ return initWithByteArrays(vShaderByteArray, fShaderByteArray); }
CC_DEPRECATED_ATTRIBUTE bool initWithVertexShaderFilename(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{ return initWithFilenames(vShaderByteArray, fShaderByteArray); }
CC_DEPRECATED_ATTRIBUTE void addAttribute(const char* attributeName, GLuint index) const { return bindAttribLocation(attributeName, index); }
CC_DEPRECATED_ATTRIBUTE bool initWithVertexShaderByteArray(const GLchar* vertexByteArray, const GLchar* fragByteArray)
{ return initWithByteArrays(vertexByteArray, fragByteArray); }
CC_DEPRECATED_ATTRIBUTE bool initWithVertexShaderFilename(const std::string &vertexFilename, const std::string& fragFilename)
{ return initWithFilenames(vertexFilename, fragFilename); }
CC_DEPRECATED_ATTRIBUTE void addAttribute(const std::string &attributeName, GLuint index) const { return bindAttribLocation(attributeName, index); }
protected:
@ -307,10 +313,9 @@ protected:
std::string logForOpenGLObject(GLuint object, GLInfoFunction infoFunc, GLLogFunction logFunc) const;
GLuint _program;
GLuint _vertShader;
GLuint _fragShader;
GLint _uniforms[UNIFORM_MAX];
GLint _builtInUniforms[UNIFORM_MAX];
struct _hashUniformEntry* _hashForUniforms;
bool _hasShaderCompiler;
@ -329,8 +334,8 @@ protected:
flag_struct() { memset(this, 0, sizeof(*this)); }
} _flags;
std::unordered_map<std::string, Uniform> _uniformsDictionary;
std::unordered_map<std::string, VertexAttrib> _attributesDictionary;
std::unordered_map<std::string, Uniform> _userUniforms;
std::unordered_map<std::string, VertexAttrib> _vertexAttribs;
};
NS_CC_END

View File

@ -251,14 +251,14 @@ GLProgramState* GLProgramState::getOrCreateWithGLProgramName(const std::string &
{
GLProgram *glProgram = GLProgramCache::getInstance()->getGLProgram(glProgramName);
if( glProgram )
return getOrCreate(glProgram);
return getOrCreateWithGLProgram(glProgram);
CCLOG("cocos2d: warning: GLProgram '%s' not found", glProgramName.c_str());
return nullptr;
}
GLProgramState* GLProgramState::getOrCreate(GLProgram *glprogram)
GLProgramState* GLProgramState::getOrCreateWithGLProgram(GLProgram *glprogram)
{
GLProgramState* ret = GLProgramStateCache::getInstance()->getGLProgramState(glprogram);
return ret;
@ -283,12 +283,12 @@ bool GLProgramState::init(GLProgram* glprogram)
_glprogram = glprogram;
_glprogram->retain();
for(auto &attrib : _glprogram->_attributesDictionary) {
for(auto &attrib : _glprogram->_vertexAttribs) {
VertexAttribValue value(&attrib.second);
_attributes[attrib.first] = value;
}
for(auto &uniform : _glprogram->_uniformsDictionary) {
for(auto &uniform : _glprogram->_userUniforms) {
UniformValue value(&uniform.second, _glprogram);
_uniforms[uniform.first] = value;
}

View File

@ -150,7 +150,7 @@ public:
static GLProgramState* create(GLProgram* glprogram);
/** gets-or-creates an instance of GLProgramState for a given GLProgram */
static GLProgramState* getOrCreate(GLProgram* glprogram);
static GLProgramState* getOrCreateWithGLProgram(GLProgram* glprogram);
/** gets-or-creates an instance of GLProgramState for a given GLProgramName */
static GLProgramState* getOrCreateWithGLProgramName(const std::string &glProgramName );

View File

@ -176,7 +176,7 @@ void ShaderNode::loadShaderVertex(const std::string &vert, const std::string &fr
}
auto glprogram = GLProgram::createWithByteArrays(vertSource.c_str(), fragSource.c_str());
auto glprogramstate = GLProgramState::getOrCreate(glprogram);
auto glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram);
setGLProgramState(glprogramstate);
}
@ -493,7 +493,7 @@ void SpriteBlur::initGLProgram()
FileUtils::getInstance()->fullPathForFilename("Shaders/example_Blur.fsh").c_str())->getCString();
auto program = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, fragSource);
auto glProgramState = GLProgramState::getOrCreate(program);
auto glProgramState = GLProgramState::getOrCreateWithGLProgram(program);
setGLProgramState(glProgramState);
}
@ -761,7 +761,7 @@ bool ShaderMultiTexture::init()
sprite->setPosition(Vector2(s.width/2, s.height/2));
auto glprogram = GLProgram::createWithFilenames("Shaders/example_MultiTexture.vsh", "Shaders/example_MultiTexture.fsh");
auto glprogramstate = GLProgramState::getOrCreate(glprogram);
auto glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram);
sprite->setGLProgramState(glprogramstate);
glprogramstate->setUniformTexture("u_texture1", texture1);

View File

@ -41,6 +41,8 @@ namespace ShaderTest2
CL(CelShadingSpriteTest),
CL(LensFlareSpriteTest),
CL(OutlineShadingSpriteTest),
CL(EffectSprite_Blur),
};
static unsigned int TEST_CASE_COUNT = sizeof(ShaderTest2::createFunctions) / sizeof(ShaderTest2::createFunctions[0]);
@ -127,6 +129,150 @@ public:
}
};
//
// Effect
//
class Effect : public Ref
{
public:
GLProgramState* getGLProgramState() const { return _glprogramstate; }
protected:
bool initGLProgramState(const std::string &fragmentFilename);
Effect() : _glprogramstate(nullptr)
{}
virtual ~Effect() {}
GLProgramState *_glprogramstate;
};
bool Effect::initGLProgramState(const std::string &fragmentFilename)
{
auto fileUtiles = FileUtils::getInstance();
auto fragmentFullPath = fileUtiles->fullPathForFilename(fragmentFilename);
auto fragSource = fileUtiles->getStringFromFile(fragmentFullPath);
auto glprogram = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, fragSource.c_str());
_glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram);
_glprogramstate->retain();
return _glprogramstate != nullptr;
}
class EffectBlur : public Effect
{
public:
static EffectBlur *create(float blurSize);
void setGaussian(float value);
void setCustomUniforms();
void setBlurSize(float f);
protected:
bool init(float blurSize);
int _blurRadius;
Vector2 _pixelSize;
int _samplingRadius;
float _scale;
float _cons;
float _weightSum;
};
EffectBlur *EffectBlur::create(float blurSize)
{
auto ret = new (std::nothrow) EffectBlur;
if(ret && ret->init(blurSize)) {
ret->autorelease();
return ret;
}
CC_SAFE_RELEASE(ret);
return nullptr;
}
bool EffectBlur::init(float blurSize)
{
initGLProgramState("Shaders/example_Blur.fsh");
// auto s = getTexture()->getContentSizeInPixels();
auto s = Size(100,100);
_blurRadius = 0;
_pixelSize = Vector2(1/s.width, 1/s.height);
_samplingRadius = 0;
setBlurSize(blurSize);
_glprogramstate->setUniformVec2("onePixelSize", _pixelSize);
_glprogramstate->setUniformVec4("gaussianCoefficient", Vector4(_samplingRadius, _scale, _cons, _weightSum));
return true;
}
void EffectBlur::setBlurSize(float f)
{
if(_blurRadius == (int)f)
return;
_blurRadius = (int)f;
_samplingRadius = _blurRadius;
if (_samplingRadius > 10)
{
_samplingRadius = 10;
}
if (_blurRadius > 0)
{
float sigma = _blurRadius / 2.0f;
_scale = -0.5f / (sigma * sigma);
_cons = -1.0f * _scale / 3.141592f;
_weightSum = -_cons;
float weight;
int squareX;
for(int dx = 0; dx <= _samplingRadius; ++dx)
{
squareX = dx * dx;
weight = _cons * exp(squareX * _scale);
_weightSum += 2.0 * weight;
for (int dy = 1; dy <= _samplingRadius; ++dy)
{
weight = _cons * exp((squareX + dy * dy) * _scale);
_weightSum += 4.0 * weight;
}
}
}
}
//
// EffectSprite
//
class EffectSprite : public Sprite
{
public:
static EffectSprite *create(const std::string& filename) {
auto ret = new (std::nothrow) EffectSprite;
if(ret && ret->initWithFile(filename)) {
ret->autorelease();
return ret;
}
CC_SAFE_RELEASE(ret);
return nullptr;
}
void setEffect(Effect *effect) {
if(_effect != effect) {
CC_SAFE_RELEASE(_effect);
_effect = effect;
CC_SAFE_RETAIN(_effect);
setGLProgramState(_effect->getGLProgramState());
}
}
protected:
EffectSprite() : _effect(nullptr) {}
Effect *_effect;
};
//
// ShaderSprite
//
class ShaderSprite : public Sprite
{
public:
@ -179,7 +325,7 @@ void ShaderSprite::initShader()
}
auto glprogram = GLProgram::createWithByteArrays(vertSource.c_str(), fragSource.c_str());
auto glprogramState = GLProgramState::getOrCreate(glprogram);
auto glprogramState = GLProgramState::getOrCreateWithGLProgram(glprogram);
this->setGLProgramState(glprogramState);
setCustomUniforms();
@ -583,3 +729,25 @@ OutlineShadingSpriteTest::OutlineShadingSpriteTest()
}
}
EffectSprite_Blur::EffectSprite_Blur()
{
if (ShaderTestDemo2::init()) {
auto s = Director::getInstance()->getWinSize();
EffectSprite* sprite = EffectSprite::create("Images/grossini.png");
sprite->setPosition(Vector2(0, s.height/2));
addChild(sprite);
auto jump = JumpBy::create(4, Vector2(s.width,0), 100, 4);
auto rot = RotateBy::create(4, 720);
auto spawn = Spawn::create(jump, rot, NULL);
auto rev = spawn->reverse();
auto seq = Sequence::create(spawn, rev, NULL);
auto repeat = RepeatForever::create(seq);
sprite->runAction(repeat);
auto effect = EffectBlur::create(3.0);
sprite->setEffect(effect);
}
}

View File

@ -102,5 +102,13 @@ public:
virtual std::string subtitle() const {return "OutlineShadingSpriteTest";}
};
class EffectSprite_Blur : public ShaderTestDemo2
{
public:
CREATE_FUNC(EffectSprite_Blur);
EffectSprite_Blur();
virtual std::string subtitle() const {return "Blur Effect on Sprite";}
};
#endif