diff --git a/examples/export/runtimes.sh b/examples/export/runtimes.sh index 0afa341a4..23849a312 100755 --- a/examples/export/runtimes.sh +++ b/examples/export/runtimes.sh @@ -225,8 +225,8 @@ cp -f ../celestial-circus/export/celestial-circus.png "$ROOT/spine-godot/example echo "spine-sdl" rm -f "$ROOT/spine-sdl/data/"* cp -f ../spineboy/export/spineboy-pro.json "$ROOT/spine-sdl/data/" -cp -f ../spineboy/export/spineboy.atlas "$ROOT/spine-sdl/data/" -cp -f ../spineboy/export/spineboy.png "$ROOT/spine-sdl/data/" +cp -f ../spineboy/export/spineboy-pma.atlas "$ROOT/spine-sdl/data/" +cp -f ../spineboy/export/spineboy-pma.png "$ROOT/spine-sdl/data/" echo "spine-sfml-c" rm "$ROOT/spine-sfml/c/data/"* diff --git a/spine-sdl/README.md b/spine-sdl/README.md index a2f749677..c555bfd6b 100644 --- a/spine-sdl/README.md +++ b/spine-sdl/README.md @@ -20,7 +20,7 @@ For the official legal terms governing the Spine Runtimes, please read the [Spin spine-sdl works with data exported from Spine 4.2.xx. -spine-sdl supports all Spine features except premultiplied alpha, screen blend mode, and two color tinting. +spine-sdl supports all Spine features except screen blend mode and two color tinting. ## Usage diff --git a/spine-sdl/data/spineboy.atlas b/spine-sdl/data/spineboy-pma.atlas similarity index 98% rename from spine-sdl/data/spineboy.atlas rename to spine-sdl/data/spineboy-pma.atlas index eca542b71..ad3d77b11 100644 --- a/spine-sdl/data/spineboy.atlas +++ b/spine-sdl/data/spineboy-pma.atlas @@ -1,6 +1,7 @@ -spineboy.png +spineboy-pma.png size: 1024, 256 filter: Linear, Linear + pma: true scale: 0.5 crosshair bounds: 352, 7, 45, 45 diff --git a/spine-sdl/data/spineboy-pma.png b/spine-sdl/data/spineboy-pma.png new file mode 100644 index 000000000..711fd836e Binary files /dev/null and b/spine-sdl/data/spineboy-pma.png differ diff --git a/spine-sdl/data/spineboy.png b/spine-sdl/data/spineboy.png deleted file mode 100644 index 0ea9737f3..000000000 Binary files a/spine-sdl/data/spineboy.png and /dev/null differ diff --git a/spine-sdl/example/main.c b/spine-sdl/example/main.c index bd0f8d02b..9e437823e 100644 --- a/spine-sdl/example/main.c +++ b/spine-sdl/example/main.c @@ -47,13 +47,14 @@ int main() { return -1; } - spAtlas *atlas = spAtlas_createFromFile("data/spineboy.atlas", renderer); + spAtlas *atlas = spAtlas_createFromFile("data/spineboy-pma.atlas", renderer); spSkeletonJson *json = spSkeletonJson_create(atlas); json->scale = 0.5f; spSkeletonData *skeletonData = spSkeletonJson_readSkeletonDataFile(json, "data/spineboy-pro.json"); spAnimationStateData *animationStateData = spAnimationStateData_create(skeletonData); animationStateData->defaultMix = 0.2f; spSkeletonDrawable *drawable = spSkeletonDrawable_create(skeletonData, animationStateData); + drawable->usePremultipliedAlpha = -1; drawable->skeleton->x = 400; drawable->skeleton->y = 500; spSkeleton_setToSetupPose(drawable->skeleton); diff --git a/spine-sdl/example/main.cpp b/spine-sdl/example/main.cpp index cd5796bab..654b26e8a 100644 --- a/spine-sdl/example/main.cpp +++ b/spine-sdl/example/main.cpp @@ -48,12 +48,13 @@ int main(int argc, char **argv) { } spine::SDLTextureLoader textureLoader(renderer); - spine::Atlas atlas("data/spineboy.atlas", &textureLoader); + spine::Atlas atlas("data/spineboy-pma.atlas", &textureLoader); spine::AtlasAttachmentLoader attachmentLoader(&atlas); spine::SkeletonJson json(&attachmentLoader); json.setScale(0.5f); spine::SkeletonData *skeletonData = json.readSkeletonDataFile("data/spineboy-pro.json"); spine::SkeletonDrawable drawable(skeletonData); + drawable.usePremultipliedAlpha = true; drawable.animationState->getData()->setDefaultMix(0.2f); drawable.skeleton->setPosition(400, 500); drawable.skeleton->setToSetupPose(); diff --git a/spine-sdl/src/spine-sdl-c.c b/spine-sdl/src/spine-sdl-c.c index 813f64738..27e31b765 100644 --- a/spine-sdl/src/spine-sdl-c.c +++ b/spine-sdl/src/spine-sdl-c.c @@ -42,6 +42,7 @@ spSkeletonDrawable *spSkeletonDrawable_create(spSkeletonData *skeletonData, spAn spSkeletonDrawable *self = NEW(spSkeletonDrawable); self->skeleton = spSkeleton_create(skeletonData); self->animationState = spAnimationState_create(animationStateData); + self->usePremultipliedAlpha = 0; self->sdlIndices = spIntArray_create(12); self->sdlVertices = spSdlVertexArray_create(12); self->worldVertices = spFloatArray_create(12); @@ -163,20 +164,41 @@ void spSkeletonDrawable_draw(spSkeletonDrawable *self, struct SDL_Renderer *rend for (int ii = 0; ii < (int) indicesCount; ii++) spIntArray_add(self->sdlIndices, indices[ii]); - switch (slot->data->blendMode) { - case SP_BLEND_MODE_NORMAL: - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); - break; - case SP_BLEND_MODE_MULTIPLY: - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_MOD); - break; - case SP_BLEND_MODE_ADDITIVE: - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_ADD); - break; - case SP_BLEND_MODE_SCREEN: - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); - break; - } + if (!self->usePremultipliedAlpha) { + switch (slot->data->blendMode) { + case SP_BLEND_MODE_NORMAL: + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + break; + case SP_BLEND_MODE_MULTIPLY: + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_MOD); + break; + case SP_BLEND_MODE_ADDITIVE: + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_ADD); + break; + case SP_BLEND_MODE_SCREEN: + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + break; + } + } else { + SDL_BlendMode target; + switch (slot->data->blendMode) { + case SP_BLEND_MODE_NORMAL: + target = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD); + SDL_SetTextureBlendMode(texture, target); + break; + case SP_BLEND_MODE_MULTIPLY: + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_MOD); + break; + case SP_BLEND_MODE_ADDITIVE: + target = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_ADD); + break; + case SP_BLEND_MODE_SCREEN: + target = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + break; + } + } SDL_RenderGeometry(renderer, texture, self->sdlVertices->items, self->sdlVertices->size, self->sdlIndices->items, indicesCount); diff --git a/spine-sdl/src/spine-sdl-c.h b/spine-sdl/src/spine-sdl-c.h index 8318acfad..313d68c42 100644 --- a/spine-sdl/src/spine-sdl-c.h +++ b/spine-sdl/src/spine-sdl-c.h @@ -43,6 +43,7 @@ _SP_ARRAY_DECLARE_TYPE(spSdlVertexArray, struct SDL_Vertex) typedef struct spSkeletonDrawable { spSkeleton *skeleton; spAnimationState *animationState; + int usePremultipliedAlpha; spSkeletonClipping *clipper; spFloatArray *worldVertices; diff --git a/spine-sdl/src/spine-sdl-cpp.cpp b/spine-sdl/src/spine-sdl-cpp.cpp index 91b03c2ed..945c86f0c 100644 --- a/spine-sdl/src/spine-sdl-cpp.cpp +++ b/spine-sdl/src/spine-sdl-cpp.cpp @@ -164,38 +164,37 @@ void SkeletonDrawable::draw(SDL_Renderer *renderer) { if (!usePremultipliedAlpha) { switch (slot.getData().getBlendMode()) { - case BlendMode_Normal: - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); - break; - case BlendMode_Multiply: - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_MOD); - break; - case BlendMode_Additive: - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_ADD); - break; - case BlendMode_Screen: - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); - break; + case BlendMode_Normal: + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + break; + case BlendMode_Multiply: + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_MOD); + break; + case BlendMode_Additive: + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_ADD); + break; + case BlendMode_Screen: + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + break; } - } - else { + } else { SDL_BlendMode target; switch (slot.getData().getBlendMode()) { - case BlendMode_Normal: - target = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD); - SDL_SetTextureBlendMode(texture, target); - break; - case BlendMode_Multiply: - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_MOD); - break; - case BlendMode_Additive: - target = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD); - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_ADD); - break; - case BlendMode_Screen: - target = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD); - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); - break; + case BlendMode_Normal: + target = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD); + SDL_SetTextureBlendMode(texture, target); + break; + case BlendMode_Multiply: + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_MOD); + break; + case BlendMode_Additive: + target = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_ADD); + break; + case BlendMode_Screen: + target = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + break; } } diff --git a/spine-sdl/src/spine-sdl-cpp.h b/spine-sdl/src/spine-sdl-cpp.h index 4185d352c..826b912dc 100644 --- a/spine-sdl/src/spine-sdl-cpp.h +++ b/spine-sdl/src/spine-sdl-cpp.h @@ -46,9 +46,7 @@ namespace spine { Skeleton *skeleton; AnimationState *animationState; - - void setUsePremultipliedAlpha(bool usePMA) { usePremultipliedAlpha = usePMA; }; - bool getUsePremultipliedAlpha() { return usePremultipliedAlpha; }; + bool usePremultipliedAlpha; private: bool ownsAnimationStateData; @@ -56,7 +54,6 @@ namespace spine { Vector worldVertices; Vector sdlVertices; Vector sdlIndices; - bool usePremultipliedAlpha; }; class SDLTextureLoader : public spine::TextureLoader {