diff --git a/cocos2d-x/cocos/editor-support/MeshBuffer.cpp b/cocos2d-x/cocos/editor-support/MeshBuffer.cpp index 5fb12403..8f8af9d0 100644 --- a/cocos2d-x/cocos/editor-support/MeshBuffer.cpp +++ b/cocos2d-x/cocos/editor-support/MeshBuffer.cpp @@ -38,11 +38,10 @@ MeshBuffer::MeshBuffer(int vertexFormat) } MeshBuffer::MeshBuffer(int vertexFormat, size_t indexSize, size_t vertexSize) -: _vertexFormat(vertexFormat) -, _ib(indexSize) -, _vb(vertexSize * vertexFormat * sizeof(float)) -{ - _vb.setMaxSize(MAX_VERTEX_BUFFER_SIZE * _vertexFormat * sizeof(float)); + : _vertexFormat(vertexFormat), + _ib(indexSize), + _vb(vertexSize * (vertexFormat == 7 ? 6 : (vertexFormat == 8 ? 7 : vertexFormat)) * sizeof(float)) { + _vb.setMaxSize(MAX_VERTEX_BUFFER_SIZE * (vertexFormat == 7 ? 6 : (vertexFormat == 8 ? 7 : vertexFormat)) * sizeof(float)); _ib.setMaxSize(INIT_INDEX_BUFFER_SIZE); _vb.setFullCallback([this] { @@ -66,6 +65,12 @@ MeshBuffer::MeshBuffer(int vertexFormat, size_t indexSize, size_t vertexSize) case VF_XYUVCC: glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Two_Color, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Two_Color->getBytes()); break; + case VF_XYUVCT: + glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Color_TexId, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Color_TexId->getBytes()); + break; + case VF_XYUVCCT: + glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Two_Color_TexId, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Two_Color_TexId->getBytes()); + break; default: CCASSERT(false, "MeshBuffer constructor unknow vertex format"); break; @@ -126,6 +131,12 @@ void MeshBuffer::next() case VF_XYUVCC: glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Two_Color, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Two_Color->getBytes()); break; + case VF_XYUVCT: + glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Color_TexId, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Color_TexId->getBytes()); + break; + case VF_XYUVCCT: + glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Two_Color_TexId, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Two_Color_TexId->getBytes()); + break; default: CCASSERT(false, "MeshBuffer constructor unknow vertex format"); break; diff --git a/cocos2d-x/cocos/editor-support/MiddlewareMacro.h b/cocos2d-x/cocos/editor-support/MiddlewareMacro.h index df8fa261..3fbbcb00 100644 --- a/cocos2d-x/cocos/editor-support/MiddlewareMacro.h +++ b/cocos2d-x/cocos/editor-support/MiddlewareMacro.h @@ -46,3 +46,6 @@ #define VF_XYUVC 5 #define VF_XYUVCC 6 + +#define VF_XYUVCT 7 +#define VF_XYUVCCT 8 \ No newline at end of file diff --git a/cocos2d-x/cocos/editor-support/middleware-adapter.h b/cocos2d-x/cocos/editor-support/middleware-adapter.h index 4be794b7..c026fa8c 100644 --- a/cocos2d-x/cocos/editor-support/middleware-adapter.h +++ b/cocos2d-x/cocos/editor-support/middleware-adapter.h @@ -72,6 +72,45 @@ struct V2F_T2F_C4B_C4B cocos2d::Color4B color2; // 4 bytes }; +/** + * Vertex Format with x y u v color texId. + */ +struct V2F_T2F_C4B_T1F +{ + // vertices (2F) + cocos2d::Vec2 vertex; // 8 bytes + + // tex coords (2F) + Tex2F texCoord; // 8 bytes + + // colors (4B) + cocos2d::Color4B color; // 4 bytes + + // tex id (1F) + GLfloat texId; // 4 bytes +}; + +/** + * Vertex Format with x y u v color1 color2 texId. + */ +struct V2F_T2F_C4B_C4B_T1F +{ + // vertices (2F) + cocos2d::Vec2 vertex; // 8 bytes + + // tex coords (2F) + Tex2F texCoord; // 8 bytes + + // colors (4B) + cocos2d::Color4B color; // 4 bytes + + // colors (4B) + cocos2d::Color4B color2; // 4 bytes + + // tex id (1F) + GLfloat texId; // 4 bytes +}; + struct Triangles { /**Vertex data pointer.*/ @@ -96,6 +135,30 @@ struct TwoColorTriangles int indexCount = 0; }; +struct TrianglesTexId +{ + /**Vertex data pointer.*/ + V2F_T2F_C4B_T1F* verts = nullptr; + /**Index data pointer.*/ + unsigned short* indices = nullptr; + /**The number of vertices.*/ + int vertCount = 0; + /**The number of indices.*/ + int indexCount = 0; +}; + +struct TwoColorTrianglesTexId +{ + /**Vertex data pointer.*/ + V2F_T2F_C4B_C4B_T1F* verts = nullptr; + /**Index data pointer.*/ + unsigned short* indices = nullptr; + /**The number of vertices.*/ + int vertCount = 0; + /**The number of indices.*/ + int indexCount = 0; +}; + /////////////////////////////////////////////////////////////////////// // adapt to editor texture,this is a texture delegate,not real texture /////////////////////////////////////////////////////////////////////// diff --git a/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCache.h b/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCache.h index 3287212a..12a5efa5 100644 --- a/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCache.h +++ b/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCache.h @@ -52,7 +52,31 @@ namespace spine { private: cocos2d::middleware::Texture2D* _texture = nullptr; }; - + + struct TextureMultiData { + TextureMultiData(float textureId, int vertexFloatCount, + int indexOffset, + cocos2d::renderer::Texture* texture) + : textureId(textureId), + vertexFloatCount(vertexFloatCount), + indexOffset(indexOffset), + texture(texture){}; + + int vertexFloatCount = 0; + int indexOffset = 0; + float textureId = -1; + cocos2d::renderer::Texture* texture = nullptr; + }; + + struct SegmentMultiData { + public: + int indexCount = 0; + int vertexFloatCount = 0; + int blendMode = 0; + bool inEffect = false; + std::vector textureDatas; + }; + struct BoneData { cocos2d::Mat4 globalTransformMatrix; }; diff --git a/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.cpp b/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.cpp index fc9223e9..43f22367 100644 --- a/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.cpp +++ b/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.cpp @@ -35,12 +35,17 @@ #include "renderer/scene/assembler/CustomAssembler.hpp" #include "renderer/gfx/Texture.h" #include "spine-creator-support/AttachUtil.h" +#include USING_NS_CC; USING_NS_MW; using namespace cocos2d::renderer; static const std::string techStage = "opaque"; static const std::string textureKey = "texture"; +static const std::vector textureKeys = { + "texture", "texture2", "texture3", "texture4", + "texture5", "texture6", "texture7", "texture8", +}; namespace spine { @@ -138,9 +143,77 @@ namespace spine { } _curFrameIndex = frameIdx; } - - void SkeletonCacheAnimation::render(float dt) { + + std::vector + SkeletonCacheAnimation::toMultiSegments( + const std::vector& segments){ + std::vector multiSegments; + if (segments.size() <= 0) return multiSegments; + auto end = segments.end(); + auto cur = segments.begin(); + multiSegments.emplace_back(); + auto* tmp = &multiSegments.back(); + + auto getTextureId = [&]() -> float { + auto glID = (*cur)->getTexture()->getNativeTexture()->getHandle(); + auto result = _effectTextures.find(glID); + if (result == _effectTextures.end()) { + for (size_t i = 0; i < textureKeys.size(); i++) { + auto prop = _effect->getProperty(textureKeys[i]); + if (prop->getTexture()->getHandle() == glID) { + _effectTextures.insert(std::make_pair(glID, i)); + return i; + } + } + _effectTextures.insert(std::make_pair(glID, -1)); + return -1; + } else { + return result->second; + } + }; + + tmp->blendMode = (*cur)->blendMode; + tmp->indexCount = (*cur)->indexCount; + tmp->vertexFloatCount = (*cur)->vertexFloatCount; + float curTextureId = getTextureId(); + tmp->textureDatas.emplace_back(curTextureId, (*cur)->vertexFloatCount, 0, (*cur)->getTexture()->getNativeTexture()); + tmp->inEffect = curTextureId != -1; + cur++; + + while (cur != end) + { + float curTextureId = getTextureId(); + float tmpTextureId = tmp->textureDatas[0].textureId; + + if ((*cur)->blendMode != tmp->blendMode || + (tmpTextureId != -1 && curTextureId == -1) || + tmpTextureId == -1) { + multiSegments.emplace_back(); + tmp = &multiSegments.back(); + tmp->blendMode = (*cur)->blendMode; + tmp->indexCount = (*cur)->indexCount; + tmp->vertexFloatCount = (*cur)->vertexFloatCount; + tmp->textureDatas.emplace_back(curTextureId, (*cur)->vertexFloatCount, 0, (*cur)->getTexture()->getNativeTexture()); + tmp->inEffect = curTextureId != -1; + } else { + tmp->textureDatas.emplace_back(curTextureId, (*cur)->vertexFloatCount, tmp->indexCount, (*cur)->getTexture()->getNativeTexture()); + tmp->indexCount += (*cur)->indexCount; + tmp->vertexFloatCount += (*cur)->vertexFloatCount; + } + + cur++; + } + + return multiSegments; + } + + void SkeletonCacheAnimation::render(float dt) { + if (_useMulti) { + renderMulti(dt); + return; + } + if (!_nodeProxy || !_effect) { return; } @@ -377,6 +450,289 @@ namespace spine { _attachUtil->syncAttachedNode(_nodeProxy, frameData); } } + + void SkeletonCacheAnimation::renderMulti(float dt) { + if (!_nodeProxy || !_effect) { + return; + } + + CustomAssembler* assembler = (CustomAssembler*)_nodeProxy->getAssembler(); + if (assembler == nullptr) { + return; + } + assembler->reset(); + assembler->setUseModel(!_batch); + + if (!_animationData) return; + SkeletonCache::FrameData* frameData = _animationData->getFrameData(_curFrameIndex); + if (!frameData) return; + + auto& tmpSegments = frameData->getSegments(); + auto& colors = frameData->getColors(); + if (tmpSegments.size() == 0 || colors.size() == 0) return; + + auto mgr = MiddlewareManager::getInstance(); + if (!mgr->isRendering) return; + + _nodeColor.a = _nodeProxy->getRealOpacity() / (float)255; + + auto vertexFormat = _useTint ? VF_XYUVCCT : VF_XYUVCT; + middleware::MeshBuffer* mb = mgr->getMeshBuffer(vertexFormat); + middleware::IOBuffer& vb = mb->getVB(); + middleware::IOBuffer& ib = mb->getIB(); + const auto& srcVB = frameData->vb; + const auto& srcIB = frameData->ib; + + // vertex size int bytes with one color + int vbs1 = sizeof(V2F_T2F_C4B_T1F); + // vertex size in floats with one color + int vs1 = vbs1 / sizeof(float); + // vertex size int bytes with two color + int vbs2 = sizeof(V2F_T2F_C4B_C4B_T1F); + // vertex size in floats with two color + int vs2 = vbs2 / sizeof(float); + + int vbs3 = sizeof(V2F_T2F_C4B); + int vs3 = vbs3 / sizeof(float); + + int vbs4 = sizeof(V2F_T2F_C4B_C4B); + int vs4 = vbs4 / sizeof(float); + + int vs = _useTint ? vs2 : vs1; + int vbs = _useTint ? vbs2 : vbs1; + + const cocos2d::Mat4& nodeWorldMat = _nodeProxy->getWorldMatrix(); + + int colorOffset = 0; + SkeletonCache::ColorData* nowColor = colors[colorOffset++]; + auto maxVFOffset = nowColor->vertexFloatOffset; + + Color4B finalColor; + Color4B darkColor; + float tempR = 0.0f, tempG = 0.0f, tempB = 0.0f, tempA = 0.0f; + float multiplier = 1.0f; + int srcVertexBytesOffset = 0; + int srcVertexBytes = 0; + int vertexBytes = 0; + int vertexFloats = 0; + int tintBytes = 0; + int srcIndexBytesOffset = 0; + int indexBytes = 0; + GLuint textureHandle = 0; + double effectHash = 0; + int blendMode = 0; + int dstVertexOffset = 0; + float* dstVertexBuffer = nullptr; + unsigned int* dstColorBuffer = nullptr; + unsigned short* dstIndexBuffer = nullptr; + bool needColor = false; + BlendFactor curBlendSrc = BlendFactor::ONE; + BlendFactor curBlendDst = BlendFactor::ZERO; + + if (abs(_nodeColor.r - 1.0f) > 0.0001f || + abs(_nodeColor.g - 1.0f) > 0.0001f || + abs(_nodeColor.b - 1.0f) > 0.0001f || + abs(_nodeColor.a - 1.0f) > 0.0001f || + _premultipliedAlpha) { + needColor = true; + } + + auto handleColor = [&](SkeletonCache::ColorData* colorData){ + tempA = colorData->finalColor.a * _nodeColor.a; + multiplier = _premultipliedAlpha ? tempA / 255 : 1; + tempR = _nodeColor.r * multiplier; + tempG = _nodeColor.g * multiplier; + tempB = _nodeColor.b * multiplier; + + finalColor.a = (GLubyte)tempA; + finalColor.r = (GLubyte)(colorData->finalColor.r * tempR); + finalColor.g = (GLubyte)(colorData->finalColor.g * tempG); + finalColor.b = (GLubyte)(colorData->finalColor.b * tempB); + + darkColor.r = (GLubyte)(colorData->darkColor.r * tempR); + darkColor.g = (GLubyte)(colorData->darkColor.g * tempG); + darkColor.b = (GLubyte)(colorData->darkColor.b * tempB); + darkColor.a = _premultipliedAlpha ? 255 : 0; + }; + + handleColor(nowColor); + + // 重新生成多纹理使用的 segments + auto segments = toMultiSegments(tmpSegments); + + for (std::size_t segIndex = 0, segLen = segments.size(); segIndex < segLen; segIndex++) { + auto segment = &segments[segIndex]; + srcVertexBytes = segment->vertexFloatCount * sizeof(float); + if (!_useTint) { + vertexBytes = srcVertexBytes; + vertexFloats = segment->vertexFloatCount; + } else { + tintBytes = segment->vertexFloatCount / vs4 * sizeof(float); + vertexBytes = srcVertexBytes + tintBytes; + vertexFloats = vertexBytes / sizeof(float); + } + + // fill vertex buffer + vb.checkSpace(vertexBytes, true); + dstVertexOffset = (int)vb.getCurPos() / vbs; + dstVertexBuffer = (float*)vb.getCurBuffer(); + dstColorBuffer = (unsigned int*)vb.getCurBuffer(); + + char* srcBuffer = (char*)srcVB.getBuffer() + srcVertexBytesOffset; + auto curTextureData = segment->textureDatas.begin(); + auto curTextureDataVfc = (*curTextureData).vertexFloatCount * sizeof(float); + + if (!_useTint) { + int t = 0; + for (std::size_t srcBufferIdx = 0; srcBufferIdx < srcVertexBytes; srcBufferIdx += vbs4) { + if (curTextureDataVfc <= srcBufferIdx) { + curTextureData++; + curTextureDataVfc += (*curTextureData).vertexFloatCount * sizeof(float); + } + vb.writeBytes(srcBuffer + srcBufferIdx, vbs3); + vb.writeFloat32((*curTextureData).textureId); + } + } else { + for (std::size_t srcBufferIdx = 0; srcBufferIdx < srcVertexBytes; srcBufferIdx += vbs4) { + if (curTextureDataVfc <= srcBufferIdx) { + curTextureData++; + curTextureDataVfc += (*curTextureData).vertexFloatCount * sizeof(float); + } + vb.writeBytes(srcBuffer + srcBufferIdx, vbs4); + vb.writeFloat32((*curTextureData).textureId); + } + } + + // batch handle + if (_batch) { + cocos2d::Vec3* point = nullptr; + float tempZ = 0.0f; + for (auto posIndex = 0; posIndex < vertexFloats; posIndex += vs) + { + point = (cocos2d::Vec3*)(dstVertexBuffer + posIndex); + tempZ = point->z; + point->z = 0; + nodeWorldMat.transformPoint(point); + point->z = tempZ; + } + } + + // handle vertex color + if (needColor) { + int srcVertexFloatOffset = srcVertexBytesOffset / sizeof(float); + if (_useTint) { + for (auto colorIndex = 0; colorIndex < vertexFloats; colorIndex += vs, srcVertexFloatOffset += vs4) + { + if (srcVertexFloatOffset >= maxVFOffset) { + nowColor = colors[colorOffset++]; + handleColor(nowColor); + maxVFOffset = nowColor->vertexFloatOffset; + } + memcpy(dstColorBuffer + colorIndex + 4, &finalColor, sizeof(finalColor)); + memcpy(dstColorBuffer + colorIndex + 5, &darkColor, sizeof(darkColor)); + } + } else { + for (auto colorIndex = 0; colorIndex < vertexFloats; colorIndex += vs, srcVertexFloatOffset += vs4) + { + if (srcVertexFloatOffset >= maxVFOffset) { + nowColor = colors[colorOffset++]; + handleColor(nowColor); + maxVFOffset = nowColor->vertexFloatOffset; + } + memcpy(dstColorBuffer + colorIndex + 4, &finalColor, sizeof(finalColor)); + } + } + } + + // move src vertex buffer offset + srcVertexBytesOffset += srcVertexBytes; + + // fill index buffer + indexBytes = segment->indexCount * sizeof(unsigned short); + ib.checkSpace(indexBytes, true); + assembler->updateIARange(segIndex, (int)ib.getCurPos() / sizeof(unsigned short), segment->indexCount); + dstIndexBuffer = (unsigned short*)ib.getCurBuffer(); + ib.writeBytes((char*)srcIB.getBuffer() + srcIndexBytesOffset, indexBytes); + + curTextureData = ++segment->textureDatas.begin(); + curTextureDataVfc = 0; + auto leftTextureData = segment->textureDatas.begin(); + auto curTextureDataIo = curTextureData == segment->textureDatas.end() ? INT_MAX : (*curTextureData).indexOffset; + + for (auto indexPos = 0; indexPos < segment->indexCount; indexPos++) { + if (curTextureDataIo <= indexPos) { + curTextureDataVfc += (*leftTextureData).vertexFloatCount / vs4; + leftTextureData = curTextureData; + curTextureData++; + curTextureDataIo = curTextureData == segment->textureDatas.end() ? INT_MAX : (*curTextureData).indexOffset; + } + dstIndexBuffer[indexPos] += dstVertexOffset + curTextureDataVfc; + } + srcIndexBytesOffset += indexBytes; + + // set assembler glvb and glib + assembler->updateIABuffer(segIndex, mb->getGLVB(), mb->getGLIB()); + + // handle material + blendMode = segment->blendMode; + effectHash = + segment->inEffect + ? ((blendMode << 16) + ((int)_useTint << 24) + + ((int)_batch << 25) + ((int)_effect->getHash() << 26)) + : (segment->textureDatas[0].texture->getHandle() + (blendMode << 16) + ((int)_useTint << 24) + + ((int)_batch << 25) + ((int)_effect->getHash() << 26)); + EffectVariant* renderEffect = assembler->getEffect(segIndex); + bool needUpdate = false; + if (renderEffect) { + double renderHash = renderEffect->getHash(); + if (abs(renderHash - effectHash) >= 0.01) { + needUpdate = true; + } + } + else { + auto effect = new cocos2d::renderer::EffectVariant(); + effect->autorelease(); + effect->copy(_effect); + + assembler->updateEffect(segIndex, effect); + renderEffect = effect; + needUpdate = true; + } + + if (needUpdate) { + if (!segment->inEffect) { + renderEffect->setProperty(textureKey, segment->textureDatas[0].texture); + } + + switch (blendMode) { + case BlendMode_Additive: + curBlendSrc = _premultipliedAlpha ? BlendFactor::ONE : BlendFactor::SRC_ALPHA; + curBlendDst = BlendFactor::ONE; + break; + case BlendMode_Multiply: + curBlendSrc = BlendFactor::DST_COLOR; + curBlendDst = BlendFactor::ONE_MINUS_SRC_ALPHA; + break; + case BlendMode_Screen: + curBlendSrc = BlendFactor::ONE; + curBlendDst = BlendFactor::ONE_MINUS_SRC_COLOR; + break; + default: + curBlendSrc = _premultipliedAlpha ? BlendFactor::ONE : BlendFactor::SRC_ALPHA; + curBlendDst = BlendFactor::ONE_MINUS_SRC_ALPHA; + } + renderEffect->setBlend(true, BlendOp::ADD, curBlendSrc, curBlendDst, + BlendOp::ADD, curBlendSrc, curBlendDst); + } + + renderEffect->updateHash(effectHash); + } + + if (_attachUtil) + { + _attachUtil->syncAttachedNode(_nodeProxy, frameData); + } + } Skeleton* SkeletonCacheAnimation::getSkeleton() const { return _skeletonCache->getSkeleton(); @@ -466,7 +822,11 @@ namespace spine { void SkeletonCacheAnimation::setUseTint(bool enabled) { _useTint = enabled; } - + + void SkeletonCacheAnimation::setUseMulti(bool enabled) { + _useMulti = enabled; + } + void SkeletonCacheAnimation::setAnimation (const std::string& name, bool loop) { _playTimes = loop ? 0 : 1; _animationName = name; @@ -524,6 +884,7 @@ namespace spine { } void SkeletonCacheAnimation::setEffect(cocos2d::renderer::EffectVariant* effect) { + _effectTextures.clear(); if (effect == _effect) return; CC_SAFE_RELEASE(_effect); _effect = effect; diff --git a/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.h b/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.h index 63ab1b05..49193e0e 100644 --- a/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.h +++ b/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonCacheAnimation.h @@ -47,7 +47,11 @@ namespace spine { virtual void update(float dt) override; virtual void render(float dt) override; virtual uint32_t getRenderOrder() const override; - + + void renderMulti(float dt); + std::vector toMultiSegments( + const std::vector& segments); + Skeleton* getSkeleton() const; void setTimeScale (float scale); @@ -78,7 +82,8 @@ namespace spine { void onEnable(); void onDisable(); void setUseTint(bool enabled); - + void setUseMulti(bool enabled); + void setAnimation (const std::string& name, bool loop); void addAnimation (const std::string& name, bool loop, float delay = 0); Animation* findAnimation(const std::string& name) const; @@ -118,7 +123,8 @@ namespace spine { bool _isAniComplete = true; std::string _animationName = ""; bool _useTint = false; - + bool _useMulti = false; + struct AniQueueData { std::string animationName = ""; bool loop = false; @@ -127,5 +133,7 @@ namespace spine { std::queue _animationQueue; AniQueueData* _headAnimation = nullptr; CacheModeAttachUtil* _attachUtil = nullptr; + + std::unordered_map _effectTextures = std::unordered_map(); }; } diff --git a/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp b/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp index 243352f8..8d705efd 100644 --- a/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp +++ b/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp @@ -39,6 +39,7 @@ #include "SkeletonDataMgr.h" #include "renderer/gfx/Texture.h" #include "spine-creator-support/AttachUtil.h" +#include USING_NS_CC; USING_NS_MW; @@ -51,6 +52,10 @@ using namespace cocos2d::renderer; static const std::string techStage = "opaque"; static const std::string textureKey = "texture"; +static const std::vector textureKeys = { + "texture", "texture2", "texture3", "texture4", + "texture5", "texture6", "texture7", "texture8", +}; static Cocos2dTextureLoader textureLoader; @@ -286,17 +291,17 @@ void SkeletonRenderer::render (float deltaTime) { Color4F darkColor; AttachmentVertices* attachmentVertices = nullptr; bool inRange = _startSlotIndex != -1 || _endSlotIndex != -1 ? false : true; - auto vertexFormat = _useTint? VF_XYUVCC : VF_XYUVC; + auto vertexFormat = _useMulti ? (_useTint ? VF_XYUVCCT : VF_XYUVCT) : (_useTint? VF_XYUVCC : VF_XYUVC); middleware::MeshBuffer* mb = mgr->getMeshBuffer(vertexFormat); middleware::IOBuffer& vb = mb->getVB(); middleware::IOBuffer& ib = mb->getIB(); // vertex size int bytes with one color - int vbs1 = sizeof(V2F_T2F_C4B); - // vertex size in floats with one color + int vbs1 = _useMulti ? sizeof(V2F_T2F_C4B_T1F) : sizeof(V2F_T2F_C4B); + // vertex size in floats with one color int vs1 = vbs1 / sizeof(float); // vertex size int bytes with two color - int vbs2 = sizeof(V2F_T2F_C4B_C4B); + int vbs2 = _useMulti ? sizeof(V2F_T2F_C4B_C4B_T1F) :sizeof(V2F_T2F_C4B_C4B); // verex size in floats with two color int vs2 = vbs2 / sizeof(float); const cocos2d::Mat4& nodeWorldMat = _nodeProxy->getWorldMatrix(); @@ -310,8 +315,11 @@ void SkeletonRenderer::render (float deltaTime) { int preBlendMode = -1; GLuint preTextureIndex = -1; GLuint curTextureIndex = -1; - - int preISegWritePos = -1; + + float curTextureId = -1; + bool texInEffect = false; + + int preISegWritePos = -1; int curISegLen = 0; int materialLen = 0; @@ -353,8 +361,14 @@ void SkeletonRenderer::render (float deltaTime) { curBlendSrc = _premultipliedAlpha ? BlendFactor::ONE : BlendFactor::SRC_ALPHA; curBlendDst = BlendFactor::ONE_MINUS_SRC_ALPHA; } - - double curHash = curTextureIndex + (curBlendMode << 16) + ((int)_useTint << 24) + ((int)_batch << 25) + ((int)_effect->getHash() << 26); + + double curHash = + (_useMulti && texInEffect) + ? ((curBlendMode << 16) + ((int)_useTint << 24) + + ((int)_batch << 25) + ((int)_effect->getHash() << 26)) + : (curTextureIndex + (curBlendMode << 16) + + ((int)_useTint << 24) + ((int)_batch << 25) + + ((int)_effect->getHash() << 26)); EffectVariant* renderEffect = assembler->getEffect(materialLen); bool needUpdate = false; if (renderEffect) { @@ -374,7 +388,10 @@ void SkeletonRenderer::render (float deltaTime) { } if (needUpdate) { - renderEffect->setProperty(textureKey, texture->getNativeTexture()); + if (!_useMulti || !texInEffect) { + renderEffect->setProperty(textureKey, + texture->getNativeTexture()); + } renderEffect->setBlend(true, BlendOp::ADD, curBlendSrc, curBlendDst, BlendOp::ADD, curBlendSrc, curBlendDst); } @@ -439,6 +456,8 @@ void SkeletonRenderer::render (float deltaTime) { Triangles triangles; TwoColorTriangles trianglesTwoColor; + TrianglesTexId trianglesTexId; + TwoColorTrianglesTexId trianglesTwoColorTexId; if (slot->getAttachment()->getRTTI().isExactly(RegionAttachment::rtti)) { RegionAttachment* attachment = (RegionAttachment*)slot->getAttachment(); @@ -450,34 +469,68 @@ void SkeletonRenderer::render (float deltaTime) { continue; } - if (!_useTint) { - triangles.vertCount = attachmentVertices->_triangles->vertCount; - vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B); - isFull |= vb.checkSpace(vbSize, true); - triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer(); - memcpy(triangles.verts, attachmentVertices->_triangles->verts, vbSize); - attachment->computeWorldVertices(slot->getBone(), (float*)triangles.verts, 0, vs1); + if (!_useMulti) { + if (!_useTint) { + triangles.vertCount = attachmentVertices->_triangles->vertCount; + vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B); + isFull |= vb.checkSpace(vbSize, true); + triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer(); + memcpy(triangles.verts, attachmentVertices->_triangles->verts, vbSize); + attachment->computeWorldVertices(slot->getBone(), (float*)triangles.verts, 0, vs1); - triangles.indexCount = attachmentVertices->_triangles->indexCount; - ibSize = triangles.indexCount * sizeof(unsigned short); - ib.checkSpace(ibSize, true); - triangles.indices = (unsigned short*)ib.getCurBuffer(); - memcpy(triangles.indices, attachmentVertices->_triangles->indices, ibSize); - } else { - trianglesTwoColor.vertCount = attachmentVertices->_triangles->vertCount; - vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B); - isFull |= vb.checkSpace(vbSize, true); - trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer(); - for (int ii = 0; ii < trianglesTwoColor.vertCount; ii++) { - trianglesTwoColor.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord; + triangles.indexCount = attachmentVertices->_triangles->indexCount; + ibSize = triangles.indexCount * sizeof(unsigned short); + ib.checkSpace(ibSize, true); + triangles.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(triangles.indices, attachmentVertices->_triangles->indices, ibSize); + } else { + trianglesTwoColor.vertCount = attachmentVertices->_triangles->vertCount; + vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B); + isFull |= vb.checkSpace(vbSize, true); + trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer(); + for (int ii = 0; ii < trianglesTwoColor.vertCount; ii++) { + trianglesTwoColor.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord; + } + attachment->computeWorldVertices(slot->getBone(), (float*)trianglesTwoColor.verts, 0, vs2); + + trianglesTwoColor.indexCount = attachmentVertices->_triangles->indexCount; + ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short); + ib.checkSpace(ibSize, true); + trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize); + } + } else { + if (!_useTint) { + trianglesTexId.vertCount = attachmentVertices->_triangles->vertCount; + vbSize = trianglesTexId.vertCount * sizeof(V2F_T2F_C4B_T1F); + isFull |= vb.checkSpace(vbSize, true); + trianglesTexId.verts = (V2F_T2F_C4B_T1F*)vb.getCurBuffer(); + for (int ii = 0; ii < trianglesTexId.vertCount; ii++) { + trianglesTexId.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord; + } + attachment->computeWorldVertices(slot->getBone(), (float*)trianglesTexId.verts, 0, vs1); + + trianglesTexId.indexCount = attachmentVertices->_triangles->indexCount; + ibSize = trianglesTexId.indexCount * sizeof(unsigned short); + ib.checkSpace(ibSize, true); + trianglesTexId.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(trianglesTexId.indices, attachmentVertices->_triangles->indices, ibSize); + } else { + trianglesTwoColorTexId.vertCount = attachmentVertices->_triangles->vertCount; + vbSize = trianglesTwoColorTexId.vertCount * sizeof(V2F_T2F_C4B_C4B_T1F); + isFull |= vb.checkSpace(vbSize, true); + trianglesTwoColorTexId.verts = (V2F_T2F_C4B_C4B_T1F*)vb.getCurBuffer(); + for (int ii = 0; ii < trianglesTwoColorTexId.vertCount; ii++) { + trianglesTwoColorTexId.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord; + } + attachment->computeWorldVertices(slot->getBone(), (float*)trianglesTwoColorTexId.verts, 0, vs2); + + trianglesTwoColorTexId.indexCount = attachmentVertices->_triangles->indexCount; + ibSize = trianglesTwoColorTexId.indexCount * sizeof(unsigned short); + ib.checkSpace(ibSize, true); + trianglesTwoColorTexId.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(trianglesTwoColorTexId.indices, attachmentVertices->_triangles->indices, ibSize); } - attachment->computeWorldVertices(slot->getBone(), (float*)trianglesTwoColor.verts, 0, vs2); - - trianglesTwoColor.indexCount = attachmentVertices->_triangles->indexCount; - ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short); - ib.checkSpace(ibSize, true); - trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer(); - memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize); } color.r = attachment->getColor().r; @@ -488,7 +541,11 @@ void SkeletonRenderer::render (float deltaTime) { if(_debugSlots) { _debugBuffer->writeFloat32(DebugType::Slots); _debugBuffer->writeFloat32(8); - float* vertices = _useTint ? (float*)trianglesTwoColor.verts : (float*)triangles.verts; + float* vertices = + _useMulti ? (_useTint ? (float*)trianglesTwoColorTexId.verts + : (float*)trianglesTexId.verts) + : (_useTint ? (float*)trianglesTwoColor.verts + : (float*)triangles.verts); int stride = _useTint ? vs2 : vs1; // Quadrangle has 4 vertex. for (int ii = 0; ii < 4; ii ++) { @@ -507,34 +564,68 @@ void SkeletonRenderer::render (float deltaTime) { continue; } - if (!_useTint) { - triangles.vertCount = attachmentVertices->_triangles->vertCount; - vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B); - isFull |= vb.checkSpace(vbSize, true); - triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer(); - memcpy(triangles.verts, attachmentVertices->_triangles->verts, vbSize); - attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)triangles.verts, 0, vs1); + if (!_useMulti) { + if (!_useTint) { + triangles.vertCount = attachmentVertices->_triangles->vertCount; + vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B); + isFull |= vb.checkSpace(vbSize, true); + triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer(); + memcpy(triangles.verts, attachmentVertices->_triangles->verts, vbSize); + attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)triangles.verts, 0, vs1); - triangles.indexCount = attachmentVertices->_triangles->indexCount; - ibSize = triangles.indexCount * sizeof(unsigned short); - ib.checkSpace(ibSize, true); - triangles.indices = (unsigned short*)ib.getCurBuffer(); - memcpy(triangles.indices, attachmentVertices->_triangles->indices, ibSize); - } else { - trianglesTwoColor.vertCount = attachmentVertices->_triangles->vertCount; - vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B); - isFull |= vb.checkSpace(vbSize, true); - trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer(); - for (int ii = 0; ii < trianglesTwoColor.vertCount; ii++) { - trianglesTwoColor.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord; + triangles.indexCount = attachmentVertices->_triangles->indexCount; + ibSize = triangles.indexCount * sizeof(unsigned short); + ib.checkSpace(ibSize, true); + triangles.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(triangles.indices, attachmentVertices->_triangles->indices, ibSize); + } else { + trianglesTwoColor.vertCount = attachmentVertices->_triangles->vertCount; + vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B); + isFull |= vb.checkSpace(vbSize, true); + trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer(); + for (int ii = 0; ii < trianglesTwoColor.vertCount; ii++) { + trianglesTwoColor.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord; + } + attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)trianglesTwoColor.verts, 0, vs2); + + trianglesTwoColor.indexCount = attachmentVertices->_triangles->indexCount; + ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short); + ib.checkSpace(ibSize, true); + trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize); + } + } else { + if (!_useTint) { + trianglesTexId.vertCount = attachmentVertices->_triangles->vertCount; + vbSize = trianglesTexId.vertCount * sizeof(V2F_T2F_C4B_T1F); + isFull |= vb.checkSpace(vbSize, true); + trianglesTexId.verts = (V2F_T2F_C4B_T1F*)vb.getCurBuffer(); + for (int ii = 0; ii < trianglesTexId.vertCount; ii++) { + trianglesTexId.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord; + } + attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)trianglesTexId.verts, 0, vs1); + + trianglesTexId.indexCount = attachmentVertices->_triangles->indexCount; + ibSize = trianglesTexId.indexCount * sizeof(unsigned short); + ib.checkSpace(ibSize, true); + trianglesTexId.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(trianglesTexId.indices, attachmentVertices->_triangles->indices, ibSize); + } else { + trianglesTwoColorTexId.vertCount = attachmentVertices->_triangles->vertCount; + vbSize = trianglesTwoColorTexId.vertCount * sizeof(V2F_T2F_C4B_C4B_T1F); + isFull |= vb.checkSpace(vbSize, true); + trianglesTwoColorTexId.verts = (V2F_T2F_C4B_C4B_T1F*)vb.getCurBuffer(); + for (int ii = 0; ii < trianglesTwoColorTexId.vertCount; ii++) { + trianglesTwoColorTexId.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord; + } + attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)trianglesTwoColorTexId.verts, 0, vs2); + + trianglesTwoColorTexId.indexCount = attachmentVertices->_triangles->indexCount; + ibSize = trianglesTwoColorTexId.indexCount * sizeof(unsigned short); + ib.checkSpace(ibSize, true); + trianglesTwoColorTexId.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(trianglesTwoColorTexId.indices, attachmentVertices->_triangles->indices, ibSize); } - attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)trianglesTwoColor.verts, 0, vs2); - - trianglesTwoColor.indexCount = attachmentVertices->_triangles->indexCount; - ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short); - ib.checkSpace(ibSize, true); - trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer(); - memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize); } color.r = attachment->getColor().r; @@ -543,10 +634,23 @@ void SkeletonRenderer::render (float deltaTime) { color.a = attachment->getColor().a; if(_debugMesh) { - int indexCount = _useTint ? trianglesTwoColor.indexCount : triangles.indexCount; - unsigned short* indices = _useTint ? (unsigned short*)trianglesTwoColor.indices : (unsigned short*)triangles.indices; - float* vertices = _useTint ? (float*)trianglesTwoColor.verts : (float*)triangles.verts; - + int indexCount = + _useMulti ? (_useTint ? trianglesTwoColorTexId.indexCount + : trianglesTexId.indexCount) + : (_useTint ? trianglesTwoColor.indexCount + : triangles.indexCount); + unsigned short* indices = + _useMulti + ? (_useTint ? (unsigned short*)trianglesTwoColorTexId.indices + : (unsigned short*)trianglesTexId.indices) + : (_useTint ? (unsigned short*)trianglesTwoColor.indices + : (unsigned short*)triangles.indices); + float* vertices = + _useMulti ? (_useTint ? (float*)trianglesTwoColorTexId.verts + : (float*)trianglesTexId.verts) + : (_useTint ? (float*)trianglesTwoColor.verts + : (float*)triangles.verts); + int stride = _useTint ? vs2 : vs1; _debugBuffer->writeFloat32(DebugType::Mesh); _debugBuffer->writeFloat32(indexCount * 2); @@ -598,214 +702,465 @@ void SkeletonRenderer::render (float deltaTime) { darkColor.b = 0; } darkColor.a = _premultipliedAlpha ? 255 : 0; - - // One color tint logic - if (!_useTint) { - // Cliping logic - if (_clipper->isClipping()) { - _clipper->clipTriangles((float*)&triangles.verts[0].vertex, triangles.indices, triangles.indexCount, (float*)&triangles.verts[0].texCoord, vs1); - - if (_clipper->getClippedTriangles().size() == 0) { - _clipper->clipEnd(*slot); - continue; - } - - triangles.vertCount = (int)_clipper->getClippedVertices().size() >> 1; - vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B); - isFull |= vb.checkSpace(vbSize, true); - triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer(); - - triangles.indexCount = (int)_clipper->getClippedTriangles().size(); - ibSize = triangles.indexCount * sizeof(unsigned short); - ib.checkSpace(ibSize, true); - triangles.indices = (unsigned short*)ib.getCurBuffer(); - memcpy(triangles.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size()); - - float* verts = _clipper->getClippedVertices().buffer(); - float* uvs = _clipper->getClippedUVs().buffer(); - if (effect) { - Color light; - Color dark; - light.r = color.r / 255.0f; - light.g = color.g / 255.0f; - light.b = color.b / 255.0f; - light.a = color.a / 255.0f; - dark.r = dark.g = dark.b = dark.a = 0; - for (int v = 0, vn = triangles.vertCount, vv = 0; v < vn; ++v, vv+=2) { - V2F_T2F_C4B* vertex = triangles.verts + v; - Color lightCopy = light; - Color darkCopy = dark; - vertex->vertex.x = verts[vv]; - vertex->vertex.y = verts[vv + 1]; - vertex->texCoord.u = uvs[vv]; - vertex->texCoord.v = uvs[vv + 1]; - effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); - vertex->color.r = (GLubyte)(lightCopy.r * 255); - vertex->color.g = (GLubyte)(lightCopy.g * 255); - vertex->color.b = (GLubyte)(lightCopy.b * 255); - vertex->color.a = (GLubyte)(lightCopy.a * 255); - } - } else { - for (int v = 0, vn = triangles.vertCount, vv = 0; v < vn; ++v, vv+=2) { - V2F_T2F_C4B* vertex = triangles.verts + v; - vertex->vertex.x = verts[vv]; - vertex->vertex.y = verts[vv + 1]; - vertex->texCoord.u = uvs[vv]; - vertex->texCoord.v = uvs[vv + 1]; - vertex->color.r = (GLubyte)color.r; - vertex->color.g = (GLubyte)color.g; - vertex->color.b = (GLubyte)color.b; - vertex->color.a = (GLubyte)color.a; - } - } - // No cliping logic - } else { - if (effect) { - Color light; - Color dark; - light.r = color.r / 255.0f; - light.g = color.g / 255.0f; - light.b = color.b / 255.0f; - light.a = color.a / 255.0f; - dark.r = dark.g = dark.b = dark.a = 0; - for (int v = 0, vn = triangles.vertCount; v < vn; ++v) { - V2F_T2F_C4B* vertex = triangles.verts + v; - Color lightCopy = light; - Color darkCopy = dark; - effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); - vertex->color.r = (GLubyte)(lightCopy.r * 255); - vertex->color.g = (GLubyte)(lightCopy.g * 255); - vertex->color.b = (GLubyte)(lightCopy.b * 255); - vertex->color.a = (GLubyte)(lightCopy.a * 255); - } - } else { - for (int v = 0, vn = triangles.vertCount; v < vn; ++v) { - V2F_T2F_C4B* vertex = triangles.verts + v; - vertex->color.r = (GLubyte)color.r; - vertex->color.g = (GLubyte)color.g; - vertex->color.b = (GLubyte)color.b; - vertex->color.a = (GLubyte)color.a; - } - } - } - } - // Two color tint logic - else { - if (_clipper->isClipping()) { - _clipper->clipTriangles((float*)&trianglesTwoColor.verts[0].vertex, trianglesTwoColor.indices, trianglesTwoColor.indexCount, (float*)&trianglesTwoColor.verts[0].texCoord, vs2); - - if (_clipper->getClippedTriangles().size() == 0) { - _clipper->clipEnd(*slot); - continue; - } - - trianglesTwoColor.vertCount = (int)_clipper->getClippedVertices().size() >> 1; - vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B); - isFull |= vb.checkSpace(vbSize, true); - trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer(); - - trianglesTwoColor.indexCount = (int)_clipper->getClippedTriangles().size(); - ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short); - trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer(); - memcpy(trianglesTwoColor.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size()); - - float* verts = _clipper->getClippedVertices().buffer(); - float* uvs = _clipper->getClippedUVs().buffer(); - - if (effect) { - Color light; - Color dark; - light.r = color.r / 255.0f; - light.g = color.g / 255.0f; - light.b = color.b / 255.0f; - light.a = color.a / 255.0f; - dark.r = darkColor.r / 255.0f; - dark.g = darkColor.g / 255.0f; - dark.b = darkColor.b / 255.0f; - dark.a = darkColor.a / 255.0f; - for (int v = 0, vn = trianglesTwoColor.vertCount, vv = 0; v < vn; ++v, vv += 2) { - V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v; - Color lightCopy = light; - Color darkCopy = dark; - vertex->vertex.x = verts[vv]; - vertex->vertex.y = verts[vv + 1]; - vertex->texCoord.u = uvs[vv]; - vertex->texCoord.v = uvs[vv + 1]; - effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); - vertex->color.r = (GLubyte)(lightCopy.r * 255); - vertex->color.g = (GLubyte)(lightCopy.g * 255); - vertex->color.b = (GLubyte)(lightCopy.b * 255); - vertex->color.a = (GLubyte)(lightCopy.a * 255); - vertex->color2.r = (GLubyte)(darkCopy.r * 255); - vertex->color2.g = (GLubyte)(darkCopy.g * 255); - vertex->color2.b = (GLubyte)(darkCopy.b * 255); - vertex->color2.a = (GLubyte)darkColor.a; - } - } else { - for (int v = 0, vn = trianglesTwoColor.vertCount, vv = 0; v < vn; ++v, vv += 2) { - V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v; - vertex->vertex.x = verts[vv]; - vertex->vertex.y = verts[vv + 1]; - vertex->texCoord.u = uvs[vv]; - vertex->texCoord.v = uvs[vv + 1]; - vertex->color.r = (GLubyte)color.r; - vertex->color.g = (GLubyte)color.g; - vertex->color.b = (GLubyte)color.b; - vertex->color.a = (GLubyte)color.a; - vertex->color2.r = (GLubyte)darkColor.r; - vertex->color2.g = (GLubyte)darkColor.g; - vertex->color2.b = (GLubyte)darkColor.b; - vertex->color2.a = (GLubyte)darkColor.a; - } - } - } else { - if (effect) { - Color light; - Color dark; - light.r = color.r / 255.0f; - light.g = color.g / 255.0f; - light.b = color.b / 255.0f; - light.a = color.a / 255.0f; - dark.r = darkColor.r / 255.0f; - dark.g = darkColor.g / 255.0f; - dark.b = darkColor.b / 255.0f; - dark.a = darkColor.a / 255.0f; + + if (!_useMulti) { + // One color tint logic + if (!_useTint) { + // Cliping logic + if (_clipper->isClipping()) { + _clipper->clipTriangles((float*)&triangles.verts[0].vertex, triangles.indices, triangles.indexCount, (float*)&triangles.verts[0].texCoord, vs1); - for (int v = 0, vn = trianglesTwoColor.vertCount; v < vn; ++v) { - V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v; - Color lightCopy = light; - Color darkCopy = dark; - effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); - vertex->color.r = (GLubyte)(lightCopy.r * 255); - vertex->color.g = (GLubyte)(lightCopy.g * 255); - vertex->color.b = (GLubyte)(lightCopy.b * 255); - vertex->color.a = (GLubyte)(lightCopy.a * 255); - vertex->color2.r = (GLubyte)(darkCopy.r * 255); - vertex->color2.g = (GLubyte)(darkCopy.g * 255); - vertex->color2.b = (GLubyte)(darkCopy.b * 255); - vertex->color2.a = (GLubyte)darkColor.a; + if (_clipper->getClippedTriangles().size() == 0) { + _clipper->clipEnd(*slot); + continue; } + + triangles.vertCount = (int)_clipper->getClippedVertices().size() >> 1; + vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B); + isFull |= vb.checkSpace(vbSize, true); + triangles.verts = (V2F_T2F_C4B*)vb.getCurBuffer(); + + triangles.indexCount = (int)_clipper->getClippedTriangles().size(); + ibSize = triangles.indexCount * sizeof(unsigned short); + ib.checkSpace(ibSize, true); + triangles.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(triangles.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size()); + + float* verts = _clipper->getClippedVertices().buffer(); + float* uvs = _clipper->getClippedUVs().buffer(); + if (effect) { + Color light; + Color dark; + light.r = color.r / 255.0f; + light.g = color.g / 255.0f; + light.b = color.b / 255.0f; + light.a = color.a / 255.0f; + dark.r = dark.g = dark.b = dark.a = 0; + for (int v = 0, vn = triangles.vertCount, vv = 0; v < vn; ++v, vv+=2) { + V2F_T2F_C4B* vertex = triangles.verts + v; + Color lightCopy = light; + Color darkCopy = dark; + vertex->vertex.x = verts[vv]; + vertex->vertex.y = verts[vv + 1]; + vertex->texCoord.u = uvs[vv]; + vertex->texCoord.v = uvs[vv + 1]; + effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); + vertex->color.r = (GLubyte)(lightCopy.r * 255); + vertex->color.g = (GLubyte)(lightCopy.g * 255); + vertex->color.b = (GLubyte)(lightCopy.b * 255); + vertex->color.a = (GLubyte)(lightCopy.a * 255); + } + } else { + for (int v = 0, vn = triangles.vertCount, vv = 0; v < vn; ++v, vv+=2) { + V2F_T2F_C4B* vertex = triangles.verts + v; + vertex->vertex.x = verts[vv]; + vertex->vertex.y = verts[vv + 1]; + vertex->texCoord.u = uvs[vv]; + vertex->texCoord.v = uvs[vv + 1]; + vertex->color.r = (GLubyte)color.r; + vertex->color.g = (GLubyte)color.g; + vertex->color.b = (GLubyte)color.b; + vertex->color.a = (GLubyte)color.a; + } + } + // No cliping logic } else { - for (int v = 0, vn = trianglesTwoColor.vertCount; v < vn; ++v) { - V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v; - vertex->color.r = (GLubyte)color.r; - vertex->color.g = (GLubyte)color.g; - vertex->color.b = (GLubyte)color.b; - vertex->color.a = (GLubyte)color.a; - vertex->color2.r = (GLubyte)darkColor.r; - vertex->color2.g = (GLubyte)darkColor.g; - vertex->color2.b = (GLubyte)darkColor.b; - vertex->color2.a = (GLubyte)darkColor.a; + if (effect) { + Color light; + Color dark; + light.r = color.r / 255.0f; + light.g = color.g / 255.0f; + light.b = color.b / 255.0f; + light.a = color.a / 255.0f; + dark.r = dark.g = dark.b = dark.a = 0; + for (int v = 0, vn = triangles.vertCount; v < vn; ++v) { + V2F_T2F_C4B* vertex = triangles.verts + v; + Color lightCopy = light; + Color darkCopy = dark; + effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); + vertex->color.r = (GLubyte)(lightCopy.r * 255); + vertex->color.g = (GLubyte)(lightCopy.g * 255); + vertex->color.b = (GLubyte)(lightCopy.b * 255); + vertex->color.a = (GLubyte)(lightCopy.a * 255); + } + } else { + for (int v = 0, vn = triangles.vertCount; v < vn; ++v) { + V2F_T2F_C4B* vertex = triangles.verts + v; + vertex->color.r = (GLubyte)color.r; + vertex->color.g = (GLubyte)color.g; + vertex->color.b = (GLubyte)color.b; + vertex->color.a = (GLubyte)color.a; + } } } } + // Two color tint logic + else { + if (_clipper->isClipping()) { + _clipper->clipTriangles((float*)&trianglesTwoColor.verts[0].vertex, trianglesTwoColor.indices, trianglesTwoColor.indexCount, (float*)&trianglesTwoColor.verts[0].texCoord, vs2); + + if (_clipper->getClippedTriangles().size() == 0) { + _clipper->clipEnd(*slot); + continue; + } + + trianglesTwoColor.vertCount = (int)_clipper->getClippedVertices().size() >> 1; + vbSize = trianglesTwoColor.vertCount * sizeof(V2F_T2F_C4B_C4B); + isFull |= vb.checkSpace(vbSize, true); + trianglesTwoColor.verts = (V2F_T2F_C4B_C4B*)vb.getCurBuffer(); + + trianglesTwoColor.indexCount = (int)_clipper->getClippedTriangles().size(); + ibSize = trianglesTwoColor.indexCount * sizeof(unsigned short); + trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(trianglesTwoColor.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size()); + + float* verts = _clipper->getClippedVertices().buffer(); + float* uvs = _clipper->getClippedUVs().buffer(); + + if (effect) { + Color light; + Color dark; + light.r = color.r / 255.0f; + light.g = color.g / 255.0f; + light.b = color.b / 255.0f; + light.a = color.a / 255.0f; + dark.r = darkColor.r / 255.0f; + dark.g = darkColor.g / 255.0f; + dark.b = darkColor.b / 255.0f; + dark.a = darkColor.a / 255.0f; + for (int v = 0, vn = trianglesTwoColor.vertCount, vv = 0; v < vn; ++v, vv += 2) { + V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v; + Color lightCopy = light; + Color darkCopy = dark; + vertex->vertex.x = verts[vv]; + vertex->vertex.y = verts[vv + 1]; + vertex->texCoord.u = uvs[vv]; + vertex->texCoord.v = uvs[vv + 1]; + effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); + vertex->color.r = (GLubyte)(lightCopy.r * 255); + vertex->color.g = (GLubyte)(lightCopy.g * 255); + vertex->color.b = (GLubyte)(lightCopy.b * 255); + vertex->color.a = (GLubyte)(lightCopy.a * 255); + vertex->color2.r = (GLubyte)(darkCopy.r * 255); + vertex->color2.g = (GLubyte)(darkCopy.g * 255); + vertex->color2.b = (GLubyte)(darkCopy.b * 255); + vertex->color2.a = (GLubyte)darkColor.a; + } + } else { + for (int v = 0, vn = trianglesTwoColor.vertCount, vv = 0; v < vn; ++v, vv += 2) { + V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v; + vertex->vertex.x = verts[vv]; + vertex->vertex.y = verts[vv + 1]; + vertex->texCoord.u = uvs[vv]; + vertex->texCoord.v = uvs[vv + 1]; + vertex->color.r = (GLubyte)color.r; + vertex->color.g = (GLubyte)color.g; + vertex->color.b = (GLubyte)color.b; + vertex->color.a = (GLubyte)color.a; + vertex->color2.r = (GLubyte)darkColor.r; + vertex->color2.g = (GLubyte)darkColor.g; + vertex->color2.b = (GLubyte)darkColor.b; + vertex->color2.a = (GLubyte)darkColor.a; + } + } + } else { + if (effect) { + Color light; + Color dark; + light.r = color.r / 255.0f; + light.g = color.g / 255.0f; + light.b = color.b / 255.0f; + light.a = color.a / 255.0f; + dark.r = darkColor.r / 255.0f; + dark.g = darkColor.g / 255.0f; + dark.b = darkColor.b / 255.0f; + dark.a = darkColor.a / 255.0f; + + for (int v = 0, vn = trianglesTwoColor.vertCount; v < vn; ++v) { + V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v; + Color lightCopy = light; + Color darkCopy = dark; + effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); + vertex->color.r = (GLubyte)(lightCopy.r * 255); + vertex->color.g = (GLubyte)(lightCopy.g * 255); + vertex->color.b = (GLubyte)(lightCopy.b * 255); + vertex->color.a = (GLubyte)(lightCopy.a * 255); + vertex->color2.r = (GLubyte)(darkCopy.r * 255); + vertex->color2.g = (GLubyte)(darkCopy.g * 255); + vertex->color2.b = (GLubyte)(darkCopy.b * 255); + vertex->color2.a = (GLubyte)darkColor.a; + } + } else { + for (int v = 0, vn = trianglesTwoColor.vertCount; v < vn; ++v) { + V2F_T2F_C4B_C4B* vertex = trianglesTwoColor.verts + v; + vertex->color.r = (GLubyte)color.r; + vertex->color.g = (GLubyte)color.g; + vertex->color.b = (GLubyte)color.b; + vertex->color.a = (GLubyte)color.a; + vertex->color2.r = (GLubyte)darkColor.r; + vertex->color2.g = (GLubyte)darkColor.g; + vertex->color2.b = (GLubyte)darkColor.b; + vertex->color2.a = (GLubyte)darkColor.a; + } + } + } + } + + texture = attachmentVertices->_texture; + curTextureIndex = + attachmentVertices->_texture->getNativeTexture()->getHandle(); + // If texture or blendMode change,will change material. + if (preTextureIndex != curTextureIndex || + preBlendMode != slot->getData().getBlendMode() || isFull) { + flush(); + } } - - texture = attachmentVertices->_texture; - curTextureIndex = attachmentVertices->_texture->getNativeTexture()->getHandle(); - // If texture or blendMode change,will change material. - if (preTextureIndex != curTextureIndex || preBlendMode != slot->getData().getBlendMode() || isFull) { - flush(); + else { + texture = attachmentVertices->_texture; + curTextureIndex = attachmentVertices->_texture->getNativeTexture()->getHandle(); + + auto result = _effectTextures.find(curTextureIndex); + if (result == _effectTextures.end()) { + curTextureId = -1; + for (size_t i = 0; i < textureKeys.size(); i++) { + auto prop = _effect->getProperty(textureKeys[i]); + if (prop->getTexture()->getHandle() == curTextureIndex) { + curTextureId = i; + break; + } + } + _effectTextures.insert(std::make_pair( + curTextureIndex, curTextureId)); + } else { + curTextureId = result->second; + } + + if (curTextureId == -1) { + curTextureId = 0; + texInEffect = false; + } else { + texInEffect = true; + } + + // One color tint logic + if (!_useTint) { + // Cliping logic + if (_clipper->isClipping()) { + _clipper->clipTriangles((float*)&trianglesTexId.verts[0].vertex, trianglesTexId.indices, trianglesTexId.indexCount, (float*)&trianglesTexId.verts[0].texCoord, vs1); + + if (_clipper->getClippedTriangles().size() == 0) { + _clipper->clipEnd(*slot); + continue; + } + + trianglesTexId.vertCount = (int)_clipper->getClippedVertices().size() >> 1; + vbSize = trianglesTexId.vertCount * sizeof(V2F_T2F_C4B_T1F); + isFull |= vb.checkSpace(vbSize, true); + trianglesTexId.verts = (V2F_T2F_C4B_T1F*)vb.getCurBuffer(); + + trianglesTexId.indexCount = (int)_clipper->getClippedTriangles().size(); + ibSize = trianglesTexId.indexCount * sizeof(unsigned short); + ib.checkSpace(ibSize, true); + trianglesTexId.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(trianglesTexId.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size()); + + float* verts = _clipper->getClippedVertices().buffer(); + float* uvs = _clipper->getClippedUVs().buffer(); + if (effect) { + Color light; + Color dark; + light.r = color.r / 255.0f; + light.g = color.g / 255.0f; + light.b = color.b / 255.0f; + light.a = color.a / 255.0f; + dark.r = dark.g = dark.b = dark.a = 0; + for (int v = 0, vn = trianglesTexId.vertCount, vv = 0; v < vn; ++v, vv+=2) { + V2F_T2F_C4B_T1F* vertex = trianglesTexId.verts + v; + Color lightCopy = light; + Color darkCopy = dark; + vertex->vertex.x = verts[vv]; + vertex->vertex.y = verts[vv + 1]; + vertex->texCoord.u = uvs[vv]; + vertex->texCoord.v = uvs[vv + 1]; + effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); + vertex->color.r = (GLubyte)(lightCopy.r * 255); + vertex->color.g = (GLubyte)(lightCopy.g * 255); + vertex->color.b = (GLubyte)(lightCopy.b * 255); + vertex->color.a = (GLubyte)(lightCopy.a * 255); + vertex->texId = (GLfloat)(curTextureId); + } + } else { + for (int v = 0, vn = trianglesTexId.vertCount, vv = 0; v < vn; ++v, vv+=2) { + V2F_T2F_C4B_T1F* vertex = trianglesTexId.verts + v; + vertex->vertex.x = verts[vv]; + vertex->vertex.y = verts[vv + 1]; + vertex->texCoord.u = uvs[vv]; + vertex->texCoord.v = uvs[vv + 1]; + vertex->color.r = (GLubyte)color.r; + vertex->color.g = (GLubyte)color.g; + vertex->color.b = (GLubyte)color.b; + vertex->color.a = (GLubyte)color.a; + vertex->texId = (GLfloat)(curTextureId); + } + } + // No cliping logic + } else { + if (effect) { + Color light; + Color dark; + light.r = color.r / 255.0f; + light.g = color.g / 255.0f; + light.b = color.b / 255.0f; + light.a = color.a / 255.0f; + dark.r = dark.g = dark.b = dark.a = 0; + for (int v = 0, vn = trianglesTexId.vertCount; v < vn; ++v) { + V2F_T2F_C4B_T1F* vertex = trianglesTexId.verts + v; + Color lightCopy = light; + Color darkCopy = dark; + effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); + vertex->color.r = (GLubyte)(lightCopy.r * 255); + vertex->color.g = (GLubyte)(lightCopy.g * 255); + vertex->color.b = (GLubyte)(lightCopy.b * 255); + vertex->color.a = (GLubyte)(lightCopy.a * 255); + vertex->texId = (GLfloat)(curTextureId); + } + } else { + for (int v = 0, vn = trianglesTexId.vertCount; v < vn; ++v) { + V2F_T2F_C4B_T1F* vertex = trianglesTexId.verts + v; + vertex->color.r = (GLubyte)color.r; + vertex->color.g = (GLubyte)color.g; + vertex->color.b = (GLubyte)color.b; + vertex->color.a = (GLubyte)color.a; + vertex->texId = (GLfloat)(curTextureId); + } + } + } + } + // Two color tint logic + else { + if (_clipper->isClipping()) { + _clipper->clipTriangles((float*)&trianglesTwoColorTexId.verts[0].vertex, trianglesTwoColorTexId.indices, trianglesTwoColorTexId.indexCount, (float*)&trianglesTwoColorTexId.verts[0].texCoord, vs2); + + if (_clipper->getClippedTriangles().size() == 0) { + _clipper->clipEnd(*slot); + continue; + } + + trianglesTwoColorTexId.vertCount = (int)_clipper->getClippedVertices().size() >> 1; + vbSize = trianglesTwoColorTexId.vertCount * sizeof(V2F_T2F_C4B_C4B_T1F); + isFull |= vb.checkSpace(vbSize, true); + trianglesTwoColorTexId.verts = (V2F_T2F_C4B_C4B_T1F*)vb.getCurBuffer(); + + trianglesTwoColorTexId.indexCount = (int)_clipper->getClippedTriangles().size(); + ibSize = trianglesTwoColorTexId.indexCount * sizeof(unsigned short); + trianglesTwoColorTexId.indices = (unsigned short*)ib.getCurBuffer(); + memcpy(trianglesTwoColorTexId.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size()); + + float* verts = _clipper->getClippedVertices().buffer(); + float* uvs = _clipper->getClippedUVs().buffer(); + + if (effect) { + Color light; + Color dark; + light.r = color.r / 255.0f; + light.g = color.g / 255.0f; + light.b = color.b / 255.0f; + light.a = color.a / 255.0f; + dark.r = darkColor.r / 255.0f; + dark.g = darkColor.g / 255.0f; + dark.b = darkColor.b / 255.0f; + dark.a = darkColor.a / 255.0f; + for (int v = 0, vn = trianglesTwoColorTexId.vertCount, vv = 0; v < vn; ++v, vv += 2) { + V2F_T2F_C4B_C4B_T1F* vertex = trianglesTwoColorTexId.verts + v; + Color lightCopy = light; + Color darkCopy = dark; + vertex->vertex.x = verts[vv]; + vertex->vertex.y = verts[vv + 1]; + vertex->texCoord.u = uvs[vv]; + vertex->texCoord.v = uvs[vv + 1]; + effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); + vertex->color.r = (GLubyte)(lightCopy.r * 255); + vertex->color.g = (GLubyte)(lightCopy.g * 255); + vertex->color.b = (GLubyte)(lightCopy.b * 255); + vertex->color.a = (GLubyte)(lightCopy.a * 255); + vertex->color2.r = (GLubyte)(darkCopy.r * 255); + vertex->color2.g = (GLubyte)(darkCopy.g * 255); + vertex->color2.b = (GLubyte)(darkCopy.b * 255); + vertex->color2.a = (GLubyte)darkColor.a; + vertex->texId = (GLfloat)(curTextureId); + } + } else { + for (int v = 0, vn = trianglesTwoColorTexId.vertCount, vv = 0; v < vn; ++v, vv += 2) { + V2F_T2F_C4B_C4B_T1F* vertex = trianglesTwoColorTexId.verts + v; + vertex->vertex.x = verts[vv]; + vertex->vertex.y = verts[vv + 1]; + vertex->texCoord.u = uvs[vv]; + vertex->texCoord.v = uvs[vv + 1]; + vertex->color.r = (GLubyte)color.r; + vertex->color.g = (GLubyte)color.g; + vertex->color.b = (GLubyte)color.b; + vertex->color.a = (GLubyte)color.a; + vertex->color2.r = (GLubyte)darkColor.r; + vertex->color2.g = (GLubyte)darkColor.g; + vertex->color2.b = (GLubyte)darkColor.b; + vertex->color2.a = (GLubyte)darkColor.a; + vertex->texId = (GLfloat)(curTextureId); + } + } + } else { + if (effect) { + Color light; + Color dark; + light.r = color.r / 255.0f; + light.g = color.g / 255.0f; + light.b = color.b / 255.0f; + light.a = color.a / 255.0f; + dark.r = darkColor.r / 255.0f; + dark.g = darkColor.g / 255.0f; + dark.b = darkColor.b / 255.0f; + dark.a = darkColor.a / 255.0f; + + for (int v = 0, vn = trianglesTwoColorTexId.vertCount; v < vn; ++v) { + V2F_T2F_C4B_C4B_T1F* vertex = trianglesTwoColorTexId.verts + v; + Color lightCopy = light; + Color darkCopy = dark; + effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy); + vertex->color.r = (GLubyte)(lightCopy.r * 255); + vertex->color.g = (GLubyte)(lightCopy.g * 255); + vertex->color.b = (GLubyte)(lightCopy.b * 255); + vertex->color.a = (GLubyte)(lightCopy.a * 255); + vertex->color2.r = (GLubyte)(darkCopy.r * 255); + vertex->color2.g = (GLubyte)(darkCopy.g * 255); + vertex->color2.b = (GLubyte)(darkCopy.b * 255); + vertex->color2.a = (GLubyte)darkColor.a; + vertex->texId = (GLfloat)(curTextureId); + } + } else { + for (int v = 0, vn = trianglesTwoColorTexId.vertCount; v < vn; ++v) { + V2F_T2F_C4B_C4B_T1F* vertex = trianglesTwoColorTexId.verts + v; + vertex->color.r = (GLubyte)color.r; + vertex->color.g = (GLubyte)color.g; + vertex->color.b = (GLubyte)color.b; + vertex->color.a = (GLubyte)color.a; + vertex->color2.r = (GLubyte)darkColor.r; + vertex->color2.g = (GLubyte)darkColor.g; + vertex->color2.b = (GLubyte)darkColor.b; + vertex->color2.a = (GLubyte)darkColor.a; + vertex->texId = (GLfloat)(curTextureId); + } + } + } + } + + if (texInEffect) { + if (preBlendMode != slot->getData().getBlendMode() || isFull) { + flush(); + } + } else if (preTextureIndex != curTextureIndex || + preBlendMode != slot->getData().getBlendMode() || + isFull) { + flush(); + } } if (vbSize > 0 && ibSize > 0) { @@ -999,6 +1354,10 @@ void SkeletonRenderer::setUseTint(bool enabled) { _useTint = enabled; } +void SkeletonRenderer::setUseMulti(bool enabled) { + _useMulti = enabled; +} + void SkeletonRenderer::setVertexEffectDelegate(VertexEffectDelegate *effectDelegate) { if (_effectDelegate == effectDelegate) { return; @@ -1075,6 +1434,7 @@ void SkeletonRenderer::bindNodeProxy(cocos2d::renderer::NodeProxy* node) { } void SkeletonRenderer::setEffect(cocos2d::renderer::EffectVariant* effect) { + _effectTextures.clear(); if (effect == _effect) return; CC_SAFE_RELEASE(_effect); _effect = effect; diff --git a/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonRenderer.h b/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonRenderer.h index 1674035e..59e83a92 100644 --- a/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonRenderer.h +++ b/cocos2d-x/cocos/editor-support/spine-creator-support/SkeletonRenderer.h @@ -97,7 +97,9 @@ namespace spine { /* Enables/disables two color tinting for this instance. May break batching */ void setUseTint(bool enabled); - + + void setUseMulti(bool enabled); + /* Sets the vertex effect to be used, set to 0 to disable vertex effects */ void setVertexEffectDelegate(VertexEffectDelegate* effectDelegate); /* Sets the range of slots that should be rendered. Use -1, -1 to clear the range */ @@ -164,6 +166,7 @@ namespace spine { bool _premultipliedAlpha = false; SkeletonClipping* _clipper = nullptr; bool _useTint = false; + bool _useMulti = false; std::string _uuid = ""; int _startSlotIndex = -1; @@ -172,6 +175,9 @@ namespace spine { cocos2d::middleware::IOTypedArray* _debugBuffer = nullptr; cocos2d::renderer::NodeProxy* _nodeProxy = nullptr; cocos2d::renderer::EffectVariant* _effect = nullptr; + + std::unordered_map _effectTextures = std::unordered_map(); + RealTimeAttachUtil* _attachUtil = nullptr; }; diff --git a/cocos2d-x/cocos/editor-support/spine/AtlasAttachmentLoader.cpp b/cocos2d-x/cocos/editor-support/spine/AtlasAttachmentLoader.cpp index 92e4d16d..724e02d5 100644 --- a/cocos2d-x/cocos/editor-support/spine/AtlasAttachmentLoader.cpp +++ b/cocos2d-x/cocos/editor-support/spine/AtlasAttachmentLoader.cpp @@ -60,9 +60,12 @@ RegionAttachment *AtlasAttachmentLoader::newRegionAttachment(Skin &skin, const S RegionAttachment &attachment = *attachmentP; attachment.setRendererObject(regionP); - attachment.setUVs(region.u, region.v, region.u2, region.v2, region.rotate); + attachment.setUVs(region.u, region.v, region.u2, region.v2, region.degrees); + attachment._regionDegrees = region.degrees; attachment._regionOffsetX = region.offsetX; attachment._regionOffsetY = region.offsetY; + attachment._regionX = region.x; + attachment._regionY = region.y; attachment._regionWidth = (float)region.width; attachment._regionHeight = (float)region.height; attachment._regionOriginalWidth = (float)region.originalWidth; @@ -90,6 +93,8 @@ MeshAttachment *AtlasAttachmentLoader::newMeshAttachment(Skin &skin, const Strin attachment._regionDegrees = region.degrees; attachment._regionOffsetX = region.offsetX; attachment._regionOffsetY = region.offsetY; + attachment._regionX = region.x; + attachment._regionY = region.y; attachment._regionWidth = (float)region.width; attachment._regionHeight = (float)region.height; attachment._regionOriginalWidth = (float)region.originalWidth; diff --git a/cocos2d-x/cocos/editor-support/spine/MeshAttachment.cpp b/cocos2d-x/cocos/editor-support/spine/MeshAttachment.cpp index bc2afc75..60de0fa9 100644 --- a/cocos2d-x/cocos/editor-support/spine/MeshAttachment.cpp +++ b/cocos2d-x/cocos/editor-support/spine/MeshAttachment.cpp @@ -98,8 +98,8 @@ void MeshAttachment::updateUVs() { return; } case 270: { - float textureWidth = _regionWidth / (_regionU2 - _regionU); - float textureHeight = _regionHeight / (_regionV2 - _regionV); + float textureWidth = _regionHeight / (_regionV2 - _regionV); + float textureHeight = _regionWidth / (_regionU2 - _regionU); u -= _regionOffsetY / textureWidth; v -= _regionOffsetX / textureHeight; width = _regionOriginalHeight / textureWidth; @@ -217,6 +217,22 @@ void MeshAttachment::setRegionOffsetY(float inValue) { _regionOffsetY = inValue; } +float MeshAttachment::getRegionX() { + return _regionX; +} + +void MeshAttachment::setRegionX(float inValue) { + _regionX = inValue; +} + +float MeshAttachment::getRegionY() { + return _regionY; +} + +void MeshAttachment::setRegionY(float inValue) { + _regionY = inValue; +} + float MeshAttachment::getRegionWidth() { return _regionWidth; } diff --git a/cocos2d-x/cocos/editor-support/spine/MeshAttachment.h b/cocos2d-x/cocos/editor-support/spine/MeshAttachment.h index dece05f9..cb0b6c56 100644 --- a/cocos2d-x/cocos/editor-support/spine/MeshAttachment.h +++ b/cocos2d-x/cocos/editor-support/spine/MeshAttachment.h @@ -91,6 +91,12 @@ namespace spine { float getRegionOffsetY(); void setRegionOffsetY(float inValue); + float getRegionX(); + void setRegionX(float inValue); + + float getRegionY(); + void setRegionY(float inValue); + float getRegionWidth(); void setRegionWidth(float inValue); @@ -120,7 +126,7 @@ namespace spine { MeshAttachment* newLinkedMesh(); private: - float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight; + float _regionOffsetX, _regionOffsetY, _regionX, _regionY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight; MeshAttachment* _parentMesh; Vector _uvs; Vector _regionUVs; diff --git a/cocos2d-x/cocos/editor-support/spine/RegionAttachment.cpp b/cocos2d-x/cocos/editor-support/spine/RegionAttachment.cpp index 461a5a9f..1017eb60 100644 --- a/cocos2d-x/cocos/editor-support/spine/RegionAttachment.cpp +++ b/cocos2d-x/cocos/editor-support/spine/RegionAttachment.cpp @@ -103,26 +103,35 @@ void RegionAttachment::updateOffset() { _vertexOffset[BRY] = localYCos + localX2Sin; } -void RegionAttachment::setUVs(float u, float v, float u2, float v2, bool rotate) { - if (rotate) { - _uvs[URX] = u; - _uvs[URY] = v2; - _uvs[BRX] = u; - _uvs[BRY] = v; - _uvs[BLX] = u2; - _uvs[BLY] = v; - _uvs[ULX] = u2; - _uvs[ULY] = v2; - } else { - _uvs[ULX] = u; - _uvs[ULY] = v2; - _uvs[URX] = u; - _uvs[URY] = v; - _uvs[BRX] = u2; - _uvs[BRY] = v; - _uvs[BLX] = u2; - _uvs[BLY] = v2; - } +void RegionAttachment::setUVs(float u, float v, float u2, float v2, float degrees) { + if (degrees == 90) { + _uvs[URX] = u; + _uvs[URY] = v2; + _uvs[BRX] = u; + _uvs[BRY] = v; + _uvs[BLX] = u2; + _uvs[BLY] = v; + _uvs[ULX] = u2; + _uvs[ULY] = v2; + } else if (degrees == 270) { + _uvs[BLX] = u; + _uvs[BLY] = v2; + _uvs[ULX] = u; + _uvs[ULY] = v; + _uvs[URX] = u2; + _uvs[URY] = v; + _uvs[BRX] = u2; + _uvs[BRY] = v2; + } else { + _uvs[ULX] = u; + _uvs[ULY] = v2; + _uvs[URX] = u; + _uvs[URY] = v; + _uvs[BRX] = u2; + _uvs[BRY] = v; + _uvs[BLX] = u2; + _uvs[BLY] = v2; + } } void RegionAttachment::computeWorldVertices(Bone &bone, Vector &worldVertices, size_t offset, size_t stride) { @@ -223,6 +232,14 @@ void RegionAttachment::setPath(const String &inValue) { _path = inValue; } +float RegionAttachment::getRegionDegrees() { + return _regionDegrees; +} + +void RegionAttachment::setRegionDegrees(float inValue) { + _regionDegrees = inValue; +} + float RegionAttachment::getRegionOffsetX() { return _regionOffsetX; } @@ -239,6 +256,22 @@ void RegionAttachment::setRegionOffsetY(float inValue) { _regionOffsetY = inValue; } +float RegionAttachment::getRegionX() { + return _regionX; +} + +void RegionAttachment::setRegionX(float inValue) { + _regionX = inValue; +} + +float RegionAttachment::getRegionY() { + return _regionY; +} + +void RegionAttachment::setRegionY(float inValue) { + _regionY = inValue; +} + float RegionAttachment::getRegionWidth() { return _regionWidth; } diff --git a/cocos2d-x/cocos/editor-support/spine/RegionAttachment.h b/cocos2d-x/cocos/editor-support/spine/RegionAttachment.h index fe872070..26898266 100644 --- a/cocos2d-x/cocos/editor-support/spine/RegionAttachment.h +++ b/cocos2d-x/cocos/editor-support/spine/RegionAttachment.h @@ -54,7 +54,7 @@ namespace spine { void updateOffset(); - void setUVs(float u, float v, float u2, float v2, bool rotate); + void setUVs(float u, float v, float u2, float v2, float degress); /// Transforms the attachment's four vertices to world coordinates. /// @param bone The parent bone. @@ -84,12 +84,21 @@ namespace spine { const String& getPath(); void setPath(const String& inValue); + float getRegionDegrees(); + void setRegionDegrees(float inValue); + float getRegionOffsetX(); void setRegionOffsetX(float inValue); float getRegionOffsetY(); void setRegionOffsetY(float inValue); + float getRegionX(); + void setRegionX(float inValue); + + float getRegionY(); + void setRegionY(float inValue); + float getRegionWidth(); void setRegionWidth(float inValue); @@ -118,7 +127,7 @@ namespace spine { static const int BRY; float _x, _y, _rotation, _scaleX, _scaleY, _width, _height; - float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight; + float _regionOffsetX, _regionOffsetY, _regionX, _regionY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight; Vector _vertexOffset; Vector _uvs; String _path; @@ -127,6 +136,7 @@ namespace spine { float _regionU2; float _regionV2; Color _color; + float _regionDegrees; }; } diff --git a/cocos2d-x/cocos/editor-support/spine/Skin.cpp b/cocos2d-x/cocos/editor-support/spine/Skin.cpp index caf02258..e20acec9 100644 --- a/cocos2d-x/cocos/editor-support/spine/Skin.cpp +++ b/cocos2d-x/cocos/editor-support/spine/Skin.cpp @@ -143,6 +143,29 @@ Skin::AttachmentMap::Entries Skin::getAttachments() { return _attachments.getEntries(); } +std::vector> Skin::getAttachmentsForJSB() { + std::vector> vec; + + Skin::AttachmentMap::Entries entries = _attachments.getEntries(); + + size_t slotIndex = -1; + std::map* map = nullptr; + + while (entries.hasNext()) { + Skin::AttachmentMap::Entry &entry = entries.next(); + + if (slotIndex != entry._slotIndex){ + slotIndex = entry._slotIndex; + vec.emplace_back(); + map = &vec.back(); + } + + map->insert({ entry._name.buffer(), entry._attachment }); + } + + return vec; +} + void Skin::attachAll(Skeleton &skeleton, Skin &oldSkin) { Vector &slots = skeleton.getSlots(); Skin::AttachmentMap::Entries entries = oldSkin.getAttachments(); diff --git a/cocos2d-x/cocos/editor-support/spine/Skin.h b/cocos2d-x/cocos/editor-support/spine/Skin.h index 18dadba7..b7e0c865 100644 --- a/cocos2d-x/cocos/editor-support/spine/Skin.h +++ b/cocos2d-x/cocos/editor-support/spine/Skin.h @@ -147,6 +147,8 @@ public: AttachmentMap::Entries getAttachments(); + std::vector> getAttachmentsForJSB(); + Vector& getBones(); Vector& getConstraints(); diff --git a/cocos2d-x/cocos/renderer/Types.cpp b/cocos2d-x/cocos/renderer/Types.cpp index c0ae823f..55f805ca 100644 --- a/cocos2d-x/cocos/renderer/Types.cpp +++ b/cocos2d-x/cocos/renderer/Types.cpp @@ -44,6 +44,7 @@ const char* ATTRIB_NAME_UV4 = "a_uv4"; const char* ATTRIB_NAME_UV5 = "a_uv5"; const char* ATTRIB_NAME_UV6 = "a_uv6"; const char* ATTRIB_NAME_UV7 = "a_uv7"; +const char* ATTRIB_NAME_TEXID = "a_texId"; const size_t ATTRIB_NAME_POSITION_HASH = std::hash{}(ATTRIB_NAME_POSITION); const size_t ATTRIB_NAME_NORMAL_HASH = std::hash{}(ATTRIB_NAME_NORMAL); @@ -63,6 +64,7 @@ const size_t ATTRIB_NAME_UV4_HASH = std::hash{}(ATTRIB_NAME_UV4); const size_t ATTRIB_NAME_UV5_HASH = std::hash{}(ATTRIB_NAME_UV5); const size_t ATTRIB_NAME_UV6_HASH = std::hash{}(ATTRIB_NAME_UV6); const size_t ATTRIB_NAME_UV7_HASH = std::hash{}(ATTRIB_NAME_UV7); +const size_t ATTRIB_NAME_TEXID_HASH = std::hash{}(ATTRIB_NAME_TEXID); Rect Rect::ZERO; diff --git a/cocos2d-x/cocos/renderer/Types.h b/cocos2d-x/cocos/renderer/Types.h index b9b62da6..8166e6f2 100644 --- a/cocos2d-x/cocos/renderer/Types.h +++ b/cocos2d-x/cocos/renderer/Types.h @@ -152,6 +152,7 @@ extern const char* ATTRIB_NAME_UV4; extern const char* ATTRIB_NAME_UV5; extern const char* ATTRIB_NAME_UV6; extern const char* ATTRIB_NAME_UV7; +extern const char* ATTRIB_NAME_TEXID; extern const size_t ATTRIB_NAME_POSITION_HASH; extern const size_t ATTRIB_NAME_NORMAL_HASH; @@ -171,6 +172,7 @@ extern const size_t ATTRIB_NAME_UV4_HASH; extern const size_t ATTRIB_NAME_UV5_HASH; extern const size_t ATTRIB_NAME_UV6_HASH; extern const size_t ATTRIB_NAME_UV7_HASH; +extern const size_t ATTRIB_NAME_TEXID_HASH; // vertex attribute type enum class AttribType : uint16_t diff --git a/cocos2d-x/cocos/renderer/gfx/VertexFormat.cpp b/cocos2d-x/cocos/renderer/gfx/VertexFormat.cpp index dc881722..ddbeb647 100644 --- a/cocos2d-x/cocos/renderer/gfx/VertexFormat.cpp +++ b/cocos2d-x/cocos/renderer/gfx/VertexFormat.cpp @@ -48,6 +48,21 @@ static uint32_t attrTypeBytes(AttribType attrType) return 0; } +VertexFormat* VertexFormat::XY_UV_Two_Color_TexId = new VertexFormat(std::vector({ + Info(ATTRIB_NAME_POSITION, AttribType::FLOAT32, 2), + Info(ATTRIB_NAME_UV0, AttribType::FLOAT32, 2), + Info(ATTRIB_NAME_COLOR, AttribType::UINT8, 4, true), + Info(ATTRIB_NAME_COLOR0, AttribType::UINT8, 4, true), + Info(ATTRIB_NAME_TEXID, AttribType::FLOAT32, 1) +})); + +VertexFormat* VertexFormat::XY_UV_Color_TexId = new VertexFormat(std::vector({ + Info(ATTRIB_NAME_POSITION, AttribType::FLOAT32, 2), + Info(ATTRIB_NAME_UV0, AttribType::FLOAT32, 2), + Info(ATTRIB_NAME_COLOR, AttribType::UINT8, 4, true), + Info(ATTRIB_NAME_TEXID, AttribType::FLOAT32, 1) +})); + VertexFormat* VertexFormat::XY_UV_Two_Color = new VertexFormat(std::vector({ Info(ATTRIB_NAME_POSITION, AttribType::FLOAT32, 2), Info(ATTRIB_NAME_UV0, AttribType::FLOAT32, 2), diff --git a/cocos2d-x/cocos/renderer/gfx/VertexFormat.h b/cocos2d-x/cocos/renderer/gfx/VertexFormat.h index 9354d582..0ec10b12 100644 --- a/cocos2d-x/cocos/renderer/gfx/VertexFormat.h +++ b/cocos2d-x/cocos/renderer/gfx/VertexFormat.h @@ -166,7 +166,15 @@ public: * Gets total byte size of a vertex */ uint32_t getBytes() const { return _bytes; }; - + + /* + * Builtin VertexFormat with 2d position, uv, color, color0, texId attributes + */ + static VertexFormat* XY_UV_Two_Color_TexId; + /* + * Builtin VertexFormat with 2d position, uv, color, texId attributes + */ + static VertexFormat* XY_UV_Color_TexId; /* * Builtin VertexFormat with 2d position, uv, color, color0 attributes */ diff --git a/cocos2d-x/cocos/scripting/js-bindings/auto/api/jsb_cocos2dx_spine_auto_api.js b/cocos2d-x/cocos/scripting/js-bindings/auto/api/jsb_cocos2dx_spine_auto_api.js index 0eb52585..d30672b4 100644 --- a/cocos2d-x/cocos/scripting/js-bindings/auto/api/jsb_cocos2dx_spine_auto_api.js +++ b/cocos2d-x/cocos/scripting/js-bindings/auto/api/jsb_cocos2dx_spine_auto_api.js @@ -3938,14 +3938,14 @@ getRegionOriginalWidth : function ( * @param {float} arg1 * @param {float} arg2 * @param {float} arg3 - * @param {bool} arg4 + * @param {float} arg4 */ setUVs : function ( float, float, float, float, -bool +float ) { }, diff --git a/cocos2d-x/cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.cpp b/cocos2d-x/cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.cpp index 2e5b49be..eb56dce6 100644 --- a/cocos2d-x/cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.cpp +++ b/cocos2d-x/cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.cpp @@ -5938,6 +5938,44 @@ static bool js_cocos2dx_spine_MeshAttachment_setRegionOffsetX(se::State& s) } SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionOffsetX) +static bool js_cocos2dx_spine_MeshAttachment_setRegionY(se::State& s) +{ + spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_MeshAttachment_setRegionY : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 1) { + float arg0 = 0; + ok &= seval_to_float(args[0], &arg0); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionY : Error processing arguments"); + cobj->setRegionY(arg0); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionY) + +static bool js_cocos2dx_spine_MeshAttachment_setRegionX(se::State& s) +{ + spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_MeshAttachment_setRegionX : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 1) { + float arg0 = 0; + ok &= seval_to_float(args[0], &arg0); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionX : Error processing arguments"); + cobj->setRegionX(arg0); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionX) + static bool js_cocos2dx_spine_MeshAttachment_copy(se::State& s) { spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject(); @@ -6579,6 +6617,42 @@ static bool js_cocos2dx_spine_MeshAttachment_getRegionOffsetX(se::State& s) } SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionOffsetX) +static bool js_cocos2dx_spine_MeshAttachment_getRegionY(se::State& s) +{ + spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_MeshAttachment_getRegionY : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 0) { + float result = cobj->getRegionY(); + ok &= float_to_seval(result, &s.rval()); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_MeshAttachment_getRegionY : Error processing arguments"); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionY) + +static bool js_cocos2dx_spine_MeshAttachment_getRegionX(se::State& s) +{ + spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_MeshAttachment_getRegionX : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 0) { + float result = cobj->getRegionX(); + ok &= float_to_seval(result, &s.rval()); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_MeshAttachment_getRegionX : Error processing arguments"); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionX) + static bool js_cocos2dx_spine_MeshAttachment_getRegionV(se::State& s) { spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject(); @@ -6662,6 +6736,8 @@ bool js_register_cocos2dx_spine_MeshAttachment(se::Object* obj) cls->defineFunction("setRegionOriginalHeight", _SE(js_cocos2dx_spine_MeshAttachment_setRegionOriginalHeight)); cls->defineFunction("setRegionOffsetY", _SE(js_cocos2dx_spine_MeshAttachment_setRegionOffsetY)); cls->defineFunction("setRegionOffsetX", _SE(js_cocos2dx_spine_MeshAttachment_setRegionOffsetX)); + cls->defineFunction("setRegionY", _SE(js_cocos2dx_spine_MeshAttachment_setRegionY)); + cls->defineFunction("setRegionX", _SE(js_cocos2dx_spine_MeshAttachment_setRegionX)); cls->defineFunction("copy", _SE(js_cocos2dx_spine_MeshAttachment_copy)); cls->defineFunction("getRegionOriginalWidth", _SE(js_cocos2dx_spine_MeshAttachment_getRegionOriginalWidth)); cls->defineFunction("getWidth", _SE(js_cocos2dx_spine_MeshAttachment_getWidth)); @@ -6697,6 +6773,8 @@ bool js_register_cocos2dx_spine_MeshAttachment(se::Object* obj) cls->defineFunction("getTriangles", _SE(js_cocos2dx_spine_MeshAttachment_getTriangles)); cls->defineFunction("getRegionOffsetY", _SE(js_cocos2dx_spine_MeshAttachment_getRegionOffsetY)); cls->defineFunction("getRegionOffsetX", _SE(js_cocos2dx_spine_MeshAttachment_getRegionOffsetX)); + cls->defineFunction("getRegionY", _SE(js_cocos2dx_spine_MeshAttachment_getRegionY)); + cls->defineFunction("getRegionX", _SE(js_cocos2dx_spine_MeshAttachment_getRegionX)); cls->defineFunction("getRegionV", _SE(js_cocos2dx_spine_MeshAttachment_getRegionV)); cls->defineFunction("getRegionRotate", _SE(js_cocos2dx_spine_MeshAttachment_getRegionRotate)); cls->defineFunction("getParentMesh", _SE(js_cocos2dx_spine_MeshAttachment_getParentMesh)); @@ -7905,6 +7983,43 @@ static bool js_cocos2dx_spine_RegionAttachment_setRegionOriginalHeight(se::State } SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionOriginalHeight) +static bool js_cocos2dx_spine_RegionAttachment_setRegionDegrees(se::State& s) +{ + spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_setRegionDegrees : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 1) { + int arg0 = 0; + do { int32_t tmp = 0; ok &= seval_to_int32(args[0], &tmp); arg0 = (int)tmp; } while(false); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionDegrees : Error processing arguments"); + cobj->setRegionDegrees(arg0); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionDegrees) + +static bool js_cocos2dx_spine_RegionAttachment_getRegionDegrees(se::State& s) +{ + spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_getRegionDegrees : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 0) { + int result = cobj->getRegionDegrees(); + ok &= int32_to_seval(result, &s.rval()); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_getRegionDegrees : Error processing arguments"); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionDegrees) + static bool js_cocos2dx_spine_RegionAttachment_setRegionOffsetY(se::State& s) { spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject(); @@ -7943,6 +8058,44 @@ static bool js_cocos2dx_spine_RegionAttachment_setRegionOffsetX(se::State& s) } SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionOffsetX) +static bool js_cocos2dx_spine_RegionAttachment_setRegionY(se::State& s) +{ + spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_setRegionY : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 1) { + float arg0 = 0; + ok &= seval_to_float(args[0], &arg0); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionY : Error processing arguments"); + cobj->setRegionY(arg0); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionY) + +static bool js_cocos2dx_spine_RegionAttachment_setRegionX(se::State& s) +{ + spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_setRegionX : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 1) { + float arg0 = 0; + ok &= seval_to_float(args[0], &arg0); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionX : Error processing arguments"); + cobj->setRegionX(arg0); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionX) + static bool js_cocos2dx_spine_RegionAttachment_getRegionOriginalWidth(se::State& s) { spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject(); @@ -7973,12 +8126,12 @@ static bool js_cocos2dx_spine_RegionAttachment_setUVs(se::State& s) float arg1 = 0; float arg2 = 0; float arg3 = 0; - bool arg4; + float arg4 = 0; ok &= seval_to_float(args[0], &arg0); ok &= seval_to_float(args[1], &arg1); ok &= seval_to_float(args[2], &arg2); ok &= seval_to_float(args[3], &arg3); - ok &= seval_to_boolean(args[4], &arg4); + ok &= seval_to_float(args[4], &arg4); SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_setUVs : Error processing arguments"); cobj->setUVs(arg0, arg1, arg2, arg3, arg4); return true; @@ -8518,6 +8671,41 @@ static bool js_cocos2dx_spine_RegionAttachment_getRegionOffsetX(se::State& s) } SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionOffsetX) +static bool js_cocos2dx_spine_RegionAttachment_getRegionY(se::State& s) +{ + spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_getRegionY : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 0) { + float result = cobj->getRegionY(); + ok &= float_to_seval(result, &s.rval()); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_getRegionY : Error processing arguments"); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionY) + +static bool js_cocos2dx_spine_RegionAttachment_getRegionX(se::State& s) +{ + spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_getRegionX : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 0) { + float result = cobj->getRegionX(); + ok &= float_to_seval(result, &s.rval()); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_getRegionX : Error processing arguments"); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionX) extern se::Object* __jsb_spine_Attachment_proto; @@ -8529,6 +8717,8 @@ bool js_register_cocos2dx_spine_RegionAttachment(se::Object* obj) cls->defineFunction("setRegionOriginalHeight", _SE(js_cocos2dx_spine_RegionAttachment_setRegionOriginalHeight)); cls->defineFunction("setRegionOffsetY", _SE(js_cocos2dx_spine_RegionAttachment_setRegionOffsetY)); cls->defineFunction("setRegionOffsetX", _SE(js_cocos2dx_spine_RegionAttachment_setRegionOffsetX)); + cls->defineFunction("setRegionY", _SE(js_cocos2dx_spine_RegionAttachment_setRegionY)); + cls->defineFunction("setRegionX", _SE(js_cocos2dx_spine_RegionAttachment_setRegionX)); cls->defineFunction("getRegionOriginalWidth", _SE(js_cocos2dx_spine_RegionAttachment_getRegionOriginalWidth)); cls->defineFunction("setUVs", _SE(js_cocos2dx_spine_RegionAttachment_setUVs)); cls->defineFunction("getWidth", _SE(js_cocos2dx_spine_RegionAttachment_getWidth)); @@ -8560,6 +8750,10 @@ bool js_register_cocos2dx_spine_RegionAttachment(se::Object* obj) cls->defineFunction("getRegionOriginalHeight", _SE(js_cocos2dx_spine_RegionAttachment_getRegionOriginalHeight)); cls->defineFunction("getRegionOffsetY", _SE(js_cocos2dx_spine_RegionAttachment_getRegionOffsetY)); cls->defineFunction("getRegionOffsetX", _SE(js_cocos2dx_spine_RegionAttachment_getRegionOffsetX)); + cls->defineFunction("getRegionY", _SE(js_cocos2dx_spine_RegionAttachment_getRegionY)); + cls->defineFunction("getRegionX", _SE(js_cocos2dx_spine_RegionAttachment_getRegionX)); + cls->defineFunction("setRegionDegrees", _SE(js_cocos2dx_spine_RegionAttachment_setRegionDegrees)); + cls->defineFunction("getRegionDegrees", _SE(js_cocos2dx_spine_RegionAttachment_getRegionDegrees)); cls->install(); JSBClassType::registerClass(cls); @@ -12876,6 +13070,25 @@ static bool js_cocos2dx_spine_SkeletonRenderer_setUseTint(se::State& s) } SE_BIND_FUNC(js_cocos2dx_spine_SkeletonRenderer_setUseTint) +static bool js_cocos2dx_spine_SkeletonRenderer_setUseMulti(se::State& s) +{ + spine::SkeletonRenderer* cobj = (spine::SkeletonRenderer*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_SkeletonRenderer_setUseMulti : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 1) { + bool arg0; + ok &= seval_to_boolean(args[0], &arg0); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_SkeletonRenderer_setUseMulti : Error processing arguments"); + cobj->setUseMulti(arg0); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_SkeletonRenderer_setUseMulti) + static bool js_cocos2dx_spine_SkeletonRenderer_setTimeScale(se::State& s) { spine::SkeletonRenderer* cobj = (spine::SkeletonRenderer*)s.nativeThisObject(); @@ -13913,6 +14126,7 @@ bool js_register_cocos2dx_spine_SkeletonRenderer(se::Object* obj) auto cls = se::Class::create("Skeleton", obj, nullptr, _SE(js_cocos2dx_spine_SkeletonRenderer_constructor)); cls->defineFunction("setUseTint", _SE(js_cocos2dx_spine_SkeletonRenderer_setUseTint)); + cls->defineFunction("setUseMulti", _SE(js_cocos2dx_spine_SkeletonRenderer_setUseMulti)); cls->defineFunction("setTimeScale", _SE(js_cocos2dx_spine_SkeletonRenderer_setTimeScale)); cls->defineFunction("render", _SE(js_cocos2dx_spine_SkeletonRenderer_render)); cls->defineFunction("initWithUUID", _SE(js_cocos2dx_spine_SkeletonRenderer_initWithUUID)); @@ -15341,6 +15555,25 @@ static bool js_cocos2dx_spine_SkeletonCacheAnimation_setUseTint(se::State& s) } SE_BIND_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setUseTint) +static bool js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti(se::State& s) +{ + spine::SkeletonCacheAnimation* cobj = (spine::SkeletonCacheAnimation*)s.nativeThisObject(); + SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 1) { + bool arg0; + ok &= seval_to_boolean(args[0], &arg0); + SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti : Error processing arguments"); + cobj->setUseMulti(arg0); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti) + static bool js_cocos2dx_spine_SkeletonCacheAnimation_setTimeScale(se::State& s) { spine::SkeletonCacheAnimation* cobj = (spine::SkeletonCacheAnimation*)s.nativeThisObject(); @@ -16096,6 +16329,7 @@ bool js_register_cocos2dx_spine_SkeletonCacheAnimation(se::Object* obj) auto cls = se::Class::create("SkeletonCacheAnimation", obj, nullptr, _SE(js_cocos2dx_spine_SkeletonCacheAnimation_constructor)); cls->defineFunction("setUseTint", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setUseTint)); + cls->defineFunction("setUseMulti", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti)); cls->defineFunction("setTimeScale", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setTimeScale)); cls->defineFunction("findAnimation", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_findAnimation)); cls->defineFunction("setAttachUtil", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setAttachUtil)); diff --git a/cocos2d-x/cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.hpp b/cocos2d-x/cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.hpp index c88f8478..cc86d543 100644 --- a/cocos2d-x/cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.hpp +++ b/cocos2d-x/cocos/scripting/js-bindings/auto/jsb_cocos2dx_spine_auto.hpp @@ -420,6 +420,8 @@ bool register_all_cocos2dx_spine(se::Object* obj); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionOriginalHeight); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionOffsetY); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionOffsetX); +SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionY); +SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionX); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_copy); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionOriginalWidth); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getWidth); @@ -455,6 +457,8 @@ SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionHeight); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getTriangles); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionOffsetY); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionOffsetX); +SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionY); +SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionX); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionV); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionRotate); SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getParentMesh); @@ -563,11 +567,15 @@ bool register_all_cocos2dx_spine(se::Object* obj); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionOriginalHeight); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionOffsetY); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionOffsetX); +SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionY); +SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionX); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionOriginalWidth); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setUVs); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getWidth); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getY); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRotation); +SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionDegrees); +SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionDegrees); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setWidth); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionWidth); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getUVs); @@ -594,6 +602,8 @@ SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_updateOffset); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionOriginalHeight); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionOffsetY); SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionOffsetX); +SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionY); +SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionX); extern se::Object* __jsb_spine_RotateTimeline_proto; extern se::Class* __jsb_spine_RotateTimeline_class; @@ -906,6 +916,7 @@ extern se::Class* __jsb_spine_SkeletonRenderer_class; bool js_register_spine_SkeletonRenderer(se::Object* obj); bool register_all_cocos2dx_spine(se::Object* obj); SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_setUseTint); +SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_setUseMulti); SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_setTimeScale); SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_render); SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_initWithUUID); @@ -1006,6 +1017,7 @@ extern se::Class* __jsb_spine_SkeletonCacheAnimation_class; bool js_register_spine_SkeletonCacheAnimation(se::Object* obj); bool register_all_cocos2dx_spine(se::Object* obj); SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setUseTint); +SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti); SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setTimeScale); SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_findAnimation); SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setAttachUtil); diff --git a/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_conversions.hpp b/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_conversions.hpp index 5b6dd5d1..85e7c98a 100644 --- a/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_conversions.hpp +++ b/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_conversions.hpp @@ -672,6 +672,32 @@ bool seval_to_spine_Vector_T_ptr(const se::Value& v, spine::Vector* ret) return true; } +bool spine_skin_attachments_to_seval(std::vector>& v, se::Value* ret) { + assert(ret != nullptr); + bool ok = true; + se::HandleObject arr(se::Object::createArrayObject(v.size())); + + int i = 0; + + for (const auto &vv : v) + { + se::HandleObject obj(se::Object::createPlainObject()); + + se::Value tmp; + for (const auto& e : vv) { + native_ptr_to_rooted_seval(e.second, &tmp); + obj->setProperty(e.first.c_str(), tmp); + } + + arr->setArrayElement(i, se::Value(obj)); + i++; + } + + ret->setObject(arr, true); + + return ok; +} + bool seval_to_spine_Vector_String(const se::Value& v, spine::Vector* ret); bool spine_Vector_String_to_seval(const spine::Vector& v, se::Value* ret); #endif diff --git a/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_spine_manual.cpp b/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_spine_manual.cpp index 6ea65f02..1d780c62 100644 --- a/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_spine_manual.cpp +++ b/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_spine_manual.cpp @@ -51,6 +51,8 @@ #include "cocos/editor-support/spine/spine.h" #include "cocos/editor-support/spine-creator-support/spine-cocos2dx.h" +#include "cocos/editor-support/spine-creator-support/AttachmentVertices.h" + using namespace cocos2d; static spine::Cocos2dTextureLoader textureLoader; @@ -233,6 +235,252 @@ static bool js_register_spine_retainSkeletonData(se::State& s) } SE_BIND_FUNC(js_register_spine_retainSkeletonData) +static bool js_cocos2dx_spine_Skin_getAttachmentsForJSB(se::State& s) { + spine::Skin* cobj = (spine::Skin*)s.nativeThisObject(); + SE_PRECONDITION2( + cobj, false, + "js_cocos2dx_spine_Skin_getAttachmentsForJSB : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 0) { + std::vector> result = + cobj->getAttachmentsForJSB(); + ok &= spine_skin_attachments_to_seval(result, &s.rval()); + SE_PRECONDITION2(ok, false, + "js_cocos2dx_spine_Skin_getAttachmentsForJSB : Error " + "processing arguments"); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", + (int)argc, 0); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_Skin_getAttachmentsForJSB) + +static bool js_cocos2dx_spine_RegionAttachment_getTextureForJSB(se::State& s) { + spine::RegionAttachment* cobj = + (spine::RegionAttachment*)s.nativeThisObject(); + SE_PRECONDITION2( + cobj, false, + "js_cocos2dx_spine_RegionAttachment_getTextureForJSB : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 0) { + spine::AttachmentVertices* attachmentVertices = (spine::AttachmentVertices*)cobj->getRendererObject(); + ok &= native_ptr_to_seval((cocos2d::middleware::Texture2D*)attachmentVertices->_texture, &s.rval()); + SE_PRECONDITION2(ok, false, + "js_cocos2dx_spine_RegionAttachment_getTextureForJSB : Error " + "processing arguments"); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", + (int)argc, 0); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_getTextureForJSB) + +static bool js_cocos2dx_spine_RegionAttachment_setRegionForJSB(se::State& s) { + spine::RegionAttachment* attachment = + (spine::RegionAttachment*)s.nativeThisObject(); + SE_PRECONDITION2( + attachment, false, + "js_cocos2dx_spine_RegionAttachment_setRegionForJSB : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + if (argc != 5) { + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 5); + return false; + } + bool ok = false; + + if (attachment == nullptr) return false; + + cocos2d::middleware::Texture2D* texture = nullptr; + ok = seval_to_native_ptr(args[0], &texture); + SE_PRECONDITION2( + ok, false, + "js_cocos2dx_spine_RegionAttachment_setRegionForJSB: Converting Middleware Texture2D failed!"); + + cocos2d::renderer::Rect rect; + ok = seval_to_Rect(args[1], &rect); + SE_PRECONDITION2( + ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionForJSB: Converting Invalid Rect failed!"); + + cocos2d::Size originalSize; + ok = seval_to_Size(args[2], &originalSize); + SE_PRECONDITION2( + ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionForJSB: Converting Invalid OriginalSize failed!"); + + cocos2d::Vec2 offset; + ok = seval_to_Vec2(args[3], &offset); + SE_PRECONDITION2( + ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionForJSB: Converting Invalid Offset failed!"); + + float degrees; + ok = seval_to_float(args[4], °rees); + SE_PRECONDITION2( + ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionForJSB: Converting Invalid Degrees failed!"); + + spine::AttachmentVertices* attachmentVertices = (spine::AttachmentVertices*)attachment->getRendererObject(); + + CC_SAFE_RELEASE(attachmentVertices->_texture); + attachmentVertices->_texture = texture; + CC_SAFE_RETAIN(texture); + + float u, v, u2, v2; + float w = texture->getNativeTexture()->getWidth(); + float h = texture->getNativeTexture()->getHeight(); + if (degrees != 0) { + u = rect.x / w; + v = rect.y / h; + u2 = (rect.x + rect.h) / w; + v2 = (rect.y + rect.w) / h; + } else { + u = rect.x / w; + v = rect.y / h; + u2 = (rect.x + rect.w) / w; + v2 = (rect.y + rect.h) / h; + } + + attachment->setRegionX(rect.x); + attachment->setRegionY(rect.y); + attachment->setRegionWidth(rect.w); + attachment->setRegionHeight(rect.h); + attachment->setRegionOriginalWidth(originalSize.width); + attachment->setRegionOriginalHeight(originalSize.height); + attachment->setRegionOffsetX(offset.x); + attachment->setRegionOffsetY(offset.y); + attachment->setRegionDegrees(degrees); + + attachment->setUVs(u, v, u2, v2, degrees); + attachment->updateOffset(); + + cocos2d::middleware::V2F_T2F_C4B* vertices = attachmentVertices->_triangles->verts; + for (int i = 0, ii = 0; i < 4; ++i, ii += 2) { + vertices[i].texCoord.u = attachment->getUVs()[ii]; + vertices[i].texCoord.v = attachment->getUVs()[ii + 1]; + } + + return true; +} +SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionForJSB) + +static bool js_cocos2dx_spine_MeshAttachment_getTextureForJSB(se::State& s) { + spine::MeshAttachment* cobj = + (spine::MeshAttachment*)s.nativeThisObject(); + SE_PRECONDITION2( + cobj, false, + "js_cocos2dx_spine_MeshAttachment_getTextureForJSB : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 0) { + spine::AttachmentVertices* attachmentVertices = (spine::AttachmentVertices*)cobj->getRendererObject(); + ok &= native_ptr_to_seval((cocos2d::middleware::Texture2D*)attachmentVertices->_texture, &s.rval()); + SE_PRECONDITION2(ok, false, + "js_cocos2dx_spine_MeshAttachment_getTextureForJSB : Error " + "processing arguments"); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", + (int)argc, 0); + return false; +} +SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_getTextureForJSB) + +static bool js_cocos2dx_spine_MeshAttachment_setRegionForJSB(se::State& s) { + spine::MeshAttachment* attachment = + (spine::MeshAttachment*)s.nativeThisObject(); + SE_PRECONDITION2( + attachment, false, + "js_cocos2dx_spine_MeshAttachment_setRegionForJSB : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + if (argc != 5) { + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 5); + return false; + } + bool ok = false; + + if (attachment == nullptr) return false; + + cocos2d::middleware::Texture2D* texture = nullptr; + ok = seval_to_native_ptr(args[0], &texture); + SE_PRECONDITION2( + ok, false, + "js_cocos2dx_spine_MeshAttachment_setRegionForJSB: Converting Middleware Texture2D failed!"); + + cocos2d::renderer::Rect rect; + ok = seval_to_Rect(args[1], &rect); + SE_PRECONDITION2( + ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionForJSB: Converting Invalid Rect failed!"); + + cocos2d::Size originalSize; + ok = seval_to_Size(args[2], &originalSize); + SE_PRECONDITION2( + ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionForJSB: Converting Invalid OriginalSize failed!"); + + cocos2d::Vec2 offset; + ok = seval_to_Vec2(args[3], &offset); + SE_PRECONDITION2( + ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionForJSB: Converting Invalid Offset failed!"); + + float degrees; + ok = seval_to_float(args[4], °rees); + SE_PRECONDITION2( + ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionForJSB: Converting Invalid Degrees failed!"); + + spine::AttachmentVertices* attachmentVertices = (spine::AttachmentVertices*)attachment->getRendererObject(); + + CC_SAFE_RELEASE(attachmentVertices->_texture); + attachmentVertices->_texture = texture; + CC_SAFE_RETAIN(texture); + + float u, v, u2, v2; + float w = texture->getNativeTexture()->getWidth(); + float h = texture->getNativeTexture()->getHeight(); + if (degrees != 0) { + u = rect.x / w; + v = rect.y / h; + u2 = (rect.x + rect.h) / w; + v2 = (rect.y + rect.w) / h; + } else { + u = rect.x / w; + v = rect.y / h; + u2 = (rect.x + rect.w) / w; + v2 = (rect.y + rect.h) / h; + } + + attachment->setRegionU(u); + attachment->setRegionV(v); + attachment->setRegionU2(u2); + attachment->setRegionV2(v2); + attachment->setRegionRotate(degrees != 0); + attachment->setRegionDegrees(degrees); + + attachment->setRegionX(rect.x); + attachment->setRegionY(rect.y); + attachment->setRegionWidth(rect.w); + attachment->setRegionHeight(rect.h); + attachment->setRegionOriginalWidth(originalSize.width); + attachment->setRegionOriginalHeight(originalSize.height); + attachment->setRegionOffsetX(offset.x); + attachment->setRegionOffsetY(offset.y); + + attachment->updateUVs(); + + cocos2d::middleware::V2F_T2F_C4B* vertices = attachmentVertices->_triangles->verts; + for (size_t i = 0, ii = 0, nn = attachment->getWorldVerticesLength(); ii < nn; ++i, ii += 2) { + vertices[i].texCoord.u = attachment->getUVs()[ii]; + vertices[i].texCoord.v = attachment->getUVs()[ii + 1]; + } + + return true; +} +SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionForJSB) + bool register_all_spine_manual(se::Object* obj) { // Get the ns @@ -249,7 +497,15 @@ bool register_all_spine_manual(se::Object* obj) ns->defineFunction("initSkeletonData", _SE(js_register_spine_initSkeletonData)); ns->defineFunction("retainSkeletonData", _SE(js_register_spine_retainSkeletonData)); ns->defineFunction("disposeSkeletonData", _SE(js_register_spine_disposeSkeletonData)); - + + __jsb_spine_Skin_proto->defineFunction("getAttachments", _SE(js_cocos2dx_spine_Skin_getAttachmentsForJSB)); + + __jsb_spine_RegionAttachment_proto->defineFunction("getTextureForJSB",_SE(js_cocos2dx_spine_RegionAttachment_getTextureForJSB)); + __jsb_spine_RegionAttachment_proto->defineFunction("setRegionForJSB",_SE(js_cocos2dx_spine_RegionAttachment_setRegionForJSB)); + + __jsb_spine_MeshAttachment_proto->defineFunction("getTextureForJSB",_SE(js_cocos2dx_spine_MeshAttachment_getTextureForJSB)); + __jsb_spine_MeshAttachment_proto->defineFunction("setRegionForJSB",_SE(js_cocos2dx_spine_MeshAttachment_setRegionForJSB)); + spine::setSpineObjectDisposeCallback([](void* spineObj){ se::Object* seObj = nullptr; diff --git a/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_spine_manual.hpp b/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_spine_manual.hpp index b106af8c..d08b9129 100644 --- a/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_spine_manual.hpp +++ b/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_spine_manual.hpp @@ -30,4 +30,7 @@ namespace se { class Object; } +SE_DECLARE_FUNC(js_cocos2dx_spine_Skin_getAttachmentsForJSB); +SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getTextureForJSB); + bool register_all_spine_manual(se::Object* obj);