[bugfix] fix label effects (#19554)

This commit is contained in:
Arnold 2019-04-02 14:56:29 +08:00 committed by minggo
parent 45183919e9
commit d6614cc0da
4 changed files with 230 additions and 111 deletions

View File

@ -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];

View File

@ -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.
*

View File

@ -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)

View File

@ -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;