diff --git a/spine-cocos2dx/src/spine/SkeletonRenderer.cpp b/spine-cocos2dx/src/spine/SkeletonRenderer.cpp index 0380fe8f2..dbc521d31 100644 --- a/spine-cocos2dx/src/spine/SkeletonRenderer.cpp +++ b/spine-cocos2dx/src/spine/SkeletonRenderer.cpp @@ -433,7 +433,7 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t #if COCOS2D_VERSION < 0x00040000 cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _glProgramState, blendFunc, triangles, transform, transformFlags); #else - cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, blendFunc, triangles, transform, transformFlags); + cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _programState, blendFunc, triangles, transform, transformFlags); #endif const float* verts = _clipper->getClippedVertices().buffer(); @@ -465,7 +465,7 @@ void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t #if COCOS2D_VERSION < 0x00040000 cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _glProgramState, blendFunc, triangles, transform, transformFlags); #else - cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, blendFunc, triangles, transform, transformFlags); + cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _programState, blendFunc, triangles, transform, transformFlags); #endif if (_effect) { diff --git a/spine-cocos2dx/src/spine/v4/SkeletonBatch.cpp b/spine-cocos2dx/src/spine/v4/SkeletonBatch.cpp index 2cdf7f017..651e286ca 100644 --- a/spine-cocos2dx/src/spine/v4/SkeletonBatch.cpp +++ b/spine-cocos2dx/src/spine/v4/SkeletonBatch.cpp @@ -40,6 +40,7 @@ using std::max; #include "renderer/ccShaders.h" #include "renderer/backend/Device.h" +#include "renderer/backend/ProgramState.h" namespace spine { @@ -60,22 +61,8 @@ void SkeletonBatch::destroyInstance () { SkeletonBatch::SkeletonBatch () { auto program = backend::Program::getBuiltinProgram(backend::ProgramType::POSITION_TEXTURE_COLOR); - _programState = std::make_shared(program); - - auto vertexLayout = _programState->getVertexLayout(); - - auto locPosition = _programState->getAttributeLocation("a_position"); - auto locTexcoord = _programState->getAttributeLocation("a_texCoord"); - auto locColor = _programState->getAttributeLocation("a_color"); - vertexLayout->setAttribute("a_position", locPosition, backend::VertexFormat::FLOAT3, offsetof(V3F_C4B_T2F, vertices), false); - vertexLayout->setAttribute("a_color", locColor, backend::VertexFormat::UBYTE4, offsetof(V3F_C4B_T2F, colors), true); - vertexLayout->setAttribute("a_texCoord", locTexcoord, backend::VertexFormat::FLOAT2, offsetof(V3F_C4B_T2F, texCoords), false); - vertexLayout->setLayout(sizeof(_vertices[0])); - - - _locMVP = _programState->getUniformLocation("u_MVPMatrix"); - _locTexture = _programState->getUniformLocation("u_texture"); - + _programState = new backend::ProgramState(program); // new default program state + updateProgramStateLayout(_programState); for (unsigned int i = 0; i < INITIAL_SIZE; i++) { _commandsPool.push_back(createNewTrianglesCommand()); } @@ -95,6 +82,25 @@ SkeletonBatch::~SkeletonBatch () { delete _commandsPool[i]; _commandsPool[i] = nullptr; } + + CC_SAFE_RELEASE(_programState); +} + +void SkeletonBatch::updateProgramStateLayout(cocos2d::backend::ProgramState* programState) +{ + auto vertexLayout = programState->getVertexLayout(); + + auto locPosition = programState->getAttributeLocation("a_position"); + auto locTexcoord = programState->getAttributeLocation("a_texCoord"); + auto locColor = programState->getAttributeLocation("a_color"); + vertexLayout->setAttribute("a_position", locPosition, backend::VertexFormat::FLOAT3, offsetof(V3F_C4B_T2F, vertices), false); + vertexLayout->setAttribute("a_color", locColor, backend::VertexFormat::UBYTE4, offsetof(V3F_C4B_T2F, colors), true); + vertexLayout->setAttribute("a_texCoord", locTexcoord, backend::VertexFormat::FLOAT2, offsetof(V3F_C4B_T2F, texCoords), false); + vertexLayout->setLayout(sizeof(_vertices[0])); + + + _locMVP = programState->getUniformLocation("u_MVPMatrix"); + _locTexture = programState->getUniformLocation("u_texture"); } void SkeletonBatch::update (float delta) { @@ -148,15 +154,27 @@ void SkeletonBatch::deallocateIndices(uint32_t numIndices) { } -cocos2d::TrianglesCommand* SkeletonBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) { +cocos2d::TrianglesCommand* SkeletonBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, backend::ProgramState* programState, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) { TrianglesCommand* command = nextFreeCommand(); const cocos2d::Mat4& projectionMat = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); - auto programState = command->getPipelineDescriptor().programState; - CCASSERT(programState, "programState should not be null"); + if (programState == nullptr) + programState = _programState; - programState->setUniform(_locMVP, projectionMat.m, sizeof(projectionMat.m)); - programState->setTexture(_locTexture, 0, texture->getBackendTexture()); + CCASSERT(programState, "programState should not be null"); + + auto& pipelinePS = command->getPipelineDescriptor().programState; + if (pipelinePS != programState) + { + CC_SAFE_RELEASE(pipelinePS); + pipelinePS = programState; + CC_SAFE_RETAIN(pipelinePS); + + updateProgramStateLayout(pipelinePS); + } + + pipelinePS->setUniform(_locMVP, projectionMat.m, sizeof(projectionMat.m)); + pipelinePS->setTexture(_locTexture, 0, texture->getBackendTexture()); command->init(globalOrder, texture, blendType, triangles, mv, flags); renderer->addCommand(command); @@ -177,12 +195,6 @@ cocos2d::TrianglesCommand* SkeletonBatch::nextFreeCommand() { } } auto* command = _commandsPool[_nextFreeCommand++]; - auto& pipelineDescriptor = command->getPipelineDescriptor(); - if (pipelineDescriptor.programState == nullptr) - { - CCASSERT(_programState, "programState should not be null"); - pipelineDescriptor.programState = _programState->clone(); - } return command; } diff --git a/spine-cocos2dx/src/spine/v4/SkeletonBatch.h b/spine-cocos2dx/src/spine/v4/SkeletonBatch.h index d0bae6b5b..7f96ca285 100644 --- a/spine-cocos2dx/src/spine/v4/SkeletonBatch.h +++ b/spine-cocos2dx/src/spine/v4/SkeletonBatch.h @@ -36,6 +36,12 @@ #include #include +namespace cocos2d { + namespace backend { + class ProgramState; + } +} + namespace spine { class SkeletonBatch { @@ -50,8 +56,10 @@ namespace spine { void deallocateVertices(uint32_t numVertices); unsigned short* allocateIndices(uint32_t numIndices); void deallocateIndices(uint32_t numVertices); - cocos2d::TrianglesCommand* addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags); + cocos2d::TrianglesCommand* addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::backend::ProgramState* programState, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags); + void updateProgramStateLayout(cocos2d::backend::ProgramState* programState); + protected: SkeletonBatch (); virtual ~SkeletonBatch (); @@ -61,7 +69,9 @@ namespace spine { cocos2d::TrianglesCommand* nextFreeCommand (); cocos2d::TrianglesCommand* createNewTrianglesCommand(); - std::shared_ptr _programState = nullptr; + + // the default program state for batch draw + cocos2d::backend::ProgramState* _programState = nullptr; cocos2d::backend::UniformLocation _locMVP; cocos2d::backend::UniformLocation _locTexture;