diff --git a/spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.cpp b/spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.cpp index 68232b12c..fdbd0a5de 100755 --- a/spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.cpp +++ b/spine-c/spine-c-unit-tests/tests/C_InterfaceTestFixture.cpp @@ -6,13 +6,13 @@ #include "KMemory.h" // last include -#define SPINEBOY_JSON "testdata/spineboy/spineboy.json" +#define SPINEBOY_JSON "testdata/spineboy/spineboy-ess.json" #define SPINEBOY_ATLAS "testdata/spineboy/spineboy.atlas" -#define RAPTOR_JSON "testdata/raptor/raptor.json" +#define RAPTOR_JSON "testdata/raptor/raptor-pro.json" #define RAPTOR_ATLAS "testdata/raptor/raptor.atlas" -#define GOBLINS_JSON "testdata/goblins/goblins.json" +#define GOBLINS_JSON "testdata/goblins/goblins-pro.json" #define GOBLINS_ATLAS "testdata/goblins/goblins.atlas" #define MAX_RUN_TIME 6000 // equal to about 100 seconds of execution diff --git a/spine-c/spine-c-unit-tests/tests/MemoryTestFixture.cpp b/spine-c/spine-c-unit-tests/tests/MemoryTestFixture.cpp index aad253f25..f695da416 100755 --- a/spine-c/spine-c-unit-tests/tests/MemoryTestFixture.cpp +++ b/spine-c/spine-c-unit-tests/tests/MemoryTestFixture.cpp @@ -6,7 +6,7 @@ #include "KMemory.h" // last include -#define SPINEBOY_JSON "testdata/spineboy/spineboy.json" +#define SPINEBOY_JSON "testdata/spineboy/spineboy-ess.json" #define SPINEBOY_ATLAS "testdata/spineboy/spineboy.atlas" #define MAX_RUN_TIME 6000 // equal to about 100 seconds of execution diff --git a/spine-c/spine-c/include/spine/Array.h b/spine-c/spine-c/include/spine/Array.h index 161741a95..8f29eb9ea 100644 --- a/spine-c/spine-c/include/spine/Array.h +++ b/spine-c/spine-c/include/spine/Array.h @@ -100,7 +100,6 @@ extern "C" { void name##_removeAt(name* self, int index) { \ self->size--; \ memmove(self->items + index, self->items + index + 1, sizeof(itemType) * (self->size - index)); \ - self->items[self->size] = 0; \ } \ int name##_contains(name* self, itemType value) { \ itemType* items = self->items; \ @@ -112,7 +111,6 @@ extern "C" { } \ itemType name##_pop(name* self) { \ itemType item = self->items[--self->size]; \ - self->items[self->size] = 0; \ return item; \ } \ itemType name##_peek(name* self) { \ diff --git a/spine-c/spine-c/include/spine/Color.h b/spine-c/spine-c/include/spine/Color.h index 8c4e6b677..4c2384a41 100644 --- a/spine-c/spine-c/include/spine/Color.h +++ b/spine-c/spine-c/include/spine/Color.h @@ -42,6 +42,10 @@ typedef struct spColor { spColor() : r(0), g(0), b(0), a(0) { } + + bool operator==(const spColor& rhs) { + return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a; + } #endif } spColor; diff --git a/spine-c/spine-c/include/spine/VertexEffect.h b/spine-c/spine-c/include/spine/VertexEffect.h new file mode 100644 index 000000000..ae738ccd1 --- /dev/null +++ b/spine-c/spine-c/include/spine/VertexEffect.h @@ -0,0 +1,84 @@ +/****************************************************************************** + * Spine Runtimes Software License v2.5 + * + * Copyright (c) 2013-2016, 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 and derivative works solely for personal or internal + * use. Without the written permission of Esoteric Software (see Section 2 of + * the Spine Software License Agreement), you may not (a) modify, translate, + * adapt, or develop new applications using the Spine Runtimes or otherwise + * create derivative works or improvements of the Spine Runtimes or (b) remove, + * delete, alter, or obscure any trademarks or any copyright, trademark, patent, + * 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 + * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF + * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef SPINE_VERTEXEFFECT_H_ +#define SPINE_VERTEXEFFECT_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct spVertexEffect; + +typedef void (*spVertexEffectBegin)(struct spVertexEffect *self, spSkeleton *skeleton); + +typedef void (*spVertexEffectTransform)(struct spVertexEffect *self, float *x, float *y, float *u, float *v, + spColor *light, spColor *dark); + +typedef void (*spVertexEffectEnd)(struct spVertexEffect *self); + +typedef struct spVertexEffect { + spVertexEffectBegin begin; + spVertexEffectTransform transform; + spVertexEffectEnd end; +} spVertexEffect; + +typedef struct spJitterVertexEffect { + spVertexEffect super; + float jitterX; + float jitterY; +} spJitterVertexEffect; + +typedef struct spSwirlVertexEffect { + spVertexEffect super; + float centerX; + float centerY; + float radius; + float angle; + float worldX; + float worldY; +} spSwirlVertexEffect; + +spJitterVertexEffect *spJitterVertexEffect_create(float jitterX, float jitterY); + +void spJitterVertexEffect_dispose(spJitterVertexEffect *effect); + +spSwirlVertexEffect *spSwirlVertexEffect_create(float radius); + +void spSwirlVertexEffect_dispose(spSwirlVertexEffect *effect); + +#ifdef __cplusplus +} +#endif + +#endif /* SPINE_VERTEX_EFFECT_H_ */ diff --git a/spine-c/spine-c/include/spine/extension.h b/spine-c/spine-c/include/spine/extension.h index 79155ee8b..021027217 100644 --- a/spine-c/spine-c/include/spine/extension.h +++ b/spine-c/spine-c/include/spine/extension.h @@ -103,6 +103,7 @@ #define COS(A) cosf(A) #define SQRT(A) sqrtf(A) #define ACOS(A) acosf(A) +#define POW(A,B) pow(A, B); #else #define FMOD(A,B) (float)fmod(A, B) #define ATAN2(A,B) (float)atan2(A, B) @@ -110,6 +111,7 @@ #define SIN(A) (float)sin(A) #define SQRT(A) (float)sqrt(A) #define ACOS(A) (float)acos(A) +#define POW(A,B) (float)pow(A, B) #endif #define SIN_DEG(A) SIN((A) * DEG_RAD) @@ -166,14 +168,27 @@ void* _malloc (size_t size, const char* file, int line); void* _calloc (size_t num, size_t size, const char* file, int line); void* _realloc(void* ptr, size_t size); void _free (void* ptr); +float _random (); void _setMalloc (void* (*_malloc) (size_t size)); void _setDebugMalloc (void* (*_malloc) (size_t size, const char* file, int line)); void _setRealloc(void* (*_realloc) (void* ptr, size_t size)); void _setFree (void (*_free) (void* ptr)); +void _setRandom(float (*_random) ()); char* _readFile (const char* path, int* length); + +/* + * Math utilities + */ +float _spMath_random(float min, float max); +float _spMath_randomTriangular(float min, float max); +float _spMath_randomTriangularWith(float min, float max, float mode); +float _spMath_interpolate(float (*apply) (float a), float start, float end, float a); +float _spMath_pow2_apply(float a); +float _spMath_pow2out_apply(float a); + /**/ typedef union _spEventQueueItem { diff --git a/spine-c/spine-c/include/spine/spine.h b/spine-c/spine-c/include/spine/spine.h index e57b33f5f..56f4b3cde 100644 --- a/spine-c/spine-c/include/spine/spine.h +++ b/spine-c/spine-c/include/spine/spine.h @@ -57,5 +57,6 @@ #include #include #include +#include #endif /* SPINE_SPINE_H_ */ diff --git a/spine-c/spine-c/src/spine/VertexEffect.c b/spine-c/spine-c/src/spine/VertexEffect.c new file mode 100644 index 000000000..68d4d1f68 --- /dev/null +++ b/spine-c/spine-c/src/spine/VertexEffect.c @@ -0,0 +1,98 @@ +/****************************************************************************** + * Spine Runtimes Software License v2.5 + * + * Copyright (c) 2013-2016, 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 and derivative works solely for personal or internal + * use. Without the written permission of Esoteric Software (see Section 2 of + * the Spine Software License Agreement), you may not (a) modify, translate, + * adapt, or develop new applications using the Spine Runtimes or otherwise + * create derivative works or improvements of the Spine Runtimes or (b) remove, + * delete, alter, or obscure any trademarks or any copyright, trademark, patent, + * 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 + * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF + * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include +#include + +void _spJitterVertexEffect_begin(spVertexEffect* self, spSkeleton* skeleton) { +} + +void _spJitterVertexEffect_transform(spVertexEffect* self, float* x, float* y, float* u, float* v, spColor* light, spColor* dark) { + spJitterVertexEffect* internal = (spJitterVertexEffect*)self; + float jitterX = internal->jitterX; + float jitterY = internal->jitterY; + (*x) += _spMath_randomTriangular(-jitterX, jitterY); + (*y) += _spMath_randomTriangular(-jitterX, jitterY); +} + +void _spJitterVertexEffect_end(spVertexEffect* self) { +} + +spJitterVertexEffect* spJitterVertexEffect_create(float jitterX, float jitterY) { + spJitterVertexEffect* effect = CALLOC(spJitterVertexEffect, 1); + effect->super.begin = _spJitterVertexEffect_begin; + effect->super.transform = _spJitterVertexEffect_transform; + effect->super.end = _spJitterVertexEffect_end; + effect->jitterX = jitterX; + effect->jitterY = jitterY; + return effect; +} + +void spJitterVertexEffect_dispose(spJitterVertexEffect* effect) { + FREE(effect); +} + +void _spSwirlVertexEffect_begin(spVertexEffect* self, spSkeleton* skeleton) { + spSwirlVertexEffect* internal = (spSwirlVertexEffect*)self; + internal->worldX = skeleton->x + internal->centerX; + internal->worldY = skeleton->y + internal->centerY; +} + +void _spSwirlVertexEffect_transform(spVertexEffect* self, float* positionX, float* positionY, float* u, float* v, spColor* light, spColor* dark) { + spSwirlVertexEffect* internal = (spSwirlVertexEffect*)self; + float radAngle = internal->angle * DEG_RAD; + float x = *positionX - internal->worldX; + float y = *positionY - internal->worldY; + float dist = SQRT(x * x + y * y); + if (dist < internal->radius) { + float theta = _spMath_interpolate(_spMath_pow2_apply, 0, radAngle, (internal->radius - dist) / internal->radius); + float cosine = COS(theta); + float sine = SIN(theta); + (*positionX) = cosine * x - sine * y + internal->worldX; + (*positionY) = sine * x + cosine * y + internal->worldY; + } +} + +void _spSwirlVertexEffect_end(spVertexEffect* self) { +} + +spSwirlVertexEffect* spSwirlVertexEffect_create(float radius) { + spSwirlVertexEffect* effect = CALLOC(spSwirlVertexEffect, 1); + effect->super.begin = _spSwirlVertexEffect_begin; + effect->super.transform = _spSwirlVertexEffect_transform; + effect->super.end = _spSwirlVertexEffect_end; + effect->radius = radius; + return effect; +} + +void spSwirlVertexEffect_dispose(spSwirlVertexEffect* effect) { + FREE(effect); +} + diff --git a/spine-c/spine-c/src/spine/extension.c b/spine-c/spine-c/src/spine/extension.c index cccb6d65b..ee3a7d45b 100644 --- a/spine-c/spine-c/src/spine/extension.c +++ b/spine-c/spine-c/src/spine/extension.c @@ -31,10 +31,15 @@ #include #include +float _spRandom () { + return rand() / (float)RAND_MAX; +} + static void* (*mallocFunc) (size_t size) = malloc; static void* (*reallocFunc) (void* ptr, size_t size) = realloc; static void* (*debugMallocFunc) (size_t size, const char* file, int line) = NULL; static void (*freeFunc) (void* ptr) = free; +static float (*randomFunc) () = _spRandom; void* _malloc (size_t size, const char* file, int line) { if(debugMallocFunc) @@ -54,6 +59,10 @@ void _free (void* ptr) { freeFunc(ptr); } +float _random () { + return randomFunc(); +} + void _setDebugMalloc(void* (*malloc) (size_t size, const char* file, int line)) { debugMallocFunc = malloc; } @@ -70,6 +79,10 @@ void _setFree (void (*free) (void* ptr)) { freeFunc = free; } +void _setRandom (float (*random) ()) { + randomFunc = random; +} + char* _readFile (const char* path, int* length) { char *data; FILE *file = fopen(path, "rb"); @@ -85,3 +98,31 @@ char* _readFile (const char* path, int* length) { return data; } + +float _spMath_random(float min, float max) { + return min + (max - min) * _random(); +} + +float _spMath_randomTriangular(float min, float max) { + return _spMath_randomTriangularWith(min, max, (min + max) * 0.5f); +} + +float _spMath_randomTriangularWith(float min, float max, float mode) { + float u = _random(); + float d = max - min; + if (u <= (mode - min) / d) return min + SQRT(u * d * (mode - min)); + return max - SQRT((1 - u) * d * (max - mode)); +} + +float _spMath_interpolate(float (*apply) (float a), float start, float end, float a) { + return start + (end - start) * apply(a); +} + +float _spMath_pow2_apply(float a) { + if (a <= 0.5) return POW(a * 2, 2) / 2; + return POW((a - 1) * 2, 2) / -2 + 1; +} + +float _spMath_pow2out_apply(float a) { + return POW(a - 1, 2) * -1 + 1; +} diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java index 832d9cd3c..39321c235 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java @@ -39,6 +39,7 @@ import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.math.Interpolation; +import com.esotericsoftware.spine.vertexeffects.JitterEffect; import com.esotericsoftware.spine.vertexeffects.SwirlEffect; public class VertexEffectTest extends ApplicationAdapter { diff --git a/spine-sfml/CMakeLists.txt b/spine-sfml/CMakeLists.txt index 2e2a4fb5f..33ce3282e 100644 --- a/spine-sfml/CMakeLists.txt +++ b/spine-sfml/CMakeLists.txt @@ -1,3 +1,4 @@ +cmake_minimum_required(VERSION 2.8.9) # # First download and extract SFML 2.3.2 for the respective OS we are on # diff --git a/spine-sfml/example/main.cpp b/spine-sfml/example/main.cpp index 9123c0db3..33a9bfd0f 100644 --- a/spine-sfml/example/main.cpp +++ b/spine-sfml/example/main.cpp @@ -204,6 +204,10 @@ void raptor (SkeletonData* skeletonData, Atlas* atlas) { SkeletonDrawable* drawable = new SkeletonDrawable(skeletonData); drawable->timeScale = 1; + spSwirlVertexEffect* effect = spSwirlVertexEffect_create(400); + effect->centerY = -200; + drawable->vertexEffect = &effect->super; + Skeleton* skeleton = drawable->skeleton; skeleton->x = 320; skeleton->y = 590; @@ -216,6 +220,7 @@ void raptor (SkeletonData* skeletonData, Atlas* atlas) { window.setFramerateLimit(60); sf::Event event; sf::Clock deltaClock; + float swirlTime = 0; while (window.isOpen()) { while (window.pollEvent(event)) if (event.type == sf::Event::Closed) window.close(); @@ -223,12 +228,18 @@ void raptor (SkeletonData* skeletonData, Atlas* atlas) { float delta = deltaClock.getElapsedTime().asSeconds(); deltaClock.restart(); + swirlTime += delta; + float percent = fmod(swirlTime, 2); + if (percent > 1) percent = 1 - (percent - 1); + effect->angle = _spMath_interpolate(_spMath_pow2_apply, -60, 60, percent); + drawable->update(delta); window.clear(); window.draw(*drawable); window.display(); } + spSwirlVertexEffect_dispose(effect); } void tank (SkeletonData* skeletonData, Atlas* atlas) { @@ -338,6 +349,7 @@ void coin (SkeletonData* skeletonData, Atlas* atlas) { window.setFramerateLimit(60); sf::Event event; sf::Clock deltaClock; + float swirlTime = 0; while (window.isOpen()) { while (window.pollEvent(event)) if (event.type == sf::Event::Closed) window.close(); @@ -384,7 +396,7 @@ int main () { testcase(test, "data/tank-pro.json", "data/tank-pro.skel", "data/tank.atlas", 1.0f); testcase(coin, "data/coin-pro.json", "data/coin-pro.skel", "data/coin.atlas", 0.5f); testcase(vine, "data/vine-pro.json", "data/vine-pro.skel", "data/vine.atlas", 0.5f); - testcase(tank, "data/tank-pro.json", "data/tank-pro.skel", "data/tank.atlas", 0.2f); + testcase(tank, "data/tank-pro.json", "data/tank-pro.skel", "data/tank.atlas", 0.2f);*/ testcase(raptor, "data/raptor-pro.json", "data/raptor-pro.skel", "data/raptor.atlas", 0.5f); testcase(spineboy, "data/spineboy-ess.json", "data/spineboy-ess.skel", "data/spineboy.atlas", 0.6f); testcase(goblins, "data/goblins-pro.json", "data/goblins-pro.skel", "data/goblins.atlas", 1.4f); diff --git a/spine-sfml/src/spine/spine-sfml.cpp b/spine-sfml/src/spine/spine-sfml.cpp index 9fe0ea975..89189d01d 100644 --- a/spine-sfml/src/spine/spine-sfml.cpp +++ b/spine-sfml/src/spine/spine-sfml.cpp @@ -36,6 +36,8 @@ using namespace sf; +_SP_ARRAY_IMPLEMENT_TYPE(spColorArray, spColor) + void _AtlasPage_createTexture (AtlasPage* self, const char* path){ Texture* texture = new Texture(); if (!texture->loadFromFile(path)) return; @@ -64,10 +66,13 @@ namespace spine { SkeletonDrawable::SkeletonDrawable (SkeletonData* skeletonData, AnimationStateData* stateData) : timeScale(1), vertexArray(new VertexArray(Triangles, skeletonData->bonesCount * 4)), + vertexEffect(0), worldVertices(0), clipper(0) { Bone_setYDown(true); worldVertices = MALLOC(float, SPINE_MESH_VERTEX_COUNT_MAX); skeleton = Skeleton_create(skeletonData); + tempUvs = spFloatArray_create(16); + tempColors = spColorArray_create(16); ownsAnimationStateData = stateData == 0; if (ownsAnimationStateData) stateData = AnimationStateData_create(skeletonData); @@ -84,6 +89,8 @@ SkeletonDrawable::~SkeletonDrawable () { AnimationState_dispose(state); Skeleton_dispose(skeleton); spSkeletonClipping_dispose(clipper); + spFloatArray_dispose(tempUvs); + spColorArray_dispose(tempColors); } void SkeletonDrawable::update (float deltaTime) { @@ -98,6 +105,8 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const { states.texture = 0; unsigned short quadIndices[6] = { 0, 1, 2, 2, 3, 0 }; + if (vertexEffect != 0) vertexEffect->begin(vertexEffect, skeleton); + sf::Vertex vertex; Texture* texture = 0; for (int i = 0; i < skeleton->slotsCount; ++i) { @@ -147,6 +156,12 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const { vertex.color.b = b; vertex.color.a = a; + spColor light; + light.r = r / 255.0f; + light.g = g / 255.0f; + light.b = b / 255.0f; + light.a = a / 255.0f; + sf::BlendMode blend; switch (slot->data->blendMode) { case BLEND_MODE_ADDITIVE: @@ -179,19 +194,57 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const { } Vector2u size = texture->getSize(); - for (int i = 0; i < indicesCount; ++i) { - int index = indices[i] << 1; - vertex.position.x = vertices[index]; - vertex.position.y = vertices[index + 1]; - vertex.texCoords.x = uvs[index] * size.x; - vertex.texCoords.y = uvs[index + 1] * size.y; - vertexArray->append(vertex); + + if (vertexEffect != 0) { + spFloatArray_clear(tempUvs); + spColorArray_clear(tempColors); + for (int i = 0; i < verticesCount; i++) { + spColor vertexColor = light; + spColor dark; + dark.r = dark.g = dark.b = dark.a = 0; + int index = i << 1; + float x = vertices[index]; + float y = vertices[index + 1]; + float u = uvs[index]; + float v = uvs[index + 1]; + vertexEffect->transform(vertexEffect, &x, &y, &u, &v, &vertexColor, &dark); + vertices[index] = x; + vertices[index + 1] = y; + spFloatArray_add(tempUvs, u); + spFloatArray_add(tempUvs, v); + spColorArray_add(tempColors, vertexColor); + } + + for (int i = 0; i < indicesCount; ++i) { + int index = indices[i] << 1; + vertex.position.x = vertices[index]; + vertex.position.y = vertices[index + 1]; + vertex.texCoords.x = uvs[index] * size.x; + vertex.texCoords.y = uvs[index + 1] * size.y; + spColor vertexColor = tempColors->items[index >> 1]; + vertex.color.r = static_cast(vertexColor.r * 255); + vertex.color.g = static_cast(vertexColor.g * 255); + vertex.color.b = static_cast(vertexColor.b * 255); + vertex.color.a = static_cast(vertexColor.a * 255); + vertexArray->append(vertex); + } + } else { + for (int i = 0; i < indicesCount; ++i) { + int index = indices[i] << 1; + vertex.position.x = vertices[index]; + vertex.position.y = vertices[index + 1]; + vertex.texCoords.x = uvs[index] * size.x; + vertex.texCoords.y = uvs[index + 1] * size.y; + vertexArray->append(vertex); + } } spSkeletonClipping_clipEnd(clipper, slot); } target.draw(*vertexArray, states); spSkeletonClipping_clipEnd2(clipper); + + if (vertexEffect != 0) vertexEffect->end(vertexEffect); } } /* namespace spine */ diff --git a/spine-sfml/src/spine/spine-sfml.h b/spine-sfml/src/spine/spine-sfml.h index 6fa1fc139..4074b71f0 100644 --- a/spine-sfml/src/spine/spine-sfml.h +++ b/spine-sfml/src/spine/spine-sfml.h @@ -40,6 +40,8 @@ #include #include +_SP_ARRAY_DECLARE_TYPE(spColorArray, spColor) + namespace spine { class SkeletonDrawable: public sf::Drawable { @@ -48,6 +50,7 @@ public: AnimationState* state; float timeScale; sf::VertexArray* vertexArray; + spVertexEffect* vertexEffect; SkeletonDrawable (SkeletonData* skeleton, AnimationStateData* stateData = 0); ~SkeletonDrawable (); @@ -58,6 +61,8 @@ public: private: bool ownsAnimationStateData; float* worldVertices; + spFloatArray* tempUvs; + spColorArray* tempColors; spSkeletonClipping* clipper; };