Reimplement LayerColor and LayerGradient for auto batch draw

This commit is contained in:
halx99 2021-08-29 18:59:09 +08:00
parent 89f0e21508
commit 8e1d7bd85d
2 changed files with 163 additions and 303 deletions

View File

@ -4,8 +4,9 @@ Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011 Zynga Inc. Copyright (c) 2011 Zynga Inc.
Copyright (c) 2013-2016 Chukong Technologies Inc. Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
Copyright (c) Bytedance Inc.
http://www.cocos2d-x.org
https://adxe.org
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -46,30 +47,27 @@ THE SOFTWARE.
#include "renderer/backend/ProgramState.h" #include "renderer/backend/ProgramState.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) #if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
#include "platform/desktop/CCGLViewImpl-desktop.h" # include "platform/desktop/CCGLViewImpl-desktop.h"
#endif #endif
NS_CC_BEGIN NS_CC_BEGIN
// Layer // Layer
Layer::Layer() Layer::Layer()
: _touchEnabled(false) : _touchEnabled(false)
, _accelerometerEnabled(false) , _accelerometerEnabled(false)
, _keyboardEnabled(false) , _keyboardEnabled(false)
, _touchListener(nullptr) , _touchListener(nullptr)
, _keyboardListener(nullptr) , _keyboardListener(nullptr)
, _accelerationListener(nullptr) , _accelerationListener(nullptr)
, _touchMode(Touch::DispatchMode::ALL_AT_ONCE) , _touchMode(Touch::DispatchMode::ALL_AT_ONCE)
, _swallowsTouches(true) , _swallowsTouches(true)
{ {
_ignoreAnchorPointForPosition = true; _ignoreAnchorPointForPosition = true;
setAnchorPoint(Vec2(0.5f, 0.5f)); setAnchorPoint(Vec2(0.5f, 0.5f));
} }
Layer::~Layer() Layer::~Layer() {}
{
}
bool Layer::init() bool Layer::init()
{ {
@ -77,9 +75,9 @@ bool Layer::init()
return true; return true;
} }
Layer *Layer::create() Layer* Layer::create()
{ {
Layer *ret = new (std::nothrow) Layer(); Layer* ret = new (std::nothrow) Layer();
if (ret && ret->init()) if (ret && ret->init())
{ {
ret->autorelease(); ret->autorelease();
@ -106,7 +104,9 @@ int Layer::executeScriptTouchHandler(EventTouch::EventCode eventType, Touch* tou
#endif #endif
} }
int Layer::executeScriptTouchesHandler(EventTouch::EventCode eventType, const std::vector<Touch*>& touches, Event* event) int Layer::executeScriptTouchesHandler(EventTouch::EventCode eventType,
const std::vector<Touch*>& touches,
Event* event)
{ {
#if CC_ENABLE_SCRIPT_BINDING #if CC_ENABLE_SCRIPT_BINDING
TouchesScriptData data(eventType, this, touches, event); TouchesScriptData data(eventType, this, touches, event);
@ -120,27 +120,24 @@ int Layer::executeScriptTouchesHandler(EventTouch::EventCode eventType, const st
#endif #endif
} }
void Layer::onAcceleration(Acceleration* acc, Event* /*unused_event*/) void Layer::onAcceleration(Acceleration* acc, Event* /*unused_event*/)
{ {
#if CC_ENABLE_SCRIPT_BINDING #if CC_ENABLE_SCRIPT_BINDING
BasicScriptData data(this,(void*)acc); BasicScriptData data(this, (void*)acc);
ScriptEvent event(kAccelerometerEvent,&data); ScriptEvent event(kAccelerometerEvent, &data);
ScriptEngineManager::sendEventToLua(event); ScriptEngineManager::sendEventToLua(event);
#else #else
CC_UNUSED_PARAM(acc); CC_UNUSED_PARAM(acc);
#endif #endif
} }
void Layer::onKeyPressed(EventKeyboard::KeyCode /*keyCode*/, Event* /*unused_event*/) void Layer::onKeyPressed(EventKeyboard::KeyCode /*keyCode*/, Event* /*unused_event*/) {}
{
}
void Layer::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* /*unused_event*/) void Layer::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* /*unused_event*/)
{ {
#if CC_ENABLE_SCRIPT_BINDING #if CC_ENABLE_SCRIPT_BINDING
KeypadScriptData data(keyCode, this); KeypadScriptData data(keyCode, this);
ScriptEvent event(kKeypadEvent,&data); ScriptEvent event(kKeypadEvent, &data);
ScriptEngineManager::sendEventToLua(event); ScriptEngineManager::sendEventToLua(event);
#else #else
CC_UNUSED_PARAM(keyCode); CC_UNUSED_PARAM(keyCode);
@ -149,7 +146,7 @@ void Layer::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* /*unused_event*
/// Callbacks /// Callbacks
bool Layer::onTouchBegan(Touch *touch, Event *event) bool Layer::onTouchBegan(Touch* touch, Event* event)
{ {
#if CC_ENABLE_SCRIPT_BINDING #if CC_ENABLE_SCRIPT_BINDING
return executeScriptTouchHandler(EventTouch::EventCode::BEGAN, touch, event) == 0 ? false : true; return executeScriptTouchHandler(EventTouch::EventCode::BEGAN, touch, event) == 0 ? false : true;
@ -161,7 +158,7 @@ bool Layer::onTouchBegan(Touch *touch, Event *event)
#endif #endif
} }
void Layer::onTouchMoved(Touch *touch, Event *event) void Layer::onTouchMoved(Touch* touch, Event* event)
{ {
#if CC_ENABLE_SCRIPT_BINDING #if CC_ENABLE_SCRIPT_BINDING
executeScriptTouchHandler(EventTouch::EventCode::MOVED, touch, event); executeScriptTouchHandler(EventTouch::EventCode::MOVED, touch, event);
@ -171,7 +168,7 @@ void Layer::onTouchMoved(Touch *touch, Event *event)
#endif #endif
} }
void Layer::onTouchEnded(Touch *touch, Event *event) void Layer::onTouchEnded(Touch* touch, Event* event)
{ {
#if CC_ENABLE_SCRIPT_BINDING #if CC_ENABLE_SCRIPT_BINDING
executeScriptTouchHandler(EventTouch::EventCode::ENDED, touch, event); executeScriptTouchHandler(EventTouch::EventCode::ENDED, touch, event);
@ -181,7 +178,7 @@ void Layer::onTouchEnded(Touch *touch, Event *event)
#endif #endif
} }
void Layer::onTouchCancelled(Touch *touch, Event *event) void Layer::onTouchCancelled(Touch* touch, Event* event)
{ {
#if CC_ENABLE_SCRIPT_BINDING #if CC_ENABLE_SCRIPT_BINDING
executeScriptTouchHandler(EventTouch::EventCode::CANCELLED, touch, event); executeScriptTouchHandler(EventTouch::EventCode::CANCELLED, touch, event);
@ -189,9 +186,9 @@ void Layer::onTouchCancelled(Touch *touch, Event *event)
CC_UNUSED_PARAM(touch); CC_UNUSED_PARAM(touch);
CC_UNUSED_PARAM(event); CC_UNUSED_PARAM(event);
#endif #endif
} }
void Layer::onTouchesBegan(const std::vector<Touch*>& touches, Event *event) void Layer::onTouchesBegan(const std::vector<Touch*>& touches, Event* event)
{ {
#if CC_ENABLE_SCRIPT_BINDING #if CC_ENABLE_SCRIPT_BINDING
executeScriptTouchesHandler(EventTouch::EventCode::BEGAN, touches, event); executeScriptTouchesHandler(EventTouch::EventCode::BEGAN, touches, event);
@ -201,7 +198,7 @@ void Layer::onTouchesBegan(const std::vector<Touch*>& touches, Event *event)
#endif #endif
} }
void Layer::onTouchesMoved(const std::vector<Touch*>& touches, Event *event) void Layer::onTouchesMoved(const std::vector<Touch*>& touches, Event* event)
{ {
#if CC_ENABLE_SCRIPT_BINDING #if CC_ENABLE_SCRIPT_BINDING
executeScriptTouchesHandler(EventTouch::EventCode::MOVED, touches, event); executeScriptTouchesHandler(EventTouch::EventCode::MOVED, touches, event);
@ -211,7 +208,7 @@ void Layer::onTouchesMoved(const std::vector<Touch*>& touches, Event *event)
#endif #endif
} }
void Layer::onTouchesEnded(const std::vector<Touch*>& touches, Event *event) void Layer::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
{ {
#if CC_ENABLE_SCRIPT_BINDING #if CC_ENABLE_SCRIPT_BINDING
executeScriptTouchesHandler(EventTouch::EventCode::ENDED, touches, event); executeScriptTouchesHandler(EventTouch::EventCode::ENDED, touches, event);
@ -221,7 +218,7 @@ void Layer::onTouchesEnded(const std::vector<Touch*>& touches, Event *event)
#endif #endif
} }
void Layer::onTouchesCancelled(const std::vector<Touch*>& touches, Event *event) void Layer::onTouchesCancelled(const std::vector<Touch*>& touches, Event* event)
{ {
#if CC_ENABLE_SCRIPT_BINDING #if CC_ENABLE_SCRIPT_BINDING
executeScriptTouchesHandler(EventTouch::EventCode::CANCELLED, touches, event); executeScriptTouchesHandler(EventTouch::EventCode::CANCELLED, touches, event);
@ -237,59 +234,7 @@ std::string Layer::getDescription() const
} }
/// LayerColor /// LayerColor
LayerColor::LayerColor() {}
LayerColor::LayerColor()
{
// default blend function
_blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
auto& pipelinePS = _customCommand.getPipelineDescriptor().programState;
auto* program = backend::Program::getBuiltinProgram(backend::ProgramType::POSITION_COLOR);
//!!! LayerColor private programState don't want affect by Node::_programState, so store at _customCommand
pipelinePS = new backend::ProgramState(program);
auto vertexLayout = pipelinePS->getVertexLayout();
const auto& attributeInfo = pipelinePS->getProgram()->getActiveAttributes();
auto iter = attributeInfo.find("a_position");
if(iter != attributeInfo.end())
{
vertexLayout->setAttribute("a_position", iter->second.location, backend::VertexFormat::FLOAT3, 0, false);
}
iter = attributeInfo.find("a_color");
if(iter != attributeInfo.end())
{
vertexLayout->setAttribute("a_color", iter->second.location, backend::VertexFormat::FLOAT4, sizeof(_vertexData[0].vertices), false);
}
vertexLayout->setLayout(sizeof(_vertexData[0]));
_mvpMatrixLocation = pipelinePS->getUniformLocation("u_MVPMatrix");
_customCommand.createIndexBuffer(CustomCommand::IndexFormat::U_SHORT, 6, CustomCommand::BufferUsage::STATIC);
unsigned short indices[] = {0, 1, 2, 2, 1, 3};
_customCommand.updateIndexBuffer(indices, sizeof(indices));
_customCommand.createVertexBuffer(sizeof(_vertexData[0]), 4, CustomCommand::BufferUsage::DYNAMIC);
_customCommand.setDrawType(CustomCommand::DrawType::ELEMENT);
_customCommand.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE);
}
LayerColor::~LayerColor()
{
CC_SAFE_RELEASE_NULL(_customCommand.getPipelineDescriptor().programState);
}
/// blendFunc getter
const BlendFunc &LayerColor::getBlendFunc() const
{
return _blendFunc;
}
/// blendFunc setter
void LayerColor::setBlendFunc(const BlendFunc &var)
{
_blendFunc = var;
}
LayerColor* LayerColor::create() LayerColor* LayerColor::create()
{ {
@ -305,10 +250,10 @@ LayerColor* LayerColor::create()
return ret; return ret;
} }
LayerColor * LayerColor::create(const Color4B& color, float width, float height) LayerColor* LayerColor::create(const Color4B& color, float width, float height)
{ {
LayerColor * layer = new (std::nothrow) LayerColor(); LayerColor* layer = new (std::nothrow) LayerColor();
if( layer && layer->initWithColor(color,width,height)) if (layer && layer->initWithColor(color, width, height))
{ {
layer->autorelease(); layer->autorelease();
return layer; return layer;
@ -317,10 +262,10 @@ LayerColor * LayerColor::create(const Color4B& color, float width, float height)
return nullptr; return nullptr;
} }
LayerColor * LayerColor::create(const Color4B& color) LayerColor* LayerColor::create(const Color4B& color)
{ {
LayerColor * layer = new (std::nothrow) LayerColor(); LayerColor* layer = new (std::nothrow) LayerColor();
if(layer && layer->initWithColor(color)) if (layer && layer->initWithColor(color))
{ {
layer->autorelease(); layer->autorelease();
return layer; return layer;
@ -332,30 +277,22 @@ LayerColor * LayerColor::create(const Color4B& color)
bool LayerColor::init() bool LayerColor::init()
{ {
Size s = _director->getWinSize(); Size s = _director->getWinSize();
return initWithColor(Color4B(0,0,0,0), s.width, s.height); return initWithColor(Color4B(0, 0, 0, 0), s.width, s.height);
} }
bool LayerColor::initWithColor(const Color4B& color, float w, float h) bool LayerColor::initWithColor(const Color4B& color, float w, float h)
{ {
if (Layer::init()) if (Sprite::init())
{ {
// Anchor behavior same with Layer
_ignoreAnchorPointForPosition = true;
setAnchorPoint(Vec2(0.5f, 0.5f));
// default blend function const Rect defaultRect{0.f, 0.f, 2.f, 2.f};
_blendFunc = BlendFunc::ALPHA_NON_PREMULTIPLIED; setTextureRect(defaultRect, false, defaultRect.size);
_displayedColor.r = _realColor.r = color.r;
_displayedColor.g = _realColor.g = color.g;
_displayedColor.b = _realColor.b = color.b;
_displayedOpacity = _realOpacity = color.a;
for (size_t i = 0; i<sizeof(_squareVertices) / sizeof( _squareVertices[0]); i++ )
{
_squareVertices[i].x = 0.0f;
_squareVertices[i].y = 0.0f;
}
updateColor();
setContentSize(Size(w, h)); setContentSize(Size(w, h));
setColor(Color3B{color});
setOpacity(color.a);
return true; return true;
} }
@ -368,18 +305,7 @@ bool LayerColor::initWithColor(const Color4B& color)
return initWithColor(color, s.width, s.height); return initWithColor(color, s.width, s.height);
} }
/// override contentSize void LayerColor::changeWidthAndHeight(float w, float h)
void LayerColor::setContentSize(const Size & size)
{
_squareVertices[1].x = size.width;
_squareVertices[2].y = size.height;
_squareVertices[3].x = size.width;
_squareVertices[3].y = size.height;
Layer::setContentSize(size);
}
void LayerColor::changeWidthAndHeight(float w ,float h)
{ {
this->setContentSize(Size(w, h)); this->setContentSize(Size(w, h));
} }
@ -394,57 +320,17 @@ void LayerColor::changeHeight(float h)
this->setContentSize(Size(_contentSize.width, h)); this->setContentSize(Size(_contentSize.width, h));
} }
void LayerColor::updateColor()
{
for (int i = 0; i < 4; i++ )
{
_vertexData[i].colors.r = _displayedColor.r / 255.0f;
_vertexData[i].colors.g = _displayedColor.g / 255.0f;
_vertexData[i].colors.b = _displayedColor.b / 255.0f;
_vertexData[i].colors.a = _displayedOpacity / 255.0f;
}
}
void LayerColor::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
_customCommand.init(_globalZOrder, _blendFunc);
renderer->addCommand(&_customCommand);
cocos2d::Mat4 projectionMat = _director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
pipelineDescriptor.programState->setUniform(_mvpMatrixLocation, projectionMat.m, sizeof(projectionMat.m));
for(int i = 0; i < 4; ++i)
{
Vec4 pos;
pos.x = _squareVertices[i].x; pos.y = _squareVertices[i].y; pos.z = _positionZ;
pos.w = 1;
_modelViewTransform.transformVector(&pos);
_vertexData[i].vertices = Vec3(pos.x,pos.y,pos.z)/pos.w;
}
updateVertexBuffer();
}
void LayerColor::updateVertexBuffer()
{
_customCommand.updateVertexBuffer(_vertexData, sizeof(_vertexData));
}
// //
// LayerGradient // LayerGradient
// //
LayerGradient::LayerGradient() LayerGradient::LayerGradient() {}
{
}
LayerGradient::~LayerGradient() LayerGradient::~LayerGradient() {}
{
}
LayerGradient* LayerGradient::create(const Color4B& start, const Color4B& end) LayerGradient* LayerGradient::create(const Color4B& start, const Color4B& end)
{ {
LayerGradient * layer = new (std::nothrow) LayerGradient(); LayerGradient* layer = new (std::nothrow) LayerGradient();
if( layer && layer->initWithColor(start, end)) if (layer && layer->initWithColor(start, end))
{ {
layer->autorelease(); layer->autorelease();
return layer; return layer;
@ -455,8 +341,8 @@ LayerGradient* LayerGradient::create(const Color4B& start, const Color4B& end)
LayerGradient* LayerGradient::create(const Color4B& start, const Color4B& end, const Vec2& v) LayerGradient* LayerGradient::create(const Color4B& start, const Color4B& end, const Vec2& v)
{ {
LayerGradient * layer = new (std::nothrow) LayerGradient(); LayerGradient* layer = new (std::nothrow) LayerGradient();
if( layer && layer->initWithColor(start, end, v)) if (layer && layer->initWithColor(start, end, v))
{ {
layer->autorelease(); layer->autorelease();
return layer; return layer;
@ -491,13 +377,13 @@ bool LayerGradient::initWithColor(const Color4B& start, const Color4B& end)
bool LayerGradient::initWithColor(const Color4B& start, const Color4B& end, const Vec2& v) bool LayerGradient::initWithColor(const Color4B& start, const Color4B& end, const Vec2& v)
{ {
_endColor.r = end.r; _endColor.r = end.r;
_endColor.g = end.g; _endColor.g = end.g;
_endColor.b = end.b; _endColor.b = end.b;
_endOpacity = end.a; _endOpacity = end.a;
_startOpacity = start.a; _startOpacity = start.a;
_alongVector = v; _alongVector = v;
_compressedInterpolation = true; _compressedInterpolation = true;
@ -506,8 +392,6 @@ bool LayerGradient::initWithColor(const Color4B& start, const Color4B& end, cons
void LayerGradient::updateColor() void LayerGradient::updateColor()
{ {
LayerColor::updateColor();
float h = _alongVector.getLength(); float h = _alongVector.getLength();
if (h == 0) if (h == 0)
return; return;
@ -518,46 +402,48 @@ void LayerGradient::updateColor()
// Compressed Interpolation mode // Compressed Interpolation mode
if (_compressedInterpolation) if (_compressedInterpolation)
{ {
float h2 = 1 / ( fabsf(u.x) + fabsf(u.y) ); float h2 = 1 / (fabsf(u.x) + fabsf(u.y));
u = u * (h2 * (float)c); u = u * (h2 * (float)c);
} }
float opacityf = (float)_displayedOpacity / 255.0f; float opacityf = (float)_displayedOpacity / 255.0f;
Color4F S( Color4F S(_displayedColor.r / 255.0f, _displayedColor.g / 255.0f, _displayedColor.b / 255.0f,
_displayedColor.r / 255.0f, _startOpacity * opacityf / 255.0f);
_displayedColor.g / 255.0f,
_displayedColor.b / 255.0f,
_startOpacity * opacityf / 255.0f
);
Color4F E( Color4F E(_endColor.r / 255.0f, _endColor.g / 255.0f, _endColor.b / 255.0f, _endOpacity * opacityf / 255.0f);
_endColor.r / 255.0f,
_endColor.g / 255.0f,
_endColor.b / 255.0f,
_endOpacity * opacityf / 255.0f
);
// (-1, -1) // (-1, -1)
_vertexData[0].colors.r = E.r + (S.r - E.r) * ((c + u.x + u.y) / (2.0f * c)); _quad.bl.colors.r = (E.r + (S.r - E.r) * ((c + u.x + u.y) / (2.0f * c))) * 255;
_vertexData[0].colors.g = E.g + (S.g - E.g) * ((c + u.x + u.y) / (2.0f * c)); _quad.bl.colors.g = (E.g + (S.g - E.g) * ((c + u.x + u.y) / (2.0f * c))) * 255;
_vertexData[0].colors.b = E.b + (S.b - E.b) * ((c + u.x + u.y) / (2.0f * c)); _quad.bl.colors.b = (E.b + (S.b - E.b) * ((c + u.x + u.y) / (2.0f * c))) * 255;
_vertexData[0].colors.a = E.a + (S.a - E.a) * ((c + u.x + u.y) / (2.0f * c)); _quad.bl.colors.a = (E.a + (S.a - E.a) * ((c + u.x + u.y) / (2.0f * c))) * 255;
// (1, -1) // (1, -1)
_vertexData[1].colors.r = E.r + (S.r - E.r) * ((c - u.x + u.y) / (2.0f * c)); _quad.br.colors.r = (E.r + (S.r - E.r) * ((c - u.x + u.y) / (2.0f * c))) * 255;
_vertexData[1].colors.g = E.g + (S.g - E.g) * ((c - u.x + u.y) / (2.0f * c)); _quad.br.colors.g = (E.g + (S.g - E.g) * ((c - u.x + u.y) / (2.0f * c))) * 255;
_vertexData[1].colors.b = E.b + (S.b - E.b) * ((c - u.x + u.y) / (2.0f * c)); _quad.br.colors.b = (E.b + (S.b - E.b) * ((c - u.x + u.y) / (2.0f * c))) * 255;
_vertexData[1].colors.a = E.a + (S.a - E.a) * ((c - u.x + u.y) / (2.0f * c)); _quad.br.colors.a = (E.a + (S.a - E.a) * ((c - u.x + u.y) / (2.0f * c))) * 255;
// (-1, 1) // (-1, 1)
_vertexData[2].colors.r = E.r + (S.r - E.r) * ((c + u.x - u.y) / (2.0f * c)); _quad.tl.colors.r = (E.r + (S.r - E.r) * ((c + u.x - u.y) / (2.0f * c))) * 255;
_vertexData[2].colors.g = E.g + (S.g - E.g) * ((c + u.x - u.y) / (2.0f * c)); _quad.tl.colors.g = (E.g + (S.g - E.g) * ((c + u.x - u.y) / (2.0f * c))) * 255;
_vertexData[2].colors.b = E.b + (S.b - E.b) * ((c + u.x - u.y) / (2.0f * c)); _quad.tl.colors.b = (E.b + (S.b - E.b) * ((c + u.x - u.y) / (2.0f * c))) * 255;
_vertexData[2].colors.a = E.a + (S.a - E.a) * ((c + u.x - u.y) / (2.0f * c)); _quad.tl.colors.a = (E.a + (S.a - E.a) * ((c + u.x - u.y) / (2.0f * c))) * 255;
// (1, 1) // (1, 1)
_vertexData[3].colors.r = E.r + (S.r - E.r) * ((c - u.x - u.y) / (2.0f * c)); _quad.tr.colors.r = (E.r + (S.r - E.r) * ((c - u.x - u.y) / (2.0f * c))) * 255;
_vertexData[3].colors.g = E.g + (S.g - E.g) * ((c - u.x - u.y) / (2.0f * c)); _quad.tr.colors.g = (E.g + (S.g - E.g) * ((c - u.x - u.y) / (2.0f * c))) * 255;
_vertexData[3].colors.b = E.b + (S.b - E.b) * ((c - u.x - u.y) / (2.0f * c)); _quad.tr.colors.b = (E.b + (S.b - E.b) * ((c - u.x - u.y) / (2.0f * c))) * 255;
_vertexData[3].colors.a = E.a + (S.a - E.a) * ((c - u.x - u.y) / (2.0f * c)); _quad.tr.colors.a = (E.a + (S.a - E.a) * ((c - u.x - u.y) / (2.0f * c))) * 255;
// renders using batch node
if (_renderMode == RenderMode::QUAD_BATCHNODE)
{
if (_atlasIndex != INDEX_NOT_INITIALIZED)
_textureAtlas->updateQuad(&_quad, _atlasIndex);
else
// no need to set it recursively
// update dirty_, don't update recursiveDirty_
setDirty(true);
}
} }
const Color3B& LayerGradient::getStartColor() const const Color3B& LayerGradient::getStartColor() const
@ -633,7 +519,11 @@ std::string LayerGradient::getDescription() const
/** /**
* LayerRadialGradient * LayerRadialGradient
*/ */
LayerRadialGradient* LayerRadialGradient::create(const Color4B& startColor, const Color4B& endColor, float radius, const Vec2& center, float expand) LayerRadialGradient* LayerRadialGradient::create(const Color4B& startColor,
const Color4B& endColor,
float radius,
const Vec2& center,
float expand)
{ {
auto layerGradient = new LayerRadialGradient(); auto layerGradient = new LayerRadialGradient();
if (layerGradient && layerGradient->initWithColor(startColor, endColor, radius, center, expand)) if (layerGradient && layerGradient->initWithColor(startColor, endColor, radius, center, expand))
@ -641,7 +531,7 @@ LayerRadialGradient* LayerRadialGradient::create(const Color4B& startColor, cons
layerGradient->autorelease(); layerGradient->autorelease();
return layerGradient; return layerGradient;
} }
delete layerGradient; delete layerGradient;
return nullptr; return nullptr;
} }
@ -649,12 +539,12 @@ LayerRadialGradient* LayerRadialGradient::create(const Color4B& startColor, cons
LayerRadialGradient* LayerRadialGradient::create() LayerRadialGradient* LayerRadialGradient::create()
{ {
auto layerGradient = new LayerRadialGradient(); auto layerGradient = new LayerRadialGradient();
if (layerGradient && layerGradient->initWithColor(Color4B::BLACK, Color4B::BLACK, 0, Vec2(0,0), 0)) if (layerGradient && layerGradient->initWithColor(Color4B::BLACK, Color4B::BLACK, 0, Vec2(0, 0), 0))
{ {
layerGradient->autorelease(); layerGradient->autorelease();
return layerGradient; return layerGradient;
} }
delete layerGradient; delete layerGradient;
return nullptr; return nullptr;
} }
@ -662,26 +552,27 @@ LayerRadialGradient* LayerRadialGradient::create()
LayerRadialGradient::LayerRadialGradient() LayerRadialGradient::LayerRadialGradient()
{ {
auto& pipelinePS = _customCommand.getPipelineDescriptor().programState; auto& pipelinePS = _customCommand.getPipelineDescriptor().programState;
auto* program = backend::Program::getBuiltinProgram(backend::ProgramType::LAYER_RADIA_GRADIENT); auto* program = backend::Program::getBuiltinProgram(backend::ProgramType::LAYER_RADIA_GRADIENT);
//!!! LayerRadialGradient private programState don't want affect by Node::_programState, so store at _customCommand //!!! LayerRadialGradient private programState don't want affect by Node::_programState, so store at _customCommand
pipelinePS = new backend::ProgramState(program); pipelinePS = new backend::ProgramState(program);
_mvpMatrixLocation = pipelinePS->getUniformLocation("u_MVPMatrix"); _mvpMatrixLocation = pipelinePS->getUniformLocation("u_MVPMatrix");
_startColorLocation = pipelinePS->getUniformLocation("u_startColor"); _startColorLocation = pipelinePS->getUniformLocation("u_startColor");
_endColorLocation = pipelinePS->getUniformLocation("u_endColor"); _endColorLocation = pipelinePS->getUniformLocation("u_endColor");
_centerLocation = pipelinePS->getUniformLocation("u_center"); _centerLocation = pipelinePS->getUniformLocation("u_center");
_radiusLocation = pipelinePS->getUniformLocation("u_radius"); _radiusLocation = pipelinePS->getUniformLocation("u_radius");
_expandLocation = pipelinePS->getUniformLocation("u_expand"); _expandLocation = pipelinePS->getUniformLocation("u_expand");
auto vertexLayout = pipelinePS->getVertexLayout(); auto vertexLayout = pipelinePS->getVertexLayout();
const auto& attributeInfo = pipelinePS->getProgram()->getActiveAttributes(); const auto& attributeInfo = pipelinePS->getProgram()->getActiveAttributes();
auto iter = attributeInfo.find("a_position"); auto iter = attributeInfo.find("a_position");
if(iter != attributeInfo.end()) if (iter != attributeInfo.end())
{ {
vertexLayout->setAttribute("a_position", iter->second.location, backend::VertexFormat::FLOAT2, 0, false); vertexLayout->setAttribute("a_position", iter->second.location, backend::VertexFormat::FLOAT2, 0, false);
} }
vertexLayout->setLayout(sizeof(_vertices[0])); vertexLayout->setLayout(sizeof(_vertices[0]));
_customCommand.createVertexBuffer(sizeof(_vertices[0]), sizeof(_vertices) / sizeof(_vertices[0]), CustomCommand::BufferUsage::STATIC); _customCommand.createVertexBuffer(sizeof(_vertices[0]), sizeof(_vertices) / sizeof(_vertices[0]),
CustomCommand::BufferUsage::STATIC);
_customCommand.setDrawType(CustomCommand::DrawType::ARRAY); _customCommand.setDrawType(CustomCommand::DrawType::ARRAY);
_customCommand.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE_STRIP); _customCommand.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE_STRIP);
} }
@ -691,39 +582,43 @@ LayerRadialGradient::~LayerRadialGradient()
CC_SAFE_RELEASE_NULL(_customCommand.getPipelineDescriptor().programState); CC_SAFE_RELEASE_NULL(_customCommand.getPipelineDescriptor().programState);
} }
bool LayerRadialGradient::initWithColor(const cocos2d::Color4B &startColor, const cocos2d::Color4B &endColor, float radius, const Vec2& center, float expand) bool LayerRadialGradient::initWithColor(const cocos2d::Color4B& startColor,
const cocos2d::Color4B& endColor,
float radius,
const Vec2& center,
float expand)
{ {
// should do it before Layer::init() // should do it before Layer::init()
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
_vertices[i] = {0.0f, 0.0f}; _vertices[i] = {0.0f, 0.0f};
if (Layer::init()) if (Layer::init())
{ {
convertColor4B24F(_startColorRend, startColor); convertColor4B24F(_startColorRend, startColor);
_startColor = startColor; _startColor = startColor;
convertColor4B24F(_endColorRend, endColor); convertColor4B24F(_endColorRend, endColor);
_endColor = endColor; _endColor = endColor;
_expand = expand; _expand = expand;
setRadius(radius); setRadius(radius);
setCenter(center); setCenter(center);
return true; return true;
} }
return false; return false;
} }
void LayerRadialGradient::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) void LayerRadialGradient::draw(Renderer* renderer, const Mat4& transform, uint32_t flags)
{ {
_customCommand.init(_globalZOrder, _blendFunc); _customCommand.init(_globalZOrder, _blendFunc);
renderer->addCommand(&_customCommand); renderer->addCommand(&_customCommand);
const auto& projectionMat = _director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); const auto& projectionMat = _director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
auto programState = _customCommand.getPipelineDescriptor().programState; auto programState = _customCommand.getPipelineDescriptor().programState;
Mat4 finalMat = projectionMat * transform; Mat4 finalMat = projectionMat * transform;
programState->setUniform(_mvpMatrixLocation, finalMat.m, sizeof(finalMat.m)); programState->setUniform(_mvpMatrixLocation, finalMat.m, sizeof(finalMat.m));
programState->setUniform(_startColorLocation, &_startColorRend, sizeof(_startColorRend)); programState->setUniform(_startColorLocation, &_startColorRend, sizeof(_startColorRend));
@ -747,7 +642,7 @@ void LayerRadialGradient::setContentSize(const Size& size)
void LayerRadialGradient::setStartOpacity(uint8_t opacity) void LayerRadialGradient::setStartOpacity(uint8_t opacity)
{ {
_startColorRend.a = opacity / 255.0f; _startColorRend.a = opacity / 255.0f;
_startColor.a = opacity; _startColor.a = opacity;
} }
uint8_t LayerRadialGradient::getStartOpacity() const uint8_t LayerRadialGradient::getStartOpacity() const
@ -758,7 +653,7 @@ uint8_t LayerRadialGradient::getStartOpacity() const
void LayerRadialGradient::setEndOpacity(uint8_t opacity) void LayerRadialGradient::setEndOpacity(uint8_t opacity)
{ {
_endColorRend.a = opacity / 255.0f; _endColorRend.a = opacity / 255.0f;
_endColor.a = opacity; _endColor.a = opacity;
} }
uint8_t LayerRadialGradient::getEndOpacity() const uint8_t LayerRadialGradient::getEndOpacity() const
@ -801,7 +696,7 @@ void LayerRadialGradient::setStartColor(const Color3B& color)
setStartColor(Color4B(color)); setStartColor(Color4B(color));
} }
void LayerRadialGradient::setStartColor(const cocos2d::Color4B &color) void LayerRadialGradient::setStartColor(const cocos2d::Color4B& color)
{ {
_startColor = color; _startColor = color;
convertColor4B24F(_startColorRend, _startColor); convertColor4B24F(_startColorRend, _startColor);
@ -822,7 +717,7 @@ void LayerRadialGradient::setEndColor(const Color3B& color)
setEndColor(Color4B(color)); setEndColor(Color4B(color));
} }
void LayerRadialGradient::setEndColor(const cocos2d::Color4B &color) void LayerRadialGradient::setEndColor(const cocos2d::Color4B& color)
{ {
_endColor = color; _endColor = color;
convertColor4B24F(_endColorRend, _endColor); convertColor4B24F(_endColorRend, _endColor);
@ -856,28 +751,25 @@ void LayerRadialGradient::convertColor4B24F(Color4F& outColor, const Color4B& in
outColor.a = inColor.a / 255.0f; outColor.a = inColor.a / 255.0f;
} }
/// MultiplexLayer /// MultiplexLayer
LayerMultiplex::LayerMultiplex() LayerMultiplex::LayerMultiplex() : _enabledLayer(0) {}
: _enabledLayer(0)
{
}
LayerMultiplex::~LayerMultiplex() LayerMultiplex::~LayerMultiplex()
{ {
for(const auto &layer : _layers) { for (const auto& layer : _layers)
{
layer->cleanup(); layer->cleanup();
} }
} }
LayerMultiplex * LayerMultiplex::create(Layer * layer, ...) LayerMultiplex* LayerMultiplex::create(Layer* layer, ...)
{ {
va_list args; va_list args;
va_start(args,layer); va_start(args, layer);
LayerMultiplex * multiplexLayer = new (std::nothrow) LayerMultiplex(); LayerMultiplex* multiplexLayer = new (std::nothrow) LayerMultiplex();
if(multiplexLayer && multiplexLayer->initWithLayers(layer, args)) if (multiplexLayer && multiplexLayer->initWithLayers(layer, args))
{ {
multiplexLayer->autorelease(); multiplexLayer->autorelease();
va_end(args); va_end(args);
@ -888,7 +780,7 @@ LayerMultiplex * LayerMultiplex::create(Layer * layer, ...)
return nullptr; return nullptr;
} }
LayerMultiplex * LayerMultiplex::createWithLayer(Layer* layer) LayerMultiplex* LayerMultiplex::createWithLayer(Layer* layer)
{ {
return LayerMultiplex::create(layer, nullptr); return LayerMultiplex::create(layer, nullptr);
} }
@ -929,7 +821,7 @@ void LayerMultiplex::addLayer(Layer* layer)
{ {
sEngine->retainScriptObject(this, layer); sEngine->retainScriptObject(this, layer);
} }
#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
_layers.pushBack(layer); _layers.pushBack(layer);
} }
@ -943,7 +835,7 @@ bool LayerMultiplex::init()
return false; return false;
} }
bool LayerMultiplex::initWithLayers(Layer *layer, va_list params) bool LayerMultiplex::initWithLayers(Layer* layer, va_list params)
{ {
if (Layer::init()) if (Layer::init())
{ {
@ -954,19 +846,20 @@ bool LayerMultiplex::initWithLayers(Layer *layer, va_list params)
{ {
sEngine->retainScriptObject(this, layer); sEngine->retainScriptObject(this, layer);
} }
#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
_layers.pushBack(layer); _layers.pushBack(layer);
Layer *l = va_arg(params,Layer*); Layer* l = va_arg(params, Layer*);
while( l ) { while (l)
{
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
if (sEngine) if (sEngine)
{ {
sEngine->retainScriptObject(this, l); sEngine->retainScriptObject(this, l);
} }
#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
_layers.pushBack(l); _layers.pushBack(l);
l = va_arg(params,Layer*); l = va_arg(params, Layer*);
} }
_enabledLayer = 0; _enabledLayer = 0;
@ -985,7 +878,7 @@ bool LayerMultiplex::initWithArray(const Vector<Layer*>& arrayOfLayers)
auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine(); auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
if (sEngine) if (sEngine)
{ {
for (const auto &layer : arrayOfLayers) for (const auto& layer : arrayOfLayers)
{ {
if (layer) if (layer)
{ {
@ -993,7 +886,7 @@ bool LayerMultiplex::initWithArray(const Vector<Layer*>& arrayOfLayers)
} }
} }
} }
#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
_layers.reserve(arrayOfLayers.size()); _layers.reserve(arrayOfLayers.size());
_layers.pushBack(arrayOfLayers); _layers.pushBack(arrayOfLayers);
@ -1006,24 +899,24 @@ bool LayerMultiplex::initWithArray(const Vector<Layer*>& arrayOfLayers)
void LayerMultiplex::switchTo(int n) void LayerMultiplex::switchTo(int n)
{ {
switchTo(n, true); switchTo(n, true);
} }
void LayerMultiplex::switchTo(int n, bool cleanup) void LayerMultiplex::switchTo(int n, bool cleanup)
{ {
CCASSERT( n < _layers.size(), "Invalid index in MultiplexLayer switchTo message" ); CCASSERT(n < _layers.size(), "Invalid index in MultiplexLayer switchTo message");
this->removeChild(_layers.at(_enabledLayer), cleanup); this->removeChild(_layers.at(_enabledLayer), cleanup);
_enabledLayer = n; _enabledLayer = n;
this->addChild(_layers.at(n)); this->addChild(_layers.at(n));
} }
void LayerMultiplex::switchToAndReleaseMe(int n) void LayerMultiplex::switchToAndReleaseMe(int n)
{ {
CCASSERT( n < _layers.size(), "Invalid index in MultiplexLayer switchTo message" ); CCASSERT(n < _layers.size(), "Invalid index in MultiplexLayer switchTo message");
this->removeChild(_layers.at(_enabledLayer), true); this->removeChild(_layers.at(_enabledLayer), true);
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
@ -1032,8 +925,8 @@ void LayerMultiplex::switchToAndReleaseMe(int n)
{ {
sEngine->releaseScriptObject(this, _layers.at(_enabledLayer)); sEngine->releaseScriptObject(this, _layers.at(_enabledLayer));
} }
#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
_layers.replace(_enabledLayer, nullptr); _layers.replace(_enabledLayer, nullptr);
_enabledLayer = n; _enabledLayer = n;

View File

@ -3,9 +3,9 @@ Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2010-2012 cocos2d-x.org Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011 Zynga Inc. Copyright (c) 2011 Zynga Inc.
Copyright (c) 2013-2016 Chukong Technologies Inc. Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. Copyright (c) Bytedance Inc.
http://www.cocos2d-x.org https://adxe.org
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -28,6 +28,7 @@ THE SOFTWARE.
#pragma once #pragma once
#include "2d/CCNode.h" #include "2d/CCNode.h"
#include "2d/CCSprite.h"
#include "base/CCProtocols.h" #include "base/CCProtocols.h"
#include "renderer/CCCustomCommand.h" #include "renderer/CCCustomCommand.h"
@ -196,7 +197,7 @@ All features from Layer are valid, plus the following new features:
- opacity - opacity
- RGB colors - RGB colors
*/ */
class CC_DLL LayerColor : public Layer, public BlendProtocol class CC_DLL LayerColor : public Sprite
{ {
public: public:
@ -238,46 +239,12 @@ public:
*/ */
void changeWidthAndHeight(float w, float h); void changeWidthAndHeight(float w, float h);
//
// Overrides
//
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
virtual void setContentSize(const Size & var) override;
/** BlendFunction. Conforms to BlendProtocol protocol */
/**
* @lua NA
*/
virtual const BlendFunc& getBlendFunc() const override;
/**
*@code
*When this function bound into js or lua,the parameter will be changed
*In js: var setBlendFunc(var src, var dst)
*In lua: local setBlendFunc(local src, local dst)
*@endcode
*/
virtual void setBlendFunc(const BlendFunc& blendFunc) override;
CC_CONSTRUCTOR_ACCESS: CC_CONSTRUCTOR_ACCESS:
LayerColor(); LayerColor();
virtual ~LayerColor();
bool init() override; bool init() override;
bool initWithColor(const Color4B& color, float width, float height); bool initWithColor(const Color4B& color, float width, float height);
bool initWithColor(const Color4B& color); bool initWithColor(const Color4B& color);
protected:
virtual void updateColor() override;
void updateVertexBuffer();
BlendFunc _blendFunc;
Vec2 _squareVertices[4];
CustomCommand _customCommand;
V3F_C4F _vertexData[4];
backend::UniformLocation _mvpMatrixLocation;
private: private:
CC_DISALLOW_COPY_AND_ASSIGN(LayerColor); CC_DISALLOW_COPY_AND_ASSIGN(LayerColor);