diff --git a/spine-c/src/spine/SkeletonBinary.c b/spine-c/src/spine/SkeletonBinary.c index 5a0485ac0..06eb15fa6 100644 --- a/spine-c/src/spine/SkeletonBinary.c +++ b/spine-c/src/spine/SkeletonBinary.c @@ -656,7 +656,11 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput int i; spAttachmentType type; const char* name = readString(input); - if (!name) MALLOC_STR(name, attachmentName); + int freeName = name != 0; + if (!name) { + freeName = 0; + MALLOC_STR(name, attachmentName); + } type = (spAttachmentType)readByte(input); @@ -680,6 +684,7 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput readColor(input, ®ion->r, ®ion->g, ®ion->b, ®ion->a); spRegionAttachment_updateOffset(region); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); + if (freeName) FREE(name); return attachment; } case SP_ATTACHMENT_BOUNDING_BOX: { @@ -689,6 +694,7 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput _readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount); if (nonessential) readInt(input); /* Skip color. */ spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); + if (freeName) FREE(name); return attachment; } case SP_ATTACHMENT_MESH: { @@ -717,6 +723,7 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput mesh->height = 0; } spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); + if (freeName) FREE(name); return attachment; } case SP_ATTACHMENT_LINKED_MESH: { @@ -738,6 +745,7 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput mesh->height = readFloat(input) * self->scale; } _spSkeletonBinary_addLinkedMesh(self, mesh, skinName, slotIndex, parent); + if (freeName) FREE(name); return attachment; } case SP_ATTACHMENT_PATH: { @@ -755,10 +763,12 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput path->lengths[i] = readFloat(input) * self->scale; } if (nonessential) readInt(input); /* Skip color. */ + if (freeName) FREE(name); return attachment; } } + if (freeName) FREE(name); return 0; } diff --git a/spine-cocos2dx/example/Classes/BatchingExample.cpp b/spine-cocos2dx/example/Classes/BatchingExample.cpp index fe919fa25..0577fd077 100644 --- a/spine-cocos2dx/example/Classes/BatchingExample.cpp +++ b/spine-cocos2dx/example/Classes/BatchingExample.cpp @@ -44,10 +44,6 @@ Scene* BatchingExample::scene () { bool BatchingExample::init () { if (!LayerColor::initWithColor(Color4B(128, 128, 128, 255))) return false; - // To avoid the SkeletonBatch buffer from being resized, set this to the number of vertices ever rendered in one frame. - // BatchingExample needs ~3200, but let's set it low to test the buffer resizing. - SkeletonBatch::setBufferSize(512); - // Load the texture atlas. _atlas = spAtlas_createFromFile("spineboy.atlas", 0); CCASSERT(_atlas, "Error reading atlas file."); diff --git a/spine-cocos2dx/src/spine/SkeletonBatch.cpp b/spine-cocos2dx/src/spine/SkeletonBatch.cpp index 1237f0d74..19ea80171 100644 --- a/spine-cocos2dx/src/spine/SkeletonBatch.cpp +++ b/spine-cocos2dx/src/spine/SkeletonBatch.cpp @@ -1,10 +1,10 @@ /****************************************************************************** * Spine Runtimes Software License * Version 2.3 - * + * * Copyright (c) 2013-2015, Esoteric Software * All rights reserved. - * + * * You are granted a perpetual, non-exclusive, non-sublicensable and * non-transferable license to use, install, execute and perform the Spine * Runtimes Software (the "Software") and derivative works solely for personal @@ -16,7 +16,7 @@ * or other intellectual property or proprietary rights notices on or in the * Software, including any copy thereof. Redistributions in binary or source * form must include this license and terms. - * + * * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO @@ -38,102 +38,72 @@ USING_NS_CC; using std::max; namespace spine { - -static SkeletonBatch* instance = nullptr; - -void SkeletonBatch::setBufferSize (int vertexCount) { - if (instance) delete instance; - instance = new SkeletonBatch(vertexCount); -} - -SkeletonBatch* SkeletonBatch::getInstance () { - if (!instance) instance = new SkeletonBatch(8192); - return instance; -} -void SkeletonBatch::destroyInstance () { - if (instance) { - delete instance; - instance = nullptr; + static SkeletonBatch* instance = nullptr; + + SkeletonBatch* SkeletonBatch::getInstance () { + if (!instance) instance = new SkeletonBatch(); + return instance; } -} - -SkeletonBatch::SkeletonBatch (int capacity) : - _capacity(capacity), _position(0) -{ - _buffer = new V3F_C4B_T2F[capacity]; - _firstCommand = new Command(); - _command = _firstCommand; - - Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom){ - this->update(0); - });; -} - -SkeletonBatch::~SkeletonBatch () { - Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION); - - Command* command = _firstCommand; - while (command) { - Command* next = command->next; - delete command; - command = next; - } - - delete [] _buffer; -} - -void SkeletonBatch::update (float delta) { - _position = 0; - _command = _firstCommand; -} - -void SkeletonBatch::addCommand (cocos2d::Renderer* renderer, float globalZOrder, GLuint textureID, GLProgramState* glProgramState, - BlendFunc blendFunc, const TrianglesCommand::Triangles& triangles, const Mat4& transform, uint32_t transformFlags -) { - if (_position + triangles.vertCount > _capacity) { - int newCapacity = max(_capacity + _capacity / 2, _position + triangles.vertCount); - V3F_C4B_T2F* newBuffer = new V3F_C4B_T2F[newCapacity]; - memcpy(newBuffer, _buffer, _position); - - int newPosition = 0; - Command* command = _firstCommand; - while (newPosition < _position) { - command->triangles->verts = newBuffer + newPosition; - newPosition += command->triangles->vertCount; - command = command->next; - } - - delete [] _buffer; - _buffer = newBuffer; - _capacity = newCapacity; - } - - memcpy(_buffer + _position, triangles.verts, sizeof(V3F_C4B_T2F) * triangles.vertCount); - _command->triangles->verts = _buffer + _position; - _position += triangles.vertCount; - - _command->triangles->vertCount = triangles.vertCount; - _command->triangles->indexCount = triangles.indexCount; - _command->triangles->indices = triangles.indices; - - _command->trianglesCommand->init(globalZOrder, textureID, glProgramState, blendFunc, *_command->triangles, transform, transformFlags); - renderer->addCommand(_command->trianglesCommand); - - if (!_command->next) _command->next = new Command(); - _command = _command->next; -} - -SkeletonBatch::Command::Command () : - next(nullptr) -{ - trianglesCommand = new TrianglesCommand(); - triangles = new TrianglesCommand::Triangles(); -} - -SkeletonBatch::Command::~Command () { - delete triangles; - delete trianglesCommand; -} - -} + + void SkeletonBatch::destroyInstance () { + if (instance) { + delete instance; + instance = nullptr; + } + } + + SkeletonBatch::SkeletonBatch () + { + _firstCommand = new Command(); + _command = _firstCommand; + + Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom){ + this->update(0); + });; + } + + SkeletonBatch::~SkeletonBatch () { + Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION); + + Command* command = _firstCommand; + while (command) { + Command* next = command->next; + delete command; + command = next; + } + } + + void SkeletonBatch::update (float delta) { + _command = _firstCommand; + } + + void SkeletonBatch::addCommand (cocos2d::Renderer* renderer, float globalZOrder, GLuint textureID, GLProgramState* glProgramState, + BlendFunc blendFunc, const TrianglesCommand::Triangles& triangles, const Mat4& transform, uint32_t transformFlags + ) { + _command->triangles->verts = triangles.verts; + + _command->triangles->vertCount = triangles.vertCount; + _command->triangles->indexCount = triangles.indexCount; + _command->triangles->indices = triangles.indices; + + _command->trianglesCommand->init(globalZOrder, textureID, glProgramState, blendFunc, *_command->triangles, transform); + renderer->addCommand(_command->trianglesCommand); + + if (!_command->next) _command->next = new Command(); + _command = _command->next; + } + + SkeletonBatch::Command::Command () : + next(nullptr) + { + trianglesCommand = new TrianglesCommand(); + triangles = new TrianglesCommand::Triangles(); + } + + SkeletonBatch::Command::~Command () { + delete triangles; + delete trianglesCommand; + } + +} \ No newline at end of file diff --git a/spine-cocos2dx/src/spine/SkeletonBatch.h b/spine-cocos2dx/src/spine/SkeletonBatch.h index 98419bef1..6c2069ce4 100644 --- a/spine-cocos2dx/src/spine/SkeletonBatch.h +++ b/spine-cocos2dx/src/spine/SkeletonBatch.h @@ -1,10 +1,10 @@ /****************************************************************************** * Spine Runtimes Software License * Version 2.3 - * + * * Copyright (c) 2013-2015, Esoteric Software * All rights reserved. - * + * * You are granted a perpetual, non-exclusive, non-sublicensable and * non-transferable license to use, install, execute and perform the Spine * Runtimes Software (the "Software") and derivative works solely for personal @@ -16,7 +16,7 @@ * or other intellectual property or proprietary rights notices on or in the * Software, including any copy thereof. Redistributions in binary or source * form must include this license and terms. - * + * * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO @@ -36,45 +36,36 @@ #include "cocos2d.h" namespace spine { - -class SkeletonBatch { -public: - /* Sets the max number of vertices that can be drawn in a single frame. The buffer will grow automatically as needed, but - * setting it to the appropriate is more efficient. Best to call before getInstance is called for the first time. Default is - * 8192. */ - static void setBufferSize (int vertexCount); - - static SkeletonBatch* getInstance (); - static void destroyInstance (); - - void update (float delta); - - void addCommand (cocos2d::Renderer* renderer, float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, - cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand:: Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags); - -protected: - SkeletonBatch (int capacity); - virtual ~SkeletonBatch (); - - cocos2d::V3F_C4B_T2F* _buffer; - int _capacity; - int _position; - - class Command { - public: - Command (); - virtual ~Command (); - - cocos2d::TrianglesCommand* trianglesCommand; - cocos2d::TrianglesCommand::Triangles* triangles; - Command* next; - }; - - Command* _firstCommand; - Command* _command; -}; - + class SkeletonBatch { + public: + static SkeletonBatch* getInstance (); + + static void destroyInstance (); + + void update (float delta); + + void addCommand (cocos2d::Renderer* renderer, float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, + cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand:: Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags); + + protected: + SkeletonBatch (); + virtual ~SkeletonBatch (); + + class Command { + public: + Command (); + virtual ~Command (); + + cocos2d::TrianglesCommand* trianglesCommand; + cocos2d::TrianglesCommand::Triangles* triangles; + Command* next; + }; + + Command* _firstCommand; + Command* _command; + }; + } -#endif // SPINE_SKELETONBATCH_H_ +#endif // SPINE_SKELETONBATCH_H_ \ No newline at end of file diff --git a/spine-ts/README.md b/spine-ts/README.md index c93ee1b9c..0717e5533 100644 --- a/spine-ts/README.md +++ b/spine-ts/README.md @@ -36,9 +36,8 @@ All `*.js` files are self-contained and include both the core and respective bac If you write your app with TypeScript, additionally copy the corresponding `build/spine-*.d.ts` file to your project. -## Example -To run the examples, spawn a light-weight web server in the root of spine-ts, then navigate to the respective -`index.html` file. E.g.: +## Examples +To run the examples, the image, atlas, and JSON files must be served by a webserver, they can't be loaded from your local disk. Spawn a light-weight web server in the root of spine-ts, then navigate to the `index.html` file for the example you want to view. E.g.: ``` cd spine-ts @@ -47,6 +46,22 @@ python -m SimpleHTTPServer Then open `http://localhost:8000/webgl/example`, `http://localhost:8000/canvas/example`, `https://localhost:8000/threejs/example` or `http://localhost:8000/widget/example` in your browser. +## WebGL Demos +The spine-ts WebGL demos load their image, atlas, and JSON files from our webserver and so can be run directly, without needing a webserver. View the demos [all on one page](http://esotericsoftware.com/spine-demos/) or use the [standalone demos]() which are easy for you to explore and edit. The standalone demos can also be viewed here: + +- [Spine vs sprite sheets](http://rawgit.com/EsotericSoftware/spine-runtimes/master/spine-ts/webgl/demos/spritesheets.html) +- [Image changes](http://rawgit.com/EsotericSoftware/spine-runtimes/master/spine-ts/webgl/demos/imagechanges.html) +- [Transitions](http://rawgit.com/EsotericSoftware/spine-runtimes/master/spine-ts/webgl/demos/transitions.html) +- [Meshes](http://rawgit.com/EsotericSoftware/spine-runtimes/master/spine-ts/webgl/demos/meshes.html) +- [Skins](http://rawgit.com/EsotericSoftware/spine-runtimes/master/spine-ts/webgl/demos/skins.html) +- [Hoverboard](http://rawgit.com/EsotericSoftware/spine-runtimes/master/spine-ts/webgl/demos/hoverboard.html) +- [Transform constraints](http://rawgit.com/EsotericSoftware/spine-runtimes/master/spine-ts/webgl/demos/transforms.html) +- [Tank](http://rawgit.com/EsotericSoftware/spine-runtimes/master/spine-ts/webgl/demos/tank.html) +- [Vine](http://rawgit.com/EsotericSoftware/spine-runtimes/master/spine-ts/webgl/demos/vine.html) +- [Stretchyman](http://rawgit.com/EsotericSoftware/spine-runtimes/master/spine-ts/webgl/demos/stretchyman.html) + +Please note that Chrome and possibly other browsers do not use the original CORS headers when loading cached resources. After the initial page load for a demo, you may need to forcefully refresh (hold `shift` and click refresh) or clear your browser cache. + ## Development Setup The spine-ts runtime and the various backends are implemented in TypeScript for greater maintainability and better tooling support. To setup a development environment, follow these steps. @@ -58,7 +73,7 @@ setup a development environment, follow these steps. 5. Start the TypeScript compiler in watcher mode for the backend you want to work on: * **Core**: `tsc -w -p tsconfig.core.json`, builds `core/src`, outputs `build/spine-core.js|d.ts|js.map` * **WebGL**: `tsc -w -p tsconfig.webgl.json`, builds `core/src` and `webgl/src`, outputs `build/spine-webgl.js|d.ts|js.map` - * **WebGL**: `tsc -w -p tsconfig.canvas.json`, builds `core/src` and `canvas/src`, outputs `build/spine-canvas.js|d.ts|js.map` + * **Canvas**: `tsc -w -p tsconfig.canvas.json`, builds `core/src` and `canvas/src`, outputs `build/spine-canvas.js|d.ts|js.map` * **THREE.JS**: `tsc -w -p tsconfig.threejs.json`, builds `core/src` and `threejs/src`, outputs `build/spine-threejs.js|d.ts|js.map` * **Widget**: `tsc -w -p tsconfig.widget.json`, builds `core/src` and `widget/src`, outputs `build/spine-widget.js|d.ts|js.map` 6. Open the `spine-ts` folder in Visual Studio Code. VS Code will use the `tsconfig.json` file all source files from core and all diff --git a/spine-ts/webgl/demos/demos.css b/spine-ts/webgl/demos/demos.css index 2701203a1..343868faa 100644 --- a/spine-ts/webgl/demos/demos.css +++ b/spine-ts/webgl/demos/demos.css @@ -1,18 +1,43 @@ body, html { margin: 0; - padding: 0; height: 100%; font-family: Tahoma; font-size: 11pt; } -canvas { - position: absolute; width: 100% ;height: 100%; +body { + padding: 15px; +} +br { + display: block; + content: ""; + margin-top: 15px; +} +.aspect { + margin-bottom: 15px; + max-width: 800px; + text-align: center; +} +.aspect div { + position: relative; + padding-bottom: 70.14%; +} +.aspect canvas { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: 100%; + height: 100%; + border: 1px solid black; } .slider { - width: 50%; + width: 100%; + max-width: 800px; border-radius: 3px; text-align: left; transform: translateZ(0); + background: #222; } .slider, .slider.filled span { height: 15px; diff --git a/spine-ts/webgl/demos/framebyframe.html b/spine-ts/webgl/demos/framebyframe.html deleted file mode 100644 index e0c85fe3c..000000000 --- a/spine-ts/webgl/demos/framebyframe.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - -
- - -