2014-05-09 06:43:12 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2014 Chukong Technologies Inc.
|
|
|
|
|
|
|
|
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.
|
|
|
|
****************************************************************************/
|
|
|
|
|
2014-05-09 09:01:48 +08:00
|
|
|
|
2014-05-09 06:43:12 +08:00
|
|
|
#include "ShaderTest2.h"
|
2013-09-09 17:49:13 +08:00
|
|
|
#include "ShaderTest.h"
|
|
|
|
#include "../testResource.h"
|
|
|
|
#include "cocos2d.h"
|
2014-05-16 03:58:13 +08:00
|
|
|
#include <tuple>
|
2013-09-09 17:49:13 +08:00
|
|
|
|
|
|
|
namespace ShaderTest2
|
|
|
|
{
|
|
|
|
static std::function<Layer*()> createFunctions[] =
|
|
|
|
{
|
2014-05-15 04:09:33 +08:00
|
|
|
CL(EffectSpriteTest),
|
2014-10-14 16:54:52 +08:00
|
|
|
CL(EffectSpriteLamp),
|
2013-09-09 17:49:13 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static unsigned int TEST_CASE_COUNT = sizeof(ShaderTest2::createFunctions) / sizeof(ShaderTest2::createFunctions[0]);
|
|
|
|
|
|
|
|
static int sceneIdx=-1;
|
|
|
|
Layer* createTest(int index)
|
|
|
|
{
|
|
|
|
auto layer = (createFunctions[index])();;
|
|
|
|
return layer;
|
|
|
|
}
|
|
|
|
|
|
|
|
Layer* nextAction();
|
|
|
|
Layer* backAction();
|
|
|
|
Layer* restartAction();
|
|
|
|
|
|
|
|
Layer* nextAction()
|
|
|
|
{
|
|
|
|
sceneIdx++;
|
|
|
|
sceneIdx = sceneIdx % TEST_CASE_COUNT;
|
|
|
|
|
|
|
|
return createTest(sceneIdx);
|
|
|
|
}
|
|
|
|
|
|
|
|
Layer* backAction()
|
|
|
|
{
|
|
|
|
sceneIdx--;
|
|
|
|
if( sceneIdx < 0 )
|
|
|
|
sceneIdx = TEST_CASE_COUNT -1;
|
|
|
|
|
|
|
|
return createTest(sceneIdx);
|
|
|
|
}
|
|
|
|
|
|
|
|
Layer* restartAction()
|
|
|
|
{
|
|
|
|
return createTest(sceneIdx);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ShaderTestDemo2::ShaderTestDemo2()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-02-20 10:53:49 +08:00
|
|
|
void ShaderTestDemo2::backCallback(Ref* sender)
|
2013-09-09 17:49:13 +08:00
|
|
|
{
|
2013-11-14 09:36:33 +08:00
|
|
|
auto s = ShaderTestScene2::create();
|
2013-09-09 17:49:13 +08:00
|
|
|
s->addChild( ShaderTest2::backAction() );
|
|
|
|
Director::getInstance()->replaceScene(s);
|
|
|
|
}
|
|
|
|
|
2014-02-20 10:53:49 +08:00
|
|
|
void ShaderTestDemo2::nextCallback(Ref* sender)
|
2013-09-09 17:49:13 +08:00
|
|
|
{
|
2013-11-14 09:36:33 +08:00
|
|
|
auto s = ShaderTestScene2::create();
|
2013-09-09 17:49:13 +08:00
|
|
|
s->addChild( ShaderTest2::nextAction() );
|
|
|
|
Director::getInstance()->replaceScene(s);
|
|
|
|
}
|
|
|
|
|
2014-02-20 10:53:49 +08:00
|
|
|
void ShaderTestDemo2::restartCallback(Ref* sender)
|
2013-09-09 17:49:13 +08:00
|
|
|
{
|
2013-11-14 09:36:33 +08:00
|
|
|
auto s = ShaderTestScene2::create();
|
|
|
|
s->addChild(ShaderTest2::restartAction());
|
2013-09-09 17:49:13 +08:00
|
|
|
Director::getInstance()->replaceScene(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ShaderTestScene2::runThisTest()
|
|
|
|
{
|
|
|
|
auto layer = ShaderTest2::nextAction();
|
|
|
|
addChild(layer);
|
|
|
|
Director::getInstance()->replaceScene(this);
|
|
|
|
}
|
|
|
|
|
2014-05-14 09:12:58 +08:00
|
|
|
//
|
2014-05-15 04:09:33 +08:00
|
|
|
// EffectSprite
|
2014-05-14 09:12:58 +08:00
|
|
|
//
|
2014-05-16 03:58:13 +08:00
|
|
|
static int tuple_sort( const std::tuple<ssize_t,Effect*,QuadCommand> &tuple1, const std::tuple<ssize_t,Effect*,QuadCommand> &tuple2 )
|
|
|
|
{
|
|
|
|
return std::get<0>(tuple1) < std::get<0>(tuple2);
|
|
|
|
}
|
|
|
|
|
2014-05-15 04:09:33 +08:00
|
|
|
class Effect;
|
|
|
|
class EffectSprite : public Sprite
|
2014-05-14 09:12:58 +08:00
|
|
|
{
|
|
|
|
public:
|
2014-05-15 04:09:33 +08:00
|
|
|
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;
|
|
|
|
}
|
2014-05-14 09:12:58 +08:00
|
|
|
|
2014-05-16 03:58:13 +08:00
|
|
|
void setEffect(Effect* effect) {
|
|
|
|
if(_defaultEffect != effect) {
|
2014-05-15 04:09:33 +08:00
|
|
|
effect->setTarget(this);
|
|
|
|
|
2014-05-16 03:58:13 +08:00
|
|
|
CC_SAFE_RELEASE(_defaultEffect);
|
|
|
|
_defaultEffect = effect;
|
|
|
|
CC_SAFE_RETAIN(_defaultEffect);
|
|
|
|
|
|
|
|
setGLProgramState(_defaultEffect->getGLProgramState());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void addEffect(Effect *effect, ssize_t order) {
|
|
|
|
effect->retain();
|
|
|
|
effect->setTarget(this);
|
|
|
|
|
|
|
|
_effects.push_back(std::make_tuple(order,effect,QuadCommand()));
|
|
|
|
|
|
|
|
std::sort(std::begin(_effects), std::end(_effects), tuple_sort);
|
|
|
|
}
|
|
|
|
|
2014-05-31 07:42:05 +08:00
|
|
|
void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override
|
2014-05-16 03:58:13 +08:00
|
|
|
{
|
|
|
|
// Don't do calculate the culling if the transform was not updated
|
2014-05-31 12:50:39 +08:00
|
|
|
_insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;
|
2014-05-16 03:58:13 +08:00
|
|
|
|
|
|
|
if(_insideBounds)
|
|
|
|
{
|
|
|
|
// negative effects: order < 0
|
|
|
|
int idx=0;
|
|
|
|
for(auto &effect : _effects) {
|
|
|
|
|
|
|
|
if(std::get<0>(effect) >=0)
|
|
|
|
break;
|
|
|
|
QuadCommand &q = std::get<2>(effect);
|
|
|
|
q.init(_globalZOrder, _texture->getName(), std::get<1>(effect)->getGLProgramState(), _blendFunc, &_quad, 1, transform);
|
|
|
|
renderer->addCommand(&q);
|
|
|
|
idx++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// normal effect: order == 0
|
|
|
|
_quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform);
|
|
|
|
renderer->addCommand(&_quadCommand);
|
|
|
|
|
|
|
|
// postive effects: oder >= 0
|
|
|
|
for(auto it = std::begin(_effects)+idx; it != std::end(_effects); ++it) {
|
|
|
|
QuadCommand &q = std::get<2>(*it);
|
|
|
|
q.init(_globalZOrder, _texture->getName(), std::get<1>(*it)->getGLProgramState(), _blendFunc, &_quad, 1, transform);
|
|
|
|
renderer->addCommand(&q);
|
|
|
|
idx++;
|
|
|
|
}
|
2014-05-15 04:09:33 +08:00
|
|
|
}
|
|
|
|
}
|
2014-05-14 09:12:58 +08:00
|
|
|
protected:
|
2014-05-16 03:58:13 +08:00
|
|
|
EffectSprite() : _defaultEffect(nullptr)
|
|
|
|
{
|
|
|
|
_effects.reserve(2);
|
|
|
|
}
|
|
|
|
~EffectSprite() {
|
|
|
|
for(auto &tuple : _effects) {
|
|
|
|
std::get<1>(tuple)->release();
|
|
|
|
}
|
|
|
|
CC_SAFE_RELEASE(_defaultEffect);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::tuple<ssize_t,Effect*,QuadCommand>> _effects;
|
|
|
|
Effect* _defaultEffect;
|
2014-05-14 09:12:58 +08:00
|
|
|
};
|
|
|
|
|
2014-05-15 04:09:33 +08:00
|
|
|
//
|
|
|
|
// Effect
|
|
|
|
//
|
|
|
|
|
2014-05-14 09:12:58 +08:00
|
|
|
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());
|
2014-05-29 12:43:04 +08:00
|
|
|
|
|
|
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
|
|
|
_fragSource = fragSource;
|
|
|
|
#endif
|
|
|
|
|
2014-05-14 09:12:58 +08:00
|
|
|
_glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram);
|
|
|
|
_glprogramstate->retain();
|
|
|
|
|
|
|
|
return _glprogramstate != nullptr;
|
|
|
|
}
|
|
|
|
|
2014-05-29 12:43:04 +08:00
|
|
|
Effect::Effect()
|
|
|
|
: _glprogramstate(nullptr)
|
|
|
|
{
|
|
|
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
2014-07-09 23:03:04 +08:00
|
|
|
_backgroundListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED,
|
2014-05-29 12:43:04 +08:00
|
|
|
[this](EventCustom*)
|
|
|
|
{
|
|
|
|
auto glProgram = _glprogramstate->getGLProgram();
|
|
|
|
glProgram->reset();
|
|
|
|
glProgram->initWithByteArrays(ccPositionTextureColor_noMVP_vert, _fragSource.c_str());
|
|
|
|
glProgram->link();
|
|
|
|
glProgram->updateUniforms();
|
|
|
|
}
|
|
|
|
);
|
|
|
|
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backgroundListener, -1);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
Effect::~Effect()
|
|
|
|
{
|
|
|
|
CC_SAFE_RELEASE_NULL(_glprogramstate);
|
|
|
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
|
|
|
Director::getInstance()->getEventDispatcher()->removeEventListener(_backgroundListener);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-05-15 04:09:33 +08:00
|
|
|
// Blur
|
2014-05-14 09:12:58 +08:00
|
|
|
class EffectBlur : public Effect
|
|
|
|
{
|
|
|
|
public:
|
2014-05-15 04:09:33 +08:00
|
|
|
CREATE_FUNC(EffectBlur);
|
|
|
|
virtual void setTarget(EffectSprite *sprite) override;
|
2014-06-11 14:54:14 +08:00
|
|
|
void setBlurRadius(float radius);
|
2014-06-12 09:49:48 +08:00
|
|
|
void setBlurSampleNum(float num);
|
2014-05-14 09:12:58 +08:00
|
|
|
|
|
|
|
protected:
|
2014-06-12 09:49:48 +08:00
|
|
|
bool init(float blurRadius = 10.0f, float sampleNum = 5.0f);
|
2014-06-11 14:54:14 +08:00
|
|
|
|
|
|
|
float _blurRadius;
|
2014-06-12 09:49:48 +08:00
|
|
|
float _blurSampleNum;
|
2014-05-14 09:12:58 +08:00
|
|
|
};
|
|
|
|
|
2014-05-15 04:09:33 +08:00
|
|
|
void EffectBlur::setTarget(EffectSprite *sprite)
|
2014-05-14 09:12:58 +08:00
|
|
|
{
|
2014-06-11 14:54:14 +08:00
|
|
|
Size size = sprite->getTexture()->getContentSizeInPixels();
|
|
|
|
_glprogramstate->setUniformVec2("resolution", size);
|
|
|
|
_glprogramstate->setUniformFloat("blurRadius", _blurRadius);
|
2014-06-12 09:49:48 +08:00
|
|
|
_glprogramstate->setUniformFloat("sampleNum", _blurSampleNum);
|
2014-05-14 09:12:58 +08:00
|
|
|
}
|
|
|
|
|
2014-06-12 09:49:48 +08:00
|
|
|
bool EffectBlur::init(float blurRadius, float sampleNum)
|
2014-05-14 09:12:58 +08:00
|
|
|
{
|
|
|
|
initGLProgramState("Shaders/example_Blur.fsh");
|
2014-06-11 14:54:14 +08:00
|
|
|
_blurRadius = blurRadius;
|
2014-06-12 09:49:48 +08:00
|
|
|
_blurSampleNum = sampleNum;
|
2014-06-11 14:54:14 +08:00
|
|
|
|
2014-05-14 09:12:58 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-06-11 14:54:14 +08:00
|
|
|
void EffectBlur::setBlurRadius(float radius)
|
2014-05-14 09:12:58 +08:00
|
|
|
{
|
2014-06-11 14:54:14 +08:00
|
|
|
_blurRadius = radius;
|
2014-05-14 09:12:58 +08:00
|
|
|
}
|
|
|
|
|
2014-06-12 09:49:48 +08:00
|
|
|
void EffectBlur::setBlurSampleNum(float num)
|
|
|
|
{
|
|
|
|
_blurSampleNum = num;
|
|
|
|
}
|
|
|
|
|
2014-05-15 04:09:33 +08:00
|
|
|
// Outline
|
|
|
|
class EffectOutline : public Effect
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CREATE_FUNC(EffectOutline);
|
|
|
|
|
|
|
|
bool init()
|
|
|
|
{
|
|
|
|
initGLProgramState("Shaders/example_outline.fsh");
|
2014-05-14 09:12:58 +08:00
|
|
|
|
2014-07-10 00:45:27 +08:00
|
|
|
Vec3 color(1.0f, 0.2f, 0.3f);
|
|
|
|
GLfloat radius = 0.01f;
|
2014-05-15 04:09:33 +08:00
|
|
|
GLfloat threshold = 1.75;
|
|
|
|
|
|
|
|
_glprogramstate->setUniformVec3("u_outlineColor", color);
|
|
|
|
_glprogramstate->setUniformFloat("u_radius", radius);
|
|
|
|
_glprogramstate->setUniformFloat("u_threshold", threshold);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Noise
|
|
|
|
class EffectNoise : public Effect
|
2014-05-14 09:12:58 +08:00
|
|
|
{
|
|
|
|
public:
|
2014-05-15 04:09:33 +08:00
|
|
|
CREATE_FUNC(EffectNoise);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
bool init() {
|
|
|
|
initGLProgramState("Shaders/example_Noisy.fsh");
|
|
|
|
return true;
|
2014-05-14 09:12:58 +08:00
|
|
|
}
|
|
|
|
|
2014-05-15 07:55:57 +08:00
|
|
|
virtual void setTarget(EffectSprite* sprite) override
|
2014-05-15 04:09:33 +08:00
|
|
|
{
|
|
|
|
auto s = sprite->getTexture()->getContentSizeInPixels();
|
|
|
|
getGLProgramState()->setUniformVec2("resolution", Vec2(s.width, s.height));
|
2014-05-14 09:12:58 +08:00
|
|
|
}
|
2014-05-15 04:09:33 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// Edge Detect
|
|
|
|
class EffectEdgeDetect : public Effect
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CREATE_FUNC(EffectEdgeDetect);
|
|
|
|
|
2014-05-14 09:12:58 +08:00
|
|
|
protected:
|
2014-05-15 04:09:33 +08:00
|
|
|
bool init() {
|
|
|
|
initGLProgramState("Shaders/example_edgeDetection.fsh");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-05-15 07:55:57 +08:00
|
|
|
virtual void setTarget(EffectSprite* sprite) override
|
2014-05-15 04:09:33 +08:00
|
|
|
{
|
|
|
|
auto s = sprite->getTexture()->getContentSizeInPixels();
|
|
|
|
getGLProgramState()->setUniformVec2("resolution", Vec2(s.width, s.height));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Grey
|
|
|
|
class EffectGreyScale : public Effect
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CREATE_FUNC(EffectGreyScale);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
bool init() {
|
|
|
|
initGLProgramState("Shaders/example_greyScale.fsh");
|
|
|
|
return true;
|
|
|
|
}
|
2014-05-14 09:12:58 +08:00
|
|
|
};
|
|
|
|
|
2014-05-15 07:55:57 +08:00
|
|
|
// Sepia
|
|
|
|
class EffectSepia : public Effect
|
2013-09-09 17:49:13 +08:00
|
|
|
{
|
|
|
|
public:
|
2014-05-15 07:55:57 +08:00
|
|
|
CREATE_FUNC(EffectSepia);
|
2013-09-09 17:49:13 +08:00
|
|
|
|
|
|
|
protected:
|
2014-05-15 07:55:57 +08:00
|
|
|
bool init() {
|
|
|
|
initGLProgramState("Shaders/example_sepia.fsh");
|
|
|
|
return true;
|
2014-04-14 11:52:17 +08:00
|
|
|
}
|
2013-09-09 17:49:13 +08:00
|
|
|
};
|
|
|
|
|
2014-05-15 07:55:57 +08:00
|
|
|
// bloom
|
|
|
|
class EffectBloom : public Effect
|
2013-09-09 17:49:13 +08:00
|
|
|
{
|
|
|
|
public:
|
2014-05-15 07:55:57 +08:00
|
|
|
CREATE_FUNC(EffectBloom);
|
|
|
|
|
2013-09-09 17:49:13 +08:00
|
|
|
protected:
|
2014-05-15 07:55:57 +08:00
|
|
|
bool init() {
|
|
|
|
initGLProgramState("Shaders/example_bloom.fsh");
|
|
|
|
return true;
|
|
|
|
}
|
2014-05-09 06:43:12 +08:00
|
|
|
|
2014-05-15 07:55:57 +08:00
|
|
|
virtual void setTarget(EffectSprite* sprite) override
|
|
|
|
{
|
|
|
|
auto s = sprite->getTexture()->getContentSizeInPixels();
|
|
|
|
getGLProgramState()->setUniformVec2("resolution", Vec2(s.width, s.height));
|
|
|
|
}
|
2013-09-09 17:49:13 +08:00
|
|
|
};
|
|
|
|
|
2014-05-15 07:55:57 +08:00
|
|
|
// cel shading
|
|
|
|
class EffectCelShading : public Effect
|
2013-09-12 10:25:55 +08:00
|
|
|
{
|
|
|
|
public:
|
2014-05-15 07:55:57 +08:00
|
|
|
CREATE_FUNC(EffectCelShading);
|
2014-05-09 06:43:12 +08:00
|
|
|
|
|
|
|
protected:
|
2014-05-15 07:55:57 +08:00
|
|
|
bool init() {
|
|
|
|
initGLProgramState("Shaders/example_celShading.fsh");
|
|
|
|
return true;
|
|
|
|
}
|
2014-05-09 06:43:12 +08:00
|
|
|
|
2014-05-15 07:55:57 +08:00
|
|
|
virtual void setTarget(EffectSprite* sprite) override
|
|
|
|
{
|
|
|
|
auto s = sprite->getTexture()->getContentSizeInPixels();
|
|
|
|
getGLProgramState()->setUniformVec2("resolution", Vec2(s.width, s.height));
|
|
|
|
}
|
2013-09-12 10:25:55 +08:00
|
|
|
};
|
|
|
|
|
2014-05-15 07:55:57 +08:00
|
|
|
// Lens Flare
|
|
|
|
class EffectLensFlare : public Effect
|
2013-09-12 10:25:55 +08:00
|
|
|
{
|
2014-05-15 07:55:57 +08:00
|
|
|
public:
|
|
|
|
CREATE_FUNC(EffectLensFlare);
|
2013-09-12 10:25:55 +08:00
|
|
|
|
2014-05-15 07:55:57 +08:00
|
|
|
protected:
|
|
|
|
bool init() {
|
|
|
|
initGLProgramState("Shaders/example_lensFlare.fsh");
|
|
|
|
return true;
|
2013-09-09 17:49:13 +08:00
|
|
|
}
|
|
|
|
|
2014-05-15 07:55:57 +08:00
|
|
|
virtual void setTarget(EffectSprite* sprite) override
|
2013-09-09 17:49:13 +08:00
|
|
|
{
|
2014-05-15 07:55:57 +08:00
|
|
|
auto s = sprite->getTexture()->getContentSizeInPixels();
|
|
|
|
getGLProgramState()->setUniformVec2("textureResolution", Vec2(s.width, s.height));
|
|
|
|
|
|
|
|
s = Director::getInstance()->getWinSize();
|
|
|
|
getGLProgramState()->setUniformVec2("resolution", Vec2(s.width, s.height));
|
2013-09-12 10:25:55 +08:00
|
|
|
|
|
|
|
}
|
2014-05-15 07:55:57 +08:00
|
|
|
};
|
|
|
|
|
2014-10-14 16:54:52 +08:00
|
|
|
class EffectNormalMapped : public Effect
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CREATE_FUNC(EffectNormalMapped);
|
|
|
|
static EffectNormalMapped* create(const std::string&normalMapFileName)
|
|
|
|
{
|
|
|
|
EffectNormalMapped *normalMappedSprite = new (std::nothrow) EffectNormalMapped();
|
|
|
|
if (normalMappedSprite && normalMappedSprite->init() && normalMappedSprite->initNormalMap(normalMapFileName))
|
|
|
|
{
|
|
|
|
|
|
|
|
normalMappedSprite->autorelease();
|
|
|
|
return normalMappedSprite;
|
|
|
|
}
|
|
|
|
CC_SAFE_DELETE(normalMappedSprite);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
void setKBump(float value);
|
|
|
|
void setLightPos(const Vec3& pos);
|
|
|
|
void setLightColor(const Color4F& color);
|
|
|
|
float getKBump()const{return _kBump;}
|
|
|
|
protected:
|
|
|
|
bool init();
|
|
|
|
bool initNormalMap(const std::string&normalMapFileName);
|
|
|
|
virtual void setTarget(EffectSprite* sprite) override;
|
|
|
|
EffectSprite* _sprite;
|
|
|
|
Vec3 _lightPos;
|
|
|
|
Color4F _lightColor;
|
|
|
|
float _kBump;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool EffectNormalMapped::init()
|
|
|
|
{
|
|
|
|
initGLProgramState("Shaders3D/Normal.frag");
|
|
|
|
_kBump = 2;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool EffectNormalMapped::initNormalMap(const std::string&normalMapFileName)
|
|
|
|
{
|
|
|
|
auto normalMapTextrue = TextureCache::getInstance()->addImage(normalMapFileName.c_str());
|
|
|
|
getGLProgramState()->setUniformTexture("u_normalMap", normalMapTextrue);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
void EffectNormalMapped::setTarget(EffectSprite* sprite)
|
|
|
|
{
|
|
|
|
_sprite = sprite;
|
|
|
|
getGLProgramState()->setUniformFloat("u_kBump", _kBump);
|
|
|
|
getGLProgramState()->setUniformVec2("u_contentSize", Vec2(sprite->getContentSize().width,sprite->getContentSize().height));
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectNormalMapped::setKBump(float value)
|
|
|
|
{
|
|
|
|
_kBump = value;
|
|
|
|
auto glProgramState = getGLProgramState();
|
|
|
|
if(glProgramState) glProgramState->setUniformFloat("u_kBump", _kBump);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectNormalMapped::setLightPos(const Vec3& pos)
|
|
|
|
{
|
|
|
|
_lightPos = pos;
|
|
|
|
auto glProgramState = getGLProgramState();
|
|
|
|
if(glProgramState) glProgramState->setUniformVec4("u_lightPosInLocalSpace", Vec4(_lightPos.x,_lightPos.y,_lightPos.z,1));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectNormalMapped::setLightColor(const Color4F& color)
|
|
|
|
{
|
|
|
|
_lightColor = color;
|
|
|
|
auto glProgramState = getGLProgramState();
|
|
|
|
if(glProgramState) getGLProgramState()->setUniformVec3("u_diffuseL", Vec3(_lightColor.r,_lightColor.g,_lightColor.b));
|
|
|
|
|
|
|
|
}
|
2014-04-14 11:52:17 +08:00
|
|
|
|
2014-05-15 04:09:33 +08:00
|
|
|
EffectSpriteTest::EffectSpriteTest()
|
2014-04-14 11:52:17 +08:00
|
|
|
{
|
|
|
|
if (ShaderTestDemo2::init()) {
|
2014-05-15 04:09:33 +08:00
|
|
|
|
2014-04-14 11:52:17 +08:00
|
|
|
auto s = Director::getInstance()->getWinSize();
|
2014-05-07 02:19:51 +08:00
|
|
|
|
2014-05-15 07:55:57 +08:00
|
|
|
auto itemPrev = MenuItemImage::create("Images/b1.png", "Images/b2.png",
|
|
|
|
[&](Ref *sender) {
|
|
|
|
_vectorIndex--;
|
|
|
|
if(_vectorIndex<0)
|
|
|
|
_vectorIndex = _effects.size()-1;
|
|
|
|
_sprite->setEffect(_effects.at(_vectorIndex));
|
|
|
|
});
|
|
|
|
|
|
|
|
auto itemNext = MenuItemImage::create("Images/f1.png", "Images/f2.png",
|
2014-05-15 04:09:33 +08:00
|
|
|
[&](Ref *sender) {
|
|
|
|
_vectorIndex++;
|
|
|
|
if(_vectorIndex>=_effects.size())
|
|
|
|
_vectorIndex = 0;
|
|
|
|
_sprite->setEffect(_effects.at(_vectorIndex));
|
|
|
|
});
|
2014-05-14 09:12:58 +08:00
|
|
|
|
2014-07-10 00:45:27 +08:00
|
|
|
auto menu = Menu::create(itemPrev, itemNext, nullptr);
|
2014-05-15 07:55:57 +08:00
|
|
|
menu->alignItemsHorizontally();
|
|
|
|
menu->setScale(0.5);
|
|
|
|
menu->setAnchorPoint(Vec2(0,0));
|
|
|
|
menu->setPosition(Vec2(s.width/2,70));
|
2014-05-15 04:09:33 +08:00
|
|
|
addChild(menu);
|
|
|
|
|
|
|
|
_sprite = EffectSprite::create("Images/grossini.png");
|
|
|
|
_sprite->setPosition(Vec2(0, s.height/2));
|
|
|
|
addChild(_sprite);
|
2014-05-14 09:12:58 +08:00
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
auto jump = JumpBy::create(4, Vec2(s.width,0), 100, 4);
|
2014-05-14 09:12:58 +08:00
|
|
|
auto rot = RotateBy::create(4, 720);
|
2014-07-10 00:45:27 +08:00
|
|
|
auto spawn = Spawn::create(jump, rot, nullptr);
|
2014-05-14 09:12:58 +08:00
|
|
|
auto rev = spawn->reverse();
|
2014-07-10 00:45:27 +08:00
|
|
|
auto seq = Sequence::create(spawn, rev, nullptr);
|
2014-05-14 09:12:58 +08:00
|
|
|
auto repeat = RepeatForever::create(seq);
|
2014-05-15 04:09:33 +08:00
|
|
|
_sprite->runAction(repeat);
|
|
|
|
|
|
|
|
// set the Effects
|
|
|
|
_effects.pushBack(EffectBlur::create());
|
|
|
|
_effects.pushBack(EffectOutline::create());
|
|
|
|
_effects.pushBack(EffectNoise::create());
|
|
|
|
_effects.pushBack(EffectEdgeDetect::create());
|
|
|
|
_effects.pushBack(EffectGreyScale::create());
|
2014-05-15 07:55:57 +08:00
|
|
|
_effects.pushBack(EffectSepia::create());
|
|
|
|
_effects.pushBack(EffectBloom::create());
|
|
|
|
_effects.pushBack(EffectCelShading::create());
|
|
|
|
_effects.pushBack(EffectLensFlare::create());
|
2014-05-14 09:12:58 +08:00
|
|
|
|
2014-05-15 04:09:33 +08:00
|
|
|
_vectorIndex = 0;
|
|
|
|
_sprite->setEffect( _effects.at(_vectorIndex) );
|
2014-05-16 03:58:13 +08:00
|
|
|
|
|
|
|
// _sprite->addEffect( _effects.at(8), -10 );
|
|
|
|
// _sprite->addEffect( _effects.at(1), 1 );
|
|
|
|
|
2014-05-14 09:12:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-14 16:54:52 +08:00
|
|
|
EffectSpriteLamp::EffectSpriteLamp()
|
|
|
|
{
|
|
|
|
if (ShaderTestDemo2::init()) {
|
|
|
|
|
|
|
|
auto s = Director::getInstance()->getWinSize();
|
|
|
|
_sprite = EffectSprite::create("Images/elephant1_Diffuse.png");
|
|
|
|
//auto contentSize = _sprite->getContentSize();
|
|
|
|
_sprite->setPosition(Vec2(s.width/2, s.height/2));
|
|
|
|
addChild(_sprite);
|
|
|
|
|
|
|
|
auto lampEffect = EffectNormalMapped::create("Images/elephant1_Normal.png");
|
|
|
|
|
|
|
|
Vec3 pos(150,150, 50);
|
|
|
|
_lightSprite = Sprite::create("Images/ball.png");
|
|
|
|
this->addChild(_lightSprite);
|
|
|
|
_lightSprite->setPosition(Vec2(pos.x, s.height- pos.y));
|
|
|
|
Mat4 mat = _sprite->getNodeToWorldTransform();
|
|
|
|
Point lightPosInLocalSpace=PointApplyAffineTransform(Vec2(pos.x, pos.y),_sprite->worldToNodeTransform());
|
|
|
|
lampEffect->setLightColor(Color4F(1,1,1,1));
|
|
|
|
lampEffect->setLightPos(Vec3(lightPosInLocalSpace.x, lightPosInLocalSpace.y, 50));
|
|
|
|
lampEffect->setKBump(2);
|
|
|
|
_sprite->setEffect(lampEffect);
|
|
|
|
_effect = lampEffect;
|
|
|
|
auto listerner = EventListenerTouchAllAtOnce::create();
|
|
|
|
listerner->onTouchesBegan = CC_CALLBACK_2(EffectSpriteLamp::onTouchesBegan, this);
|
|
|
|
listerner->onTouchesMoved = CC_CALLBACK_2(EffectSpriteLamp::onTouchesMoved, this);
|
|
|
|
listerner->onTouchesEnded = CC_CALLBACK_2(EffectSpriteLamp::onTouchesEnded, this);
|
|
|
|
_eventDispatcher->addEventListenerWithSceneGraphPriority(listerner, this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void EffectSpriteLamp::onTouchesBegan(const std::vector<Touch*>& touches, Event *unused_event)
|
|
|
|
{
|
|
|
|
for ( auto &item: touches )
|
|
|
|
{
|
|
|
|
auto touch = item;
|
|
|
|
auto s = Director::getInstance()->getWinSize();
|
|
|
|
Point loc_winSpace = touch->getLocationInView();
|
|
|
|
_lightSprite->setPosition(Vec2( loc_winSpace.x, s.height - loc_winSpace.y));
|
|
|
|
Vec3 pos(loc_winSpace.x,loc_winSpace.y, 50);
|
|
|
|
Mat4 mat = _sprite->getNodeToWorldTransform();
|
|
|
|
Point lightPosInLocalSpace=PointApplyAffineTransform(Vec2(pos.x, pos.y),_sprite->worldToNodeTransform());
|
|
|
|
((EffectNormalMapped*)_effect)->setLightPos(Vec3(lightPosInLocalSpace.x, lightPosInLocalSpace.y, 50));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSpriteLamp::onTouchesMoved(const std::vector<Touch*>& touches, Event *unused_event)
|
|
|
|
{
|
|
|
|
for ( auto &item: touches )
|
|
|
|
{
|
|
|
|
auto touch = item;
|
|
|
|
auto s = Director::getInstance()->getWinSize();
|
|
|
|
Point loc_winSpace = touch->getLocationInView();
|
|
|
|
_lightSprite->setPosition(Vec2( loc_winSpace.x, s.height - loc_winSpace.y));
|
|
|
|
Vec3 pos(loc_winSpace.x,loc_winSpace.y, 50);
|
|
|
|
Mat4 mat = _sprite->getNodeToWorldTransform();
|
|
|
|
Point lightPosInLocalSpace=PointApplyAffineTransform(Vec2(pos.x, pos.y),_sprite->worldToNodeTransform());
|
|
|
|
((EffectNormalMapped*)_effect)->setLightPos(Vec3(lightPosInLocalSpace.x, lightPosInLocalSpace.y, 50));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectSpriteLamp::onTouchesEnded(const std::vector<Touch*>& touches, Event *unused_event)
|
|
|
|
{
|
|
|
|
for ( auto &item: touches )
|
|
|
|
{
|
|
|
|
auto touch = item;
|
|
|
|
auto s = Director::getInstance()->getWinSize();
|
|
|
|
Point loc_winSpace = touch->getLocationInView();
|
|
|
|
_lightSprite->setPosition(Vec2( loc_winSpace.x, s.height - loc_winSpace.y));
|
|
|
|
Vec3 pos(loc_winSpace.x,loc_winSpace.y, 50);
|
|
|
|
Mat4 mat = _sprite->getNodeToWorldTransform();
|
|
|
|
Point lightPosInLocalSpace=PointApplyAffineTransform(Vec2(pos.x, pos.y),_sprite->worldToNodeTransform());
|
|
|
|
((EffectNormalMapped*)_effect)->setLightPos(Vec3(lightPosInLocalSpace.x, lightPosInLocalSpace.y, 50));
|
|
|
|
}
|
|
|
|
}
|