Sfoglia il codice sorgente

Fix custom program state not applied at cocos2d-x-4.0

halx99 4 anni fa
parent
commit
84b0af8ac5

+ 2 - 2
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) {

+ 39 - 27
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<backend::ProgramState>(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;
+
+	CCASSERT(programState, "programState should not be null");
 
-    programState->setUniform(_locMVP, projectionMat.m, sizeof(projectionMat.m));
-    programState->setTexture(_locTexture, 0, texture->getBackendTexture());
+	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;
 }
 

+ 12 - 2
spine-cocos2dx/src/spine/v4/SkeletonBatch.h

@@ -36,6 +36,12 @@
 #include <spine/spine.h>
 #include <vector>
 
+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<cocos2d::backend::ProgramState>     _programState = nullptr;
+
+        // the default program state for batch draw
+        cocos2d::backend::ProgramState*                     _programState = nullptr;
         cocos2d::backend::UniformLocation                   _locMVP;
         cocos2d::backend::UniformLocation                   _locTexture;