mirror of https://github.com/axmolengine/axmol.git
[bugfix] fix label effects (#19554)
This commit is contained in:
parent
45183919e9
commit
d6614cc0da
|
@ -112,18 +112,8 @@ void FontAtlas::reinit()
|
|||
_currentPageData = new (std::nothrow) unsigned char[_currentPageDataSize];
|
||||
memset(_currentPageData, 0, _currentPageDataSize);
|
||||
|
||||
//metal do no support AI88 format
|
||||
if(outlineSize > 0)
|
||||
{
|
||||
texture->initWithData(_currentPageDataRGBA, _currentPageDataSizeRGBA,
|
||||
Texture2D::PixelFormat::RGBA8888, CacheTextureWidth, CacheTextureHeight, Size(CacheTextureWidth,CacheTextureHeight) );
|
||||
}
|
||||
else
|
||||
{
|
||||
texture->initWithData(_currentPageData, _currentPageDataSize,
|
||||
Texture2D::PixelFormat::A8, CacheTextureWidth, CacheTextureHeight, Size(CacheTextureWidth,CacheTextureHeight) );
|
||||
|
||||
}
|
||||
initTextureWithZeros(texture);
|
||||
|
||||
addTexture(texture,0);
|
||||
texture->release();
|
||||
}
|
||||
|
@ -153,6 +143,29 @@ FontAtlas::~FontAtlas()
|
|||
#endif
|
||||
}
|
||||
|
||||
void FontAtlas::initTextureWithZeros(Texture2D *texture)
|
||||
{
|
||||
char *zeros = nullptr;
|
||||
Texture2D::PixelFormat pixelFormat;
|
||||
float outlineSize = _fontFreeType->getOutlineSize();
|
||||
size_t zeroBytes = 0;
|
||||
if (outlineSize > 0)
|
||||
{
|
||||
//metal do no support AI88 format
|
||||
pixelFormat = Texture2D::PixelFormat::RGBA8888;
|
||||
zeroBytes = CacheTextureWidth * CacheTextureWidth * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
pixelFormat = Texture2D::PixelFormat::A8;
|
||||
zeroBytes = CacheTextureWidth * CacheTextureWidth;
|
||||
}
|
||||
zeros = new char[zeroBytes]();
|
||||
//std::fill(zeros, zeros + cnt, 0);
|
||||
texture->initWithData(zeros, zeroBytes, pixelFormat, CacheTextureWidth, CacheTextureHeight, Size(CacheTextureWidth, CacheTextureHeight));
|
||||
delete[] zeros;
|
||||
}
|
||||
|
||||
void FontAtlas::reset()
|
||||
{
|
||||
releaseTextures();
|
||||
|
@ -405,6 +418,9 @@ bool FontAtlas::prepareLetterDefinitions(const std::u32string& utf32Text)
|
|||
memset(_currentPageData, 0, _currentPageDataSize);
|
||||
_currentPage++;
|
||||
auto tex = new (std::nothrow) Texture2D;
|
||||
|
||||
initTextureWithZeros(tex);
|
||||
|
||||
if (_antialiasEnabled)
|
||||
{
|
||||
tex->setAntiAliasTexParameters();
|
||||
|
@ -413,9 +429,8 @@ bool FontAtlas::prepareLetterDefinitions(const std::u32string& utf32Text)
|
|||
{
|
||||
tex->setAliasTexParameters();
|
||||
}
|
||||
tex->initWithData(_currentPageData, _currentPageDataSize,
|
||||
pixelFormat, CacheTextureWidth, CacheTextureHeight, Size(CacheTextureWidth, CacheTextureHeight));
|
||||
addTexture(tex, _currentPage);
|
||||
|
||||
tex->release();
|
||||
}
|
||||
}
|
||||
|
@ -469,6 +484,7 @@ void FontAtlas::updateTextureContent(Texture2D::PixelFormat format, int startY)
|
|||
{
|
||||
int nLen = CacheTextureWidth * (_currentPageOrigY - startY + _currLineHeight);
|
||||
data = _currentPageData + CacheTextureWidth * (int)startY * 2;
|
||||
memset(_currentPageDataRGBA, 0, 4 * nLen);
|
||||
for (auto i = 0; i < nLen; i++)
|
||||
{
|
||||
_currentPageDataRGBA[i*4] = data[i*2];
|
||||
|
|
|
@ -122,6 +122,8 @@ protected:
|
|||
|
||||
void conversionU32TOGB2312(const std::u32string& u32Text, std::unordered_map<unsigned int, unsigned int>& charCodeMap);
|
||||
|
||||
void initTextureWithZeros(Texture2D *texture);
|
||||
|
||||
/**
|
||||
* Scale each font letter by scaleFactor.
|
||||
*
|
||||
|
|
|
@ -36,8 +36,10 @@
|
|||
#include "2d/CCDrawNode.h"
|
||||
#include "2d/CCCamera.h"
|
||||
#include "base/ccUTF8.h"
|
||||
#include "base/ccMacros.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
#include "renderer/CCRenderer.h"
|
||||
#include "renderer/CCRenderCommand.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/CCEventListenerCustom.h"
|
||||
#include "base/CCEventDispatcher.h"
|
||||
|
@ -48,6 +50,29 @@
|
|||
#include "renderer/backend/ProgramState.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
||||
namespace {
|
||||
void updateBlend(backend::BlendDescriptor &blendDescriptor, BlendFunc blendFunc)
|
||||
{
|
||||
blendDescriptor.blendEnabled = true;
|
||||
if (blendFunc == BlendFunc::ALPHA_NON_PREMULTIPLIED)
|
||||
{
|
||||
blendDescriptor.sourceRGBBlendFactor = backend::BlendFactor::SRC_ALPHA;
|
||||
blendDescriptor.destinationRGBBlendFactor = backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||
blendDescriptor.sourceAlphaBlendFactor = backend::BlendFactor::SRC_ALPHA;
|
||||
blendDescriptor.destinationAlphaBlendFactor = backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
else
|
||||
{
|
||||
blendDescriptor.sourceRGBBlendFactor = backend::BlendFactor::ONE;
|
||||
blendDescriptor.destinationRGBBlendFactor = backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||
blendDescriptor.sourceAlphaBlendFactor = backend::BlendFactor::ONE;
|
||||
blendDescriptor.destinationAlphaBlendFactor = backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LabelLetter used to update the quad in texture atlas without SpriteBatchNode.
|
||||
*/
|
||||
|
@ -173,6 +198,28 @@ private:
|
|||
bool _letterVisible;
|
||||
};
|
||||
|
||||
Label::BatchCommand::BatchCommand()
|
||||
{
|
||||
textCommand.setDrawType(CustomCommand::DrawType::ELEMENT);
|
||||
textCommand.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE);
|
||||
shadowCommand.setDrawType(CustomCommand::DrawType::ELEMENT);
|
||||
shadowCommand.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE);
|
||||
outLineCommand.setDrawType(CustomCommand::DrawType::ELEMENT);
|
||||
outLineCommand.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE);
|
||||
}
|
||||
|
||||
Label::BatchCommand::~BatchCommand()
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(textCommand.getPipelineDescriptor().programState);
|
||||
CC_SAFE_RELEASE_NULL(shadowCommand.getPipelineDescriptor().programState);
|
||||
CC_SAFE_RELEASE_NULL(outLineCommand.getPipelineDescriptor().programState);
|
||||
}
|
||||
|
||||
std::array<CustomCommand*, 3> Label::BatchCommand::getCommandArray()
|
||||
{
|
||||
return std::array<CustomCommand*, 3>{&textCommand, &shadowCommand, &outLineCommand};
|
||||
}
|
||||
|
||||
Label* Label::create()
|
||||
{
|
||||
auto ret = new (std::nothrow) Label;
|
||||
|
@ -398,6 +445,7 @@ Label::Label(TextHAlignment hAlignment /* = TextHAlignment::LEFT */,
|
|||
it.second->setTexture(nullptr);
|
||||
}
|
||||
_batchNodes.clear();
|
||||
_batchCommands.clear();
|
||||
|
||||
if (_fontAtlas)
|
||||
{
|
||||
|
@ -437,6 +485,7 @@ Label::~Label()
|
|||
_batchNodes.clear();
|
||||
FontAtlasCache::releaseFontAtlas(_fontAtlas);
|
||||
}
|
||||
_batchCommands.clear();
|
||||
_eventDispatcher->removeEventListener(_purgeTextureListener);
|
||||
_eventDispatcher->removeEventListener(_resetTextureListener);
|
||||
|
||||
|
@ -454,6 +503,7 @@ void Label::reset()
|
|||
CC_SAFE_RELEASE_NULL(_reusedLetter);
|
||||
_letters.clear();
|
||||
_batchNodes.clear();
|
||||
_batchCommands.clear();
|
||||
_lettersInfo.clear();
|
||||
if (_fontAtlas)
|
||||
{
|
||||
|
@ -563,9 +613,7 @@ void Label::setVertexLayout(PipelineDescriptor& pipelineDescriptor)
|
|||
layout.setAtrribute("a_color", iter->second.location, backend::VertexFormat::UBYTE4, offsetof(V3F_C4B_T2F, colors), true);
|
||||
}
|
||||
layout.setLayout(sizeof(V3F_C4B_T2F), backend::VertexStepMode::VERTEX);
|
||||
|
||||
_customCommand.setDrawType(CustomCommand::DrawType::ELEMENT);
|
||||
_customCommand.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE);
|
||||
|
||||
}
|
||||
|
||||
void Label::setProgramState(backend::ProgramState *programState)
|
||||
|
@ -576,11 +624,15 @@ void Label::setProgramState(backend::ProgramState *programState)
|
|||
_programState = programState;
|
||||
CC_SAFE_RETAIN(programState);
|
||||
}
|
||||
|
||||
auto &pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
pipelineDescriptor.programState = programState;
|
||||
updateUniformLocations();
|
||||
setVertexLayout(pipelineDescriptor);
|
||||
for (auto &batch : _batchCommands)
|
||||
{
|
||||
updateBatchCommand(batch);
|
||||
}
|
||||
|
||||
auto &quadPipeline = _quadCommand.getPipelineDescriptor();
|
||||
setVertexLayout(quadPipeline);
|
||||
quadPipeline.programState = _programState;
|
||||
}
|
||||
|
||||
void Label::updateShaderProgram()
|
||||
|
@ -649,23 +701,51 @@ void Label::updateShaderProgram()
|
|||
return;
|
||||
}
|
||||
}
|
||||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
|
||||
CC_SAFE_RELEASE(_programState);
|
||||
_programState = new (std::nothrow) backend::ProgramState(vert, frag);
|
||||
pipelineDescriptor.programState = _programState;
|
||||
_programState = new backend::ProgramState(vert, frag);
|
||||
|
||||
updateUniformLocations();
|
||||
|
||||
for (auto &batch : _batchCommands)
|
||||
{
|
||||
updateBatchCommand(batch);
|
||||
}
|
||||
|
||||
auto &quadPipeline = _quadCommand.getPipelineDescriptor();
|
||||
setVertexLayout(quadPipeline);
|
||||
quadPipeline.programState = _programState;
|
||||
}
|
||||
|
||||
void Label::updateBatchCommand(Label::BatchCommand &batch)
|
||||
{
|
||||
CCASSERT(_programState, "programState should be set!");
|
||||
|
||||
auto& pipelineDescriptor = batch.textCommand.getPipelineDescriptor();
|
||||
CC_SAFE_RELEASE_NULL(pipelineDescriptor.programState);
|
||||
pipelineDescriptor.programState = _programState->clone();
|
||||
setVertexLayout(pipelineDescriptor);
|
||||
|
||||
auto &pipelineShadow = batch.shadowCommand.getPipelineDescriptor();
|
||||
CC_SAFE_RELEASE_NULL(pipelineShadow.programState);
|
||||
pipelineShadow.programState = _programState->clone();;
|
||||
setVertexLayout(pipelineShadow);
|
||||
|
||||
auto &pipelineOutline = batch.outLineCommand.getPipelineDescriptor();
|
||||
CC_SAFE_RELEASE_NULL(pipelineOutline.programState);
|
||||
pipelineOutline.programState = _programState->clone();
|
||||
setVertexLayout(pipelineOutline);
|
||||
|
||||
}
|
||||
|
||||
void Label::updateUniformLocations()
|
||||
{
|
||||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
_mvpMatrixLocation = pipelineDescriptor.programState->getUniformLocation("u_MVPMatrix");
|
||||
_textureLocation = pipelineDescriptor.programState->getUniformLocation("u_texture");
|
||||
_alphaTextureLocation = pipelineDescriptor.programState->getUniformLocation("u_texture1");
|
||||
_textColorLocation = pipelineDescriptor.programState->getUniformLocation("u_textColor");
|
||||
_effectColorLocation = pipelineDescriptor.programState->getUniformLocation("u_effectColor");
|
||||
_effectTypeLocation = pipelineDescriptor.programState->getUniformLocation("u_effectType");
|
||||
_mvpMatrixLocation = _programState->getUniformLocation("u_MVPMatrix");
|
||||
_textureLocation = _programState->getUniformLocation("u_texture");
|
||||
_alphaTextureLocation = _programState->getUniformLocation("u_texture1");
|
||||
_textColorLocation = _programState->getUniformLocation("u_textColor");
|
||||
_effectColorLocation = _programState->getUniformLocation("u_effectColor");
|
||||
_effectTypeLocation = _programState->getUniformLocation("u_effectType");
|
||||
}
|
||||
|
||||
void Label::setFontAtlas(FontAtlas* atlas,bool distanceFieldEnabled /* = false */, bool useA8Shader /* = false */)
|
||||
|
@ -1434,6 +1514,7 @@ void Label::updateContent()
|
|||
if (_fontAtlas)
|
||||
{
|
||||
_batchNodes.clear();
|
||||
_batchCommands.clear();
|
||||
CC_SAFE_RELEASE_NULL(_reusedLetter);
|
||||
FontAtlasCache::releaseFontAtlas(_fontAtlas);
|
||||
_fontAtlas = nullptr;
|
||||
|
@ -1539,27 +1620,25 @@ void Label::updateBuffer(TextureAtlas* textureAtlas, CustomCommand& customComman
|
|||
if (textureAtlas->getTotalQuads() > customCommand.getVertexCapacity())
|
||||
{
|
||||
customCommand.createVertexBuffer((unsigned int)sizeof(V3F_C4B_T2F_Quad), (unsigned int)textureAtlas->getTotalQuads(), CustomCommand::BufferUsage::DYNAMIC);
|
||||
customCommand.createIndexBuffer(CustomCommand::IndexFormat::U_SHORT, (unsigned int)textureAtlas->getTotalQuads()*6, CustomCommand::BufferUsage::DYNAMIC);
|
||||
customCommand.createIndexBuffer(CustomCommand::IndexFormat::U_SHORT, (unsigned int)textureAtlas->getTotalQuads() * 6, CustomCommand::BufferUsage::DYNAMIC);
|
||||
}
|
||||
customCommand.updateVertexBuffer(textureAtlas->getQuads(), (unsigned int)(textureAtlas->getTotalQuads() * sizeof(V3F_C4B_T2F_Quad)) );
|
||||
customCommand.updateIndexBuffer(textureAtlas->getIndices(), (unsigned int)(textureAtlas->getTotalQuads()*6*sizeof(unsigned short)) );
|
||||
customCommand.setIndexDrawInfo(0, (unsigned int)(textureAtlas->getTotalQuads()*6));
|
||||
customCommand.updateVertexBuffer(textureAtlas->getQuads(), (unsigned int)(textureAtlas->getTotalQuads() * sizeof(V3F_C4B_T2F_Quad)));
|
||||
customCommand.updateIndexBuffer(textureAtlas->getIndices(), (unsigned int)(textureAtlas->getTotalQuads() * 6 * sizeof(unsigned short)));
|
||||
customCommand.setIndexDrawInfo(0, (unsigned int)(textureAtlas->getTotalQuads() * 6));
|
||||
}
|
||||
|
||||
void Label::updateEffectUniforms(TextureAtlas* textureAtlas, Renderer *renderer, const Mat4 &transform)
|
||||
void Label::updateEffectUniforms(BatchCommand &batch, TextureAtlas* textureAtlas, Renderer *renderer, const Mat4 &transform)
|
||||
{
|
||||
updateBuffer(textureAtlas, _customCommand);
|
||||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
updateBuffer(textureAtlas, batch.textCommand);
|
||||
|
||||
auto & matrixProjection = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||
|
||||
if (_shadowEnabled) {
|
||||
updateBuffer(textureAtlas, _customCommandShadow);
|
||||
auto& pipelineShadow = _customCommandShadow.getPipelineDescriptor();
|
||||
pipelineShadow = pipelineDescriptor;
|
||||
pipelineShadow.programState = pipelineDescriptor.programState;
|
||||
const auto& matrixP = _director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||
Mat4 matrixMVP = matrixP * _shadowTransform;
|
||||
pipelineShadow.programState->setUniform(_mvpMatrixLocation, matrixMVP.m, sizeof(matrixMVP.m));
|
||||
updateBuffer(textureAtlas, batch.shadowCommand);
|
||||
auto shadowMatrix = matrixProjection * _shadowTransform;
|
||||
batch.shadowCommand.getPipelineDescriptor().programState->setUniform(_mvpMatrixLocation, shadowMatrix.m, sizeof(shadowMatrix.m));
|
||||
}
|
||||
|
||||
|
||||
if(_currentLabelType == LabelType::TTF)
|
||||
{
|
||||
switch (_currLabelEffect) {
|
||||
|
@ -1572,43 +1651,43 @@ void Label::updateEffectUniforms(TextureAtlas* textureAtlas, Renderer *renderer,
|
|||
if(_shadowEnabled)
|
||||
{
|
||||
effectType = 2;
|
||||
auto& pipelineShadow = _customCommandShadow.getPipelineDescriptor();
|
||||
Vec4 shadowColor = Vec4(_shadowColor4F.r, _shadowColor4F.g, _shadowColor4F.b, _shadowColor4F.a);
|
||||
pipelineShadow.programState->setUniform(_effectColorLocation, &shadowColor, sizeof(Vec4));
|
||||
pipelineShadow.programState->setUniform(_effectTypeLocation, &effectType, sizeof(effectType));
|
||||
_customCommandShadow.init(_globalZOrder);
|
||||
renderer->addCommand(&_customCommandShadow);
|
||||
auto *programStateShadow = batch.shadowCommand.getPipelineDescriptor().programState;
|
||||
programStateShadow->setUniform(_effectColorLocation, &shadowColor, sizeof(Vec4));
|
||||
programStateShadow->setUniform(_effectTypeLocation, &effectType, sizeof(effectType));
|
||||
batch.shadowCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&batch.shadowCommand);
|
||||
}
|
||||
|
||||
//draw outline
|
||||
{
|
||||
effectType = 1;
|
||||
updateBuffer(textureAtlas, _customCommandOutLine);
|
||||
auto& pipelineOutline = _customCommandOutLine.getPipelineDescriptor();
|
||||
pipelineOutline = pipelineDescriptor;
|
||||
pipelineOutline.programState = pipelineDescriptor.programState;
|
||||
pipelineOutline.programState->setUniform(_effectColorLocation, &effectColor, sizeof(Vec4));
|
||||
pipelineOutline.programState->setUniform(_effectTypeLocation, &effectType, sizeof(effectType));
|
||||
_customCommandOutLine.init(_globalZOrder);
|
||||
renderer->addCommand(&_customCommandOutLine);
|
||||
updateBuffer(textureAtlas, batch.outLineCommand);
|
||||
auto *programStateOutline = batch.outLineCommand.getPipelineDescriptor().programState;
|
||||
programStateOutline->setUniform(_effectColorLocation, &effectColor, sizeof(Vec4));
|
||||
programStateOutline->setUniform(_effectTypeLocation, &effectType, sizeof(effectType));
|
||||
batch.outLineCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&batch.outLineCommand);
|
||||
}
|
||||
|
||||
//draw text
|
||||
{
|
||||
effectType = 0;
|
||||
pipelineDescriptor.programState->setUniform(_effectColorLocation, &effectColor, sizeof(Vec4));
|
||||
pipelineDescriptor.programState->setUniform(_effectTypeLocation, &effectType, sizeof(effectType));
|
||||
auto *programStateText= batch.textCommand.getPipelineDescriptor().programState;
|
||||
|
||||
programStateText->setUniform(_effectColorLocation, &effectColor, sizeof(effectColor));
|
||||
programStateText->setUniform(_effectTypeLocation, &effectType, sizeof(effectType));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LabelEffect::NORMAL:
|
||||
{
|
||||
if (_shadowEnabled) {
|
||||
auto& pipelineShadow = _customCommandShadow.getPipelineDescriptor();
|
||||
Vec4 shadowColor = Vec4(_shadowColor4F.r, _shadowColor4F.g, _shadowColor4F.b, _shadowColor4F.a);
|
||||
pipelineShadow.programState->setUniform(_textColorLocation, &shadowColor, sizeof(Vec4));
|
||||
_customCommandShadow.init(_globalZOrder);
|
||||
renderer->addCommand(&_customCommandShadow);
|
||||
auto *programStateShadow = batch.shadowCommand.getPipelineDescriptor().programState;
|
||||
programStateShadow->setUniform(_textColorLocation, &shadowColor, sizeof(Vec4));
|
||||
batch.shadowCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&batch.shadowCommand);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1617,16 +1696,16 @@ void Label::updateEffectUniforms(TextureAtlas* textureAtlas, Renderer *renderer,
|
|||
//draw shadow
|
||||
if(_shadowEnabled)
|
||||
{
|
||||
auto& pipelineShadow = _customCommandShadow.getPipelineDescriptor();
|
||||
Vec4 shadowColor = Vec4(_shadowColor4F.r, _shadowColor4F.g, _shadowColor4F.b, _shadowColor4F.a);
|
||||
pipelineShadow.programState->setUniform(_textColorLocation, &shadowColor, sizeof(Vec4));
|
||||
pipelineShadow.programState->setUniform(_effectColorLocation, &shadowColor, sizeof(Vec4));
|
||||
_customCommandShadow.init(_globalZOrder);
|
||||
renderer->addCommand(&_customCommandShadow);
|
||||
auto *programStateShadow = batch.shadowCommand.getPipelineDescriptor().programState;
|
||||
programStateShadow->setUniform(_textColorLocation, &shadowColor, sizeof(Vec4));
|
||||
programStateShadow->setUniform(_effectColorLocation, &shadowColor, sizeof(Vec4));
|
||||
batch.shadowCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&batch.shadowCommand);
|
||||
}
|
||||
|
||||
Vec4 effectColor(_effectColorF.r, _effectColorF.g, _effectColorF.b, _effectColorF.a);
|
||||
pipelineDescriptor.programState->setUniform(_effectColorLocation, &effectColor, sizeof(Vec4));
|
||||
batch.textCommand.getPipelineDescriptor().programState->setUniform(_effectColorLocation, &effectColor, sizeof(Vec4));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -1640,17 +1719,17 @@ void Label::updateEffectUniforms(TextureAtlas* textureAtlas, Renderer *renderer,
|
|||
GLubyte oldOPacity = _displayedOpacity;
|
||||
_displayedOpacity = _shadowColor4F.a * (oldOPacity / 255.0f) * 255;
|
||||
setColor(Color3B(_shadowColor4F));
|
||||
_customCommandShadow.updateVertexBuffer(textureAtlas->getQuads(), (unsigned int)(textureAtlas->getTotalQuads() * sizeof(V3F_C4B_T2F_Quad)) );
|
||||
_customCommandShadow.init(_globalZOrder);
|
||||
renderer->addCommand(&_customCommandShadow);
|
||||
batch.shadowCommand.updateVertexBuffer(textureAtlas->getQuads(), (unsigned int)(textureAtlas->getTotalQuads() * sizeof(V3F_C4B_T2F_Quad)) );
|
||||
batch.shadowCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&batch.shadowCommand);
|
||||
|
||||
_displayedOpacity = oldOPacity;
|
||||
setColor(oldColor);
|
||||
}
|
||||
}
|
||||
|
||||
_customCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&_customCommand);
|
||||
batch.textCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&batch.textCommand);
|
||||
}
|
||||
|
||||
void Label::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
||||
|
@ -1675,11 +1754,10 @@ void Label::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
if (_insideBounds)
|
||||
#endif
|
||||
{
|
||||
updateBlendState();
|
||||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
cocos2d::Mat4 matrixProjection = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||
if (!_shadowEnabled && (_currentLabelType == LabelType::BMFONT || _currentLabelType == LabelType::CHARMAP))
|
||||
{
|
||||
updateBlendState();
|
||||
for (auto&& it : _letters)
|
||||
{
|
||||
it.second->updateTransform();
|
||||
|
@ -1691,8 +1769,6 @@ void Label::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
|
||||
auto texture = textureAtlas->getTexture();
|
||||
auto& pipelineQuad = _quadCommand.getPipelineDescriptor();
|
||||
pipelineQuad = pipelineDescriptor;
|
||||
pipelineQuad.programState = pipelineDescriptor.programState;
|
||||
pipelineQuad.programState->setUniform(_mvpMatrixLocation, matrixProjection.m, sizeof(matrixProjection.m));
|
||||
pipelineQuad.programState->setTexture(_textureLocation, 0, texture->getBackendTexture());
|
||||
auto alphaTexture = textureAtlas->getTexture()->getAlphaTexture();
|
||||
|
@ -1705,23 +1781,45 @@ void Label::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
}
|
||||
else
|
||||
{
|
||||
cocos2d::Mat4 matrixMVP = matrixProjection * transform;
|
||||
|
||||
for (auto &&it : _letters)
|
||||
{
|
||||
it.second->updateTransform();
|
||||
}
|
||||
int i = 0;
|
||||
|
||||
if (_batchCommands.size() != _batchNodes.size())
|
||||
{
|
||||
_batchCommands.resize(_batchNodes.size());
|
||||
updateShaderProgram();
|
||||
}
|
||||
|
||||
updateBlendState();
|
||||
|
||||
for (auto&& batchNode : _batchNodes)
|
||||
{
|
||||
auto textureAtlas = batchNode->getTextureAtlas();
|
||||
if(!textureAtlas->getTotalQuads())
|
||||
if (!textureAtlas->getTotalQuads())
|
||||
return;
|
||||
|
||||
cocos2d::Mat4 matrixMVP = matrixProjection * transform;
|
||||
pipelineDescriptor.programState->setUniform(_mvpMatrixLocation, matrixMVP.m, sizeof(matrixMVP.m));
|
||||
Vec4 textColor(_textColorF.r, _textColorF.g, _textColorF.b, _textColorF.a);
|
||||
pipelineDescriptor.programState->setUniform(_textColorLocation, &textColor, sizeof(Vec4));
|
||||
pipelineDescriptor.programState->setTexture(_textureLocation, 0, textureAtlas->getTexture()->getBackendTexture());
|
||||
auto alphaTexture = textureAtlas->getTexture()->getAlphaTexture();
|
||||
if(alphaTexture && alphaTexture->getBackendTexture())
|
||||
|
||||
auto &batch = _batchCommands[i++];
|
||||
auto &&commands = batch.getCommandArray();
|
||||
for (auto command : commands)
|
||||
{
|
||||
pipelineDescriptor.programState->setTexture(_alphaTextureLocation, 1, alphaTexture->getBackendTexture());
|
||||
auto *programState = command->getPipelineDescriptor().programState;
|
||||
Vec4 textColor(_textColorF.r, _textColorF.g, _textColorF.b, _textColorF.a);
|
||||
programState->setUniform(_textColorLocation, &textColor, sizeof(Vec4));
|
||||
programState->setTexture(_textureLocation, 0, textureAtlas->getTexture()->getBackendTexture());
|
||||
auto alphaTexture = textureAtlas->getTexture()->getAlphaTexture();
|
||||
if (alphaTexture && alphaTexture->getBackendTexture())
|
||||
{
|
||||
programState->setTexture(_alphaTextureLocation, 1, alphaTexture->getBackendTexture());
|
||||
}
|
||||
}
|
||||
updateEffectUniforms(textureAtlas, renderer, transform);
|
||||
batch.textCommand.getPipelineDescriptor().programState->setUniform(_mvpMatrixLocation, matrixMVP.m, sizeof(matrixMVP.m));
|
||||
batch.outLineCommand.getPipelineDescriptor().programState->setUniform(_mvpMatrixLocation, matrixMVP.m, sizeof(matrixMVP.m));
|
||||
updateEffectUniforms(batch, textureAtlas, renderer, transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1729,24 +1827,15 @@ void Label::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
|
||||
void Label::updateBlendState()
|
||||
{
|
||||
backend::BlendDescriptor& blendDescriptor = _customCommand.getPipelineDescriptor().blendDescriptor;
|
||||
blendDescriptor.blendEnabled = true;
|
||||
if (_blendFunc == BlendFunc::ALPHA_NON_PREMULTIPLIED)
|
||||
setOpacityModifyRGB(_blendFunc != BlendFunc::ALPHA_NON_PREMULTIPLIED);
|
||||
for(auto &batch: _batchCommands)
|
||||
{
|
||||
blendDescriptor.sourceRGBBlendFactor = backend::BlendFactor::SRC_ALPHA;
|
||||
blendDescriptor.destinationRGBBlendFactor = backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||
blendDescriptor.sourceAlphaBlendFactor = backend::BlendFactor::SRC_ALPHA;
|
||||
blendDescriptor.destinationAlphaBlendFactor = backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||
setOpacityModifyRGB(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
blendDescriptor.sourceRGBBlendFactor = backend::BlendFactor::ONE;
|
||||
blendDescriptor.destinationRGBBlendFactor = backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||
blendDescriptor.sourceAlphaBlendFactor = backend::BlendFactor::ONE;
|
||||
blendDescriptor.destinationAlphaBlendFactor = backend::BlendFactor::ONE_MINUS_SRC_ALPHA;
|
||||
setOpacityModifyRGB(true);
|
||||
for(auto *command : batch.getCommandArray()) {
|
||||
auto & blendDescriptor = command->getPipelineDescriptor().blendDescriptor;
|
||||
updateBlend(blendDescriptor, _blendFunc);
|
||||
}
|
||||
}
|
||||
updateBlend(_quadCommand.getPipelineDescriptor().blendDescriptor, _blendFunc);
|
||||
}
|
||||
|
||||
void Label::visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t parentFlags)
|
||||
|
|
|
@ -647,6 +647,17 @@ protected:
|
|||
int lineIndex;
|
||||
};
|
||||
|
||||
struct BatchCommand {
|
||||
BatchCommand();
|
||||
~BatchCommand();
|
||||
|
||||
CustomCommand textCommand;
|
||||
CustomCommand outLineCommand;
|
||||
CustomCommand shadowCommand;
|
||||
|
||||
std::array<CustomCommand*, 3> getCommandArray();
|
||||
};
|
||||
|
||||
virtual void setFontAtlas(FontAtlas* atlas, bool distanceFieldEnabled = false, bool useA8Shader = false);
|
||||
bool getFontLetterDef(char32_t character, FontLetterDefinition& letterDef) const;
|
||||
|
||||
|
@ -695,9 +706,11 @@ protected:
|
|||
void updateUniformLocations();
|
||||
void setVertexLayout(PipelineDescriptor& vertexLayout);
|
||||
void updateBlendState();
|
||||
void updateEffectUniforms(TextureAtlas* textureAtlas, Renderer *renderer, const Mat4 &transform);
|
||||
void updateEffectUniforms(BatchCommand &batch, TextureAtlas* textureAtlas, Renderer *renderer, const Mat4 &transform);
|
||||
void updateBuffer(TextureAtlas* textureAtlas, CustomCommand& customCommand);
|
||||
|
||||
void updateBatchCommand(BatchCommand &batch);
|
||||
|
||||
LabelType _currentLabelType;
|
||||
bool _contentDirty;
|
||||
std::u32string _utf32Text;
|
||||
|
@ -749,9 +762,8 @@ protected:
|
|||
Color4F _textColorF;
|
||||
|
||||
QuadCommand _quadCommand;
|
||||
CustomCommand _customCommand;
|
||||
CustomCommand _customCommandOutLine;
|
||||
CustomCommand _customCommandShadow;
|
||||
|
||||
std::vector<BatchCommand> _batchCommands;
|
||||
|
||||
Mat4 _shadowTransform;
|
||||
GLint _uniformEffectColor;
|
||||
|
|
Loading…
Reference in New Issue