From 3dbab2122d5536244421bc4cc3e0721995d66608 Mon Sep 17 00:00:00 2001 From: badlogic Date: Fri, 6 Oct 2017 15:22:49 +0200 Subject: [PATCH 1/8] [c] Fixed KMemory and test harness for GCC on Linux. --- spine-c/spine-c-unit-tests/main.cpp | 10 +++++----- spine-c/spine-c-unit-tests/memory/KMemory.cpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spine-c/spine-c-unit-tests/main.cpp b/spine-c/spine-c-unit-tests/main.cpp index 9b2868895..bd013f6ea 100755 --- a/spine-c/spine-c-unit-tests/main.cpp +++ b/spine-c/spine-c-unit-tests/main.cpp @@ -22,11 +22,11 @@ void RegisterMemoryLeakDetector() { // Register our malloc and free functions to track memory leaks #ifdef KANJI_MEMTRACE - _setDebugMalloc(_kanjimalloc); + _spSetDebugMalloc(_kanjimalloc); #endif - _setMalloc(_kanjimalloc); - _setRealloc(_kanjirealloc); - _setFree(_kanjifree); + _spSetMalloc(_kanjimalloc); + _spSetRealloc(_kanjirealloc); + _spSetFree(_kanjifree); } int main(int argc, char* argv[]) @@ -74,6 +74,6 @@ extern "C" { // probably unnecessary } char* _spUtil_readFile(const char* path, int* length) { - return _readFile(path, length); + return _spReadFile(path, length); } } diff --git a/spine-c/spine-c-unit-tests/memory/KMemory.cpp b/spine-c/spine-c-unit-tests/memory/KMemory.cpp index ec91465a2..a21cbafba 100755 --- a/spine-c/spine-c-unit-tests/memory/KMemory.cpp +++ b/spine-c/spine-c-unit-tests/memory/KMemory.cpp @@ -30,7 +30,7 @@ /////////////////////////////////////////////////////////////////////////////// // Our memory system is thread-safe, but instead of linking massive libraries, // we attempt to use C++11 std::mutex. -#ifdef USE_CPP11_MUTEX +#ifdef USE_CPP11_MUTEX_DISABLED #include typedef std::recursive_mutex KSysLock; // rentrant struct KAutoLock { @@ -300,4 +300,4 @@ size_t KMemoryAllocated() size += info.size; } return size; -} \ No newline at end of file +} From d61782201fa4783d3fae7b8f1a9a1d93e63d4742 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Fri, 6 Oct 2017 15:26:07 +0200 Subject: [PATCH 2/8] Update README.md --- spine-sfml/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spine-sfml/README.md b/spine-sfml/README.md index 52a163db8..834641813 100644 --- a/spine-sfml/README.md +++ b/spine-sfml/README.md @@ -44,13 +44,13 @@ The Spine SFML example works on Windows, Linux and Mac OS X. The entire example code is contained in [main.cpp](example/main.cpp#L61) ### Linux -1. Install the SFML dependencies, e.g. on Ubuntu/Debian via `sudo apt-get install -y libpthread-stubs0-dev libgl1-mesa-dev libx11-dev libxrandr-dev libfreetype6-dev libglew1.5-dev libjpeg8-dev libsndfile1-dev libopenal-dev libudev-dev libxcb-image0-dev libjpeg-dev libflac-dev` +1. Install the SFML dependencies, e.g. on Ubuntu/Debian via `sudo apt install libsfml-dev` 2. Install CMake, e.g. on Ubuntu/Debian via `sudo apt-get install -y cmake` 3. Download the Spine Runtimes repository using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it as a zip via the download button above. 4. Open a terminal, and `cd` into the `spine-runtimes/spine-sfml` folder 5. Type `mkdir build && cd build && cmake ../..` to generate Make files 6. Type `make` to compile the example -7. Run the example by `cd spine-sfml-example && ./spine-sfml-example` +7. Run the example by `cd spine-sfml && ./spine-sfml-example` ### Mac OS X 1. Install [Xcode](https://developer.apple.com/xcode/) From bc6132b05151cf673c9e91d6f70726f9c69da10f Mon Sep 17 00:00:00 2001 From: John Date: Sat, 7 Oct 2017 00:49:08 +0800 Subject: [PATCH 3/8] [unity] Assign default struct values. This prevents compiler errors with certain settings. Reproed in Unity 2017.3 beta based on https://github.com/dorisugita/spine-runtimes/commit/dddc1d3c67a497e51ee2ac8bb035dc96a8e15241 @dorisugita --- spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs b/spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs index 960abc265..559349be9 100644 --- a/spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs +++ b/spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs @@ -457,7 +457,7 @@ namespace Spine.Unity { var skeleton = instruction.skeleton; var drawOrderItems = skeleton.drawOrder.Items; - Color32 color; + Color32 color = default(Color32); float skeletonA = skeleton.a * 255, skeletonR = skeleton.r, skeletonG = skeleton.g, skeletonB = skeleton.b; Vector2 meshBoundsMin = this.meshBoundsMin, meshBoundsMax = this.meshBoundsMax; @@ -661,7 +661,7 @@ namespace Spine.Unity { } // Populate Verts - Color32 color; + Color32 color = default(Color32); int vertexIndex = 0; var tempVerts = this.tempVerts; From f06bfd9f1683dd931b79c1c66ac2402502f9f9df Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Mon, 9 Oct 2017 11:44:00 +0200 Subject: [PATCH 4/8] [libgdx] Better exception message for Batch that can't render meshes. --- .../src/com/esotericsoftware/spine/SkeletonRenderer.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java index a60dc87f4..c40e79202 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java @@ -101,9 +101,8 @@ public class SkeletonRenderer { continue; } else if (attachment instanceof MeshAttachment) { - throw new RuntimeException( - "SkeletonRenderer#draw(PolygonSpriteBatch, Skeleton) or #draw(TwoColorPolygonBatch, Skeleton) must be used to " - + "render meshes."); + throw new RuntimeException(batch.getClass().getSimpleName() + + " cannot render meshes, PolygonSpriteBatch or TwoColorPolygonBatch is required."); } else if (attachment instanceof SkeletonAttachment) { Skeleton attachmentSkeleton = ((SkeletonAttachment)attachment).getSkeleton(); From 76f0b208d98bdb24695f0ca1ffe9221dde9d7e5b Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Mon, 9 Oct 2017 11:52:01 +0200 Subject: [PATCH 5/8] Changed SV bg color to match editor default bg color (when gradient is off and square alpha is 0). --- .../src/com/esotericsoftware/spine/SkeletonViewer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java index bcb2bc168..302d269a7 100644 --- a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java +++ b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java @@ -253,7 +253,7 @@ public class SkeletonViewer extends ApplicationAdapter { } public void render () { - Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1); + Gdx.gl.glClearColor(112 / 255f, 111 / 255f, 118 / 255f, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); float delta = Gdx.graphics.getDeltaTime(); From 812510e948cc2c81adcb14b1b307aa60d8a07862 Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Mon, 9 Oct 2017 11:52:29 +0200 Subject: [PATCH 6/8] [libgdx] Avoid batch flush when switching between normal and additive rendering with PMA. --- .../spine/SkeletonRenderer.java | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java index c40e79202..34642d98a 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java @@ -66,6 +66,7 @@ public class SkeletonRenderer { if (vertexEffect != null) vertexEffect.begin(skeleton); boolean premultipliedAlpha = this.premultipliedAlpha; + BlendMode blendMode = null; float[] vertices = this.vertices.items; Color skeletonColor = skeleton.color; float r = skeletonColor.r, g = skeletonColor.g, b = skeletonColor.b, a = skeletonColor.a; @@ -79,6 +80,17 @@ public class SkeletonRenderer { Color color = region.getColor(), slotColor = slot.getColor(); float alpha = a * slotColor.a * color.a * 255; float multiplier = premultipliedAlpha ? alpha : 255; + + BlendMode slotBlendMode = slot.data.getBlendMode(); + if (slotBlendMode != blendMode) { + if (slotBlendMode == BlendMode.additive && premultipliedAlpha) { + slotBlendMode = BlendMode.normal; + alpha = 0; + } + blendMode = slotBlendMode; + batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest()); + } + float c = NumberUtils.intToFloatColor(((int)alpha << 24) // | ((int)(b * slotColor.b * color.b * multiplier) << 16) // | ((int)(g * slotColor.g * color.g * multiplier) << 8) // @@ -92,8 +104,6 @@ public class SkeletonRenderer { if (vertexEffect != null) applyVertexEffect(vertices, 20, 5, c, 0); - BlendMode blendMode = slot.data.getBlendMode(); - batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest()); batch.draw(region.getRegion().getTexture(), vertices, 0, 20); } else if (attachment instanceof ClippingAttachment) { @@ -174,17 +184,22 @@ public class SkeletonRenderer { Color slotColor = slot.getColor(); float alpha = a * slotColor.a * color.a * 255; float multiplier = premultipliedAlpha ? alpha : 255; + + BlendMode slotBlendMode = slot.data.getBlendMode(); + if (slotBlendMode != blendMode) { + if (slotBlendMode == BlendMode.additive && premultipliedAlpha) { + slotBlendMode = BlendMode.normal; + alpha = 0; + } + blendMode = slotBlendMode; + batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest()); + } + float c = NumberUtils.intToFloatColor(((int)alpha << 24) // | ((int)(b * slotColor.b * color.b * multiplier) << 16) // | ((int)(g * slotColor.g * color.g * multiplier) << 8) // | (int)(r * slotColor.r * color.r * multiplier)); - BlendMode slotBlendMode = slot.data.getBlendMode(); - if (slotBlendMode != blendMode) { - blendMode = slotBlendMode; - batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest()); - } - if (clipper.isClipping()) { clipper.clipTriangles(vertices, verticesLength, triangles, triangles.length, uvs, c, 0, false); FloatArray clippedVertices = clipper.getClippedVertices(); @@ -287,6 +302,17 @@ public class SkeletonRenderer { Color lightColor = slot.getColor(); float alpha = a * lightColor.a * color.a * 255; float multiplier = premultipliedAlpha ? alpha : 255; + + BlendMode slotBlendMode = slot.data.getBlendMode(); + if (slotBlendMode != blendMode) { + if (slotBlendMode == BlendMode.additive && premultipliedAlpha) { + slotBlendMode = BlendMode.normal; + alpha = 0; + } + blendMode = slotBlendMode; + batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest()); + } + float red = r * color.r * multiplier; float green = g * color.g * multiplier; float blue = b * color.b * multiplier; @@ -300,12 +326,6 @@ public class SkeletonRenderer { | (int)(green * darkColor.g) << 8 // | (int)(red * darkColor.r)); - BlendMode slotBlendMode = slot.data.getBlendMode(); - if (slotBlendMode != blendMode) { - blendMode = slotBlendMode; - batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest()); - } - if (clipper.isClipping()) { clipper.clipTriangles(vertices, verticesLength, triangles, triangles.length, uvs, light, dark, true); FloatArray clippedVertices = clipper.getClippedVertices(); From 377aee58ecacc5e0c9a468c0bb45b92589d21a63 Mon Sep 17 00:00:00 2001 From: badlogic Date: Tue, 10 Oct 2017 12:42:03 +0200 Subject: [PATCH 7/8] [c] Replaced call to locale dependent strtof with customer float parser. Closes #1009 --- spine-c/spine-c/src/spine/Json.c | 74 ++++++++++++++++++------ spine-c/spine-c/src/spine/SkeletonJson.c | 12 ---- 2 files changed, 55 insertions(+), 31 deletions(-) diff --git a/spine-c/spine-c/src/spine/Json.c b/spine-c/spine-c/src/spine/Json.c index 6225ff00c..c260bb39f 100644 --- a/spine-c/spine-c/src/spine/Json.c +++ b/spine-c/spine-c/src/spine/Json.c @@ -92,29 +92,65 @@ void Json_dispose (Json *c) { /* Parse the input text to generate a number, and populate the result into item. */ static const char* parse_number (Json *item, const char* num) { - char * endptr; - float n; + double result = 0.0; + int negative = 0; + char* ptr = (char*)num; - /* Using strtod and strtof is slightly more permissive than RFC4627, - * accepting for example hex-encoded floating point, but either - * is often leagues faster than any manual implementation. - * - * We also already know that this starts with [-0-9] from parse_value. - */ -#if __STDC_VERSION__ >= 199901L - n = strtof(num, &endptr); -#else - n = (float)strtod( num, &endptr ); -#endif - /* ignore errno's ERANGE, which returns +/-HUGE_VAL */ - /* n is 0 on any other error */ + if (*ptr == '-') { + negative = -1; + ++ptr; + } - if (endptr != num) { + while (*ptr >= '0' && *ptr <= '9') { + result = result * 10.0 + (*ptr - '0'); + ++ptr; + } + + if (*ptr == '.') { + double fraction = 0.0; + int n = 0; + ++ptr; + + while (*ptr >= '0' && *ptr <= '9') { + fraction = (fraction * 10.0) + (*ptr - '0'); + ++ptr; + ++n; + } + result += fraction / POW(10.0, n); + } + if (negative) result = -result; + + if (*ptr == 'e' || *ptr == 'E') { + double exponent = 0; + int expNegative = 0; + int n = 0; + ++ptr; + + if (*ptr == '-') { + expNegative = -1; + ++ptr; + } else if (*ptr == '+') { + ++ptr; + } + + while (*ptr >= '0' && *ptr <= '9') { + exponent = (exponent * 10.0) + (*ptr - '0'); + ++ptr; + ++n; + } + + if (expNegative) + result = result / POW(10, exponent); + else + result = result * POW(10, exponent); + } + + if (ptr != num) { /* Parse success, number found. */ - item->valueFloat = n; - item->valueInt = (int)n; + item->valueFloat = result; + item->valueInt = (int)result; item->type = Json_Number; - return endptr; + return ptr; } else { /* Parse failure, ep is set. */ ep = num; diff --git a/spine-c/spine-c/src/spine/SkeletonJson.c b/spine-c/spine-c/src/spine/SkeletonJson.c index c6136c66c..48322bad5 100644 --- a/spine-c/spine-c/src/spine/SkeletonJson.c +++ b/spine-c/spine-c/src/spine/SkeletonJson.c @@ -30,7 +30,6 @@ #include #include -#include #include "Json.h" #include #include @@ -579,25 +578,14 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha int i, ii; spSkeletonData* skeletonData; Json *root, *skeleton, *bones, *boneMap, *ik, *transform, *path, *slots, *skins, *animations, *events; - char* oldLocale; _spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self); FREE(self->error); CONST_CAST(char*, self->error) = 0; internal->linkedMeshCount = 0; -#ifndef __ANDROID__ - oldLocale = strdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, "C"); -#endif - root = Json_create(json); -#ifndef __ANDROID__ - setlocale(LC_NUMERIC, oldLocale); - free(oldLocale); -#endif - if (!root) { _spSkeletonJson_setError(self, 0, "Invalid skeleton JSON: ", Json_getError()); return 0; From 8650c668e9d29458cacd4a8085dfadb33058686f Mon Sep 17 00:00:00 2001 From: badlogic Date: Tue, 10 Oct 2017 15:37:27 +0200 Subject: [PATCH 8/8] [cocos2dx] Removed hard coded scratch buffer size, replaced with dynamic allocation. Also made it a global scratch buffer, instead of a per instance buffer. Saves 4kb per SkeletonRenderer instance. Closes #1015. --- spine-cocos2dx/src/spine/SkeletonRenderer.cpp | 59 ++++++++++++++----- spine-cocos2dx/src/spine/SkeletonRenderer.h | 4 +- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/spine-cocos2dx/src/spine/SkeletonRenderer.cpp b/spine-cocos2dx/src/spine/SkeletonRenderer.cpp index cde7ce45e..df80160a1 100644 --- a/spine-cocos2dx/src/spine/SkeletonRenderer.cpp +++ b/spine-cocos2dx/src/spine/SkeletonRenderer.cpp @@ -36,12 +36,35 @@ #include #include +#define INITIAL_WORLD_VERTICES_LENGTH 1000 +// Used for transforming attachments for bounding boxes & debug rendering +static float* worldVertices = nullptr; +static size_t worldVerticesLength = 0; + +void ensureWorldVerticesCapacity(size_t capacity) { + if (worldVerticesLength < capacity) { + float* newWorldVertices = new float[capacity]; + memcpy(newWorldVertices, worldVertices, capacity * sizeof(float)); + delete[] worldVertices; + worldVertices = newWorldVertices; + worldVerticesLength = capacity; + } +} + USING_NS_CC; using std::min; using std::max; namespace spine { +void SkeletonRenderer::destroyScratchBuffers() { + if (worldVertices) { + delete[] worldVertices; + worldVertices = nullptr; + worldVerticesLength = 0; + } +} + SkeletonRenderer* SkeletonRenderer::createWithData (spSkeletonData* skeletonData, bool ownsSkeletonData) { SkeletonRenderer* node = new SkeletonRenderer(skeletonData, ownsSkeletonData); node->autorelease(); @@ -61,7 +84,10 @@ SkeletonRenderer* SkeletonRenderer::createWithFile (const std::string& skeletonD } void SkeletonRenderer::initialize () { - _worldVertices = new float[1000]; // Max number of vertices per mesh. + if (!worldVertices) { + worldVertices = new float[INITIAL_WORLD_VERTICES_LENGTH]; + worldVerticesLength = INITIAL_WORLD_VERTICES_LENGTH; + } _clipper = spSkeletonClipping_create(); @@ -131,8 +157,7 @@ SkeletonRenderer::~SkeletonRenderer () { if (_ownsSkeletonData) spSkeletonData_dispose(_skeleton->data); spSkeleton_dispose(_skeleton); if (_atlas) spAtlas_dispose(_atlas); - if (_attachmentLoader) spAttachmentLoader_dispose(_attachmentLoader); - delete [] _worldVertices; + if (_attachmentLoader) spAttachmentLoader_dispose(_attachmentLoader); spSkeletonClipping_dispose(_clipper); } @@ -613,11 +638,11 @@ void SkeletonRenderer::drawDebug (Renderer* renderer, const Mat4 &transform, uin spSlot* slot = _skeleton->drawOrder[i]; if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_REGION) continue; spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment; - spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices, 0, 2); - points[0] = Vec2(_worldVertices[0], _worldVertices[1]); - points[1] = Vec2(_worldVertices[2], _worldVertices[3]); - points[2] = Vec2(_worldVertices[4], _worldVertices[5]); - points[3] = Vec2(_worldVertices[6], _worldVertices[7]); + spRegionAttachment_computeWorldVertices(attachment, slot->bone, worldVertices, 0, 2); + points[0] = Vec2(worldVertices[0], worldVertices[1]); + points[1] = Vec2(worldVertices[2], worldVertices[3]); + points[2] = Vec2(worldVertices[4], worldVertices[5]); + points[3] = Vec2(worldVertices[6], worldVertices[7]); drawNode->drawPoly(points, 4, true, Color4F::BLUE); } } @@ -645,12 +670,13 @@ void SkeletonRenderer::drawDebug (Renderer* renderer, const Mat4 &transform, uin for (int i = 0, n = _skeleton->slotsCount; i < n; ++i) { spSlot* slot = _skeleton->drawOrder[i]; if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_MESH) continue; - spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment; - spVertexAttachment_computeWorldVertices(SUPER(attachment), slot, 0, attachment->super.worldVerticesLength, _worldVertices, 0, 2); + spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment; + ensureWorldVerticesCapacity(attachment->super.worldVerticesLength); + spVertexAttachment_computeWorldVertices(SUPER(attachment), slot, 0, attachment->super.worldVerticesLength, worldVertices, 0, 2); for (int ii = 0; ii < attachment->trianglesCount;) { - Vec2 v1(_worldVertices + (attachment->triangles[ii++] * 2)); - Vec2 v2(_worldVertices + (attachment->triangles[ii++] * 2)); - Vec2 v3(_worldVertices + (attachment->triangles[ii++] * 2)); + Vec2 v1(worldVertices + (attachment->triangles[ii++] * 2)); + Vec2 v2(worldVertices + (attachment->triangles[ii++] * 2)); + Vec2 v3(worldVertices + (attachment->triangles[ii++] * 2)); drawNode->drawLine(v1, v2, Color4F::YELLOW); drawNode->drawLine(v2, v3, Color4F::YELLOW); drawNode->drawLine(v3, v1, Color4F::YELLOW); @@ -680,16 +706,17 @@ Rect SkeletonRenderer::getBoundingBox () const { int verticesCount; if (slot->attachment->type == SP_ATTACHMENT_REGION) { spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment; - spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices, 0, 2); + spRegionAttachment_computeWorldVertices(attachment, slot->bone, worldVertices, 0, 2); verticesCount = 8; } else if (slot->attachment->type == SP_ATTACHMENT_MESH) { spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment; - spVertexAttachment_computeWorldVertices(SUPER(mesh), slot, 0, mesh->super.worldVerticesLength, _worldVertices, 0, 2); + ensureWorldVerticesCapacity(mesh->super.worldVerticesLength); + spVertexAttachment_computeWorldVertices(SUPER(mesh), slot, 0, mesh->super.worldVerticesLength, worldVertices, 0, 2); verticesCount = mesh->super.worldVerticesLength; } else continue; for (int ii = 0; ii < verticesCount; ii += 2) { - float x = _worldVertices[ii] * scaleX, y = _worldVertices[ii + 1] * scaleY; + float x = worldVertices[ii] * scaleX, y = worldVertices[ii + 1] * scaleY; minX = min(minX, x); minY = min(minY, y); maxX = max(maxX, x); diff --git a/spine-cocos2dx/src/spine/SkeletonRenderer.h b/spine-cocos2dx/src/spine/SkeletonRenderer.h index 8ac8f9a62..426cba1aa 100644 --- a/spine-cocos2dx/src/spine/SkeletonRenderer.h +++ b/spine-cocos2dx/src/spine/SkeletonRenderer.h @@ -108,6 +108,9 @@ public: virtual const cocos2d::BlendFunc& getBlendFunc () const override; virtual void setOpacityModifyRGB (bool value) override; virtual bool isOpacityModifyRGB () const override; + + // Frees global memory used for temporay vertex transformations. + static void destroyScratchBuffers(); CC_CONSTRUCTOR_ACCESS: SkeletonRenderer (); @@ -136,7 +139,6 @@ protected: spAttachmentLoader* _attachmentLoader; cocos2d::CustomCommand _debugCommand; cocos2d::BlendFunc _blendFunc; - float* _worldVertices; bool _premultipliedAlpha; spSkeleton* _skeleton; float _timeScale;