2014-05-09 06:43:12 +08:00
|
|
|
/****************************************************************************
|
2018-01-29 16:25:32 +08:00
|
|
|
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2014-05-09 06:43:12 +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 "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
|
|
|
|
2015-04-09 12:23:47 +08:00
|
|
|
USING_NS_CC;
|
|
|
|
|
2015-04-03 14:31:03 +08:00
|
|
|
Shader2Tests::Shader2Tests()
|
2013-09-09 17:49:13 +08:00
|
|
|
{
|
2015-04-03 14:31:03 +08:00
|
|
|
ADD_TEST_CASE(EffectSpriteTest);
|
|
|
|
ADD_TEST_CASE(EffectSpriteLamp);
|
2013-09-09 17:49:13 +08:00
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2015-01-14 10:56:51 +08:00
|
|
|
#if CC_USE_CULLING
|
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)
|
2015-01-14 10:56:51 +08:00
|
|
|
#endif
|
2014-05-16 03:58:13 +08:00
|
|
|
{
|
|
|
|
// negative effects: order < 0
|
|
|
|
int idx=0;
|
|
|
|
for(auto &effect : _effects) {
|
|
|
|
|
|
|
|
if(std::get<0>(effect) >=0)
|
|
|
|
break;
|
2015-12-16 13:54:43 +08:00
|
|
|
auto glProgramState = std::get<1>(effect)->getGLProgramState();
|
|
|
|
if (glProgramState)
|
|
|
|
{
|
|
|
|
QuadCommand &q = std::get<2>(effect);
|
|
|
|
q.init(_globalZOrder, _texture->getName(), glProgramState, _blendFunc, &_quad, 1, transform, flags);
|
|
|
|
renderer->addCommand(&q);
|
|
|
|
}
|
2014-05-16 03:58:13 +08:00
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// normal effect: order == 0
|
2015-06-04 16:20:00 +08:00
|
|
|
_trianglesCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, _polyInfo.triangles, transform, flags);
|
2015-05-22 15:54:56 +08:00
|
|
|
renderer->addCommand(&_trianglesCommand);
|
2014-05-16 03:58:13 +08:00
|
|
|
|
2017-02-10 10:35:52 +08:00
|
|
|
// positive effects: order >= 0
|
2014-05-16 03:58:13 +08:00
|
|
|
for(auto it = std::begin(_effects)+idx; it != std::end(_effects); ++it) {
|
|
|
|
QuadCommand &q = std::get<2>(*it);
|
2015-01-16 06:00:49 +08:00
|
|
|
q.init(_globalZOrder, _texture->getName(), std::get<1>(*it)->getGLProgramState(), _blendFunc, &_quad, 1, transform, flags);
|
2014-05-16 03:58:13 +08:00
|
|
|
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
|
|
|
|
2015-05-09 00:19:13 +08:00
|
|
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
2014-05-29 12:43:04 +08:00
|
|
|
_fragSource = fragSource;
|
|
|
|
#endif
|
|
|
|
|
2015-12-16 13:54:43 +08:00
|
|
|
_glprogramstate = (glprogram == nullptr ? nullptr : GLProgramState::getOrCreateWithGLProgram(glprogram));
|
|
|
|
CC_SAFE_RETAIN(_glprogramstate);
|
2014-05-14 09:12:58 +08:00
|
|
|
|
|
|
|
return _glprogramstate != nullptr;
|
|
|
|
}
|
|
|
|
|
2014-05-29 12:43:04 +08:00
|
|
|
Effect::Effect()
|
|
|
|
: _glprogramstate(nullptr)
|
|
|
|
{
|
2015-05-09 00:19:13 +08:00
|
|
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
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);
|
2015-05-09 00:19:13 +08:00
|
|
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
2014-05-29 12:43:04 +08:00
|
|
|
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
|
|
|
{
|
2015-12-16 13:54:43 +08:00
|
|
|
if (_glprogramstate == nullptr)
|
|
|
|
return;
|
|
|
|
|
2014-06-11 14:54:14 +08:00
|
|
|
Size size = sprite->getTexture()->getContentSizeInPixels();
|
|
|
|
_glprogramstate->setUniformVec2("resolution", size);
|
2015-07-24 16:32:26 +08:00
|
|
|
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)
|
2014-06-11 14:54:14 +08:00
|
|
|
_glprogramstate->setUniformFloat("blurRadius", _blurRadius);
|
2014-06-12 09:49:48 +08:00
|
|
|
_glprogramstate->setUniformFloat("sampleNum", _blurSampleNum);
|
2015-07-24 16:32:26 +08:00
|
|
|
#endif
|
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
|
|
|
{
|
2015-07-24 16:32:26 +08:00
|
|
|
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)
|
2014-05-14 09:12:58 +08:00
|
|
|
initGLProgramState("Shaders/example_Blur.fsh");
|
2015-07-24 16:32:26 +08:00
|
|
|
#else
|
|
|
|
initGLProgramState("Shaders/example_Blur_winrt.fsh");
|
|
|
|
#endif
|
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()
|
|
|
|
{
|
2015-05-26 17:20:48 +08:00
|
|
|
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() {
|
2015-05-26 17:20:48 +08:00
|
|
|
initGLProgramState("Shaders/example_EdgeDetection.fsh");
|
2014-05-15 04:09:33 +08:00
|
|
|
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() {
|
2015-05-26 17:20:48 +08:00
|
|
|
initGLProgramState("Shaders/example_GreyScale.fsh");
|
2014-05-15 04:09:33 +08:00
|
|
|
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() {
|
2015-05-26 17:20:48 +08:00
|
|
|
initGLProgramState("Shaders/example_Sepia.fsh");
|
2014-05-15 07:55:57 +08:00
|
|
|
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() {
|
2015-05-26 17:20:48 +08:00
|
|
|
initGLProgramState("Shaders/example_Bloom.fsh");
|
2014-05-15 07:55:57 +08:00
|
|
|
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() {
|
2015-05-26 17:20:48 +08:00
|
|
|
initGLProgramState("Shaders/example_CelShading.fsh");
|
2014-05-15 07:55:57 +08:00
|
|
|
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() {
|
2015-05-26 17:20:48 +08:00
|
|
|
initGLProgramState("Shaders/example_LensFlare.fsh");
|
2014-05-15 07:55:57 +08:00
|
|
|
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;
|
|
|
|
}
|
2014-11-05 07:42:29 +08:00
|
|
|
bool EffectNormalMapped::initNormalMap(const std::string& normalMapFileName)
|
2014-10-14 16:54:52 +08:00
|
|
|
{
|
2016-06-29 10:04:11 +08:00
|
|
|
auto normalMapTexture = Director::getInstance()->getTextureCache()->addImage(normalMapFileName);
|
|
|
|
getGLProgramState()->setUniformTexture("u_normalMap", normalMapTexture);
|
2014-10-14 16:54:52 +08:00
|
|
|
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()
|
2015-08-24 18:19:28 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EffectSpriteTest::init()
|
2014-04-14 11:52:17 +08:00
|
|
|
{
|
|
|
|
if (ShaderTestDemo2::init()) {
|
2014-05-15 04:09:33 +08:00
|
|
|
|
2015-05-06 04:07:32 +08:00
|
|
|
auto layer = LayerColor::create(Color4B::BLUE);
|
|
|
|
this->addChild(layer);
|
|
|
|
|
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 );
|
2015-08-24 18:19:28 +08:00
|
|
|
|
|
|
|
return true;
|
2014-05-14 09:12:58 +08:00
|
|
|
}
|
2015-08-24 18:19:28 +08:00
|
|
|
return false;
|
2014-05-14 09:12:58 +08:00
|
|
|
}
|
|
|
|
|
2014-10-14 16:54:52 +08:00
|
|
|
EffectSpriteLamp::EffectSpriteLamp()
|
2015-08-24 18:19:28 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EffectSpriteLamp::init()
|
2014-10-14 16:54:52 +08:00
|
|
|
{
|
|
|
|
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();
|
2016-04-11 18:35:44 +08:00
|
|
|
Point lightPosInLocalSpace = PointApplyAffineTransform(Vec2(pos.x, pos.y), _sprite->getWorldToNodeAffineTransform());
|
2014-10-14 16:54:52 +08:00
|
|
|
lampEffect->setLightColor(Color4F(1,1,1,1));
|
|
|
|
lampEffect->setLightPos(Vec3(lightPosInLocalSpace.x, lightPosInLocalSpace.y, 50));
|
|
|
|
lampEffect->setKBump(2);
|
|
|
|
_sprite->setEffect(lampEffect);
|
|
|
|
_effect = lampEffect;
|
2017-03-06 10:01:53 +08:00
|
|
|
auto listener = EventListenerTouchAllAtOnce::create();
|
|
|
|
listener->onTouchesBegan = CC_CALLBACK_2(EffectSpriteLamp::onTouchesBegan, this);
|
|
|
|
listener->onTouchesMoved = CC_CALLBACK_2(EffectSpriteLamp::onTouchesMoved, this);
|
|
|
|
listener->onTouchesEnded = CC_CALLBACK_2(EffectSpriteLamp::onTouchesEnded, this);
|
|
|
|
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
2015-08-24 18:19:28 +08:00
|
|
|
return true;
|
2014-10-14 16:54:52 +08:00
|
|
|
}
|
2015-08-24 18:19:28 +08:00
|
|
|
return false;
|
2014-10-14 16:54:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
2016-04-11 18:35:44 +08:00
|
|
|
Point lightPosInLocalSpace = PointApplyAffineTransform(Vec2(pos.x, pos.y), _sprite->getWorldToNodeAffineTransform());
|
2014-10-14 16:54:52 +08:00
|
|
|
((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();
|
2016-04-11 18:35:44 +08:00
|
|
|
Point lightPosInLocalSpace = PointApplyAffineTransform(Vec2(pos.x, pos.y), _sprite->getWorldToNodeAffineTransform());
|
2014-10-14 16:54:52 +08:00
|
|
|
((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();
|
2016-04-11 18:35:44 +08:00
|
|
|
Point lightPosInLocalSpace = PointApplyAffineTransform(Vec2(pos.x, pos.y), _sprite->getWorldToNodeAffineTransform());
|
2014-10-14 16:54:52 +08:00
|
|
|
((EffectNormalMapped*)_effect)->setLightPos(Vec3(lightPosInLocalSpace.x, lightPosInLocalSpace.y, 50));
|
|
|
|
}
|
|
|
|
}
|