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
|
@ -119,6 +119,7 @@ bool AtlasNode::initWithTexture(Texture2D* texture, int tileWidth, int tileHeigh
|
||||||
|
|
||||||
_textureAtlas->initWithTexture(texture, itemsToRender);
|
_textureAtlas->initWithTexture(texture, itemsToRender);
|
||||||
|
|
||||||
|
updateProgramStateTexture(texture);
|
||||||
this->updateBlendFunc();
|
this->updateBlendFunc();
|
||||||
this->updateOpacityModifyRGB();
|
this->updateOpacityModifyRGB();
|
||||||
|
|
||||||
|
@ -157,7 +158,6 @@ void AtlasNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto programState = _quadCommand.getPipelineDescriptor().programState;
|
auto programState = _quadCommand.getPipelineDescriptor().programState;
|
||||||
programState->setTexture(_textureLocation, 0, _textureAtlas->getTexture()->getBackendTexture());
|
|
||||||
|
|
||||||
const auto& projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
const auto& projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||||
programState->setUniform(_mvpMatrixLocation, projectionMat.m, sizeof(projectionMat.m));
|
programState->setUniform(_mvpMatrixLocation, projectionMat.m, sizeof(projectionMat.m));
|
||||||
|
@ -251,6 +251,8 @@ void AtlasNode::updateBlendFunc()
|
||||||
void AtlasNode::setTexture(Texture2D *texture)
|
void AtlasNode::setTexture(Texture2D *texture)
|
||||||
{
|
{
|
||||||
_textureAtlas->setTexture(texture);
|
_textureAtlas->setTexture(texture);
|
||||||
|
updateProgramStateTexture(texture);
|
||||||
|
|
||||||
this->updateBlendFunc();
|
this->updateBlendFunc();
|
||||||
this->updateOpacityModifyRGB();
|
this->updateOpacityModifyRGB();
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,6 @@ protected:
|
||||||
QuadCommand _quadCommand;
|
QuadCommand _quadCommand;
|
||||||
backend::UniformLocation _textureLocation;
|
backend::UniformLocation _textureLocation;
|
||||||
backend::UniformLocation _mvpMatrixLocation;
|
backend::UniformLocation _mvpMatrixLocation;
|
||||||
backend::ProgramState* _programState = nullptr;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CC_DISALLOW_COPY_AND_ASSIGN(AtlasNode);
|
CC_DISALLOW_COPY_AND_ASSIGN(AtlasNode);
|
||||||
|
|
|
@ -336,7 +336,6 @@ protected:
|
||||||
|
|
||||||
BlendFunc _blendFunc;
|
BlendFunc _blendFunc;
|
||||||
|
|
||||||
backend::ProgramState* _programState = nullptr;
|
|
||||||
backend::ProgramState* _programStatePoint = nullptr;
|
backend::ProgramState* _programStatePoint = nullptr;
|
||||||
backend::ProgramState* _programStateLine = nullptr;
|
backend::ProgramState* _programStateLine = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -354,7 +354,6 @@ protected:
|
||||||
backend::UniformLocation _mvpMatrixLocaiton;
|
backend::UniformLocation _mvpMatrixLocaiton;
|
||||||
backend::UniformLocation _textureLocation;
|
backend::UniformLocation _textureLocation;
|
||||||
backend::UniformLocation _alphaValueLocation;
|
backend::UniformLocation _alphaValueLocation;
|
||||||
backend::ProgramState* _programState = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// end of tilemap_parallax_nodes group
|
// 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] = data[i*2];
|
||||||
_currentPageDataRGBA[i*4+3] = data[i*2+1];
|
_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
|
else
|
||||||
{
|
{
|
||||||
data = _currentPageData + CacheTextureWidth * (int)startY;
|
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 "2d/CCFontFNT.h"
|
||||||
#include "renderer/ccShaders.h"
|
#include "renderer/ccShaders.h"
|
||||||
#include "renderer/backend/ProgramState.h"
|
#include "renderer/backend/ProgramState.h"
|
||||||
|
#include "renderer/backend/ProgramStateRegistry.h"
|
||||||
|
|
||||||
NS_CC_BEGIN
|
NS_CC_BEGIN
|
||||||
|
|
||||||
|
@ -644,9 +645,9 @@ void Label::updateShaderProgram()
|
||||||
if (_currentLabelType == LabelType::BMFONT || _currentLabelType == LabelType::CHARMAP)
|
if (_currentLabelType == LabelType::BMFONT || _currentLabelType == LabelType::CHARMAP)
|
||||||
{
|
{
|
||||||
auto texture = _getTexture(this);
|
auto texture = _getTexture(this);
|
||||||
if(texture && texture->getAlphaTextureName())
|
if(texture)
|
||||||
{
|
{
|
||||||
programType = backend::ProgramType::ETC1;
|
programType = backend::ProgramStateRegistry::getInstance()->getProgramType(programType, texture->getBackendTexture());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -665,9 +666,9 @@ void Label::updateShaderProgram()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto texture = _getTexture(this);
|
auto texture = _getTexture(this);
|
||||||
if(texture && texture->getAlphaTextureName())
|
if(texture)
|
||||||
{
|
{
|
||||||
programType = backend::ProgramType::ETC1;
|
programType = backend::ProgramStateRegistry::getInstance()->getProgramType(programType, texture->getBackendTexture());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -728,7 +729,6 @@ void Label::updateUniformLocations()
|
||||||
{
|
{
|
||||||
_mvpMatrixLocation = _programState->getUniformLocation(backend::Uniform::MVP_MATRIX);
|
_mvpMatrixLocation = _programState->getUniformLocation(backend::Uniform::MVP_MATRIX);
|
||||||
_textureLocation = _programState->getUniformLocation(backend::Uniform::TEXTURE);
|
_textureLocation = _programState->getUniformLocation(backend::Uniform::TEXTURE);
|
||||||
_alphaTextureLocation = _programState->getUniformLocation(backend::Uniform::TEXTURE1);
|
|
||||||
_textColorLocation = _programState->getUniformLocation(backend::Uniform::TEXT_COLOR);
|
_textColorLocation = _programState->getUniformLocation(backend::Uniform::TEXT_COLOR);
|
||||||
_effectColorLocation = _programState->getUniformLocation(backend::Uniform::EFFECT_COLOR);
|
_effectColorLocation = _programState->getUniformLocation(backend::Uniform::EFFECT_COLOR);
|
||||||
_effectTypeLocation = _programState->getUniformLocation(backend::Uniform::EFFECT_TYPE);
|
_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 texture = textureAtlas->getTexture();
|
||||||
auto& pipelineQuad = _quadCommand.getPipelineDescriptor();
|
auto& pipelineQuad = _quadCommand.getPipelineDescriptor();
|
||||||
pipelineQuad.programState->setUniform(_mvpMatrixLocation, matrixProjection.m, sizeof(matrixProjection.m));
|
pipelineQuad.programState->setUniform(_mvpMatrixLocation, matrixProjection.m, sizeof(matrixProjection.m));
|
||||||
pipelineQuad.programState->setTexture(_textureLocation, 0, texture->getBackendTexture());
|
pipelineQuad.programState->setTexture(texture->getBackendTexture());
|
||||||
auto alphaTexture = textureAtlas->getTexture()->getAlphaTexture();
|
|
||||||
if(alphaTexture && alphaTexture->getBackendTexture())
|
|
||||||
{
|
|
||||||
pipelineQuad.programState->setTexture(_alphaTextureLocation, 1, alphaTexture->getBackendTexture());
|
|
||||||
}
|
|
||||||
_quadCommand.init(_globalZOrder, texture, _blendFunc, textureAtlas->getQuads(), textureAtlas->getTotalQuads(), transform, flags);
|
_quadCommand.init(_globalZOrder, texture, _blendFunc, textureAtlas->getQuads(), textureAtlas->getTotalQuads(), transform, flags);
|
||||||
renderer->addCommand(&_quadCommand);
|
renderer->addCommand(&_quadCommand);
|
||||||
}
|
}
|
||||||
|
@ -1796,12 +1791,7 @@ void Label::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
||||||
auto *programState = command->getPipelineDescriptor().programState;
|
auto *programState = command->getPipelineDescriptor().programState;
|
||||||
Vec4 textColor(_textColorF.r, _textColorF.g, _textColorF.b, _textColorF.a);
|
Vec4 textColor(_textColorF.r, _textColorF.g, _textColorF.b, _textColorF.a);
|
||||||
programState->setUniform(_textColorLocation, &textColor, sizeof(Vec4));
|
programState->setUniform(_textColorLocation, &textColor, sizeof(Vec4));
|
||||||
programState->setTexture(_textureLocation, 0, textureAtlas->getTexture()->getBackendTexture());
|
programState->setTexture(textureAtlas->getTexture()->getBackendTexture());
|
||||||
auto alphaTexture = textureAtlas->getTexture()->getAlphaTexture();
|
|
||||||
if (alphaTexture && alphaTexture->getBackendTexture())
|
|
||||||
{
|
|
||||||
programState->setTexture(_alphaTextureLocation, 1, alphaTexture->getBackendTexture());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
batch.textCommand.getPipelineDescriptor().programState->setUniform(_mvpMatrixLocation, matrixMVP.m, sizeof(matrixMVP.m));
|
batch.textCommand.getPipelineDescriptor().programState->setUniform(_mvpMatrixLocation, matrixMVP.m, sizeof(matrixMVP.m));
|
||||||
batch.outLineCommand.getPipelineDescriptor().programState->setUniform(_mvpMatrixLocation, matrixMVP.m, sizeof(matrixMVP.m));
|
batch.outLineCommand.getPipelineDescriptor().programState->setUniform(_mvpMatrixLocation, matrixMVP.m, sizeof(matrixMVP.m));
|
||||||
|
|
|
@ -811,13 +811,10 @@ protected:
|
||||||
|
|
||||||
backend::UniformLocation _mvpMatrixLocation;
|
backend::UniformLocation _mvpMatrixLocation;
|
||||||
backend::UniformLocation _textureLocation;
|
backend::UniformLocation _textureLocation;
|
||||||
backend::UniformLocation _alphaTextureLocation;
|
|
||||||
backend::UniformLocation _textColorLocation;
|
backend::UniformLocation _textColorLocation;
|
||||||
backend::UniformLocation _effectColorLocation;
|
backend::UniformLocation _effectColorLocation;
|
||||||
backend::UniformLocation _effectTypeLocation;
|
backend::UniformLocation _effectTypeLocation;
|
||||||
|
|
||||||
backend::ProgramState* _programState = nullptr;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CC_DISALLOW_COPY_AND_ASSIGN(Label);
|
CC_DISALLOW_COPY_AND_ASSIGN(Label);
|
||||||
};
|
};
|
||||||
|
|
|
@ -278,7 +278,6 @@ protected:
|
||||||
V3F_C4F _vertexData[4];
|
V3F_C4F _vertexData[4];
|
||||||
|
|
||||||
backend::UniformLocation _mvpMatrixLocation;
|
backend::UniformLocation _mvpMatrixLocation;
|
||||||
backend::ProgramState* _programState = nullptr;
|
|
||||||
private:
|
private:
|
||||||
CC_DISALLOW_COPY_AND_ASSIGN(LayerColor);
|
CC_DISALLOW_COPY_AND_ASSIGN(LayerColor);
|
||||||
|
|
||||||
|
|
|
@ -40,32 +40,6 @@ MotionStreak::MotionStreak()
|
||||||
{
|
{
|
||||||
_customCommand.setDrawType(CustomCommand::DrawType::ARRAY);
|
_customCommand.setDrawType(CustomCommand::DrawType::ARRAY);
|
||||||
_customCommand.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE_STRIP);
|
_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()
|
MotionStreak::~MotionStreak()
|
||||||
|
@ -236,9 +210,49 @@ void MotionStreak::setTexture(Texture2D *texture)
|
||||||
CC_SAFE_RETAIN(texture);
|
CC_SAFE_RETAIN(texture);
|
||||||
CC_SAFE_RELEASE(_texture);
|
CC_SAFE_RELEASE(_texture);
|
||||||
_texture = 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)
|
void MotionStreak::setBlendFunc(const BlendFunc &blendFunc)
|
||||||
{
|
{
|
||||||
_blendFunc = blendFunc;
|
_blendFunc = blendFunc;
|
||||||
|
@ -398,7 +412,7 @@ void MotionStreak::draw(Renderer *renderer, const Mat4 &transform, uint32_t flag
|
||||||
renderer->addCommand(&_customCommand);
|
renderer->addCommand(&_customCommand);
|
||||||
|
|
||||||
auto programState = _customCommand.getPipelineDescriptor().programState;
|
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);
|
const auto& projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||||
Mat4 finalMat = projectionMat * transform;
|
Mat4 finalMat = projectionMat * transform;
|
||||||
|
|
|
@ -147,6 +147,8 @@ public:
|
||||||
_startingPositionInitialized = bStartingPositionInitialized;
|
_startingPositionInitialized = bStartingPositionInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setProgramState(backend::ProgramState* programState) override;
|
||||||
|
|
||||||
CC_CONSTRUCTOR_ACCESS:
|
CC_CONSTRUCTOR_ACCESS:
|
||||||
MotionStreak();
|
MotionStreak();
|
||||||
virtual ~MotionStreak();
|
virtual ~MotionStreak();
|
||||||
|
@ -187,7 +189,6 @@ protected:
|
||||||
|
|
||||||
backend::UniformLocation _mvpMatrixLocaiton;
|
backend::UniformLocation _mvpMatrixLocaiton;
|
||||||
backend::UniformLocation _textureLocation;
|
backend::UniformLocation _textureLocation;
|
||||||
backend::ProgramState* _programState = nullptr;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CC_DISALLOW_COPY_AND_ASSIGN(MotionStreak);
|
CC_DISALLOW_COPY_AND_ASSIGN(MotionStreak);
|
||||||
|
|
|
@ -43,6 +43,7 @@ THE SOFTWARE.
|
||||||
#include "2d/CCComponent.h"
|
#include "2d/CCComponent.h"
|
||||||
#include "renderer/CCMaterial.h"
|
#include "renderer/CCMaterial.h"
|
||||||
#include "math/TransformUtils.h"
|
#include "math/TransformUtils.h"
|
||||||
|
#include "renderer/backend/ProgramStateRegistry.h"
|
||||||
|
|
||||||
|
|
||||||
#if CC_NODE_RENDER_SUBPIXEL
|
#if CC_NODE_RENDER_SUBPIXEL
|
||||||
|
@ -2181,6 +2182,20 @@ int Node::getAttachedNodeCount()
|
||||||
return __attachedNodeCount;
|
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)
|
void Node::setProgramState(backend::ProgramState* programState)
|
||||||
{
|
{
|
||||||
if (_programState != programState)
|
if (_programState != programState)
|
||||||
|
|
|
@ -1768,6 +1768,10 @@ public:
|
||||||
virtual void setCameraMask(unsigned short mask, bool applyChildren = true);
|
virtual void setCameraMask(unsigned short mask, bool applyChildren = true);
|
||||||
|
|
||||||
virtual void setProgramState(backend::ProgramState* programState);
|
virtual void setProgramState(backend::ProgramState* programState);
|
||||||
|
|
||||||
|
void setProgramStateWithRegistry(backend::ProgramType programType, Texture2D* texture);
|
||||||
|
void updateProgramStateTexture(Texture2D* texture);
|
||||||
|
|
||||||
virtual backend::ProgramState* getProgramState() const;
|
virtual backend::ProgramState* getProgramState() const;
|
||||||
|
|
||||||
CC_CONSTRUCTOR_ACCESS:
|
CC_CONSTRUCTOR_ACCESS:
|
||||||
|
|
|
@ -441,7 +441,7 @@ void ParticleBatchNode::draw(Renderer* renderer, const Mat4 & transform, uint32_
|
||||||
Mat4 finalMat = projectionMat * transform;
|
Mat4 finalMat = projectionMat * transform;
|
||||||
auto programState = _customCommand.getPipelineDescriptor().programState;
|
auto programState = _customCommand.getPipelineDescriptor().programState;
|
||||||
programState->setUniform(_mvpMatrixLocaiton, finalMat.m, sizeof(finalMat.m));
|
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())
|
if (_textureAtlas->isDirty())
|
||||||
{
|
{
|
||||||
|
@ -531,13 +531,16 @@ void ParticleBatchNode::updateBlendFunc()
|
||||||
void ParticleBatchNode::setTexture(Texture2D* texture)
|
void ParticleBatchNode::setTexture(Texture2D* texture)
|
||||||
{
|
{
|
||||||
_textureAtlas->setTexture(texture);
|
_textureAtlas->setTexture(texture);
|
||||||
|
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 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 ) )
|
if (!texture->hasPremultipliedAlpha() && (_blendFunc.src == CC_BLEND_SRC && _blendFunc.dst == CC_BLEND_DST))
|
||||||
{
|
{
|
||||||
_blendFunc = BlendFunc::ALPHA_NON_PREMULTIPLIED;
|
_blendFunc = BlendFunc::ALPHA_NON_PREMULTIPLIED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Texture2D* ParticleBatchNode::getTexture() const
|
Texture2D* ParticleBatchNode::getTexture() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -180,7 +180,6 @@ private:
|
||||||
|
|
||||||
backend::UniformLocation _mvpMatrixLocaiton;
|
backend::UniformLocation _mvpMatrixLocaiton;
|
||||||
backend::UniformLocation _textureLocation;
|
backend::UniformLocation _textureLocation;
|
||||||
backend::ProgramState* _programState = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// end of _2d group
|
// end of _2d group
|
||||||
|
|
|
@ -230,6 +230,9 @@ void ParticleSystemQuad::setTextureWithRect(Texture2D *texture, const Rect& rect
|
||||||
if( !_texture || texture->getBackendTexture() != _texture->getBackendTexture() )
|
if( !_texture || texture->getBackendTexture() != _texture->getBackendTexture() )
|
||||||
{
|
{
|
||||||
ParticleSystem::setTexture(texture);
|
ParticleSystem::setTexture(texture);
|
||||||
|
|
||||||
|
auto programState = _quadCommand.getPipelineDescriptor().programState;
|
||||||
|
programState->setTexture(_texture->getBackendTexture());
|
||||||
}
|
}
|
||||||
|
|
||||||
this->initTexCoordsWithRect(rect);
|
this->initTexCoordsWithRect(rect);
|
||||||
|
@ -446,7 +449,7 @@ void ParticleSystemQuad::draw(Renderer *renderer, const Mat4 &transform, uint32_
|
||||||
if(_particleCount > 0)
|
if(_particleCount > 0)
|
||||||
{
|
{
|
||||||
auto programState = _quadCommand.getPipelineDescriptor().programState;
|
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);
|
cocos2d::Mat4 projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||||
programState->setUniform(_mvpMatrixLocaiton, projectionMat.m, sizeof(projectionMat.m));
|
programState->setUniform(_mvpMatrixLocaiton, projectionMat.m, sizeof(projectionMat.m));
|
||||||
|
|
|
@ -176,7 +176,6 @@ protected:
|
||||||
|
|
||||||
backend::UniformLocation _mvpMatrixLocaiton;
|
backend::UniformLocation _mvpMatrixLocaiton;
|
||||||
backend::UniformLocation _textureLocation;
|
backend::UniformLocation _textureLocation;
|
||||||
backend::ProgramState* _programState = nullptr;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CC_DISALLOW_COPY_AND_ASSIGN(ParticleSystemQuad);
|
CC_DISALLOW_COPY_AND_ASSIGN(ParticleSystemQuad);
|
||||||
|
|
|
@ -191,7 +191,6 @@ protected:
|
||||||
CustomCommand _customCommand;
|
CustomCommand _customCommand;
|
||||||
CustomCommand _customCommand2;
|
CustomCommand _customCommand2;
|
||||||
|
|
||||||
backend::ProgramState* _programState = nullptr;
|
|
||||||
backend::ProgramState* _programState2 = nullptr;
|
backend::ProgramState* _programState2 = nullptr;
|
||||||
|
|
||||||
backend::UniformLocation _locMVP1;
|
backend::UniformLocation _locMVP1;
|
||||||
|
|
|
@ -384,14 +384,15 @@ void Sprite::updateShaders(const char* vert, const char* frag)
|
||||||
|
|
||||||
void Sprite::setProgramState(backend::ProgramType type)
|
void Sprite::setProgramState(backend::ProgramType type)
|
||||||
{
|
{
|
||||||
if(_programState != nullptr &&
|
setProgramStateWithRegistry(type, _texture);
|
||||||
|
/*if(_programState != nullptr &&
|
||||||
_programState->getProgram()->getProgramType() == type)
|
_programState->getProgram()->getProgramType() == type)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto* program = backend::Program::getBuiltinProgram(type);
|
auto* program = backend::Program::getBuiltinProgram(type);
|
||||||
auto programState = new (std::nothrow) backend::ProgramState(program);
|
auto programState = new (std::nothrow) backend::ProgramState(program);
|
||||||
setProgramState(programState);
|
setProgramState(programState);
|
||||||
CC_SAFE_RELEASE_NULL(programState);
|
CC_SAFE_RELEASE_NULL(programState);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::setProgramState(backend::ProgramState *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);
|
_mvpMatrixLocation = pipelineDescriptor.programState->getUniformLocation(backend::Uniform::MVP_MATRIX);
|
||||||
_textureLocation = pipelineDescriptor.programState->getUniformLocation(backend::Uniform::TEXTURE);
|
_textureLocation = pipelineDescriptor.programState->getUniformLocation(backend::Uniform::TEXTURE);
|
||||||
_alphaTextureLocation = pipelineDescriptor.programState->getUniformLocation(backend::Uniform::TEXTURE1);
|
|
||||||
|
|
||||||
setVertexLayout();
|
setVertexLayout();
|
||||||
updateProgramStateTexture();
|
updateProgramStateTexture(_texture);
|
||||||
setMVPMatrixUniform();
|
setMVPMatrixUniform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::setTexture(Texture2D *texture)
|
void Sprite::setTexture(Texture2D *texture)
|
||||||
{
|
{
|
||||||
auto isETC1 = texture && texture->getAlphaTextureName();
|
setProgramStateWithRegistry(backend::ProgramType::POSITION_TEXTURE_COLOR, texture);
|
||||||
setProgramState((isETC1) ? backend::ProgramType::ETC1 : backend::ProgramType::POSITION_TEXTURE_COLOR);
|
|
||||||
CCASSERT(! _batchNode || (texture && texture == _batchNode->getTexture()), "CCSprite: Batched sprites should use the same texture as the batchnode");
|
CCASSERT(! _batchNode || (texture && texture == _batchNode->getTexture()), "CCSprite: Batched sprites should use the same texture as the batchnode");
|
||||||
// accept texture==nil as argument
|
// accept texture==nil as argument
|
||||||
CCASSERT( !texture || dynamic_cast<Texture2D*>(texture), "setTexture expects a Texture2D. Invalid argument");
|
CCASSERT( !texture || dynamic_cast<Texture2D*>(texture), "setTexture expects a Texture2D. Invalid argument");
|
||||||
|
@ -450,21 +450,7 @@ void Sprite::setTexture(Texture2D *texture)
|
||||||
}
|
}
|
||||||
updateBlendFunc();
|
updateBlendFunc();
|
||||||
}
|
}
|
||||||
updateProgramStateTexture();
|
updateProgramStateTexture(_texture);
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D* Sprite::getTexture() const
|
Texture2D* Sprite::getTexture() const
|
||||||
|
|
|
@ -625,6 +625,8 @@ CC_CONSTRUCTOR_ACCESS :
|
||||||
virtual void setVertexLayout();
|
virtual void setVertexLayout();
|
||||||
virtual void updateShaders(const char* vert, const char* frag);
|
virtual void updateShaders(const char* vert, const char* frag);
|
||||||
|
|
||||||
|
void setProgramState(backend::ProgramType type);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void updateColor() override;
|
virtual void updateColor() override;
|
||||||
virtual void setTextureCoords(const Rect& rect);
|
virtual void setTextureCoords(const Rect& rect);
|
||||||
|
@ -635,13 +637,11 @@ protected:
|
||||||
virtual void setDirtyRecursively(bool value);
|
virtual void setDirtyRecursively(bool value);
|
||||||
virtual void flipX();
|
virtual void flipX();
|
||||||
virtual void flipY();
|
virtual void flipY();
|
||||||
virtual void updateProgramStateTexture();
|
|
||||||
|
|
||||||
void updatePoly();
|
void updatePoly();
|
||||||
void updateStretchFactor();
|
void updateStretchFactor();
|
||||||
void populateTriangle(int quadIndex, const V3F_C4B_T2F_Quad& quad);
|
void populateTriangle(int quadIndex, const V3F_C4B_T2F_Quad& quad);
|
||||||
void setMVPMatrixUniform();
|
void setMVPMatrixUniform();
|
||||||
void setProgramState(backend::ProgramType type);
|
|
||||||
//
|
//
|
||||||
// Data used when the sprite is rendered using a SpriteSheet
|
// Data used when the sprite is rendered using a SpriteSheet
|
||||||
//
|
//
|
||||||
|
@ -664,8 +664,6 @@ protected:
|
||||||
|
|
||||||
backend::UniformLocation _mvpMatrixLocation;
|
backend::UniformLocation _mvpMatrixLocation;
|
||||||
backend::UniformLocation _textureLocation;
|
backend::UniformLocation _textureLocation;
|
||||||
backend::UniformLocation _alphaTextureLocation;
|
|
||||||
|
|
||||||
#if CC_SPRITE_DEBUG_DRAW
|
#if CC_SPRITE_DEBUG_DRAW
|
||||||
DrawNode *_debugDrawNode = nullptr;
|
DrawNode *_debugDrawNode = nullptr;
|
||||||
#endif //CC_SPRITE_DEBUG_DRAW
|
#endif //CC_SPRITE_DEBUG_DRAW
|
||||||
|
|
|
@ -102,27 +102,30 @@ bool SpriteBatchNode::initWithTexture(Texture2D *tex, ssize_t capacity/* = DEFAU
|
||||||
|
|
||||||
_textureAtlas->initWithTexture(tex, capacity);
|
_textureAtlas->initWithTexture(tex, capacity);
|
||||||
|
|
||||||
|
setProgramStateWithRegistry(backend::ProgramType::POSITION_TEXTURE_COLOR, tex);
|
||||||
|
updateProgramStateTexture(_textureAtlas->getTexture());
|
||||||
|
|
||||||
updateBlendFunc();
|
updateBlendFunc();
|
||||||
|
|
||||||
_children.reserve(capacity);
|
_children.reserve(capacity);
|
||||||
|
|
||||||
_descendants.reserve(capacity);
|
_descendants.reserve(capacity);
|
||||||
|
|
||||||
updateShaders(positionTextureColor_vert, positionTextureColor_frag);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteBatchNode::updateShaders(const std::string &vertexShader, const std::string &fragmentShader)
|
void SpriteBatchNode::setProgramState(backend::ProgramState* programState)
|
||||||
{
|
{
|
||||||
auto& pipelineDescriptor = _quadCommand.getPipelineDescriptor();
|
auto& pipelineDescriptor = _quadCommand.getPipelineDescriptor();
|
||||||
auto* program = backend::Device::getInstance()->newProgram(vertexShader, fragmentShader);
|
if (_programState != programState)
|
||||||
|
{
|
||||||
CC_SAFE_RELEASE(_programState);
|
CC_SAFE_RELEASE(_programState);
|
||||||
_programState = new (std::nothrow) backend::ProgramState(program);
|
_programState = programState;
|
||||||
|
CC_SAFE_RETAIN(programState);
|
||||||
|
}
|
||||||
pipelineDescriptor.programState = _programState;
|
pipelineDescriptor.programState = _programState;
|
||||||
_mvpMatrixLocaiton = pipelineDescriptor.programState->getUniformLocation("u_MVPMatrix");
|
_mvpMatrixLocaiton = pipelineDescriptor.programState->getUniformLocation("u_MVPMatrix");
|
||||||
_textureLocation = pipelineDescriptor.programState->getUniformLocation("u_texture");
|
_textureLocation = pipelineDescriptor.programState->getUniformLocation("u_texture");
|
||||||
CC_SAFE_RELEASE(program);
|
|
||||||
|
|
||||||
auto vertexLayout = _programState->getVertexLayout();
|
auto vertexLayout = _programState->getVertexLayout();
|
||||||
const auto& attributeInfo = _programState->getProgram()->getActiveAttributes();
|
const auto& attributeInfo = _programState->getProgram()->getActiveAttributes();
|
||||||
|
@ -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);
|
const auto& matrixProjection = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||||
auto programState = _quadCommand.getPipelineDescriptor().programState;
|
auto programState = _quadCommand.getPipelineDescriptor().programState;
|
||||||
programState->setUniform(_mvpMatrixLocaiton, matrixProjection.m, sizeof(matrixProjection.m));
|
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);
|
_quadCommand.init(_globalZOrder, _textureAtlas->getTexture(), _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads(), transform, flags);
|
||||||
renderer->addCommand(&_quadCommand);
|
renderer->addCommand(&_quadCommand);
|
||||||
|
@ -681,6 +684,8 @@ Texture2D* SpriteBatchNode::getTexture() const
|
||||||
void SpriteBatchNode::setTexture(Texture2D *texture)
|
void SpriteBatchNode::setTexture(Texture2D *texture)
|
||||||
{
|
{
|
||||||
_textureAtlas->setTexture(texture);
|
_textureAtlas->setTexture(texture);
|
||||||
|
|
||||||
|
updateProgramStateTexture(texture);
|
||||||
updateBlendFunc();
|
updateBlendFunc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,7 +260,7 @@ protected:
|
||||||
void swap(ssize_t oldIndex, ssize_t newIndex);
|
void swap(ssize_t oldIndex, ssize_t newIndex);
|
||||||
void updateBlendFunc();
|
void updateBlendFunc();
|
||||||
|
|
||||||
virtual void updateShaders(const std::string& vertexShader, const std::string& fragmentShader);
|
void setProgramState(backend::ProgramState* programState) override;
|
||||||
|
|
||||||
TextureAtlas *_textureAtlas = nullptr;
|
TextureAtlas *_textureAtlas = nullptr;
|
||||||
BlendFunc _blendFunc;
|
BlendFunc _blendFunc;
|
||||||
|
@ -268,7 +268,6 @@ protected:
|
||||||
|
|
||||||
backend::UniformLocation _mvpMatrixLocaiton;
|
backend::UniformLocation _mvpMatrixLocaiton;
|
||||||
backend::UniformLocation _textureLocation;
|
backend::UniformLocation _textureLocation;
|
||||||
backend::ProgramState* _programState = nullptr;
|
|
||||||
|
|
||||||
// all descendants: children, grand children, etc...
|
// all descendants: children, grand children, etc...
|
||||||
// There is not need to retain/release these objects, since they are already retained by _children
|
// 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");
|
auto alphaFuncVal = getProperty("cc_alpha_func");
|
||||||
float alphaFuncValue = alphaFuncVal.asFloat();
|
float alphaFuncValue = alphaFuncVal.asFloat();
|
||||||
|
|
||||||
|
setProgramStateWithRegistry(backend::ProgramType::POSITION_TEXTURE_COLOR_ALPHA_TEST, nullptr);
|
||||||
|
|
||||||
auto& pipelineDescriptor = _quadCommand.getPipelineDescriptor();
|
auto& pipelineDescriptor = _quadCommand.getPipelineDescriptor();
|
||||||
auto& vertexShader = pipelineDescriptor.programState->getProgram()->getVertexShader();
|
auto& vertexShader = pipelineDescriptor.programState->getProgram()->getVertexShader();
|
||||||
updateShaders(vertexShader, positionTextureColorAlphaTest_frag);
|
|
||||||
auto alphaValueLocation = pipelineDescriptor.programState->getUniformLocation("u_alpha_value");
|
auto alphaValueLocation = pipelineDescriptor.programState->getUniformLocation("u_alpha_value");
|
||||||
pipelineDescriptor.programState->setUniform(alphaValueLocation, &alphaFuncValue, sizeof(alphaFuncValue));
|
pipelineDescriptor.programState->setUniform(alphaValueLocation, &alphaFuncValue, sizeof(alphaFuncValue));
|
||||||
}
|
}
|
||||||
|
|
|
@ -357,3 +357,7 @@ THE SOFTWARE.
|
||||||
#ifndef CC_STRIP_FPS
|
#ifndef CC_STRIP_FPS
|
||||||
#define CC_STRIP_FPS 0
|
#define CC_STRIP_FPS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CC_META_TEXTURES
|
||||||
|
#define CC_META_TEXTURES 2
|
||||||
|
#endif
|
||||||
|
|
|
@ -208,7 +208,6 @@ protected:
|
||||||
void setRootSkeleton(BoneNode* bone, SkeletonNode* skeleton) const;
|
void setRootSkeleton(BoneNode* bone, SkeletonNode* skeleton) const;
|
||||||
protected:
|
protected:
|
||||||
cocos2d::CustomCommand _customCommand;
|
cocos2d::CustomCommand _customCommand;
|
||||||
cocos2d::backend::ProgramState* _programState = nullptr;
|
|
||||||
cocos2d::backend::UniformLocation _mvpLocation;
|
cocos2d::backend::UniformLocation _mvpLocation;
|
||||||
|
|
||||||
cocos2d::BlendFunc _blendFunc = cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED;
|
cocos2d::BlendFunc _blendFunc = cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED;
|
||||||
|
|
|
@ -30,7 +30,6 @@ THE SOFTWARE.
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "base/CCData.h"
|
|
||||||
#include "base/ccConfig.h" // CC_USE_JPEG, CC_USE_WEBP
|
#include "base/ccConfig.h" // CC_USE_JPEG, CC_USE_WEBP
|
||||||
#include "platform/CCGL.h"
|
#include "platform/CCGL.h"
|
||||||
|
|
||||||
|
@ -481,6 +480,7 @@ bool Image::PNG_PREMULTIPLIED_ALPHA_ENABLED = true;
|
||||||
Image::Image()
|
Image::Image()
|
||||||
: _data(nullptr)
|
: _data(nullptr)
|
||||||
, _dataLen(0)
|
, _dataLen(0)
|
||||||
|
, _offset(0)
|
||||||
, _width(0)
|
, _width(0)
|
||||||
, _height(0)
|
, _height(0)
|
||||||
, _unpack(false)
|
, _unpack(false)
|
||||||
|
@ -512,7 +512,9 @@ bool Image::initWithImageFile(const std::string& path)
|
||||||
|
|
||||||
if (!data.isNull())
|
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;
|
return ret;
|
||||||
|
@ -527,19 +529,21 @@ bool Image::initWithImageFileThreadSafe(const std::string& fullpath)
|
||||||
|
|
||||||
if (!data.isNull())
|
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;
|
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;
|
bool ret = false;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
CC_BREAK_IF(! data || dataLen <= 0);
|
CC_BREAK_IF(!data || dataLen == 0);
|
||||||
|
|
||||||
unsigned char* unpackedData = nullptr;
|
unsigned char* unpackedData = nullptr;
|
||||||
ssize_t unpackedLen = 0;
|
ssize_t unpackedLen = 0;
|
||||||
|
@ -576,7 +580,7 @@ bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen)
|
||||||
ret = initWithPVRData(unpackedData, unpackedLen);
|
ret = initWithPVRData(unpackedData, unpackedLen);
|
||||||
break;
|
break;
|
||||||
case Format::ETC:
|
case Format::ETC:
|
||||||
ret = initWithETCData(unpackedData, unpackedLen);
|
ret = initWithETCData(unpackedData, unpackedLen, ownData);
|
||||||
break;
|
break;
|
||||||
case Format::S3TC:
|
case Format::S3TC:
|
||||||
ret = initWithS3TCData(unpackedData, unpackedLen);
|
ret = initWithS3TCData(unpackedData, unpackedLen);
|
||||||
|
@ -1421,7 +1425,7 @@ bool Image::initWithPVRv3Data(const unsigned char * data, ssize_t dataLen)
|
||||||
return true;
|
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);
|
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;
|
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())
|
if (Configuration::getInstance()->supportsETC())
|
||||||
{
|
{
|
||||||
//old opengl version has no define for GL_ETC1_RGB8_OES, add macro to make compiler happy.
|
//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)
|
#if defined(GL_ETC1_RGB8_OES) || defined(CC_USE_METAL)
|
||||||
_pixelFormat = backend::PixelFormat::ETC;
|
_pixelFormat = backend::PixelFormat::ETC;
|
||||||
_dataLen = dataLen - ETC_PKM_HEADER_SIZE;
|
_data = data;
|
||||||
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
|
_dataLen = dataLen;
|
||||||
memcpy(_data, static_cast<const unsigned char*>(data) + ETC_PKM_HEADER_SIZE, _dataLen);
|
_offset = ETC_PKM_HEADER_SIZE;
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
CC_UNUSED_PARAM(dataLen);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CCLOG("cocos2d: Hardware ETC1 decoder not present. Using software decoder");
|
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
|
//if it is not gles or device do not support ETC, decode texture by software
|
||||||
int bytePerPixel = 3;
|
int bytePerPixel = 3;
|
||||||
unsigned int stride = _width * bytePerPixel;
|
unsigned int stride = _width * bytePerPixel;
|
||||||
|
@ -1470,12 +1477,16 @@ bool Image::initWithETCData(const unsigned char * data, ssize_t dataLen)
|
||||||
if (_data != nullptr)
|
if (_data != nullptr)
|
||||||
{
|
{
|
||||||
free(_data);
|
free(_data);
|
||||||
|
_data = nullptr;
|
||||||
}
|
}
|
||||||
return false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
if (ownData) free((void*)data);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ownData) free((void*)data);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
#include "base/CCRef.h"
|
#include "base/CCRef.h"
|
||||||
#include "renderer/CCTexture2D.h"
|
#include "renderer/CCTexture2D.h"
|
||||||
|
#include "base/CCData.h"
|
||||||
|
|
||||||
// premultiply alpha, or the effect will be wrong when using other pixel formats in Texture2D,
|
// premultiply alpha, or the effect will be wrong when using other pixel formats in Texture2D,
|
||||||
// such as RGB888, RGB5A1
|
// such as RGB888, RGB5A1
|
||||||
|
@ -125,14 +126,14 @@ public:
|
||||||
* @js NA
|
* @js NA
|
||||||
* @lua 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
|
// @warning kFmtRawData only support RGBA8888
|
||||||
bool initWithRawData(const unsigned char * data, ssize_t dataLen, int width, int height, int bitsPerComponent, bool preMulti = false);
|
bool initWithRawData(const unsigned char * data, ssize_t dataLen, int width, int height, int bitsPerComponent, bool preMulti = false);
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
unsigned char * getData() { return _data; }
|
unsigned char * getData() { return _data + _offset; }
|
||||||
ssize_t getDataLen() { return _dataLen; }
|
ssize_t getDataLen() { return _dataLen - _offset; }
|
||||||
Format getFileType() { return _fileType; }
|
Format getFileType() { return _fileType; }
|
||||||
backend::PixelFormat getPixelFormat() { return _pixelFormat; }
|
backend::PixelFormat getPixelFormat() { return _pixelFormat; }
|
||||||
int getWidth() { return _width; }
|
int getWidth() { return _width; }
|
||||||
|
@ -163,7 +164,7 @@ protected:
|
||||||
bool initWithPVRData(const unsigned char * data, ssize_t dataLen);
|
bool initWithPVRData(const unsigned char * data, ssize_t dataLen);
|
||||||
bool initWithPVRv2Data(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 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 initWithS3TCData(const unsigned char * data, ssize_t dataLen);
|
||||||
bool initWithATITCData(const unsigned char *data, ssize_t dataLen);
|
bool initWithATITCData(const unsigned char *data, ssize_t dataLen);
|
||||||
typedef struct sImageTGA tImageTGA;
|
typedef struct sImageTGA tImageTGA;
|
||||||
|
@ -186,6 +187,7 @@ protected:
|
||||||
static bool PNG_PREMULTIPLIED_ALPHA_ENABLED;
|
static bool PNG_PREMULTIPLIED_ALPHA_ENABLED;
|
||||||
unsigned char *_data;
|
unsigned char *_data;
|
||||||
ssize_t _dataLen;
|
ssize_t _dataLen;
|
||||||
|
ssize_t _offset;
|
||||||
int _width;
|
int _width;
|
||||||
int _height;
|
int _height;
|
||||||
bool _unpack;
|
bool _unpack;
|
||||||
|
|
|
@ -97,8 +97,6 @@ void QuadCommand::init(float globalOrder, Texture2D *texture, const BlendFunc& b
|
||||||
triangles.indices = __indices;
|
triangles.indices = __indices;
|
||||||
triangles.indexCount = (int)quadCount * 6;
|
triangles.indexCount = (int)quadCount * 6;
|
||||||
TrianglesCommand::init(globalOrder, texture, blendType, triangles, mv, flags);
|
TrianglesCommand::init(globalOrder, texture, blendType, triangles, mv, flags);
|
||||||
|
|
||||||
_alphaTextureID = texture->getAlphaTextureName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_CC_END
|
NS_CC_END
|
||||||
|
|
|
@ -137,7 +137,6 @@ Texture2D::Texture2D()
|
||||||
, _antialiasEnabled(true)
|
, _antialiasEnabled(true)
|
||||||
, _ninePatchInfo(nullptr)
|
, _ninePatchInfo(nullptr)
|
||||||
, _valid(true)
|
, _valid(true)
|
||||||
, _alphaTexture(nullptr)
|
|
||||||
{
|
{
|
||||||
backend::TextureDescriptor textureDescriptor;
|
backend::TextureDescriptor textureDescriptor;
|
||||||
textureDescriptor.textureFormat = PixelFormat::NONE;
|
textureDescriptor.textureFormat = PixelFormat::NONE;
|
||||||
|
@ -149,8 +148,6 @@ Texture2D::~Texture2D()
|
||||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||||
VolatileTextureMgr::removeTexture(this);
|
VolatileTextureMgr::removeTexture(this);
|
||||||
#endif
|
#endif
|
||||||
CC_SAFE_RELEASE_NULL(_alphaTexture); // ETC1 ALPHA support.
|
|
||||||
|
|
||||||
CCLOGINFO("deallocing Texture2D: %p - id=%u", this, _name);
|
CCLOGINFO("deallocing Texture2D: %p - id=%u", this, _name);
|
||||||
|
|
||||||
CC_SAFE_DELETE(_ninePatchInfo);
|
CC_SAFE_DELETE(_ninePatchInfo);
|
||||||
|
@ -179,11 +176,6 @@ backend::TextureBackend* Texture2D::getBackendTexture() const
|
||||||
return _texture;
|
return _texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Texture2D::getAlphaTextureName() const
|
|
||||||
{
|
|
||||||
return _alphaTexture == nullptr ? 0 : _alphaTexture->getBackendTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
Size Texture2D::getContentSize() const
|
Size Texture2D::getContentSize() const
|
||||||
{
|
{
|
||||||
Size ret;
|
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)
|
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
|
//the pixelFormat must be a certain value
|
||||||
CCASSERT(pixelFormat != PixelFormat::NONE && pixelFormat != PixelFormat::AUTO, "the \"pixelFormat\" param must be a certain value!");
|
CCASSERT(pixelFormat != PixelFormat::NONE && pixelFormat != PixelFormat::AUTO, "the \"pixelFormat\" param must be a certain value!");
|
||||||
|
@ -308,7 +422,7 @@ bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::Pi
|
||||||
CCASSERT(textureDescriptor.textureFormat != backend::PixelFormat::NONE, "PixelFormat should not be NONE");
|
CCASSERT(textureDescriptor.textureFormat != backend::PixelFormat::NONE, "PixelFormat should not be NONE");
|
||||||
|
|
||||||
if (_texture->getTextureFormat() != textureDescriptor.textureFormat)
|
if (_texture->getTextureFormat() != textureDescriptor.textureFormat)
|
||||||
_texture->updateTextureDescriptor(textureDescriptor);
|
_texture->updateTextureDescriptor(textureDescriptor, index);
|
||||||
|
|
||||||
if (info.compressed)
|
if (info.compressed)
|
||||||
{
|
{
|
||||||
|
@ -316,7 +430,7 @@ bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::Pi
|
||||||
}
|
}
|
||||||
else
|
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)
|
||||||
|
@ -335,6 +449,7 @@ bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::Pi
|
||||||
height = MAX(height >> 1, 1);
|
height = MAX(height >> 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
_contentSize = Size((float)pixelsWide, (float)pixelsHigh);
|
_contentSize = Size((float)pixelsWide, (float)pixelsHigh);
|
||||||
_pixelsWide = pixelsWide;
|
_pixelsWide = pixelsWide;
|
||||||
_pixelsHigh = pixelsHigh;
|
_pixelsHigh = pixelsHigh;
|
||||||
|
@ -344,16 +459,15 @@ bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, backend::Pi
|
||||||
|
|
||||||
_hasPremultipliedAlpha = preMultipliedAlpha;
|
_hasPremultipliedAlpha = preMultipliedAlpha;
|
||||||
_hasMipmaps = mipmapsNum > 1;
|
_hasMipmaps = mipmapsNum > 1;
|
||||||
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
if (_texture && width > 0 && height > 0)
|
||||||
{
|
{
|
||||||
uint8_t* textureData = static_cast<uint8_t*>(data);
|
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 true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -373,97 +487,9 @@ bool Texture2D::initWithImage(Image *image, backend::PixelFormat format)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int imageWidth = image->getWidth();
|
|
||||||
int imageHeight = image->getHeight();
|
|
||||||
this->_filePath = image->getFilePath();
|
this->_filePath = image->getFilePath();
|
||||||
Configuration *conf = Configuration::getInstance();
|
|
||||||
|
|
||||||
int maxTextureSize = conf->getMaxTextureSize();
|
return updateWithImage(image, format);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// implementation Texture2D (Text)
|
// 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)
|
void Texture2D::setTexParameters(const Texture2D::TexParams &desc)
|
||||||
{
|
{
|
||||||
_texture->updateSamplerDescriptor(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);
|
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.
|
/** Update with texture data.
|
||||||
|
|
||||||
@param data Specifies a pointer to the image data in memory.
|
@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 width Specifies the width of the texture subimage.
|
||||||
@param height Specifies the height 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.
|
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.
|
These functions require GL_TEXTURE_2D and both GL_VERTEX_ARRAY and GL_TEXTURE_COORD_ARRAY client states to be enabled.
|
||||||
|
@ -314,11 +326,6 @@ public:
|
||||||
|
|
||||||
std::string getPath()const { return _filePath; }
|
std::string getPath()const { return _filePath; }
|
||||||
|
|
||||||
void setAlphaTexture(Texture2D* alphaTexture);
|
|
||||||
Texture2D* getAlphaTexture() const;
|
|
||||||
|
|
||||||
bool getAlphaTextureName() const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Get pixel info map, the key-value pairs is PixelFormat and PixelFormatInfo.*/
|
/** Get pixel info map, the key-value pairs is PixelFormat and PixelFormatInfo.*/
|
||||||
static const PixelFormatInfoMap& getPixelFormatInfoMap();
|
static const PixelFormatInfoMap& getPixelFormatInfoMap();
|
||||||
|
@ -409,7 +416,6 @@ protected:
|
||||||
bool _valid;
|
bool _valid;
|
||||||
std::string _filePath;
|
std::string _filePath;
|
||||||
|
|
||||||
Texture2D* _alphaTexture;
|
|
||||||
backend::ProgramState* _programState = nullptr;
|
backend::ProgramState* _programState = nullptr;
|
||||||
backend::UniformLocation _mvpMatrixLocation;
|
backend::UniformLocation _mvpMatrixLocation;
|
||||||
backend::UniformLocation _textureLocation;
|
backend::UniformLocation _textureLocation;
|
||||||
|
|
|
@ -348,11 +348,7 @@ void TextureCache::addImageAsyncCallBack(float /*dt*/)
|
||||||
texture->autorelease();
|
texture->autorelease();
|
||||||
// ETC1 ALPHA supports.
|
// ETC1 ALPHA supports.
|
||||||
if (asyncStruct->imageAlpha.getFileType() == Image::Format::ETC) {
|
if (asyncStruct->imageAlpha.getFileType() == Image::Format::ETC) {
|
||||||
auto alphaTexture = new(std::nothrow) Texture2D();
|
texture->updateWithImage(&asyncStruct->imageAlpha, Texture2D::getDefaultAlphaPixelFormat(), 1);
|
||||||
if(alphaTexture != nullptr && alphaTexture->initWithImage(&asyncStruct->imageAlpha, asyncStruct->pixelFormat)) {
|
|
||||||
texture->setAlphaTexture(alphaTexture);
|
|
||||||
}
|
|
||||||
CC_SAFE_RELEASE(alphaTexture);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -421,14 +417,10 @@ Texture2D * TextureCache::addImage(const std::string &path)
|
||||||
std::string alphaFullPath = path + s_etc1AlphaFileSuffix;
|
std::string alphaFullPath = path + s_etc1AlphaFileSuffix;
|
||||||
if (image->getFileType() == Image::Format::ETC && !s_etc1AlphaFileSuffix.empty() && FileUtils::getInstance()->isFileExist(alphaFullPath))
|
if (image->getFileType() == Image::Format::ETC && !s_etc1AlphaFileSuffix.empty() && FileUtils::getInstance()->isFileExist(alphaFullPath))
|
||||||
{
|
{
|
||||||
Image alphaImage;
|
Image imageAlpha;
|
||||||
if (alphaImage.initWithImageFile(alphaFullPath))
|
if (imageAlpha.initWithImageFile(alphaFullPath))
|
||||||
{
|
{
|
||||||
Texture2D *pAlphaTexture = new(std::nothrow) Texture2D;
|
texture->updateWithImage(&imageAlpha, Texture2D::getDefaultAlphaPixelFormat(), 1);
|
||||||
if(pAlphaTexture != nullptr && pAlphaTexture->initWithImage(&alphaImage)) {
|
|
||||||
texture->setAlphaTexture(pAlphaTexture);
|
|
||||||
}
|
|
||||||
CC_SAFE_RELEASE(pAlphaTexture);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,8 +114,6 @@ protected:
|
||||||
/**Model view matrix when rendering the triangles.*/
|
/**Model view matrix when rendering the triangles.*/
|
||||||
Mat4 _mv;
|
Mat4 _mv;
|
||||||
|
|
||||||
uint8_t _alphaTextureID = 0; // ANDROID ETC1 ALPHA supports.
|
|
||||||
|
|
||||||
// Cached value to determine to generate material id or not.
|
// Cached value to determine to generate material id or not.
|
||||||
BlendFunc _blendType = BlendFunc::DISABLE;
|
BlendFunc _blendType = BlendFunc::DISABLE;
|
||||||
backend::Program* _program = nullptr;
|
backend::Program* _program = nullptr;
|
||||||
|
|
|
@ -36,6 +36,7 @@ set(COCOS_RENDERER_HEADER
|
||||||
renderer/backend/Types.h
|
renderer/backend/Types.h
|
||||||
renderer/backend/VertexLayout.h
|
renderer/backend/VertexLayout.h
|
||||||
renderer/backend/ProgramState.h
|
renderer/backend/ProgramState.h
|
||||||
|
renderer/backend/ProgramStateRegistry.h
|
||||||
renderer/backend/ShaderCache.h
|
renderer/backend/ShaderCache.h
|
||||||
renderer/backend/DeviceInfo.h
|
renderer/backend/DeviceInfo.h
|
||||||
)
|
)
|
||||||
|
@ -70,6 +71,7 @@ set(COCOS_RENDERER_SRC
|
||||||
renderer/backend/ProgramCache.cpp
|
renderer/backend/ProgramCache.cpp
|
||||||
renderer/backend/Program.cpp
|
renderer/backend/Program.cpp
|
||||||
renderer/backend/ProgramState.cpp
|
renderer/backend/ProgramState.cpp
|
||||||
|
renderer/backend/ProgramStateRegistry.cpp
|
||||||
renderer/backend/ShaderCache.cpp
|
renderer/backend/ShaderCache.cpp
|
||||||
renderer/backend/RenderPassDescriptor.cpp
|
renderer/backend/RenderPassDescriptor.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,20 +29,6 @@
|
||||||
#include "base/ccMacros.h"
|
#include "base/ccMacros.h"
|
||||||
#include "base/CCConfiguration.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
|
CC_BACKEND_BEGIN
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -126,6 +112,16 @@ bool ProgramCache::init()
|
||||||
addProgram(ProgramType::TERRAIN_3D);
|
addProgram(ProgramType::TERRAIN_3D);
|
||||||
addProgram(ProgramType::PARTICLE_TEXTURE_3D);
|
addProgram(ProgramType::PARTICLE_TEXTURE_3D);
|
||||||
addProgram(ProgramType::PARTICLE_COLOR_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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,6 +294,7 @@ void ProgramCache::removeUnusedProgram()
|
||||||
|
|
||||||
void ProgramCache::removeAllPrograms()
|
void ProgramCache::removeAllPrograms()
|
||||||
{
|
{
|
||||||
|
ProgramStateRegistry::getInstance()->clearPrograms();
|
||||||
for (auto& program : _cachedPrograms)
|
for (auto& program : _cachedPrograms)
|
||||||
{
|
{
|
||||||
program.second->release();
|
program.second->release();
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "ProgramStateRegistry.h"
|
||||||
|
|
||||||
CC_BACKEND_BEGIN
|
CC_BACKEND_BEGIN
|
||||||
/**
|
/**
|
||||||
* @addtogroup _backend
|
* @addtogroup _backend
|
||||||
|
|
|
@ -381,6 +381,14 @@ void ProgramState::setFragmentUniform(int location, const void* data, std::size_
|
||||||
#endif
|
#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)
|
void ProgramState::setTexture(const backend::UniformLocation& uniformLocation, uint32_t slot, backend::TextureBackend* texture)
|
||||||
{
|
{
|
||||||
switch (uniformLocation.shaderStage)
|
switch (uniformLocation.shaderStage)
|
||||||
|
|
|
@ -142,6 +142,14 @@ public:
|
||||||
*/
|
*/
|
||||||
void setCallbackUniform(const backend::UniformLocation&, const UniformCallback &);
|
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.
|
* Set texture.
|
||||||
* @param uniformLocation Specifies texture location.
|
* @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()
|
TextureBackend::~TextureBackend()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void TextureBackend::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor)
|
void TextureBackend::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int /*index*/)
|
||||||
{
|
{
|
||||||
_bitsPerElement = computeBitsPerElement(descriptor.textureFormat);
|
_bitsPerElement = computeBitsPerElement(descriptor.textureFormat);
|
||||||
_textureType = descriptor.textureType;
|
_textureType = descriptor.textureType;
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
* Update sampler
|
* Update sampler
|
||||||
* @param sampler Specifies the sampler descriptor.
|
* @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
|
* Read a block of pixels from the drawable texture
|
||||||
|
@ -78,7 +78,7 @@ public:
|
||||||
* Update texture description.
|
* Update texture description.
|
||||||
* @param descriptor Specifies texture and sampler descriptor.
|
* @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.
|
* Get texture format.
|
||||||
|
@ -104,6 +104,8 @@ public:
|
||||||
*/
|
*/
|
||||||
inline bool hasMipmaps() const { return _hasMipmaps; }
|
inline bool hasMipmaps() const { return _hasMipmaps; }
|
||||||
|
|
||||||
|
virtual int getCount() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @param descriptor Specifies the texture descirptor.
|
* @param descriptor Specifies the texture descirptor.
|
||||||
|
@ -136,7 +138,7 @@ public:
|
||||||
* @param height Specifies the height of the texture image.
|
* @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.
|
* @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
|
* 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 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.
|
* @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
|
* 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)
|
Texture2DGL::Texture2DGL(const TextureDescriptor& descriptor) : Texture2DBackend(descriptor)
|
||||||
{
|
{
|
||||||
glGenTextures(1, &_textureInfo.texture);
|
glGenTextures(1, &_textureInfo.textures[0]);
|
||||||
|
|
||||||
updateTextureDescriptor(descriptor);
|
updateTextureDescriptor(descriptor);
|
||||||
|
|
||||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||||
// Listen this event to restored texture id after coming to foreground on Android.
|
// Listen this event to restored texture id after coming to foreground on Android.
|
||||||
_backToForegroundListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom*){
|
_backToForegroundListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom*){
|
||||||
glGenTextures(1, &(this->_textureInfo.texture));
|
glGenTextures(1, &(this->_textureInfo.textures[0]));
|
||||||
this->initWithZeros();
|
this->initWithZeros();
|
||||||
});
|
});
|
||||||
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, -1);
|
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, -1);
|
||||||
|
@ -100,9 +100,9 @@ void Texture2DGL::initWithZeros()
|
||||||
free(data);
|
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);
|
UtilsGL::toGLTypes(descriptor.textureFormat, _textureInfo.internalFormat, _textureInfo.format, _textureInfo.type, _isCompressed);
|
||||||
|
|
||||||
bool isPow2 = ISPOW2(_width) && ISPOW2(_height);
|
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.sAddressModeGL = UtilsGL::toGLAddressMode(descriptor.samplerDescriptor.sAddressMode, isPow2);
|
||||||
_textureInfo.tAddressModeGL = UtilsGL::toGLAddressMode(descriptor.samplerDescriptor.tAddressMode, 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.
|
// Update data here because `updateData()` may not be invoked later.
|
||||||
// For example, a texture used as depth buffer will not invoke updateData().
|
// 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()
|
Texture2DGL::~Texture2DGL()
|
||||||
{
|
{
|
||||||
if (_textureInfo.texture)
|
_textureInfo.foreach([=](GLuint texID, int) { glDeleteTextures(1, &texID); });
|
||||||
glDeleteTextures(1, &_textureInfo.texture);
|
_textureInfo.textures.fill(0);
|
||||||
_textureInfo.texture = 0;
|
|
||||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener);
|
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture2DGL::updateSamplerDescriptor(const SamplerDescriptor &sampler) {
|
void Texture2DGL::updateSamplerDescriptor(const SamplerDescriptor &sampler, int index) {
|
||||||
bool isPow2 = ISPOW2(_width) && ISPOW2(_height);
|
bool isPow2 = ISPOW2(_width) && ISPOW2(_height);
|
||||||
_textureInfo.applySamplerDescriptor(sampler, isPow2, _hasMipmaps);
|
_textureInfo.applySamplerDescriptor(sampler, isPow2, _hasMipmaps);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
ensure(index);
|
||||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
|
||||||
|
|
||||||
if (sampler.magFilter != SamplerFilter::DONT_CARE)
|
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
|
//Set the row align only when mipmapsNum == 1 and the data is uncompressed
|
||||||
auto mipmapEnalbed = isMipmapEnabled(_textureInfo.minFilterGL) || isMipmapEnabled(_textureInfo.magFilterGL);
|
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);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
auto texID = ensure(index);
|
||||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
if (!texID) return;
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _textureInfo.magFilterGL);
|
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_MIN_FILTER, _textureInfo.minFilterGL);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _textureInfo.sAddressModeGL);
|
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.format,
|
||||||
_textureInfo.type,
|
_textureInfo.type,
|
||||||
data);
|
data);
|
||||||
|
|
||||||
|
cocos2d::log("---> Texture2DGL::updateData:%u", texID);
|
||||||
|
|
||||||
CHECK_GL_ERROR_DEBUG();
|
CHECK_GL_ERROR_DEBUG();
|
||||||
|
|
||||||
if(!_hasMipmaps && level > 0)
|
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);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
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_MAG_FILTER, _textureInfo.magFilterGL);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _textureInfo.minFilterGL);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _textureInfo.minFilterGL);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _textureInfo.sAddressModeGL);
|
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;
|
_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);
|
if (!ensure(index)) return;
|
||||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
|
||||||
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D,
|
glTexSubImage2D(GL_TEXTURE_2D,
|
||||||
level,
|
level,
|
||||||
|
@ -262,7 +262,7 @@ void Texture2DGL::updateCompressedSubData(std::size_t xoffset, std::size_t yoffs
|
||||||
uint8_t *data)
|
uint8_t *data)
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
glBindTexture(GL_TEXTURE_2D, _textureInfo.textures[0]);
|
||||||
|
|
||||||
glCompressedTexSubImage2D(GL_TEXTURE_2D,
|
glCompressedTexSubImage2D(GL_TEXTURE_2D,
|
||||||
level,
|
level,
|
||||||
|
@ -282,7 +282,21 @@ void Texture2DGL::updateCompressedSubData(std::size_t xoffset, std::size_t yoffs
|
||||||
void Texture2DGL::apply(int index) const
|
void Texture2DGL::apply(int index) const
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0 + index);
|
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()
|
void Texture2DGL::generateMipmaps()
|
||||||
|
@ -293,7 +307,7 @@ void Texture2DGL::generateMipmaps()
|
||||||
if(!_hasMipmaps)
|
if(!_hasMipmaps)
|
||||||
{
|
{
|
||||||
_hasMipmaps = true;
|
_hasMipmaps = true;
|
||||||
glBindTexture(GL_TEXTURE_2D, _textureInfo.texture);
|
glBindTexture(GL_TEXTURE_2D, _textureInfo.textures[0]);
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
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;
|
GLuint frameBuffer = 0;
|
||||||
glGenFramebuffers(1, &frameBuffer);
|
glGenFramebuffers(1, &frameBuffer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 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);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
auto bytePerRow = width * _bitsPerElement / 8;
|
auto bytePerRow = width * _bitsPerElement / 8;
|
||||||
|
@ -340,7 +354,7 @@ TextureCubeGL::TextureCubeGL(const TextureDescriptor& descriptor)
|
||||||
assert(_width == _height);
|
assert(_width == _height);
|
||||||
_textureType = TextureType::TEXTURE_CUBE;
|
_textureType = TextureType::TEXTURE_CUBE;
|
||||||
UtilsGL::toGLTypes(_textureFormat, _textureInfo.internalFormat, _textureInfo.format, _textureInfo.type, _isCompressed);
|
UtilsGL::toGLTypes(_textureFormat, _textureInfo.internalFormat, _textureInfo.format, _textureInfo.type, _isCompressed);
|
||||||
glGenTextures(1, &_textureInfo.texture);
|
glGenTextures(1, &_textureInfo.textures[0]);
|
||||||
updateSamplerDescriptor(descriptor.samplerDescriptor);
|
updateSamplerDescriptor(descriptor.samplerDescriptor);
|
||||||
|
|
||||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||||
|
@ -357,7 +371,7 @@ TextureCubeGL::TextureCubeGL(const TextureDescriptor& descriptor)
|
||||||
void TextureCubeGL::setTexParameters()
|
void TextureCubeGL::setTexParameters()
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0);
|
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_MIN_FILTER, _textureInfo.minFilterGL);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, _textureInfo.magFilterGL);
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, _textureInfo.magFilterGL);
|
||||||
|
@ -367,41 +381,40 @@ void TextureCubeGL::setTexParameters()
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
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);
|
UtilsGL::toGLTypes(descriptor.textureFormat, _textureInfo.internalFormat, _textureInfo.format, _textureInfo.type, _isCompressed);
|
||||||
_textureFormat = descriptor.textureFormat;
|
_textureFormat = descriptor.textureFormat;
|
||||||
updateSamplerDescriptor(descriptor.samplerDescriptor);
|
updateSamplerDescriptor(descriptor.samplerDescriptor, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCubeGL::~TextureCubeGL()
|
TextureCubeGL::~TextureCubeGL()
|
||||||
{
|
{
|
||||||
if(_textureInfo.texture)
|
_textureInfo.foreach([=](GLuint texID, int) { glDeleteTextures(1, &texID); });
|
||||||
glDeleteTextures(1, &_textureInfo.texture);
|
_textureInfo.textures.fill(0);
|
||||||
_textureInfo.texture = 0;
|
|
||||||
|
|
||||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener);
|
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCubeGL::updateSamplerDescriptor(const SamplerDescriptor &sampler)
|
void TextureCubeGL::updateSamplerDescriptor(const SamplerDescriptor &sampler, int /*index*/)
|
||||||
{
|
{
|
||||||
_textureInfo.applySamplerDescriptor(sampler, true, _hasMipmaps);
|
_textureInfo.applySamplerDescriptor(sampler, true, _hasMipmaps);
|
||||||
setTexParameters();
|
setTexParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCubeGL::apply(int index) const
|
void TextureCubeGL::apply(int location) const
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0+ index);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.texture);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.textures[0]);
|
||||||
CHECK_GL_ERROR_DEBUG();
|
CHECK_GL_ERROR_DEBUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCubeGL::updateFaceData(TextureCubeFace side, void *data)
|
void TextureCubeGL::updateFaceData(TextureCubeFace side, void *data)
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.texture);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.textures[0]);
|
||||||
CHECK_GL_ERROR_DEBUG();
|
CHECK_GL_ERROR_DEBUG();
|
||||||
int i = static_cast<int>(side);
|
int i = static_cast<int>(side);
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
|
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;
|
GLuint frameBuffer = 0;
|
||||||
glGenFramebuffers(1, &frameBuffer);
|
glGenFramebuffers(1, &frameBuffer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 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);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
auto bytePerRow = width * _bitsPerElement / 8;
|
auto bytePerRow = width * _bitsPerElement / 8;
|
||||||
|
@ -461,7 +474,7 @@ void TextureCubeGL::generateMipmaps()
|
||||||
if(!_hasMipmaps)
|
if(!_hasMipmaps)
|
||||||
{
|
{
|
||||||
_hasMipmaps = true;
|
_hasMipmaps = true;
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.texture);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, _textureInfo.textures[0]);
|
||||||
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include "../Texture.h"
|
#include "../Texture.h"
|
||||||
#include "platform/CCGL.h"
|
#include "platform/CCGL.h"
|
||||||
#include "base/CCEventListenerCustom.h"
|
#include "base/CCEventListenerCustom.h"
|
||||||
|
@ -36,6 +37,17 @@ CC_BACKEND_BEGIN
|
||||||
struct TextureInfoGL
|
struct TextureInfoGL
|
||||||
{
|
{
|
||||||
void applySamplerDescriptor(const SamplerDescriptor &desc, bool isPow2, bool hasMipmaps);
|
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 magFilterGL = GL_LINEAR;
|
||||||
GLint minFilterGL = GL_LINEAR;
|
GLint minFilterGL = GL_LINEAR;
|
||||||
|
@ -47,7 +59,7 @@ struct TextureInfoGL
|
||||||
GLenum format = GL_RGBA;
|
GLenum format = GL_RGBA;
|
||||||
GLenum type = GL_UNSIGNED_BYTE;
|
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 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.
|
* @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
|
* 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 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.
|
* @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
|
* Update a two-dimensional texture subimage in a compressed format
|
||||||
|
@ -113,7 +125,7 @@ public:
|
||||||
* Update sampler
|
* Update sampler
|
||||||
* @param sampler Specifies the sampler descriptor.
|
* @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
|
* Read a block of pixels from the drawable texture
|
||||||
|
@ -133,13 +145,13 @@ public:
|
||||||
* Update texture description.
|
* Update texture description.
|
||||||
* @param descriptor Specifies texture and sampler descriptor.
|
* @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.
|
* Get texture object.
|
||||||
* @return Texture object.
|
* @return Texture object.
|
||||||
*/
|
*/
|
||||||
inline GLuint getHandler() const { return _textureInfo.texture; }
|
inline GLuint getHandler() const { return _textureInfo.textures[0]; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set texture to pipeline
|
* Set texture to pipeline
|
||||||
|
@ -147,10 +159,15 @@ public:
|
||||||
*/
|
*/
|
||||||
void apply(int index) const;
|
void apply(int index) const;
|
||||||
|
|
||||||
|
GLuint ensure(int index);
|
||||||
|
|
||||||
|
int getCount() const override { return _maxTextureIndex + 1; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initWithZeros();
|
void initWithZeros();
|
||||||
|
|
||||||
TextureInfoGL _textureInfo;
|
TextureInfoGL _textureInfo;
|
||||||
|
int _maxTextureIndex = 0;
|
||||||
EventListener* _backToForegroundListener = nullptr;
|
EventListener* _backToForegroundListener = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -170,7 +187,7 @@ public:
|
||||||
* Update sampler
|
* Update sampler
|
||||||
* @param sampler Specifies the sampler descriptor.
|
* @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.
|
* Update texutre cube data in give slice side.
|
||||||
|
@ -195,19 +212,21 @@ public:
|
||||||
* Update texture description.
|
* Update texture description.
|
||||||
* @param descriptor Specifies texture and sampler descriptor.
|
* @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.
|
* Get texture object.
|
||||||
* @return Texture object.
|
* @return Texture object.
|
||||||
*/
|
*/
|
||||||
inline GLuint getHandler() const { return _textureInfo.texture; }
|
inline GLuint getHandler() const { return _textureInfo.textures[0]; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set texture to pipeline
|
* Set texture to pipeline
|
||||||
* @param index Specifies the texture image unit selector.
|
* @param index Specifies the texture image unit selector.
|
||||||
*/
|
*/
|
||||||
void apply(int index) const;
|
void apply(int location) const;
|
||||||
|
|
||||||
|
int getCount() const { return 1; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setTexParameters();
|
void setTexParameters();
|
||||||
|
|
|
@ -27,6 +27,7 @@ THE SOFTWARE.
|
||||||
#include "2d/CCSprite.h"
|
#include "2d/CCSprite.h"
|
||||||
#include "editor-support/cocostudio/CocosStudioExtension.h"
|
#include "editor-support/cocostudio/CocosStudioExtension.h"
|
||||||
#include "renderer/ccShaders.h"
|
#include "renderer/ccShaders.h"
|
||||||
|
#include "renderer/backend/ProgramStateRegistry.h"
|
||||||
|
|
||||||
NS_CC_BEGIN
|
NS_CC_BEGIN
|
||||||
|
|
||||||
|
@ -309,12 +310,8 @@ void AbstractCheckButton::onPressStateChangedToNormal()
|
||||||
_backGroundBoxDisabledRenderer->setVisible(false);
|
_backGroundBoxDisabledRenderer->setVisible(false);
|
||||||
_frontCrossDisabledRenderer->setVisible(false);
|
_frontCrossDisabledRenderer->setVisible(false);
|
||||||
|
|
||||||
auto isETC1 = _backGroundBoxRenderer->getTexture() && _backGroundBoxRenderer->getTexture()->getAlphaTextureName();
|
_backGroundBoxRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||||
_backGroundBoxRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
_frontCrossRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||||
|
|
||||||
isETC1 = _frontCrossRenderer->getTexture() && _frontCrossRenderer->getTexture()->getAlphaTextureName();
|
|
||||||
_frontCrossRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
|
||||||
|
|
||||||
|
|
||||||
_backGroundBoxRenderer->setScale(_backgroundTextureScaleX, _backgroundTextureScaleY);
|
_backGroundBoxRenderer->setScale(_backgroundTextureScaleX, _backgroundTextureScaleY);
|
||||||
_frontCrossRenderer->setScale(_backgroundTextureScaleX, _backgroundTextureScaleY);
|
_frontCrossRenderer->setScale(_backgroundTextureScaleX, _backgroundTextureScaleY);
|
||||||
|
@ -329,11 +326,8 @@ void AbstractCheckButton::onPressStateChangedToNormal()
|
||||||
|
|
||||||
void AbstractCheckButton::onPressStateChangedToPressed()
|
void AbstractCheckButton::onPressStateChangedToPressed()
|
||||||
{
|
{
|
||||||
auto isETC1 = _backGroundBoxRenderer->getTexture() && _backGroundBoxRenderer->getTexture()->getAlphaTextureName();
|
_backGroundBoxRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||||
_backGroundBoxRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
_frontCrossRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||||
|
|
||||||
isETC1 = _frontCrossRenderer->getTexture() && _frontCrossRenderer->getTexture()->getAlphaTextureName();
|
|
||||||
_frontCrossRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
|
||||||
|
|
||||||
if (!_isBackgroundSelectedTextureLoaded)
|
if (!_isBackgroundSelectedTextureLoaded)
|
||||||
{
|
{
|
||||||
|
@ -356,11 +350,9 @@ void AbstractCheckButton::onPressStateChangedToDisabled()
|
||||||
if (!_isBackgroundDisabledTextureLoaded
|
if (!_isBackgroundDisabledTextureLoaded
|
||||||
|| !_isFrontCrossDisabledTextureLoaded)
|
|| !_isFrontCrossDisabledTextureLoaded)
|
||||||
{
|
{
|
||||||
auto isETC1 = _backGroundBoxRenderer->getTexture() && _backGroundBoxRenderer->getTexture()->getAlphaTextureName();
|
_backGroundBoxRenderer->setProgramState(backend::ProgramType::GRAY_SCALE);
|
||||||
_backGroundBoxRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1Gray_frag:grayScale_frag);
|
|
||||||
|
|
||||||
isETC1 = _frontCrossRenderer->getTexture() && _frontCrossRenderer->getTexture()->getAlphaTextureName();
|
_frontCrossRenderer->setProgramState(backend::ProgramType::GRAY_SCALE);
|
||||||
_frontCrossRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1Gray_frag:grayScale_frag);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "2d/CCDrawNode.h"
|
#include "2d/CCDrawNode.h"
|
||||||
#include "2d/CCCamera.h"
|
#include "2d/CCCamera.h"
|
||||||
#include "renderer/CCRenderer.h"
|
#include "renderer/CCRenderer.h"
|
||||||
|
#include "renderer/backend/ProgramStateRegistry.h"
|
||||||
|
|
||||||
using namespace cocos2d;
|
using namespace cocos2d;
|
||||||
using namespace cocos2d::ui;
|
using namespace cocos2d::ui;
|
||||||
|
@ -304,14 +305,13 @@ void Scale9Sprite::setState(Scale9Sprite::State state)
|
||||||
{
|
{
|
||||||
if (_brightState != state) {
|
if (_brightState != state) {
|
||||||
_brightState = state;
|
_brightState = state;
|
||||||
auto isETC1 = getTexture() && getTexture()->getAlphaTextureName();
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case State::NORMAL:
|
case State::NORMAL:
|
||||||
Sprite::updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
Sprite::setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||||
break;
|
break;
|
||||||
case State::GRAY:
|
case State::GRAY:
|
||||||
Sprite::updateShaders(positionTextureColor_vert, (isETC1)?etc1Gray_frag:grayScale_frag);
|
Sprite::setProgramState(backend::ProgramType::GRAY_SCALE);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -680,15 +680,13 @@ void Slider::onPressStateChangedToNormal()
|
||||||
_slidBallPressedRenderer->setVisible(false);
|
_slidBallPressedRenderer->setVisible(false);
|
||||||
_slidBallDisabledRenderer->setVisible(false);
|
_slidBallDisabledRenderer->setVisible(false);
|
||||||
|
|
||||||
auto isETC1 = _slidBallNormalRenderer->getTexture() && _slidBallNormalRenderer->getTexture()->getAlphaTextureName();
|
_slidBallNormalRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||||
_slidBallNormalRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
|
||||||
_slidBallNormalRenderer->setScale(_sliderBallNormalTextureScaleX, _sliderBallNormalTextureScaleY);
|
_slidBallNormalRenderer->setScale(_sliderBallNormalTextureScaleX, _sliderBallNormalTextureScaleY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Slider::onPressStateChangedToPressed()
|
void Slider::onPressStateChangedToPressed()
|
||||||
{
|
{
|
||||||
auto isETC1 = _slidBallNormalRenderer->getTexture() && _slidBallNormalRenderer->getTexture()->getAlphaTextureName();
|
_slidBallNormalRenderer->setProgramState(backend::ProgramType::POSITION_TEXTURE_COLOR);
|
||||||
_slidBallNormalRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
|
|
||||||
|
|
||||||
if (!_isSliderBallPressedTextureLoaded)
|
if (!_isSliderBallPressedTextureLoaded)
|
||||||
{
|
{
|
||||||
|
@ -707,8 +705,7 @@ void Slider::onPressStateChangedToDisabled()
|
||||||
{
|
{
|
||||||
if (!_isSliderBallDisabledTexturedLoaded)
|
if (!_isSliderBallDisabledTexturedLoaded)
|
||||||
{
|
{
|
||||||
auto isETC1 = _slidBallNormalRenderer->getTexture() && _slidBallNormalRenderer->getTexture()->getAlphaTextureName();
|
_slidBallNormalRenderer->setProgramState(backend::ProgramType::GRAY_SCALE);
|
||||||
_slidBallNormalRenderer->updateShaders(positionTextureColor_vert, (isETC1)?etc1Gray_frag:grayScale_frag);
|
|
||||||
_slidBallNormalRenderer->setVisible(true);
|
_slidBallNormalRenderer->setVisible(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue