mirror of https://github.com/axmolengine/axmol.git
v4-meta-multi-textures support Single Texture2D with multi GPU texture handlers.
This commit is contained in:
parent
72d605dc15
commit
e7906acfa4
|
@ -118,7 +118,8 @@ bool AtlasNode::initWithTexture(Texture2D* texture, int tileWidth, int tileHeigh
|
|||
}
|
||||
|
||||
_textureAtlas->initWithTexture(texture, itemsToRender);
|
||||
|
||||
|
||||
updateProgramStateTexture(texture);
|
||||
this->updateBlendFunc();
|
||||
this->updateOpacityModifyRGB();
|
||||
|
||||
|
@ -157,8 +158,7 @@ void AtlasNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
return;
|
||||
|
||||
auto programState = _quadCommand.getPipelineDescriptor().programState;
|
||||
programState->setTexture(_textureLocation, 0, _textureAtlas->getTexture()->getBackendTexture());
|
||||
|
||||
|
||||
const auto& projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||
programState->setUniform(_mvpMatrixLocation, projectionMat.m, sizeof(projectionMat.m));
|
||||
|
||||
|
@ -251,6 +251,8 @@ void AtlasNode::updateBlendFunc()
|
|||
void AtlasNode::setTexture(Texture2D *texture)
|
||||
{
|
||||
_textureAtlas->setTexture(texture);
|
||||
updateProgramStateTexture(texture);
|
||||
|
||||
this->updateBlendFunc();
|
||||
this->updateOpacityModifyRGB();
|
||||
}
|
||||
|
|
|
@ -143,7 +143,6 @@ protected:
|
|||
QuadCommand _quadCommand;
|
||||
backend::UniformLocation _textureLocation;
|
||||
backend::UniformLocation _mvpMatrixLocation;
|
||||
backend::ProgramState* _programState = nullptr;
|
||||
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(AtlasNode);
|
||||
|
|
|
@ -336,7 +336,6 @@ protected:
|
|||
|
||||
BlendFunc _blendFunc;
|
||||
|
||||
backend::ProgramState* _programState = nullptr;
|
||||
backend::ProgramState* _programStatePoint = nullptr;
|
||||
backend::ProgramState* _programStateLine = nullptr;
|
||||
|
||||
|
|
|
@ -354,7 +354,6 @@ protected:
|
|||
backend::UniformLocation _mvpMatrixLocaiton;
|
||||
backend::UniformLocation _textureLocation;
|
||||
backend::UniformLocation _alphaValueLocation;
|
||||
backend::ProgramState* _programState = nullptr;
|
||||
};
|
||||
|
||||
// end of tilemap_parallax_nodes group
|
||||
|
|
|
@ -485,12 +485,12 @@ void FontAtlas::updateTextureContent(backend::PixelFormat format, int startY)
|
|||
_currentPageDataRGBA[i*4] = data[i*2];
|
||||
_currentPageDataRGBA[i*4+3] = data[i*2+1];
|
||||
}
|
||||
_atlasTextures[_currentPage]->updateWithData(_currentPageDataRGBA, 0, startY, CacheTextureWidth, (int)_currentPageOrigY - startY + _currLineHeight);
|
||||
_atlasTextures[_currentPage]->updateWithSubData(_currentPageDataRGBA, 0, startY, CacheTextureWidth, (int)_currentPageOrigY - startY + _currLineHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = _currentPageData + CacheTextureWidth * (int)startY;
|
||||
_atlasTextures[_currentPage]->updateWithData(data, 0, startY, CacheTextureWidth, (int)_currentPageOrigY - startY + _currLineHeight);
|
||||
_atlasTextures[_currentPage]->updateWithSubData(data, 0, startY, CacheTextureWidth, (int)_currentPageOrigY - startY + _currLineHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "2d/CCFontFNT.h"
|
||||
#include "renderer/ccShaders.h"
|
||||
#include "renderer/backend/ProgramState.h"
|
||||
#include "renderer/backend/ProgramStateRegistry.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -644,9 +645,9 @@ void Label::updateShaderProgram()
|
|||
if (_currentLabelType == LabelType::BMFONT || _currentLabelType == LabelType::CHARMAP)
|
||||
{
|
||||
auto texture = _getTexture(this);
|
||||
if(texture && texture->getAlphaTextureName())
|
||||
if(texture)
|
||||
{
|
||||
programType = backend::ProgramType::ETC1;
|
||||
programType = backend::ProgramStateRegistry::getInstance()->getProgramType(programType, texture->getBackendTexture());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -665,9 +666,9 @@ void Label::updateShaderProgram()
|
|||
else
|
||||
{
|
||||
auto texture = _getTexture(this);
|
||||
if(texture && texture->getAlphaTextureName())
|
||||
if(texture)
|
||||
{
|
||||
programType = backend::ProgramType::ETC1;
|
||||
programType = backend::ProgramStateRegistry::getInstance()->getProgramType(programType, texture->getBackendTexture());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -728,7 +729,6 @@ void Label::updateUniformLocations()
|
|||
{
|
||||
_mvpMatrixLocation = _programState->getUniformLocation(backend::Uniform::MVP_MATRIX);
|
||||
_textureLocation = _programState->getUniformLocation(backend::Uniform::TEXTURE);
|
||||
_alphaTextureLocation = _programState->getUniformLocation(backend::Uniform::TEXTURE1);
|
||||
_textColorLocation = _programState->getUniformLocation(backend::Uniform::TEXT_COLOR);
|
||||
_effectColorLocation = _programState->getUniformLocation(backend::Uniform::EFFECT_COLOR);
|
||||
_effectTypeLocation = _programState->getUniformLocation(backend::Uniform::EFFECT_TYPE);
|
||||
|
@ -1756,12 +1756,7 @@ void Label::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
auto texture = textureAtlas->getTexture();
|
||||
auto& pipelineQuad = _quadCommand.getPipelineDescriptor();
|
||||
pipelineQuad.programState->setUniform(_mvpMatrixLocation, matrixProjection.m, sizeof(matrixProjection.m));
|
||||
pipelineQuad.programState->setTexture(_textureLocation, 0, texture->getBackendTexture());
|
||||
auto alphaTexture = textureAtlas->getTexture()->getAlphaTexture();
|
||||
if(alphaTexture && alphaTexture->getBackendTexture())
|
||||
{
|
||||
pipelineQuad.programState->setTexture(_alphaTextureLocation, 1, alphaTexture->getBackendTexture());
|
||||
}
|
||||
pipelineQuad.programState->setTexture(texture->getBackendTexture());
|
||||
_quadCommand.init(_globalZOrder, texture, _blendFunc, textureAtlas->getQuads(), textureAtlas->getTotalQuads(), transform, flags);
|
||||
renderer->addCommand(&_quadCommand);
|
||||
}
|
||||
|
@ -1796,12 +1791,7 @@ void Label::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
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());
|
||||
}
|
||||
programState->setTexture(textureAtlas->getTexture()->getBackendTexture());
|
||||
}
|
||||
batch.textCommand.getPipelineDescriptor().programState->setUniform(_mvpMatrixLocation, matrixMVP.m, sizeof(matrixMVP.m));
|
||||
batch.outLineCommand.getPipelineDescriptor().programState->setUniform(_mvpMatrixLocation, matrixMVP.m, sizeof(matrixMVP.m));
|
||||
|
|
|
@ -811,12 +811,9 @@ protected:
|
|||
|
||||
backend::UniformLocation _mvpMatrixLocation;
|
||||
backend::UniformLocation _textureLocation;
|
||||
backend::UniformLocation _alphaTextureLocation;
|
||||
backend::UniformLocation _textColorLocation;
|
||||
backend::UniformLocation _effectColorLocation;
|
||||
backend::UniformLocation _effectTypeLocation;
|
||||
|
||||
backend::ProgramState* _programState = nullptr;
|
||||
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(Label);
|
||||
|
|
|
@ -278,7 +278,6 @@ protected:
|
|||
V3F_C4F _vertexData[4];
|
||||
|
||||
backend::UniformLocation _mvpMatrixLocation;
|
||||
backend::ProgramState* _programState = nullptr;
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(LayerColor);
|
||||
|
||||
|
|
|
@ -40,32 +40,6 @@ MotionStreak::MotionStreak()
|
|||
{
|
||||
_customCommand.setDrawType(CustomCommand::DrawType::ARRAY);
|
||||
_customCommand.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE_STRIP);
|
||||
|
||||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
auto* program = backend::Program::getBuiltinProgram(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
_programState = new (std::nothrow) backend::ProgramState(program);
|
||||
pipelineDescriptor.programState = _programState;
|
||||
_mvpMatrixLocaiton = pipelineDescriptor.programState->getUniformLocation("u_MVPMatrix");
|
||||
_textureLocation = pipelineDescriptor.programState->getUniformLocation("u_texture");
|
||||
|
||||
auto vertexLayout = _programState->getVertexLayout();
|
||||
const auto& attributeInfo = _programState->getProgram()->getActiveAttributes();
|
||||
auto iter = attributeInfo.find("a_position");
|
||||
if(iter != attributeInfo.end())
|
||||
{
|
||||
vertexLayout->setAttribute("a_position", iter->second.location, backend::VertexFormat::FLOAT2, 0, false);
|
||||
}
|
||||
iter = attributeInfo.find("a_texCoord");
|
||||
if(iter != attributeInfo.end())
|
||||
{
|
||||
vertexLayout->setAttribute("a_texCoord", iter->second.location, backend::VertexFormat::FLOAT2, 2 * sizeof(float), false);
|
||||
}
|
||||
iter = attributeInfo.find("a_color");
|
||||
if(iter != attributeInfo.end())
|
||||
{
|
||||
vertexLayout->setAttribute("a_color", iter->second.location, backend::VertexFormat::UBYTE4, 4 * sizeof(float), true);
|
||||
}
|
||||
vertexLayout->setLayout(4 * sizeof(float) + 4 * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
MotionStreak::~MotionStreak()
|
||||
|
@ -236,9 +210,49 @@ void MotionStreak::setTexture(Texture2D *texture)
|
|||
CC_SAFE_RETAIN(texture);
|
||||
CC_SAFE_RELEASE(_texture);
|
||||
_texture = texture;
|
||||
|
||||
setProgramStateWithRegistry(backend::ProgramType::POSITION_TEXTURE_COLOR, _texture);
|
||||
|
||||
if (_texture)
|
||||
_programState->setTexture(_texture->getBackendTexture());
|
||||
}
|
||||
}
|
||||
|
||||
void MotionStreak::setProgramState(backend::ProgramState* programState)
|
||||
{
|
||||
CCASSERT(programState, "argument should not be nullptr");
|
||||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
if (_programState != programState)
|
||||
{
|
||||
CC_SAFE_RELEASE(_programState);
|
||||
_programState = programState;
|
||||
CC_SAFE_RETAIN(programState);
|
||||
}
|
||||
pipelineDescriptor.programState = _programState;
|
||||
|
||||
_mvpMatrixLocaiton = _programState->getUniformLocation("u_MVPMatrix");
|
||||
_textureLocation = _programState->getUniformLocation("u_texture");
|
||||
|
||||
auto vertexLayout = _programState->getVertexLayout();
|
||||
const auto& attributeInfo = _programState->getProgram()->getActiveAttributes();
|
||||
auto iter = attributeInfo.find("a_position");
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
vertexLayout->setAttribute("a_position", iter->second.location, backend::VertexFormat::FLOAT2, 0, false);
|
||||
}
|
||||
iter = attributeInfo.find("a_texCoord");
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
vertexLayout->setAttribute("a_texCoord", iter->second.location, backend::VertexFormat::FLOAT2, 2 * sizeof(float), false);
|
||||
}
|
||||
iter = attributeInfo.find("a_color");
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
vertexLayout->setAttribute("a_color", iter->second.location, backend::VertexFormat::UBYTE4, 4 * sizeof(float), true);
|
||||
}
|
||||
vertexLayout->setLayout(4 * sizeof(float) + 4 * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
void MotionStreak::setBlendFunc(const BlendFunc &blendFunc)
|
||||
{
|
||||
_blendFunc = blendFunc;
|
||||
|
@ -398,7 +412,7 @@ void MotionStreak::draw(Renderer *renderer, const Mat4 &transform, uint32_t flag
|
|||
renderer->addCommand(&_customCommand);
|
||||
|
||||
auto programState = _customCommand.getPipelineDescriptor().programState;
|
||||
programState->setTexture(_textureLocation, 0, _texture->getBackendTexture());
|
||||
// programState->setTexture(_textureLocation, 0, _texture->getBackendTexture());
|
||||
|
||||
const auto& projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||
Mat4 finalMat = projectionMat * transform;
|
||||
|
|
|
@ -147,6 +147,8 @@ public:
|
|||
_startingPositionInitialized = bStartingPositionInitialized;
|
||||
}
|
||||
|
||||
void setProgramState(backend::ProgramState* programState) override;
|
||||
|
||||
CC_CONSTRUCTOR_ACCESS:
|
||||
MotionStreak();
|
||||
virtual ~MotionStreak();
|
||||
|
@ -187,7 +189,6 @@ protected:
|
|||
|
||||
backend::UniformLocation _mvpMatrixLocaiton;
|
||||
backend::UniformLocation _textureLocation;
|
||||
backend::ProgramState* _programState = nullptr;
|
||||
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(MotionStreak);
|
||||
|
|
|
@ -43,6 +43,7 @@ THE SOFTWARE.
|
|||
#include "2d/CCComponent.h"
|
||||
#include "renderer/CCMaterial.h"
|
||||
#include "math/TransformUtils.h"
|
||||
#include "renderer/backend/ProgramStateRegistry.h"
|
||||
|
||||
|
||||
#if CC_NODE_RENDER_SUBPIXEL
|
||||
|
@ -2181,6 +2182,20 @@ int Node::getAttachedNodeCount()
|
|||
return __attachedNodeCount;
|
||||
}
|
||||
|
||||
void Node::setProgramStateWithRegistry(backend::ProgramType programType, Texture2D* texture)
|
||||
{
|
||||
auto n = texture ? texture->getBackendTexture()->getCount() : 1;
|
||||
setProgramState(backend::ProgramStateRegistry::getInstance()->getProgramState(programType, n));
|
||||
}
|
||||
|
||||
void Node::updateProgramStateTexture(Texture2D* texture)
|
||||
{
|
||||
if (texture == nullptr || texture->getBackendTexture() == nullptr || _programState == nullptr)
|
||||
return;
|
||||
|
||||
_programState->setTexture(texture->getBackendTexture());
|
||||
}
|
||||
|
||||
void Node::setProgramState(backend::ProgramState* programState)
|
||||
{
|
||||
if (_programState != programState)
|
||||
|
|
|
@ -1768,6 +1768,10 @@ public:
|
|||
virtual void setCameraMask(unsigned short mask, bool applyChildren = true);
|
||||
|
||||
virtual void setProgramState(backend::ProgramState* programState);
|
||||
|
||||
void setProgramStateWithRegistry(backend::ProgramType programType, Texture2D* texture);
|
||||
void updateProgramStateTexture(Texture2D* texture);
|
||||
|
||||
virtual backend::ProgramState* getProgramState() const;
|
||||
|
||||
CC_CONSTRUCTOR_ACCESS:
|
||||
|
|
|
@ -441,7 +441,7 @@ void ParticleBatchNode::draw(Renderer* renderer, const Mat4 & transform, uint32_
|
|||
Mat4 finalMat = projectionMat * transform;
|
||||
auto programState = _customCommand.getPipelineDescriptor().programState;
|
||||
programState->setUniform(_mvpMatrixLocaiton, finalMat.m, sizeof(finalMat.m));
|
||||
programState->setTexture(_textureLocation, 0, _textureAtlas->getTexture()->getBackendTexture());
|
||||
// programState->setTexture(_textureLocation, 0, _textureAtlas->getTexture()->getBackendTexture());
|
||||
|
||||
if (_textureAtlas->isDirty())
|
||||
{
|
||||
|
@ -531,11 +531,14 @@ void ParticleBatchNode::updateBlendFunc()
|
|||
void ParticleBatchNode::setTexture(Texture2D* texture)
|
||||
{
|
||||
_textureAtlas->setTexture(texture);
|
||||
|
||||
// If the new texture has No premultiplied alpha, AND the blendFunc hasn't been changed, then update it
|
||||
if( texture && ! texture->hasPremultipliedAlpha() && ( _blendFunc.src == CC_BLEND_SRC && _blendFunc.dst == CC_BLEND_DST ) )
|
||||
{
|
||||
_blendFunc = BlendFunc::ALPHA_NON_PREMULTIPLIED;
|
||||
if (texture) {
|
||||
auto programState = _customCommand.getPipelineDescriptor().programState;
|
||||
programState->setTexture(_textureAtlas->getTexture()->getBackendTexture());
|
||||
// If the new texture has No premultiplied alpha, AND the blendFunc hasn't been changed, then update it
|
||||
if (!texture->hasPremultipliedAlpha() && (_blendFunc.src == CC_BLEND_SRC && _blendFunc.dst == CC_BLEND_DST))
|
||||
{
|
||||
_blendFunc = BlendFunc::ALPHA_NON_PREMULTIPLIED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -180,7 +180,6 @@ private:
|
|||
|
||||
backend::UniformLocation _mvpMatrixLocaiton;
|
||||
backend::UniformLocation _textureLocation;
|
||||
backend::ProgramState* _programState = nullptr;
|
||||
};
|
||||
|
||||
// end of _2d group
|
||||
|
|
|
@ -230,6 +230,9 @@ void ParticleSystemQuad::setTextureWithRect(Texture2D *texture, const Rect& rect
|
|||
if( !_texture || texture->getBackendTexture() != _texture->getBackendTexture() )
|
||||
{
|
||||
ParticleSystem::setTexture(texture);
|
||||
|
||||
auto programState = _quadCommand.getPipelineDescriptor().programState;
|
||||
programState->setTexture(_texture->getBackendTexture());
|
||||
}
|
||||
|
||||
this->initTexCoordsWithRect(rect);
|
||||
|
@ -446,7 +449,7 @@ void ParticleSystemQuad::draw(Renderer *renderer, const Mat4 &transform, uint32_
|
|||
if(_particleCount > 0)
|
||||
{
|
||||
auto programState = _quadCommand.getPipelineDescriptor().programState;
|
||||
programState->setTexture(_textureLocation, 0, _texture->getBackendTexture());
|
||||
// programState->setTexture(_textureLocation, 0, _texture->getBackendTexture());
|
||||
|
||||
cocos2d::Mat4 projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||
programState->setUniform(_mvpMatrixLocaiton, projectionMat.m, sizeof(projectionMat.m));
|
||||
|
|
|
@ -176,7 +176,6 @@ protected:
|
|||
|
||||
backend::UniformLocation _mvpMatrixLocaiton;
|
||||
backend::UniformLocation _textureLocation;
|
||||
backend::ProgramState* _programState = nullptr;
|
||||
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(ParticleSystemQuad);
|
||||
|
|
|
@ -191,7 +191,6 @@ protected:
|
|||
CustomCommand _customCommand;
|
||||
CustomCommand _customCommand2;
|
||||
|
||||
backend::ProgramState* _programState = nullptr;
|
||||
backend::ProgramState* _programState2 = nullptr;
|
||||
|
||||
backend::UniformLocation _locMVP1;
|
||||
|
|
|
@ -384,14 +384,15 @@ void Sprite::updateShaders(const char* vert, const char* frag)
|
|||
|
||||
void Sprite::setProgramState(backend::ProgramType type)
|
||||
{
|
||||
if(_programState != nullptr &&
|
||||
setProgramStateWithRegistry(type, _texture);
|
||||
/*if(_programState != nullptr &&
|
||||
_programState->getProgram()->getProgramType() == type)
|
||||
return;
|
||||
|
||||
auto* program = backend::Program::getBuiltinProgram(type);
|
||||
auto programState = new (std::nothrow) backend::ProgramState(program);
|
||||
setProgramState(programState);
|
||||
CC_SAFE_RELEASE_NULL(programState);
|
||||
CC_SAFE_RELEASE_NULL(programState);*/
|
||||
}
|
||||
|
||||
void Sprite::setProgramState(backend::ProgramState *programState)
|
||||
|
@ -408,17 +409,16 @@ void Sprite::setProgramState(backend::ProgramState *programState)
|
|||
|
||||
_mvpMatrixLocation = pipelineDescriptor.programState->getUniformLocation(backend::Uniform::MVP_MATRIX);
|
||||
_textureLocation = pipelineDescriptor.programState->getUniformLocation(backend::Uniform::TEXTURE);
|
||||
_alphaTextureLocation = pipelineDescriptor.programState->getUniformLocation(backend::Uniform::TEXTURE1);
|
||||
|
||||
setVertexLayout();
|
||||
updateProgramStateTexture();
|
||||
updateProgramStateTexture(_texture);
|
||||
setMVPMatrixUniform();
|
||||
}
|
||||
|
||||
void Sprite::setTexture(Texture2D *texture)
|
||||
{
|
||||
auto isETC1 = texture && texture->getAlphaTextureName();
|
||||
setProgramState((isETC1) ? backend::ProgramType::ETC1 : backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
setProgramStateWithRegistry(backend::ProgramType::POSITION_TEXTURE_COLOR, texture);
|
||||
|
||||
CCASSERT(! _batchNode || (texture && texture == _batchNode->getTexture()), "CCSprite: Batched sprites should use the same texture as the batchnode");
|
||||
// accept texture==nil as argument
|
||||
CCASSERT( !texture || dynamic_cast<Texture2D*>(texture), "setTexture expects a Texture2D. Invalid argument");
|
||||
|
@ -450,21 +450,7 @@ void Sprite::setTexture(Texture2D *texture)
|
|||
}
|
||||
updateBlendFunc();
|
||||
}
|
||||
updateProgramStateTexture();
|
||||
}
|
||||
|
||||
void Sprite::updateProgramStateTexture()
|
||||
{
|
||||
if (_texture == nullptr || _texture->getBackendTexture() == nullptr)
|
||||
return;
|
||||
|
||||
auto programState = _trianglesCommand.getPipelineDescriptor().programState;
|
||||
programState->setTexture(_textureLocation, 0, _texture->getBackendTexture());
|
||||
auto alphaTexture = _texture->getAlphaTexture();
|
||||
if(alphaTexture && alphaTexture->getBackendTexture())
|
||||
{
|
||||
programState->setTexture(_alphaTextureLocation, 1, alphaTexture->getBackendTexture());
|
||||
}
|
||||
updateProgramStateTexture(_texture);
|
||||
}
|
||||
|
||||
Texture2D* Sprite::getTexture() const
|
||||
|
|
|
@ -624,7 +624,9 @@ CC_CONSTRUCTOR_ACCESS :
|
|||
|
||||
virtual void setVertexLayout();
|
||||
virtual void updateShaders(const char* vert, const char* frag);
|
||||
|
||||
|
||||
void setProgramState(backend::ProgramType type);
|
||||
|
||||
protected:
|
||||
virtual void updateColor() override;
|
||||
virtual void setTextureCoords(const Rect& rect);
|
||||
|
@ -635,13 +637,11 @@ protected:
|
|||
virtual void setDirtyRecursively(bool value);
|
||||
virtual void flipX();
|
||||
virtual void flipY();
|
||||
virtual void updateProgramStateTexture();
|
||||
|
||||
void updatePoly();
|
||||
void updateStretchFactor();
|
||||
void populateTriangle(int quadIndex, const V3F_C4B_T2F_Quad& quad);
|
||||
void setMVPMatrixUniform();
|
||||
void setProgramState(backend::ProgramType type);
|
||||
//
|
||||
// Data used when the sprite is rendered using a SpriteSheet
|
||||
//
|
||||
|
@ -664,8 +664,6 @@ protected:
|
|||
|
||||
backend::UniformLocation _mvpMatrixLocation;
|
||||
backend::UniformLocation _textureLocation;
|
||||
backend::UniformLocation _alphaTextureLocation;
|
||||
|
||||
#if CC_SPRITE_DEBUG_DRAW
|
||||
DrawNode *_debugDrawNode = nullptr;
|
||||
#endif //CC_SPRITE_DEBUG_DRAW
|
||||
|
|
|
@ -102,42 +102,45 @@ bool SpriteBatchNode::initWithTexture(Texture2D *tex, ssize_t capacity/* = DEFAU
|
|||
|
||||
_textureAtlas->initWithTexture(tex, capacity);
|
||||
|
||||
setProgramStateWithRegistry(backend::ProgramType::POSITION_TEXTURE_COLOR, tex);
|
||||
updateProgramStateTexture(_textureAtlas->getTexture());
|
||||
|
||||
updateBlendFunc();
|
||||
|
||||
_children.reserve(capacity);
|
||||
|
||||
_descendants.reserve(capacity);
|
||||
|
||||
updateShaders(positionTextureColor_vert, positionTextureColor_frag);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SpriteBatchNode::updateShaders(const std::string &vertexShader, const std::string &fragmentShader)
|
||||
void SpriteBatchNode::setProgramState(backend::ProgramState* programState)
|
||||
{
|
||||
auto& pipelineDescriptor = _quadCommand.getPipelineDescriptor();
|
||||
auto* program = backend::Device::getInstance()->newProgram(vertexShader, fragmentShader);
|
||||
CC_SAFE_RELEASE(_programState);
|
||||
_programState = new (std::nothrow) backend::ProgramState(program);
|
||||
if (_programState != programState)
|
||||
{
|
||||
CC_SAFE_RELEASE(_programState);
|
||||
_programState = programState;
|
||||
CC_SAFE_RETAIN(programState);
|
||||
}
|
||||
pipelineDescriptor.programState = _programState;
|
||||
_mvpMatrixLocaiton = pipelineDescriptor.programState->getUniformLocation("u_MVPMatrix");
|
||||
_textureLocation = pipelineDescriptor.programState->getUniformLocation("u_texture");
|
||||
CC_SAFE_RELEASE(program);
|
||||
|
||||
|
||||
auto vertexLayout = _programState->getVertexLayout();
|
||||
const auto& attributeInfo = _programState->getProgram()->getActiveAttributes();
|
||||
auto iter = attributeInfo.find("a_position");
|
||||
if(iter != attributeInfo.end())
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
vertexLayout->setAttribute("a_position", iter->second.location, backend::VertexFormat::FLOAT3, 0, false);
|
||||
}
|
||||
iter = attributeInfo.find("a_texCoord");
|
||||
if(iter != attributeInfo.end())
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
vertexLayout->setAttribute("a_texCoord", iter->second.location, backend::VertexFormat::FLOAT2, offsetof(V3F_C4B_T2F, texCoords), false);
|
||||
}
|
||||
iter = attributeInfo.find("a_color");
|
||||
if(iter != attributeInfo.end())
|
||||
if (iter != attributeInfo.end())
|
||||
{
|
||||
vertexLayout->setAttribute("a_color", iter->second.location, backend::VertexFormat::UBYTE4, offsetof(V3F_C4B_T2F, colors), true);
|
||||
}
|
||||
|
@ -421,7 +424,7 @@ void SpriteBatchNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t f
|
|||
const auto& matrixProjection = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||
auto programState = _quadCommand.getPipelineDescriptor().programState;
|
||||
programState->setUniform(_mvpMatrixLocaiton, matrixProjection.m, sizeof(matrixProjection.m));
|
||||
programState->setTexture(_textureLocation, 0, _textureAtlas->getTexture()->getBackendTexture());
|
||||
// programState->setTexture(_textureLocation, 0, _textureAtlas->getTexture()->getBackendTexture());
|
||||
|
||||
_quadCommand.init(_globalZOrder, _textureAtlas->getTexture(), _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads(), transform, flags);
|
||||
renderer->addCommand(&_quadCommand);
|
||||
|
@ -681,6 +684,8 @@ Texture2D* SpriteBatchNode::getTexture() const
|
|||
void SpriteBatchNode::setTexture(Texture2D *texture)
|
||||
{
|
||||
_textureAtlas->setTexture(texture);
|
||||
|
||||
updateProgramStateTexture(texture);
|
||||
updateBlendFunc();
|
||||
}
|
||||
|
||||
|
|
|
@ -259,8 +259,8 @@ protected:
|
|||
void updateAtlasIndex(Sprite* sprite, ssize_t* curIndex);
|
||||
void swap(ssize_t oldIndex, ssize_t newIndex);
|
||||
void updateBlendFunc();
|
||||
|
||||
virtual void updateShaders(const std::string& vertexShader, const std::string& fragmentShader);
|
||||
|
||||
void setProgramState(backend::ProgramState* programState) override;
|
||||
|
||||
TextureAtlas *_textureAtlas = nullptr;
|
||||
BlendFunc _blendFunc;
|
||||
|
@ -268,7 +268,6 @@ protected:
|
|||
|
||||
backend::UniformLocation _mvpMatrixLocaiton;
|
||||
backend::UniformLocation _textureLocation;
|
||||
backend::ProgramState* _programState = nullptr;
|
||||
|
||||
// all descendants: children, grand children, etc...
|
||||
// There is not need to retain/release these objects, since they are already retained by _children
|
||||
|
|
|
@ -249,9 +249,11 @@ void TMXLayer::parseInternalProperties()
|
|||
auto alphaFuncVal = getProperty("cc_alpha_func");
|
||||
float alphaFuncValue = alphaFuncVal.asFloat();
|
||||
|
||||
setProgramStateWithRegistry(backend::ProgramType::POSITION_TEXTURE_COLOR_ALPHA_TEST, nullptr);
|
||||
|
||||
auto& pipelineDescriptor = _quadCommand.getPipelineDescriptor();
|
||||
auto& vertexShader = pipelineDescriptor.programState->getProgram()->getVertexShader();
|
||||
updateShaders(vertexShader, positionTextureColorAlphaTest_frag);
|
||||
|
||||
auto alphaValueLocation = pipelineDescriptor.programState->getUniformLocation("u_alpha_value");
|
||||
pipelineDescriptor.programState->setUniform(alphaValueLocation, &alphaFuncValue, sizeof(alphaFuncValue));
|
||||
}
|
||||
|
|
|
@ -357,3 +357,7 @@ THE SOFTWARE.
|
|||
#ifndef CC_STRIP_FPS
|
||||
#define CC_STRIP_FPS 0
|
||||
#endif
|
||||
|
||||
#ifndef CC_META_TEXTURES
|
||||
#define CC_META_TEXTURES 2
|
||||
#endif
|
||||
|
|
|
@ -208,7 +208,6 @@ protected:
|
|||
void setRootSkeleton(BoneNode* bone, SkeletonNode* skeleton) const;
|
||||
protected:
|
||||
cocos2d::CustomCommand _customCommand;
|
||||
cocos2d::backend::ProgramState* _programState = nullptr;
|
||||
cocos2d::backend::UniformLocation _mvpLocation;
|
||||
|
||||
cocos2d::BlendFunc _blendFunc = cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED;
|
||||
|
|
|
@ -30,7 +30,6 @@ THE SOFTWARE.
|
|||
#include <string>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "base/CCData.h"
|
||||
#include "base/ccConfig.h" // CC_USE_JPEG, CC_USE_WEBP
|
||||
#include "platform/CCGL.h"
|
||||
|
||||
|
@ -481,6 +480,7 @@ bool Image::PNG_PREMULTIPLIED_ALPHA_ENABLED = true;
|
|||
Image::Image()
|
||||
: _data(nullptr)
|
||||
, _dataLen(0)
|
||||
, _offset(0)
|
||||
, _width(0)
|
||||
, _height(0)
|
||||
, _unpack(false)
|
||||
|
@ -512,7 +512,9 @@ bool Image::initWithImageFile(const std::string& path)
|
|||
|
||||
if (!data.isNull())
|
||||
{
|
||||
ret = initWithImageData(data.getBytes(), data.getSize());
|
||||
ssize_t n = 0;
|
||||
auto buf = data.takeBuffer(&n);
|
||||
ret = initWithImageData(buf, n, true);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -527,19 +529,21 @@ bool Image::initWithImageFileThreadSafe(const std::string& fullpath)
|
|||
|
||||
if (!data.isNull())
|
||||
{
|
||||
ret = initWithImageData(data.getBytes(), data.getSize());
|
||||
ssize_t n = 0;
|
||||
auto buf = data.takeBuffer(&n);
|
||||
ret = initWithImageData(buf, n, true);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen)
|
||||
bool Image::initWithImageData(const unsigned char* data, ssize_t dataLen, bool ownData)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(! data || dataLen <= 0);
|
||||
CC_BREAK_IF(!data || dataLen == 0);
|
||||
|
||||
unsigned char* unpackedData = nullptr;
|
||||
ssize_t unpackedLen = 0;
|
||||
|
@ -576,7 +580,7 @@ bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen)
|
|||
ret = initWithPVRData(unpackedData, unpackedLen);
|
||||
break;
|
||||
case Format::ETC:
|
||||
ret = initWithETCData(unpackedData, unpackedLen);
|
||||
ret = initWithETCData(unpackedData, unpackedLen, ownData);
|
||||
break;
|
||||
case Format::S3TC:
|
||||
ret = initWithS3TCData(unpackedData, unpackedLen);
|
||||
|
@ -1421,7 +1425,7 @@ bool Image::initWithPVRv3Data(const unsigned char * data, ssize_t dataLen)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Image::initWithETCData(const unsigned char * data, ssize_t dataLen)
|
||||
bool Image::initWithETCData(const unsigned char* data, ssize_t dataLen, bool ownData)
|
||||
{
|
||||
const etc1_byte* header = static_cast<const etc1_byte*>(data);
|
||||
|
||||
|
@ -1439,23 +1443,26 @@ bool Image::initWithETCData(const unsigned char * data, ssize_t dataLen)
|
|||
return false;
|
||||
}
|
||||
|
||||
// pitfall: because we do merge etc1 alpha at shader, so must mark as _hasPremultipliedAlpha=true to makesure alpha blend works well.
|
||||
// the Premultiply operation can only do at shader.
|
||||
_hasPremultipliedAlpha = true;
|
||||
|
||||
if (Configuration::getInstance()->supportsETC())
|
||||
{
|
||||
//old opengl version has no define for GL_ETC1_RGB8_OES, add macro to make compiler happy.
|
||||
#if defined(GL_ETC1_RGB8_OES) || defined(CC_USE_METAL)
|
||||
_pixelFormat = backend::PixelFormat::ETC;
|
||||
_dataLen = dataLen - ETC_PKM_HEADER_SIZE;
|
||||
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
|
||||
memcpy(_data, static_cast<const unsigned char*>(data) + ETC_PKM_HEADER_SIZE, _dataLen);
|
||||
_data = data;
|
||||
_dataLen = dataLen;
|
||||
_offset = ETC_PKM_HEADER_SIZE;
|
||||
return true;
|
||||
#else
|
||||
CC_UNUSED_PARAM(dataLen);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
CCLOG("cocos2d: Hardware ETC1 decoder not present. Using software decoder");
|
||||
|
||||
bool ret = true;
|
||||
//if it is not gles or device do not support ETC, decode texture by software
|
||||
int bytePerPixel = 3;
|
||||
unsigned int stride = _width * bytePerPixel;
|
||||
|
@ -1470,12 +1477,16 @@ bool Image::initWithETCData(const unsigned char * data, ssize_t dataLen)
|
|||
if (_data != nullptr)
|
||||
{
|
||||
free(_data);
|
||||
_data = nullptr;
|
||||
}
|
||||
return false;
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
if (ownData) free((void*)data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ownData) free((void*)data);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ THE SOFTWARE.
|
|||
|
||||
#include "base/CCRef.h"
|
||||
#include "renderer/CCTexture2D.h"
|
||||
#include "base/CCData.h"
|
||||
|
||||
// premultiply alpha, or the effect will be wrong when using other pixel formats in Texture2D,
|
||||
// such as RGB888, RGB5A1
|
||||
|
@ -125,14 +126,14 @@ public:
|
|||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
bool initWithImageData(const unsigned char * data, ssize_t dataLen);
|
||||
bool initWithImageData(const unsigned char * data, ssize_t dataLen, bool ownData = false);
|
||||
|
||||
// @warning kFmtRawData only support RGBA8888
|
||||
bool initWithRawData(const unsigned char * data, ssize_t dataLen, int width, int height, int bitsPerComponent, bool preMulti = false);
|
||||
|
||||
// Getters
|
||||
unsigned char * getData() { return _data; }
|
||||
ssize_t getDataLen() { return _dataLen; }
|
||||
unsigned char * getData() { return _data + _offset; }
|
||||
ssize_t getDataLen() { return _dataLen - _offset; }
|
||||
Format getFileType() { return _fileType; }
|
||||
backend::PixelFormat getPixelFormat() { return _pixelFormat; }
|
||||
int getWidth() { return _width; }
|
||||
|
@ -163,7 +164,7 @@ protected:
|
|||
bool initWithPVRData(const unsigned char * data, ssize_t dataLen);
|
||||
bool initWithPVRv2Data(const unsigned char * data, ssize_t dataLen);
|
||||
bool initWithPVRv3Data(const unsigned char * data, ssize_t dataLen);
|
||||
bool initWithETCData(const unsigned char * data, ssize_t dataLen);
|
||||
bool initWithETCData(const unsigned char* data, ssize_t dataLen, bool ownData);
|
||||
bool initWithS3TCData(const unsigned char * data, ssize_t dataLen);
|
||||
bool initWithATITCData(const unsigned char *data, ssize_t dataLen);
|
||||
typedef struct sImageTGA tImageTGA;
|
||||
|
@ -186,6 +187,7 @@ protected:
|
|||
static bool PNG_PREMULTIPLIED_ALPHA_ENABLED;
|
||||
unsigned char *_data;
|
||||
ssize_t _dataLen;
|
||||
ssize_t _offset;
|
||||
int _width;
|
||||
int _height;
|
||||
bool _unpack;
|
||||
|
|
|
@ -97,8 +97,6 @@ void QuadCommand::init(float globalOrder, Texture2D *texture, const BlendFunc& b
|
|||
triangles.indices = __indices;
|
||||
triangles.indexCount = (int)quadCount * 6;
|
||||
TrianglesCommand::init(globalOrder, texture, blendType, triangles, mv, flags);
|
||||
|
||||
_alphaTextureID = texture->getAlphaTextureName();
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -137,7 +137,6 @@ Texture2D::Texture2D()
|
|||
, _antialiasEnabled(true)
|
||||
, _ninePatchInfo(nullptr)
|
||||
, _valid(true)
|
||||
, _alphaTexture(nullptr)
|
||||
{
|
||||
backend::TextureDescriptor textureDescriptor;
|
||||
textureDescriptor.textureFormat = PixelFormat::NONE;
|
||||
|
@ -149,8 +148,6 @@ Texture2D::~Texture2D()
|
|||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
VolatileTextureMgr::removeTexture(this);
|
||||
#endif
|
||||
CC_SAFE_RELEASE_NULL(_alphaTexture); // ETC1 ALPHA support.
|
||||
|
||||
CCLOGINFO("deallocing Texture2D: %p - id=%u", this, _name);
|
||||
|
||||
CC_SAFE_DELETE(_ninePatchInfo);
|
||||
|
@ -179,11 +176,6 @@ backend::TextureBackend* Texture2D::getBackendTexture() const
|
|||
return _texture;
|
||||
}
|
||||
|
||||
bool Texture2D::getAlphaTextureName() const
|
||||
{
|
||||
return _alphaTexture == nullptr ? 0 : _alphaTexture->getBackendTexture();
|
||||
}
|
||||
|
||||
Size Texture2D::getContentSize() const
|
||||
{
|
||||
Size ret;
|
||||
|
@ -235,6 +227,128 @@ bool Texture2D::initWithData(const void *data, ssize_t dataLen, backend::PixelFo
|
|||
}
|
||||
|
||||
bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, bool preMultipliedAlpha)
|
||||
{
|
||||
//the pixelFormat must be a certain value
|
||||
updateWithMipmaps(mipmaps, mipmapsNum, pixelFormat, renderFormat, pixelsWide, pixelsHigh, preMultipliedAlpha);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Texture2D::updateWithImage(Image* image, backend::PixelFormat format, int index)
|
||||
{
|
||||
if (image == nullptr)
|
||||
{
|
||||
CCLOG("cocos2d: Texture2D. Can't create Texture. UIImage is nil");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(this->_filePath.empty()) this->_filePath = image->getFilePath();
|
||||
|
||||
int imageWidth = image->getWidth();
|
||||
int imageHeight = image->getHeight();
|
||||
|
||||
Configuration* conf = Configuration::getInstance();
|
||||
|
||||
int maxTextureSize = conf->getMaxTextureSize();
|
||||
if (imageWidth > maxTextureSize || imageHeight > maxTextureSize)
|
||||
{
|
||||
CCLOG("cocos2d: WARNING: Image (%u x %u) is bigger than the supported %u x %u", imageWidth, imageHeight, maxTextureSize, maxTextureSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char* tempData = image->getData();
|
||||
Size imageSize = Size((float)imageWidth, (float)imageHeight);
|
||||
backend::PixelFormat renderFormat = ((PixelFormat::NONE == format) || (PixelFormat::AUTO == format)) ? image->getPixelFormat() : format;
|
||||
backend::PixelFormat imagePixelFormat = image->getPixelFormat();
|
||||
size_t tempDataLen = image->getDataLen();
|
||||
|
||||
|
||||
#ifdef CC_USE_METAL
|
||||
//compressed format does not need conversion
|
||||
switch (imagePixelFormat) {
|
||||
case PixelFormat::PVRTC4A:
|
||||
case PixelFormat::PVRTC4:
|
||||
case PixelFormat::PVRTC2A:
|
||||
case PixelFormat::PVRTC2:
|
||||
case PixelFormat::A8:
|
||||
renderFormat = imagePixelFormat;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//override renderFormat, since some render format is not supported by metal
|
||||
switch (renderFormat)
|
||||
{
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS && !TARGET_OS_SIMULATOR)
|
||||
//packed 16 bits pixels only available on iOS
|
||||
case PixelFormat::RGB565:
|
||||
renderFormat = PixelFormat::MTL_B5G6R5;
|
||||
break;
|
||||
case PixelFormat::RGBA4444:
|
||||
renderFormat = PixelFormat::MTL_ABGR4;
|
||||
break;
|
||||
case PixelFormat::RGB5A1:
|
||||
renderFormat = PixelFormat::MTL_BGR5A1;
|
||||
break;
|
||||
#else
|
||||
case PixelFormat::RGB565:
|
||||
case PixelFormat::RGB5A1:
|
||||
case PixelFormat::RGBA4444:
|
||||
#endif
|
||||
case PixelFormat::I8:
|
||||
case PixelFormat::AI88:
|
||||
//TODO: conversion RGBA8888 -> I8(AI88) -> RGBA8888 may happends
|
||||
renderFormat = PixelFormat::RGBA8888;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (image->getNumberOfMipmaps() > 1)
|
||||
{
|
||||
if (renderFormat != image->getPixelFormat())
|
||||
{
|
||||
CCLOG("cocos2d: WARNING: This image has more than 1 mipmaps and we will not convert the data format");
|
||||
}
|
||||
|
||||
//pixel format of data is not converted, renderFormat can be different from pixelFormat
|
||||
//it will be done later
|
||||
updateWithMipmaps(image->getMipmaps(), image->getNumberOfMipmaps(), image->getPixelFormat(), renderFormat, imageWidth, imageHeight, image->hasPremultipliedAlpha(), index);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (image->isCompressed())
|
||||
{
|
||||
if (renderFormat != image->getPixelFormat())
|
||||
{
|
||||
CCLOG("cocos2d: WARNING: This image is compressed and we can't convert it for now");
|
||||
}
|
||||
|
||||
updateWithData(tempData, tempDataLen, image->getPixelFormat(), image->getPixelFormat(), imageWidth, imageHeight, imageSize, image->hasPremultipliedAlpha(), index);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//after conversion, renderFormat == pixelFormat of data
|
||||
updateWithData(tempData, tempDataLen, imagePixelFormat, renderFormat, imageWidth, imageHeight, imageSize, image->hasPremultipliedAlpha(), index);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Texture2D::updateWithData(const void* data, ssize_t dataLen, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, const Size& /*contentSize*/, bool preMultipliedAlpha, int index)
|
||||
{
|
||||
CCASSERT(dataLen > 0 && pixelsWide > 0 && pixelsHigh > 0, "Invalid size");
|
||||
|
||||
//if data has no mipmaps, we will consider it has only one mipmap
|
||||
MipmapInfo mipmap;
|
||||
mipmap.address = (unsigned char*)data;
|
||||
mipmap.len = static_cast<int>(dataLen);
|
||||
return updateWithMipmaps(&mipmap, 1, pixelFormat, renderFormat, pixelsWide, pixelsHigh, preMultipliedAlpha, index);
|
||||
}
|
||||
|
||||
bool Texture2D::updateWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, bool preMultipliedAlpha, int index)
|
||||
{
|
||||
//the pixelFormat must be a certain value
|
||||
CCASSERT(pixelFormat != PixelFormat::NONE && pixelFormat != PixelFormat::AUTO, "the \"pixelFormat\" param must be a certain value!");
|
||||
|
@ -271,7 +385,7 @@ bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::Pi
|
|||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
VolatileTextureMgr::findVolotileTexture(this);
|
||||
#endif
|
||||
|
||||
|
||||
backend::TextureDescriptor textureDescriptor;
|
||||
textureDescriptor.width = pixelsWide;
|
||||
textureDescriptor.height = pixelsHigh;
|
||||
|
@ -290,70 +404,70 @@ bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::Pi
|
|||
backend::PixelFormat oriPixelFormat = pixelFormat;
|
||||
for (int i = 0; i < mipmapsNum; ++i)
|
||||
{
|
||||
unsigned char *data = mipmaps[i].address;
|
||||
unsigned char* data = mipmaps[i].address;
|
||||
size_t dataLen = mipmaps[i].len;
|
||||
unsigned char *outData = data;
|
||||
unsigned char* outData = data;
|
||||
size_t outDataLen = dataLen;
|
||||
|
||||
if(renderFormat != oriPixelFormat && !info.compressed) //need conversion
|
||||
if (renderFormat != oriPixelFormat && !info.compressed) //need conversion
|
||||
{
|
||||
auto convertedFormat = backend::PixelFormatUtils::convertDataToFormat(data, dataLen, oriPixelFormat, renderFormat, &outData, &outDataLen);
|
||||
#ifdef CC_USE_METAL
|
||||
CCASSERT(convertedFormat == renderFormat, "PixelFormat convert failed!");
|
||||
#endif
|
||||
if(convertedFormat == renderFormat) pixelFormat = renderFormat;
|
||||
if (convertedFormat == renderFormat) pixelFormat = renderFormat;
|
||||
}
|
||||
|
||||
|
||||
textureDescriptor.textureFormat = pixelFormat;
|
||||
CCASSERT(textureDescriptor.textureFormat != backend::PixelFormat::NONE, "PixelFormat should not be NONE");
|
||||
|
||||
if(_texture->getTextureFormat() != textureDescriptor.textureFormat)
|
||||
_texture->updateTextureDescriptor(textureDescriptor);
|
||||
if (_texture->getTextureFormat() != textureDescriptor.textureFormat)
|
||||
_texture->updateTextureDescriptor(textureDescriptor, index);
|
||||
|
||||
if(info.compressed)
|
||||
if (info.compressed)
|
||||
{
|
||||
_texture->updateCompressedData(data, width, height, dataLen, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
_texture->updateData(outData, width, height, i);
|
||||
_texture->updateData(outData, width, height, i, index);
|
||||
}
|
||||
|
||||
if(outData && outData != data && outDataLen > 0)
|
||||
if (outData && outData != data && outDataLen > 0)
|
||||
{
|
||||
free(outData);
|
||||
outData = nullptr;
|
||||
outDataLen = 0;
|
||||
}
|
||||
|
||||
if (i > 0 && (width != height || ccNextPOT(width) != width ))
|
||||
|
||||
if (i > 0 && (width != height || ccNextPOT(width) != width))
|
||||
{
|
||||
CCLOG("cocos2d: Texture2D. WARNING. Mipmap level %u is not squared. Texture won't render correctly. width=%d != height=%d", i, width, height);
|
||||
}
|
||||
|
||||
|
||||
width = MAX(width >> 1, 1);
|
||||
height = MAX(height >> 1, 1);
|
||||
}
|
||||
|
||||
_contentSize = Size((float)pixelsWide, (float)pixelsHigh);
|
||||
_pixelsWide = pixelsWide;
|
||||
_pixelsHigh = pixelsHigh;
|
||||
_pixelFormat = pixelFormat;
|
||||
_maxS = 1;
|
||||
_maxT = 1;
|
||||
|
||||
_hasPremultipliedAlpha = preMultipliedAlpha;
|
||||
_hasMipmaps = mipmapsNum > 1;
|
||||
if (index == 0) {
|
||||
_contentSize = Size((float)pixelsWide, (float)pixelsHigh);
|
||||
_pixelsWide = pixelsWide;
|
||||
_pixelsHigh = pixelsHigh;
|
||||
_pixelFormat = pixelFormat;
|
||||
_maxS = 1;
|
||||
_maxT = 1;
|
||||
|
||||
return true;
|
||||
_hasPremultipliedAlpha = preMultipliedAlpha;
|
||||
_hasMipmaps = mipmapsNum > 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool Texture2D::updateWithData(void *data,int offsetX,int offsetY,int width,int height)
|
||||
bool Texture2D::updateWithSubData(void *data,int offsetX,int offsetY,int width,int height, int index)
|
||||
{
|
||||
if (_texture && width > 0 && height > 0)
|
||||
{
|
||||
uint8_t* textureData = static_cast<uint8_t*>(data);
|
||||
_texture->updateSubData(offsetX, offsetY, width, height, 0, textureData);
|
||||
_texture->updateSubData(offsetX, offsetY, width, height, 0, textureData, index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -373,97 +487,9 @@ bool Texture2D::initWithImage(Image *image, backend::PixelFormat format)
|
|||
return false;
|
||||
}
|
||||
|
||||
int imageWidth = image->getWidth();
|
||||
int imageHeight = image->getHeight();
|
||||
this->_filePath = image->getFilePath();
|
||||
Configuration *conf = Configuration::getInstance();
|
||||
|
||||
int maxTextureSize = conf->getMaxTextureSize();
|
||||
if (imageWidth > maxTextureSize || imageHeight > maxTextureSize)
|
||||
{
|
||||
CCLOG("cocos2d: WARNING: Image (%u x %u) is bigger than the supported %u x %u", imageWidth, imageHeight, maxTextureSize, maxTextureSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char* tempData = image->getData();
|
||||
Size imageSize = Size((float)imageWidth, (float)imageHeight);
|
||||
backend::PixelFormat renderFormat = ((PixelFormat::NONE == format) || (PixelFormat::AUTO == format)) ? image->getPixelFormat() : format;
|
||||
backend::PixelFormat imagePixelFormat = image->getPixelFormat();
|
||||
size_t tempDataLen = image->getDataLen();
|
||||
|
||||
|
||||
#ifdef CC_USE_METAL
|
||||
//compressed format does not need conversion
|
||||
switch (imagePixelFormat) {
|
||||
case PixelFormat::PVRTC4A:
|
||||
case PixelFormat::PVRTC4:
|
||||
case PixelFormat::PVRTC2A:
|
||||
case PixelFormat::PVRTC2:
|
||||
case PixelFormat::A8:
|
||||
renderFormat = imagePixelFormat;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//override renderFormat, since some render format is not supported by metal
|
||||
switch (renderFormat)
|
||||
{
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS && !TARGET_OS_SIMULATOR)
|
||||
//packed 16 bits pixels only available on iOS
|
||||
case PixelFormat::RGB565:
|
||||
renderFormat = PixelFormat::MTL_B5G6R5;
|
||||
break;
|
||||
case PixelFormat::RGBA4444:
|
||||
renderFormat = PixelFormat::MTL_ABGR4;
|
||||
break;
|
||||
case PixelFormat::RGB5A1:
|
||||
renderFormat = PixelFormat::MTL_BGR5A1;
|
||||
break;
|
||||
#else
|
||||
case PixelFormat::RGB565:
|
||||
case PixelFormat::RGB5A1:
|
||||
case PixelFormat::RGBA4444:
|
||||
#endif
|
||||
case PixelFormat::I8:
|
||||
case PixelFormat::AI88:
|
||||
//TODO: conversion RGBA8888 -> I8(AI88) -> RGBA8888 may happends
|
||||
renderFormat = PixelFormat::RGBA8888;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (image->getNumberOfMipmaps() > 1)
|
||||
{
|
||||
if (renderFormat != image->getPixelFormat())
|
||||
{
|
||||
CCLOG("cocos2d: WARNING: This image has more than 1 mipmaps and we will not convert the data format");
|
||||
}
|
||||
|
||||
//pixel format of data is not converted, renderFormat can be different from pixelFormat
|
||||
//it will be done later
|
||||
initWithMipmaps(image->getMipmaps(), image->getNumberOfMipmaps(), image->getPixelFormat(), renderFormat, imageWidth, imageHeight, image->hasPremultipliedAlpha());
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (image->isCompressed())
|
||||
{
|
||||
if (renderFormat != image->getPixelFormat())
|
||||
{
|
||||
CCLOG("cocos2d: WARNING: This image is compressed and we can't convert it for now");
|
||||
}
|
||||
|
||||
initWithData(tempData, tempDataLen, image->getPixelFormat(), imageWidth, imageHeight, imageSize, image->hasPremultipliedAlpha());
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//after conversion, renderFormat == pixelFormat of data
|
||||
initWithData(tempData, tempDataLen, imagePixelFormat, renderFormat, imageWidth, imageHeight, imageSize, image->hasPremultipliedAlpha());
|
||||
|
||||
return true;
|
||||
}
|
||||
return updateWithImage(image, format);
|
||||
}
|
||||
|
||||
// implementation Texture2D (Text)
|
||||
|
@ -792,22 +818,6 @@ void Texture2D::removeSpriteFrameCapInset(SpriteFrame* spriteFrame)
|
|||
}
|
||||
}
|
||||
|
||||
/// halx99 spec, ANDROID ETC1 ALPHA supports.
|
||||
void Texture2D::setAlphaTexture(Texture2D* alphaTexture)
|
||||
{
|
||||
if (alphaTexture != nullptr) {
|
||||
alphaTexture->retain();
|
||||
CC_SAFE_RELEASE(_alphaTexture);
|
||||
_alphaTexture = alphaTexture;
|
||||
_hasPremultipliedAlpha = true; // PremultipliedAlpha should be true.
|
||||
}
|
||||
}
|
||||
|
||||
Texture2D* Texture2D::getAlphaTexture() const
|
||||
{
|
||||
return _alphaTexture;
|
||||
}
|
||||
|
||||
void Texture2D::setTexParameters(const Texture2D::TexParams &desc)
|
||||
{
|
||||
_texture->updateSamplerDescriptor(desc);
|
||||
|
|
|
@ -170,6 +170,18 @@ public:
|
|||
*/
|
||||
bool initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, bool preMultipliedAlpha = false);
|
||||
|
||||
/** Update with image.
|
||||
|
||||
@param data Specifies a pointer to the image data in memory.
|
||||
@param offsetX Specifies a texel offset in the x direction within the texture array.
|
||||
@param offsetY Specifies a texel offset in the y direction within the texture array.
|
||||
@param width Specifies the width of the texture subimage.
|
||||
@param height Specifies the height of the texture subimage.
|
||||
*/
|
||||
bool updateWithImage(Image* image, backend::PixelFormat format, int index = 0);
|
||||
bool updateWithData(const void* data, ssize_t dataLen, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, const Size& /*contentSize*/, bool preMultipliedAlpha, int index = 0);
|
||||
bool updateWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::PixelFormat pixelFormat, backend::PixelFormat renderFormat, int pixelsWide, int pixelsHigh, bool preMultipliedAlpha = false, int index = 0);
|
||||
|
||||
/** Update with texture data.
|
||||
|
||||
@param data Specifies a pointer to the image data in memory.
|
||||
|
@ -178,7 +190,7 @@ public:
|
|||
@param width Specifies the width of the texture subimage.
|
||||
@param height Specifies the height of the texture subimage.
|
||||
*/
|
||||
bool updateWithData(void *data,int offsetX,int offsetY,int width,int height);
|
||||
bool updateWithSubData(void *data,int offsetX,int offsetY,int width,int height, int index = 0);
|
||||
/**
|
||||
Drawing extensions to make it easy to draw basic quads using a Texture2D object.
|
||||
These functions require GL_TEXTURE_2D and both GL_VERTEX_ARRAY and GL_TEXTURE_COORD_ARRAY client states to be enabled.
|
||||
|
@ -313,11 +325,6 @@ public:
|
|||
Size getContentSize() const;
|
||||
|
||||
std::string getPath()const { return _filePath; }
|
||||
|
||||
void setAlphaTexture(Texture2D* alphaTexture);
|
||||
Texture2D* getAlphaTexture() const;
|
||||
|
||||
bool getAlphaTextureName() const;
|
||||
|
||||
public:
|
||||
/** Get pixel info map, the key-value pairs is PixelFormat and PixelFormatInfo.*/
|
||||
|
@ -409,7 +416,6 @@ protected:
|
|||
bool _valid;
|
||||
std::string _filePath;
|
||||
|
||||
Texture2D* _alphaTexture;
|
||||
backend::ProgramState* _programState = nullptr;
|
||||
backend::UniformLocation _mvpMatrixLocation;
|
||||
backend::UniformLocation _textureLocation;
|
||||
|
|
|
@ -348,11 +348,7 @@ void TextureCache::addImageAsyncCallBack(float /*dt*/)
|
|||
texture->autorelease();
|
||||
// ETC1 ALPHA supports.
|
||||
if (asyncStruct->imageAlpha.getFileType() == Image::Format::ETC) {
|
||||
auto alphaTexture = new(std::nothrow) Texture2D();
|
||||
if(alphaTexture != nullptr && alphaTexture->initWithImage(&asyncStruct->imageAlpha, asyncStruct->pixelFormat)) {
|
||||
texture->setAlphaTexture(alphaTexture);
|
||||
}
|
||||
CC_SAFE_RELEASE(alphaTexture);
|
||||
texture->updateWithImage(&asyncStruct->imageAlpha, Texture2D::getDefaultAlphaPixelFormat(), 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -421,14 +417,10 @@ Texture2D * TextureCache::addImage(const std::string &path)
|
|||
std::string alphaFullPath = path + s_etc1AlphaFileSuffix;
|
||||
if (image->getFileType() == Image::Format::ETC && !s_etc1AlphaFileSuffix.empty() && FileUtils::getInstance()->isFileExist(alphaFullPath))
|
||||
{
|
||||
Image alphaImage;
|
||||
if (alphaImage.initWithImageFile(alphaFullPath))
|
||||
Image imageAlpha;
|
||||
if (imageAlpha.initWithImageFile(alphaFullPath))
|
||||
{
|
||||
Texture2D *pAlphaTexture = new(std::nothrow) Texture2D;
|
||||
if(pAlphaTexture != nullptr && pAlphaTexture->initWithImage(&alphaImage)) {
|
||||
texture->setAlphaTexture(pAlphaTexture);
|
||||
}
|
||||
CC_SAFE_RELEASE(pAlphaTexture);
|
||||
texture->updateWithImage(&imageAlpha, Texture2D::getDefaultAlphaPixelFormat(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,8 +114,6 @@ protected:
|
|||
/**Model view matrix when rendering the triangles.*/
|
||||
Mat4 _mv;
|
||||
|
||||
uint8_t _alphaTextureID = 0; // ANDROID ETC1 ALPHA supports.
|
||||
|
||||
// Cached value to determine to generate material id or not.
|
||||
BlendFunc _blendType = BlendFunc::DISABLE;
|
||||
backend::Program* _program = nullptr;
|
||||
|
|
|
@ -36,6 +36,7 @@ set(COCOS_RENDERER_HEADER
|
|||
renderer/backend/Types.h
|
||||
renderer/backend/VertexLayout.h
|
||||
renderer/backend/ProgramState.h
|
||||
renderer/backend/ProgramStateRegistry.h
|
||||
renderer/backend/ShaderCache.h
|
||||
renderer/backend/DeviceInfo.h
|
||||
)
|
||||
|
@ -70,6 +71,7 @@ set(COCOS_RENDERER_SRC
|
|||
renderer/backend/ProgramCache.cpp
|
||||
renderer/backend/Program.cpp
|
||||
renderer/backend/ProgramState.cpp
|
||||
renderer/backend/ProgramStateRegistry.cpp
|
||||
renderer/backend/ShaderCache.cpp
|
||||
renderer/backend/RenderPassDescriptor.cpp
|
||||
)
|
||||
|
|
|
@ -29,20 +29,6 @@
|
|||
#include "base/ccMacros.h"
|
||||
#include "base/CCConfiguration.h"
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<cocos2d::backend::ProgramType>
|
||||
{
|
||||
typedef cocos2d::backend::ProgramType argument_type;
|
||||
typedef std::size_t result_type;
|
||||
result_type operator()(argument_type const& v) const
|
||||
{
|
||||
return hash<int>()(static_cast<int>(v));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CC_BACKEND_BEGIN
|
||||
|
||||
namespace
|
||||
|
@ -126,6 +112,16 @@ bool ProgramCache::init()
|
|||
addProgram(ProgramType::TERRAIN_3D);
|
||||
addProgram(ProgramType::PARTICLE_TEXTURE_3D);
|
||||
addProgram(ProgramType::PARTICLE_COLOR_3D);
|
||||
|
||||
/* FIXME: Naming style
|
||||
** ETC1: POSITION_TEXTURE_COLOR_ETC1
|
||||
** GRAY_SCALE maybe: POSITION_TEXTURE_COLOR_GRAY
|
||||
** ETC1_GRAY maybe: POSITION_TEXTURE_COLOR_GRAY_ETC1
|
||||
*/
|
||||
ProgramStateRegistry::getInstance()->registerProgram(ProgramType::POSITION_TEXTURE_COLOR, 2,
|
||||
getBuiltinProgram(ProgramType::ETC1));
|
||||
ProgramStateRegistry::getInstance()->registerProgram(ProgramType::GRAY_SCALE, 2,
|
||||
getBuiltinProgram(ProgramType::ETC1_GRAY));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -298,6 +294,7 @@ void ProgramCache::removeUnusedProgram()
|
|||
|
||||
void ProgramCache::removeAllPrograms()
|
||||
{
|
||||
ProgramStateRegistry::getInstance()->clearPrograms();
|
||||
for (auto& program : _cachedPrograms)
|
||||
{
|
||||
program.second->release();
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "ProgramStateRegistry.h"
|
||||
|
||||
CC_BACKEND_BEGIN
|
||||
/**
|
||||
* @addtogroup _backend
|
||||
|
|
|
@ -381,6 +381,14 @@ void ProgramState::setFragmentUniform(int location, const void* data, std::size_
|
|||
#endif
|
||||
}
|
||||
|
||||
void ProgramState::setTexture(backend::TextureBackend* texture)
|
||||
{
|
||||
for (int index = 0; index < texture->getCount() && index < CC_META_TEXTURES; ++index) {
|
||||
auto location = getUniformLocation((backend::Uniform)(backend::Uniform::TEXTURE + index));
|
||||
setTexture(location, index, texture);
|
||||
}
|
||||
}
|
||||
|
||||
void ProgramState::setTexture(const backend::UniformLocation& uniformLocation, uint32_t slot, backend::TextureBackend* texture)
|
||||
{
|
||||
switch (uniformLocation.shaderStage)
|
||||
|
|
|
@ -142,6 +142,14 @@ public:
|
|||
*/
|
||||
void setCallbackUniform(const backend::UniformLocation&, const UniformCallback &);
|
||||
|
||||
/**
|
||||
* Set texture.
|
||||
* @param uniformLocation Specifies texture location.
|
||||
* @param slot Specifies texture slot selector.
|
||||
* @param texture Specifies a pointer to backend texture.
|
||||
*/
|
||||
void setTexture(backend::TextureBackend* texture);
|
||||
|
||||
/**
|
||||
* Set texture.
|
||||
* @param uniformLocation Specifies texture location.
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
#pragma once
|
||||
|
||||
#include "ProgramStateRegistry.h"
|
||||
|
||||
CC_BACKEND_BEGIN
|
||||
|
||||
static ProgramStateRegistry* _sharedStateRegistry = nullptr;
|
||||
/** returns the shared instance */
|
||||
ProgramStateRegistry* ProgramStateRegistry::getInstance()
|
||||
{
|
||||
if (_sharedStateRegistry)
|
||||
return _sharedStateRegistry;
|
||||
|
||||
_sharedStateRegistry = new (std::nothrow) ProgramStateRegistry();
|
||||
if (!_sharedStateRegistry->init())
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(_sharedStateRegistry);
|
||||
}
|
||||
|
||||
return _sharedStateRegistry;
|
||||
}
|
||||
|
||||
/** purges the cache. It releases the retained instance. */
|
||||
void ProgramStateRegistry::destroyInstance()
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(_sharedStateRegistry);
|
||||
}
|
||||
|
||||
bool ProgramStateRegistry::init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProgramStateRegistry::registerProgram(ProgramType programType, int maxCount, Program* program)
|
||||
{
|
||||
auto maxIndex = maxCount - 1;
|
||||
auto it = this->_registry.find(programType);
|
||||
if (it == this->_registry.end()) {
|
||||
it = this->_registry.emplace(programType, std::vector<Program*>{}).first;
|
||||
it->second.resize(CC_META_TEXTURES);
|
||||
}
|
||||
if (maxIndex < it->second.size())
|
||||
it->second[maxIndex] = program;
|
||||
}
|
||||
|
||||
void ProgramStateRegistry::clearPrograms() {
|
||||
this->_registry.clear();
|
||||
}
|
||||
|
||||
ProgramState* ProgramStateRegistry::getProgramState(ProgramType programType, int maxCount)
|
||||
{
|
||||
auto maxIndex = maxCount - 1;
|
||||
auto it = this->_registry.find(programType);
|
||||
if (it != this->_registry.end() && it->second.size() > maxIndex) {
|
||||
auto fallback = it->second[maxIndex];
|
||||
if (fallback)
|
||||
return new(std::nothrow) ProgramState(fallback);
|
||||
}
|
||||
|
||||
return new(std::nothrow) ProgramState(Program::getBuiltinProgram((ProgramType)programType));
|
||||
}
|
||||
|
||||
ProgramType ProgramStateRegistry::getProgramType(ProgramType programType, TextureBackend* texture2d)
|
||||
{
|
||||
return this->getProgramType(programType, texture2d->getCount());
|
||||
}
|
||||
|
||||
ProgramType ProgramStateRegistry::getProgramType(ProgramType programType, int maxCount)
|
||||
{
|
||||
auto maxIndex = maxCount - 1;
|
||||
auto it = this->_registry.find(programType);
|
||||
if (it != this->_registry.end() && it->second.size() > maxIndex) {
|
||||
auto fallback = it->second[maxIndex];
|
||||
if (fallback)
|
||||
return fallback->getProgramType();
|
||||
}
|
||||
return programType;
|
||||
}
|
||||
//end of _backend group
|
||||
/// @}
|
||||
CC_BACKEND_END
|
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
#include "Macros.h"
|
||||
#include "base/CCRef.h"
|
||||
#include "platform/CCPlatformMacros.h"
|
||||
#include "Program.h"
|
||||
#include "ProgramState.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<cocos2d::backend::ProgramType>
|
||||
{
|
||||
typedef cocos2d::backend::ProgramType argument_type;
|
||||
typedef std::size_t result_type;
|
||||
result_type operator()(argument_type const& v) const
|
||||
{
|
||||
return hash<int>()(static_cast<int>(v));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
CC_BACKEND_BEGIN
|
||||
/**
|
||||
* @addtogroup _backend
|
||||
* @{
|
||||
* #todo: Rename to ProgramStateRegistry
|
||||
*/
|
||||
/*
|
||||
Group by programType and texIndex
|
||||
default, we register:
|
||||
programType = positionTextureColor, texIndex = 0 ---> positionTextureColorDefault
|
||||
programType = positionTextureColor, texIndex = 1 ---> positionTextureColorDualETC1
|
||||
|
||||
*/
|
||||
class ProgramStateRegistry : public Ref {
|
||||
public:
|
||||
/** returns the shared instance */
|
||||
static ProgramStateRegistry* getInstance();
|
||||
|
||||
/** purges the cache. It releases the retained instance. */
|
||||
static void destroyInstance();
|
||||
|
||||
bool init();
|
||||
|
||||
void registerProgram(ProgramType programType, int maxCount, Program*);
|
||||
void clearPrograms();
|
||||
ProgramState* getProgramState(ProgramType programType, int maxCount);
|
||||
|
||||
ProgramType getProgramType(ProgramType programType, TextureBackend* texture2d);
|
||||
ProgramType getProgramType(ProgramType programType, int maxCount);
|
||||
|
||||
protected:
|
||||
|
||||
std::unordered_map<ProgramType, std::vector<Program*>> _registry;
|
||||
};
|
||||
|
||||
//end of _backend group
|
||||
/// @}
|
||||
CC_BACKEND_END
|
|
@ -107,7 +107,7 @@ TextureBackend::TextureBackend(const TextureDescriptor& descriptor)
|
|||
TextureBackend::~TextureBackend()
|
||||
{}
|
||||
|
||||
void TextureBackend::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor)
|
||||
void TextureBackend::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int /*index*/)
|
||||
{
|
||||
_bitsPerElement = computeBitsPerElement(descriptor.textureFormat);
|
||||
_textureType = descriptor.textureType;
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
* Update sampler
|
||||
* @param sampler Specifies the sampler descriptor.
|
||||
*/
|
||||
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler) = 0;
|
||||
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler, int index = 0) = 0;
|
||||
|
||||
/**
|
||||
* Read a block of pixels from the drawable texture
|
||||
|
@ -78,7 +78,7 @@ public:
|
|||
* Update texture description.
|
||||
* @param descriptor Specifies texture and sampler descriptor.
|
||||
*/
|
||||
virtual void updateTextureDescriptor(const TextureDescriptor& descriptor);
|
||||
virtual void updateTextureDescriptor(const TextureDescriptor& descriptor, int index = 0);
|
||||
|
||||
/**
|
||||
* Get texture format.
|
||||
|
@ -104,6 +104,8 @@ public:
|
|||
*/
|
||||
inline bool hasMipmaps() const { return _hasMipmaps; }
|
||||
|
||||
virtual int getCount() const = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @param descriptor Specifies the texture descirptor.
|
||||
|
@ -136,7 +138,7 @@ public:
|
|||
* @param height Specifies the height of the texture image.
|
||||
* @param level Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
|
||||
*/
|
||||
virtual void updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level) = 0;
|
||||
virtual void updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level, int index = 0) = 0;
|
||||
|
||||
/**
|
||||
* Update a two-dimensional texture image in a compressed format
|
||||
|
@ -157,7 +159,7 @@ public:
|
|||
* @param level Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
|
||||
* @param data Specifies a pointer to the image data in memory.
|
||||
*/
|
||||
virtual void updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data) = 0;
|
||||
virtual void updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data, int index = 0) = 0;
|
||||
|
||||
/**
|
||||
* Update a two-dimensional texture subimage in a compressed format
|
||||
|
|
|
@ -77,14 +77,14 @@ void TextureInfoGL::applySamplerDescriptor(const SamplerDescriptor& descriptor,
|
|||
|
||||
Texture2DGL::Texture2DGL(const TextureDescriptor& descriptor) : Texture2DBackend(descriptor)
|
||||
{
|
||||
glGenTextures(1, &_textureInfo.texture);
|
||||
glGenTextures(1, &_textureInfo.textures[0]);
|
||||
|
||||
updateTextureDescriptor(descriptor);
|
||||
|
||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
// Listen this event to restored texture id after coming to foreground on Android.
|
||||
_backToForegroundListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom*){
|
||||
glGenTextures(1, &(this->_textureInfo.texture));
|
||||
glGenTextures(1, &(this->_textureInfo.textures[0]));
|
||||
this->initWithZeros();
|
||||
});
|
||||
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, -1);
|
||||
|
@ -100,9 +100,9 @@ void Texture2DGL::initWithZeros()
|
|||
free(data);
|
||||
}
|
||||
|
||||
void Texture2DGL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor)
|
||||
void Texture2DGL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index)
|
||||
{
|
||||
TextureBackend::updateTextureDescriptor(descriptor);
|
||||
TextureBackend::updateTextureDescriptor(descriptor, index);
|
||||
UtilsGL::toGLTypes(descriptor.textureFormat, _textureInfo.internalFormat, _textureInfo.format, _textureInfo.type, _isCompressed);
|
||||
|
||||
bool isPow2 = ISPOW2(_width) && ISPOW2(_height);
|
||||
|
@ -112,7 +112,7 @@ void Texture2DGL::updateTextureDescriptor(const cocos2d::backend::TextureDescrip
|
|||
_textureInfo.sAddressModeGL = UtilsGL::toGLAddressMode(descriptor.samplerDescriptor.sAddressMode, isPow2);
|
||||
_textureInfo.tAddressModeGL = UtilsGL::toGLAddressMode(descriptor.samplerDescriptor.tAddressMode, isPow2);
|
||||
|
||||
updateSamplerDescriptor(descriptor.samplerDescriptor);
|
||||
updateSamplerDescriptor(descriptor.samplerDescriptor, index);
|
||||
|
||||
// Update data here because `updateData()` may not be invoked later.
|
||||
// For example, a texture used as depth buffer will not invoke updateData().
|
||||
|
@ -121,20 +121,18 @@ void Texture2DGL::updateTextureDescriptor(const cocos2d::backend::TextureDescrip
|
|||
|
||||
Texture2DGL::~Texture2DGL()
|
||||
{
|
||||
if (_textureInfo.texture)
|
||||
glDeleteTextures(1, &_textureInfo.texture);
|
||||
_textureInfo.texture = 0;
|
||||
_textureInfo.foreach([=](GLuint texID, int) { glDeleteTextures(1, &texID); });
|
||||
_textureInfo.textures.fill(0);
|
||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Texture2DGL::updateSamplerDescriptor(const SamplerDescriptor &sampler) {
|
||||
void Texture2DGL::updateSamplerDescriptor(const SamplerDescriptor &sampler, int index) {
|
||||
bool isPow2 = ISPOW2(_width) && ISPOW2(_height);
|
||||
_textureInfo.applySamplerDescriptor(sampler, isPow2, _hasMipmaps);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
||||
ensure(index);
|
||||
|
||||
if (sampler.magFilter != SamplerFilter::DONT_CARE)
|
||||
{
|
||||
|
@ -157,7 +155,7 @@ void Texture2DGL::updateSamplerDescriptor(const SamplerDescriptor &sampler) {
|
|||
}
|
||||
}
|
||||
|
||||
void Texture2DGL::updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level)
|
||||
void Texture2DGL::updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level, int index)
|
||||
{
|
||||
//Set the row align only when mipmapsNum == 1 and the data is uncompressed
|
||||
auto mipmapEnalbed = isMipmapEnabled(_textureInfo.minFilterGL) || isMipmapEnabled(_textureInfo.magFilterGL);
|
||||
|
@ -187,8 +185,8 @@ void Texture2DGL::updateData(uint8_t* data, std::size_t width , std::size_t heig
|
|||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
||||
auto texID = ensure(index);
|
||||
if (!texID) return;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _textureInfo.magFilterGL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _textureInfo.minFilterGL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _textureInfo.sAddressModeGL);
|
||||
|
@ -204,6 +202,9 @@ void Texture2DGL::updateData(uint8_t* data, std::size_t width , std::size_t heig
|
|||
_textureInfo.format,
|
||||
_textureInfo.type,
|
||||
data);
|
||||
|
||||
cocos2d::log("---> Texture2DGL::updateData:%u", texID);
|
||||
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
|
||||
if(!_hasMipmaps && level > 0)
|
||||
|
@ -216,7 +217,7 @@ void Texture2DGL::updateCompressedData(uint8_t *data, std::size_t width, std::si
|
|||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.textures[0]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _textureInfo.magFilterGL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _textureInfo.minFilterGL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _textureInfo.sAddressModeGL);
|
||||
|
@ -237,10 +238,9 @@ void Texture2DGL::updateCompressedData(uint8_t *data, std::size_t width, std::si
|
|||
_hasMipmaps = true;
|
||||
}
|
||||
|
||||
void Texture2DGL::updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data)
|
||||
void Texture2DGL::updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data, int index)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
||||
if (!ensure(index)) return;
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D,
|
||||
level,
|
||||
|
@ -262,7 +262,7 @@ void Texture2DGL::updateCompressedSubData(std::size_t xoffset, std::size_t yoffs
|
|||
uint8_t *data)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.textures[0]);
|
||||
|
||||
glCompressedTexSubImage2D(GL_TEXTURE_2D,
|
||||
level,
|
||||
|
@ -282,7 +282,21 @@ void Texture2DGL::updateCompressedSubData(std::size_t xoffset, std::size_t yoffs
|
|||
void Texture2DGL::apply(int index) const
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, index < CC_META_TEXTURES ? _textureInfo.textures[index] : 0);
|
||||
}
|
||||
|
||||
GLuint Texture2DGL::ensure(int index)
|
||||
{
|
||||
if (index >= CC_META_TEXTURES) return 0;
|
||||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
auto& texID = _textureInfo.textures[index];
|
||||
if (!texID)
|
||||
glGenTextures(1, &texID);
|
||||
glBindTexture(GL_TEXTURE_2D, texID);
|
||||
|
||||
if (_maxTextureIndex < index) _maxTextureIndex = index;
|
||||
|
||||
return texID;
|
||||
}
|
||||
|
||||
void Texture2DGL::generateMipmaps()
|
||||
|
@ -293,7 +307,7 @@ void Texture2DGL::generateMipmaps()
|
|||
if(!_hasMipmaps)
|
||||
{
|
||||
_hasMipmaps = true;
|
||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.textures[0]);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
|
@ -306,7 +320,7 @@ void Texture2DGL::getBytes(std::size_t x, std::size_t y, std::size_t width, std:
|
|||
GLuint frameBuffer = 0;
|
||||
glGenFramebuffers(1, &frameBuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _textureInfo.texture, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _textureInfo.textures[0], 0);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
|
||||
auto bytePerRow = width * _bitsPerElement / 8;
|
||||
|
@ -340,7 +354,7 @@ TextureCubeGL::TextureCubeGL(const TextureDescriptor& descriptor)
|
|||
assert(_width == _height);
|
||||
_textureType = TextureType::TEXTURE_CUBE;
|
||||
UtilsGL::toGLTypes(_textureFormat, _textureInfo.internalFormat, _textureInfo.format, _textureInfo.type, _isCompressed);
|
||||
glGenTextures(1, &_textureInfo.texture);
|
||||
glGenTextures(1, &_textureInfo.textures[0]);
|
||||
updateSamplerDescriptor(descriptor.samplerDescriptor);
|
||||
|
||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
|
@ -357,7 +371,7 @@ TextureCubeGL::TextureCubeGL(const TextureDescriptor& descriptor)
|
|||
void TextureCubeGL::setTexParameters()
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.texture);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.textures[0]);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, _textureInfo.minFilterGL);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, _textureInfo.magFilterGL);
|
||||
|
@ -367,41 +381,40 @@ void TextureCubeGL::setTexParameters()
|
|||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
}
|
||||
|
||||
void TextureCubeGL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor)
|
||||
void TextureCubeGL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index)
|
||||
{
|
||||
UtilsGL::toGLTypes(descriptor.textureFormat, _textureInfo.internalFormat, _textureInfo.format, _textureInfo.type, _isCompressed);
|
||||
_textureFormat = descriptor.textureFormat;
|
||||
updateSamplerDescriptor(descriptor.samplerDescriptor);
|
||||
updateSamplerDescriptor(descriptor.samplerDescriptor, index);
|
||||
}
|
||||
|
||||
TextureCubeGL::~TextureCubeGL()
|
||||
{
|
||||
if(_textureInfo.texture)
|
||||
glDeleteTextures(1, &_textureInfo.texture);
|
||||
_textureInfo.texture = 0;
|
||||
_textureInfo.foreach([=](GLuint texID, int) { glDeleteTextures(1, &texID); });
|
||||
_textureInfo.textures.fill(0);
|
||||
|
||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TextureCubeGL::updateSamplerDescriptor(const SamplerDescriptor &sampler)
|
||||
void TextureCubeGL::updateSamplerDescriptor(const SamplerDescriptor &sampler, int /*index*/)
|
||||
{
|
||||
_textureInfo.applySamplerDescriptor(sampler, true, _hasMipmaps);
|
||||
setTexParameters();
|
||||
}
|
||||
|
||||
void TextureCubeGL::apply(int index) const
|
||||
void TextureCubeGL::apply(int location) const
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0+ index);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.texture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.textures[0]);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
}
|
||||
|
||||
void TextureCubeGL::updateFaceData(TextureCubeFace side, void *data)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.texture);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.textures[0]);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
int i = static_cast<int>(side);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
|
||||
|
@ -425,7 +438,7 @@ void TextureCubeGL::getBytes(std::size_t x, std::size_t y, std::size_t width, st
|
|||
GLuint frameBuffer = 0;
|
||||
glGenFramebuffers(1, &frameBuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP, _textureInfo.texture, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP, _textureInfo.textures[0], 0);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
|
||||
auto bytePerRow = width * _bitsPerElement / 8;
|
||||
|
@ -461,7 +474,7 @@ void TextureCubeGL::generateMipmaps()
|
|||
if(!_hasMipmaps)
|
||||
{
|
||||
_hasMipmaps = true;
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.texture);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.textures[0]);
|
||||
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include "../Texture.h"
|
||||
#include "platform/CCGL.h"
|
||||
#include "base/CCEventListenerCustom.h"
|
||||
|
@ -36,6 +37,17 @@ CC_BACKEND_BEGIN
|
|||
struct TextureInfoGL
|
||||
{
|
||||
void applySamplerDescriptor(const SamplerDescriptor &desc, bool isPow2, bool hasMipmaps);
|
||||
TextureInfoGL() {
|
||||
textures.fill(0);
|
||||
}
|
||||
|
||||
template<typename _Fty>
|
||||
void foreach(const _Fty& cb) const {
|
||||
GLuint texID;
|
||||
int idx = 0;
|
||||
while (texID = textures[idx])
|
||||
cb(texID, idx++);
|
||||
}
|
||||
|
||||
GLint magFilterGL = GL_LINEAR;
|
||||
GLint minFilterGL = GL_LINEAR;
|
||||
|
@ -47,7 +59,7 @@ struct TextureInfoGL
|
|||
GLenum format = GL_RGBA;
|
||||
GLenum type = GL_UNSIGNED_BYTE;
|
||||
|
||||
GLuint texture = 0;
|
||||
std::array<GLuint, CC_META_TEXTURES + 1> textures;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -74,7 +86,7 @@ public:
|
|||
* @param height Specifies the height of the texture image.
|
||||
* @param level Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
|
||||
*/
|
||||
virtual void updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level) override;
|
||||
virtual void updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level, int index = 0) override;
|
||||
|
||||
/**
|
||||
* Update a two-dimensional texture image in a compressed format
|
||||
|
@ -95,7 +107,7 @@ public:
|
|||
* @param level Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
|
||||
* @param data Specifies a pointer to the image data in memory.
|
||||
*/
|
||||
virtual void updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data) override;
|
||||
virtual void updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data, int index = 0) override;
|
||||
|
||||
/**
|
||||
* Update a two-dimensional texture subimage in a compressed format
|
||||
|
@ -113,7 +125,7 @@ public:
|
|||
* Update sampler
|
||||
* @param sampler Specifies the sampler descriptor.
|
||||
*/
|
||||
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler) override;
|
||||
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler, int index = 0) override;
|
||||
|
||||
/**
|
||||
* Read a block of pixels from the drawable texture
|
||||
|
@ -133,13 +145,13 @@ public:
|
|||
* Update texture description.
|
||||
* @param descriptor Specifies texture and sampler descriptor.
|
||||
*/
|
||||
virtual void updateTextureDescriptor(const TextureDescriptor& descriptor) override;
|
||||
virtual void updateTextureDescriptor(const TextureDescriptor& descriptor, int index = 0) override;
|
||||
|
||||
/**
|
||||
* Get texture object.
|
||||
* @return Texture object.
|
||||
*/
|
||||
inline GLuint getHandler() const { return _textureInfo.texture; }
|
||||
inline GLuint getHandler() const { return _textureInfo.textures[0]; }
|
||||
|
||||
/**
|
||||
* Set texture to pipeline
|
||||
|
@ -147,10 +159,15 @@ public:
|
|||
*/
|
||||
void apply(int index) const;
|
||||
|
||||
GLuint ensure(int index);
|
||||
|
||||
int getCount() const override { return _maxTextureIndex + 1; }
|
||||
|
||||
private:
|
||||
void initWithZeros();
|
||||
|
||||
TextureInfoGL _textureInfo;
|
||||
int _maxTextureIndex = 0;
|
||||
EventListener* _backToForegroundListener = nullptr;
|
||||
};
|
||||
|
||||
|
@ -170,7 +187,7 @@ public:
|
|||
* Update sampler
|
||||
* @param sampler Specifies the sampler descriptor.
|
||||
*/
|
||||
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler) override;
|
||||
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler, int index = 0) override;
|
||||
|
||||
/**
|
||||
* Update texutre cube data in give slice side.
|
||||
|
@ -195,19 +212,21 @@ public:
|
|||
* Update texture description.
|
||||
* @param descriptor Specifies texture and sampler descriptor.
|
||||
*/
|
||||
virtual void updateTextureDescriptor(const TextureDescriptor& descriptor) override ;
|
||||
virtual void updateTextureDescriptor(const TextureDescriptor& descriptor, int index = 0) override ;
|
||||
|
||||
/**
|
||||
* Get texture object.
|
||||
* @return Texture object.
|
||||
*/
|
||||
inline GLuint getHandler() const { return _textureInfo.texture; }
|
||||
inline GLuint getHandler() const { return _textureInfo.textures[0]; }
|
||||
|
||||
/**
|
||||
* Set texture to pipeline
|
||||
* @param index Specifies the texture image unit selector.
|
||||
*/
|
||||
void apply(int index) const;
|
||||
void apply(int location) const;
|
||||
|
||||
int getCount() const { return 1; }
|
||||
|
||||
private:
|
||||
void setTexParameters();
|
||||
|
|
|
@ -27,6 +27,7 @@ THE SOFTWARE.
|
|||
#include "2d/CCSprite.h"
|
||||
#include "editor-support/cocostudio/CocosStudioExtension.h"
|
||||
#include "renderer/ccShaders.h"
|
||||
#include "renderer/backend/ProgramStateRegistry.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -309,12 +310,8 @@ void AbstractCheckButton::onPressStateChangedToNormal()
|
|||
_backGroundBoxDisabledRenderer->setVisible(false);
|
||||
_frontCrossDisabledRenderer->setVisible(false);
|
||||
|
||||
auto isETC1 = _backGroundBoxRenderer->getTexture() && _backGroundBoxRenderer->getTexture()->getAlphaTextureName();
|
||||
_backGroundBoxRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
||||
|
||||
isETC1 = _frontCrossRenderer->getTexture() && _frontCrossRenderer->getTexture()->getAlphaTextureName();
|
||||
_frontCrossRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
||||
|
||||
_backGroundBoxRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
_frontCrossRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
|
||||
_backGroundBoxRenderer->setScale(_backgroundTextureScaleX, _backgroundTextureScaleY);
|
||||
_frontCrossRenderer->setScale(_backgroundTextureScaleX, _backgroundTextureScaleY);
|
||||
|
@ -329,11 +326,8 @@ void AbstractCheckButton::onPressStateChangedToNormal()
|
|||
|
||||
void AbstractCheckButton::onPressStateChangedToPressed()
|
||||
{
|
||||
auto isETC1 = _backGroundBoxRenderer->getTexture() && _backGroundBoxRenderer->getTexture()->getAlphaTextureName();
|
||||
_backGroundBoxRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
||||
|
||||
isETC1 = _frontCrossRenderer->getTexture() && _frontCrossRenderer->getTexture()->getAlphaTextureName();
|
||||
_frontCrossRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
||||
_backGroundBoxRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
_frontCrossRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
|
||||
if (!_isBackgroundSelectedTextureLoaded)
|
||||
{
|
||||
|
@ -356,11 +350,9 @@ void AbstractCheckButton::onPressStateChangedToDisabled()
|
|||
if (!_isBackgroundDisabledTextureLoaded
|
||||
|| !_isFrontCrossDisabledTextureLoaded)
|
||||
{
|
||||
auto isETC1 = _backGroundBoxRenderer->getTexture() && _backGroundBoxRenderer->getTexture()->getAlphaTextureName();
|
||||
_backGroundBoxRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1Gray_frag:grayScale_frag);
|
||||
_backGroundBoxRenderer->setProgramState(backend::ProgramType::GRAY_SCALE);
|
||||
|
||||
isETC1 = _frontCrossRenderer->getTexture() && _frontCrossRenderer->getTexture()->getAlphaTextureName();
|
||||
_frontCrossRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1Gray_frag:grayScale_frag);
|
||||
_frontCrossRenderer->setProgramState(backend::ProgramType::GRAY_SCALE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "2d/CCDrawNode.h"
|
||||
#include "2d/CCCamera.h"
|
||||
#include "renderer/CCRenderer.h"
|
||||
#include "renderer/backend/ProgramStateRegistry.h"
|
||||
|
||||
using namespace cocos2d;
|
||||
using namespace cocos2d::ui;
|
||||
|
@ -304,14 +305,13 @@ void Scale9Sprite::setState(Scale9Sprite::State state)
|
|||
{
|
||||
if (_brightState != state) {
|
||||
_brightState = state;
|
||||
auto isETC1 = getTexture() && getTexture()->getAlphaTextureName();
|
||||
switch (state)
|
||||
{
|
||||
case State::NORMAL:
|
||||
Sprite::updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
||||
Sprite::setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
break;
|
||||
case State::GRAY:
|
||||
Sprite::updateShaders(positionTextureColor_vert, (isETC1)?etc1Gray_frag:grayScale_frag);
|
||||
Sprite::setProgramState(backend::ProgramType::GRAY_SCALE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -680,15 +680,13 @@ void Slider::onPressStateChangedToNormal()
|
|||
_slidBallPressedRenderer->setVisible(false);
|
||||
_slidBallDisabledRenderer->setVisible(false);
|
||||
|
||||
auto isETC1 = _slidBallNormalRenderer->getTexture() && _slidBallNormalRenderer->getTexture()->getAlphaTextureName();
|
||||
_slidBallNormalRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
||||
_slidBallNormalRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
_slidBallNormalRenderer->setScale(_sliderBallNormalTextureScaleX, _sliderBallNormalTextureScaleY);
|
||||
}
|
||||
|
||||
void Slider::onPressStateChangedToPressed()
|
||||
{
|
||||
auto isETC1 = _slidBallNormalRenderer->getTexture() && _slidBallNormalRenderer->getTexture()->getAlphaTextureName();
|
||||
_slidBallNormalRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
||||
_slidBallNormalRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||
|
||||
if (!_isSliderBallPressedTextureLoaded)
|
||||
{
|
||||
|
@ -707,8 +705,7 @@ void Slider::onPressStateChangedToDisabled()
|
|||
{
|
||||
if (!_isSliderBallDisabledTexturedLoaded)
|
||||
{
|
||||
auto isETC1 = _slidBallNormalRenderer->getTexture() && _slidBallNormalRenderer->getTexture()->getAlphaTextureName();
|
||||
_slidBallNormalRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1Gray_frag:grayScale_frag);
|
||||
_slidBallNormalRenderer->setProgramState(backend::ProgramType::GRAY_SCALE);
|
||||
_slidBallNormalRenderer->setVisible(true);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue