From 2bc3f511a1fcf8404c9be8e82ae2d7fc3c65cd70 Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Wed, 17 Apr 2013 22:06:36 +0200 Subject: [PATCH] Refactoring to make extension easier. Much less weird OOP needed. Rendering is separate from data objects. cocos2d-iphone and cocos2d-x support for multi page atlases. --- spine-c/example/main.c | 84 +---- spine-c/include/spine/Atlas.h | 13 +- spine-c/include/spine/Attachment.h | 2 - spine-c/include/spine/RegionAttachment.h | 11 +- spine-c/include/spine/Skeleton.h | 3 +- spine-c/include/spine/extension.h | 49 +-- spine-c/src/spine/Animation.c | 10 +- spine-c/src/spine/Atlas.c | 29 +- spine-c/src/spine/AtlasAttachmentLoader.c | 4 +- spine-c/src/spine/Attachment.c | 11 +- spine-c/src/spine/AttachmentLoader.c | 4 +- spine-c/src/spine/RegionAttachment.c | 41 ++- spine-c/src/spine/Skeleton.c | 20 +- .../src/spine/spine-cocos2d-iphone.h | 34 +-- .../src/spine/spine-cocos2d-iphone.m | 273 +++++++---------- spine-cocos2dx/src/spine/spine-cocos2dx.cpp | 289 ++++++++---------- spine-cocos2dx/src/spine/spine-cocos2dx.h | 26 +- spine-sfml/src/spine/spine-sfml.cpp | 219 ++++++------- spine-sfml/src/spine/spine-sfml.h | 1 - 19 files changed, 425 insertions(+), 698 deletions(-) diff --git a/spine-c/example/main.c b/spine-c/example/main.c index 3002cf92d..b1fdb894a 100644 --- a/spine-c/example/main.c +++ b/spine-c/example/main.c @@ -7,86 +7,15 @@ /**/ -typedef struct { - AtlasPage super; - int extraData; -} ExampleAtlasPage; - -void _ExampleAtlasPage_dispose (AtlasPage* page) { - ExampleAtlasPage* self = SUB_CAST(ExampleAtlasPage, page); - _AtlasPage_deinit(SUPER(self)); - - self->extraData = 0; - - FREE(self); +void _AtlasPage_createTexture (AtlasPage* self, const char* path) { + self->texture = 0; + self->width = 123; + self->height = 456; } -AtlasPage* AtlasPage_create (const char* name, const char* path) { - ExampleAtlasPage* self = NEW(ExampleAtlasPage); - _AtlasPage_init(SUPER(self), name, _ExampleAtlasPage_dispose); - - self->extraData = 123; - - return SUPER(self); +void _AtlasPage_disposeTexture (AtlasPage* self) { } -/**/ - -typedef struct { - Skeleton super; - int extraData; -} ExampleSkeleton; - -void _ExampleSkeleton_dispose (Skeleton* skeleton) { - ExampleSkeleton* self = SUB_CAST(ExampleSkeleton, skeleton); - _Skeleton_deinit(SUPER(self)); - - self->extraData = 0; - - FREE(self); -} - -Skeleton* Skeleton_create (SkeletonData* data) { - ExampleSkeleton* self = NEW(ExampleSkeleton); - _Skeleton_init(SUPER(self), data, _ExampleSkeleton_dispose); - - self->extraData = 789; - - return SUPER(self); -} - -/**/ - -typedef struct { - RegionAttachment super; - int extraData; -} ExampleRegionAttachment; - -void _ExampleRegionAttachment_dispose (Attachment* attachment) { - ExampleRegionAttachment* self = SUB_CAST(ExampleRegionAttachment, attachment); - _RegionAttachment_deinit(SUPER(self)); - - self->extraData = 0; - - FREE(self); -} - -void _ExampleRegionAttachment_draw (Attachment* attachment, Slot* slot) { - /* ExampleRegionAttachment* self = (ExampleRegionAttachment*)attachment; - Draw or queue region for drawing. */ -} - -RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) { - ExampleRegionAttachment* self = NEW(ExampleRegionAttachment); - _RegionAttachment_init(SUPER(self), name, _ExampleRegionAttachment_dispose, _ExampleRegionAttachment_draw); - - self->extraData = 456; - - return SUPER(self); -} - -/**/ - char* _Util_readFile (const char* path, int* length) { return _readFile(path, length); } @@ -96,7 +25,7 @@ char* _Util_readFile (const char* path, int* length) { int main (void) { Atlas* atlas = Atlas_readAtlasFile("data/spineboy.atlas"); printf("First region name: %s, x: %d, y: %d\n", atlas->regions->name, atlas->regions->x, atlas->regions->y); - printf("First page name: %s, extraData: %d\n", atlas->pages->name, ((ExampleAtlasPage*)atlas->pages)->extraData); + printf("First page name: %s, size: %d, %d\n", atlas->pages->name, atlas->pages->width, atlas->pages->height); SkeletonJson* json = SkeletonJson_create(atlas); SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "data/spineboy.json"); @@ -104,7 +33,6 @@ int main (void) { printf("Default skin name: %s\n", skeletonData->defaultSkin->name); Skeleton* skeleton = Skeleton_create(skeletonData); - printf("Skeleton extraData: %d\n", ((ExampleSkeleton*)skeleton)->extraData); Animation* animation = SkeletonData_findAnimation(skeletonData, "walk"); if (!animation) printf("Error: %s\n", json->error); diff --git a/spine-c/include/spine/Atlas.h b/spine-c/include/spine/Atlas.h index e58d5250b..c732918ba 100644 --- a/spine-c/include/spine/Atlas.h +++ b/spine-c/include/spine/Atlas.h @@ -55,12 +55,14 @@ struct AtlasPage { AtlasFormat format; AtlasFilter minFilter, magFilter; AtlasWrap uWrap, vWrap; - AtlasPage* next; - const void* const vtable; + void* texture; + int width, height; + + AtlasPage* next; }; -AtlasPage* AtlasPage_create (const char* name, const char* path); +AtlasPage* AtlasPage_create (const char* name); void AtlasPage_dispose (AtlasPage* self); /**/ @@ -69,6 +71,7 @@ typedef struct AtlasRegion AtlasRegion; struct AtlasRegion { const char* name; int x, y, width, height; + float u, v, u2, v2; float offsetX, offsetY; int originalWidth, originalHeight; int index; @@ -76,7 +79,9 @@ struct AtlasRegion { int/*bool*/flip; int* splits; int* pads; + AtlasPage* page; + AtlasRegion* next; }; @@ -90,7 +95,7 @@ typedef struct { AtlasRegion* regions; } Atlas; -/* Image files referenced in the atlas file will be prefixed dir. */ +/* Image files referenced in the atlas file will be prefixed with dir. */ Atlas* Atlas_readAtlas (const char* data, int length, const char* dir); /* Image files referenced in the atlas file will be prefixed with the directory containing the atlas file. */ Atlas* Atlas_readAtlasFile (const char* path); diff --git a/spine-c/include/spine/Attachment.h b/spine-c/include/spine/Attachment.h index 9dfc333b9..c8b41c51c 100644 --- a/spine-c/include/spine/Attachment.h +++ b/spine-c/include/spine/Attachment.h @@ -47,8 +47,6 @@ struct Attachment { void Attachment_dispose (Attachment* self); -void Attachment_draw (Attachment* self, struct Slot* slot); - #ifdef __cplusplus } } diff --git a/spine-c/include/spine/RegionAttachment.h b/spine-c/include/spine/RegionAttachment.h index 240135904..1046ba3f5 100644 --- a/spine-c/include/spine/RegionAttachment.h +++ b/spine-c/include/spine/RegionAttachment.h @@ -28,22 +28,31 @@ #include #include +#include #ifdef __cplusplus namespace spine { extern "C" { #endif +typedef enum { + VERTEX_X1 = 0, VERTEX_Y1, VERTEX_X2, VERTEX_Y2, VERTEX_X3, VERTEX_Y3, VERTEX_X4, VERTEX_Y4 +} VertexIndex; + typedef struct RegionAttachment RegionAttachment; struct RegionAttachment { Attachment super; float x, y, scaleX, scaleY, rotation, width, height; + AtlasRegion* region; float offset[8]; + float vertices[8]; + float uvs[8]; }; -RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region); +RegionAttachment* RegionAttachment_create (const char* name); void RegionAttachment_updateOffset (RegionAttachment* self); +void RegionAttachment_updateVertices (RegionAttachment* self, Slot* slot); #ifdef __cplusplus } diff --git a/spine-c/include/spine/Skeleton.h b/spine-c/include/spine/Skeleton.h index 5bce20358..e53d4e5bc 100644 --- a/spine-c/include/spine/Skeleton.h +++ b/spine-c/include/spine/Skeleton.h @@ -51,10 +51,9 @@ struct Skeleton { float r, g, b, a; float time; int/*bool*/flipX, flipY; - - const void* const vtable; }; +Skeleton* Skeleton_create (SkeletonData* data); void Skeleton_dispose (Skeleton* self); void Skeleton_updateWorldTransform (const Skeleton* self); diff --git a/spine-c/include/spine/extension.h b/spine-c/include/spine/extension.h index e7ec10da6..94a9d7a9a 100644 --- a/spine-c/include/spine/extension.h +++ b/spine-c/include/spine/extension.h @@ -28,10 +28,11 @@ - An OOP style is used where each "class" is made up of a struct and a number of functions prefixed with the struct name. - - struct fields that are const are readonly. Either they are set in a constructor and can never be changed, or they can only be - changed by calling a function. + - struct fields that are const are readonly. Either they are set in a create function and can never be changed, or they can only + be changed by calling a function. - Inheritance is done using a struct field named "super" as the first field, allowing the struct to be cast to its "super class". + This works because a pointer to a struct is guaranteed to be a pointer to the first struct field. - Classes intended for inheritance provide init/deinit functions which subclasses must call in their create/dispose functions. @@ -73,10 +74,10 @@ /* Gets the vtable for the specified type. Not type safe, use with care. */ #define VTABLE(TYPE,VALUE) ((_##TYPE##Vtable*)((TYPE*)VALUE)->vtable) -/* Frees memory. Can be used on const. */ +/* Frees memory. Can be used on const types. */ #define FREE(VALUE) _free((void*)VALUE) -/* Allocates a new char[], assigns it to TO, and copies FROM to it. Can be used on const. */ +/* Allocates a new char[], assigns it to TO, and copies FROM to it. Can be used on const types. */ #define MALLOC_STR(TO,FROM) strcpy(CONST_CAST(char*, TO) = (char*)malloc(strlen(FROM) + 1), FROM) #include @@ -96,10 +97,8 @@ extern "C" { * Functions that must be implemented: */ -RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region); - -AtlasPage* AtlasPage_create (const char* name, const char* path); - +void _AtlasPage_createTexture (AtlasPage* self, const char* path); +void _AtlasPage_disposeTexture (AtlasPage* self); char* _Util_readFile (const char* path, int* length); /* @@ -117,26 +116,21 @@ char* _readFile (const char* path, int* length); /**/ -void _Skeleton_init (Skeleton* self, SkeletonData* data, // - void (*dispose) (Skeleton* skeleton)); -void _Skeleton_deinit (Skeleton* self); +void _AttachmentLoader_init (AttachmentLoader* self, // + void (*dispose) (AttachmentLoader* self), // + Attachment* (*newAttachment) (AttachmentLoader* self, Skin* skin, AttachmentType type, const char* name)); +void _AttachmentLoader_deinit (AttachmentLoader* self); +void _AttachmentLoader_setError (AttachmentLoader* self, const char* error1, const char* error2); +void _AttachmentLoader_setUnknownTypeError (AttachmentLoader* self, AttachmentType type); /**/ void _Attachment_init (Attachment* self, const char* name, AttachmentType type, // - void (*dispose) (Attachment* self), // - void (*draw) (Attachment* self, struct Slot* slot)); + void (*dispose) (Attachment* self)); void _Attachment_deinit (Attachment* self); /**/ -void _RegionAttachment_init (RegionAttachment* self, const char* name, // - void (*dispose) (Attachment* self), // - void (*draw) (Attachment* self, struct Slot* slot)); -void _RegionAttachment_deinit (RegionAttachment* self); - -/**/ - void _Timeline_init (Timeline* self, // void (*dispose) (Timeline* self), // void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha)); @@ -149,21 +143,6 @@ void _CurveTimeline_init (CurveTimeline* self, int frameCount, // void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha)); void _CurveTimeline_deinit (CurveTimeline* self); -/**/ - -void _AtlasPage_init (AtlasPage* self, const char* name, // - void (*dispose) (AtlasPage* self)); -void _AtlasPage_deinit (AtlasPage* self); - -/**/ - -void _AttachmentLoader_init (AttachmentLoader* self, // - void (*dispose) (AttachmentLoader* self), // - Attachment* (*newAttachment) (AttachmentLoader* self, Skin* skin, AttachmentType type, const char* name)); -void _AttachmentLoader_deinit (AttachmentLoader* self); -void _AttachmentLoader_setError (AttachmentLoader* self, const char* error1, const char* error2); -void _AttachmentLoader_setUnknownTypeError (AttachmentLoader* self, AttachmentType type); - #ifdef __cplusplus } } diff --git a/spine-c/src/spine/Animation.c b/spine-c/src/spine/Animation.c index e33933f24..b3d0a1150 100644 --- a/spine-c/src/spine/Animation.c +++ b/spine-c/src/spine/Animation.c @@ -70,8 +70,8 @@ typedef struct _TimelineVtable { void (*dispose) (Timeline* self); } _TimelineVtable; -void _Timeline_init (Timeline* self, /**/ - void (*dispose) (Timeline* self), /**/ +void _Timeline_init (Timeline* self, // + void (*dispose) (Timeline* self), // void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha)) { CONST_CAST(_TimelineVtable*, self->vtable) = NEW(_TimelineVtable); VTABLE(Timeline, self) ->dispose = dispose; @@ -96,8 +96,8 @@ static const float CURVE_LINEAR = 0; static const float CURVE_STEPPED = -1; static const int CURVE_SEGMENTS = 10; -void _CurveTimeline_init (CurveTimeline* self, int frameCount, /**/ - void (*dispose) (Timeline* self), /**/ +void _CurveTimeline_init (CurveTimeline* self, int frameCount, // + void (*dispose) (Timeline* self), // void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha)) { _Timeline_init(SUPER(self), dispose, apply); self->curves = CALLOC(float, (frameCount - 1) * 6); @@ -203,7 +203,7 @@ void _BaseTimeline_dispose (Timeline* timeline) { } /* Many timelines have structure identical to struct BaseTimeline and extend CurveTimeline. **/ -struct BaseTimeline* _BaseTimeline_create (int frameCount, int frameSize, /**/ +struct BaseTimeline* _BaseTimeline_create (int frameCount, int frameSize, // void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha)) { struct BaseTimeline* self = NEW(struct BaseTimeline); diff --git a/spine-c/src/spine/Atlas.c b/spine-c/src/spine/Atlas.c index 3dd3e9bf4..eb3d02de7 100644 --- a/spine-c/src/spine/Atlas.c +++ b/spine-c/src/spine/Atlas.c @@ -35,20 +35,15 @@ typedef struct _AtlasPageVtable { void (*dispose) (AtlasPage* self); } _AtlasPageVtable; -void _AtlasPage_init (AtlasPage* self, const char* name, /**/ - void (*dispose) (AtlasPage* self)) { - CONST_CAST(_AtlasPageVtable*, self->vtable) = NEW(_AtlasPageVtable); - VTABLE(AtlasPage, self) ->dispose = dispose; +AtlasPage* AtlasPage_create (const char* name) { + AtlasPage* self = NEW(AtlasPage); MALLOC_STR(self->name, name); -} - -void _AtlasPage_deinit (AtlasPage* self) { - FREE(self->vtable); - FREE(self->name); + return self; } void AtlasPage_dispose (AtlasPage* self) { - VTABLE(AtlasPage, self) ->dispose(self); + FREE(self->name); + _AtlasPage_disposeTexture(self); } /**/ @@ -200,16 +195,14 @@ Atlas* Atlas_readAtlas (const char* begin, int length, const char* dir) { if (needsSlash) path[dirLength] = '/'; strcpy(path + dirLength + needsSlash, name); - page = AtlasPage_create(name, path); + page = AtlasPage_create(name); + FREE(name); if (lastPage) lastPage->next = page; else self->pages = page; lastPage = page; - FREE(name); - FREE(path); - if (!readValue(end, &str)) return abortAtlas(self); page->format = (AtlasFormat)indexOf(formatNames, 7, &str); @@ -222,6 +215,9 @@ Atlas* Atlas_readAtlas (const char* begin, int length, const char* dir) { page->uWrap = *str.begin == 'x' ? ATLAS_REPEAT : (*str.begin == 'y' ? ATLAS_CLAMPTOEDGE : ATLAS_REPEAT); page->vWrap = *str.begin == 'x' ? ATLAS_CLAMPTOEDGE : (*str.begin == 'y' ? ATLAS_REPEAT : ATLAS_REPEAT); } + + _AtlasPage_createTexture(page, path); + FREE(path); } else { AtlasRegion *region = AtlasRegion_create(); if (lastRegion) @@ -244,6 +240,11 @@ Atlas* Atlas_readAtlas (const char* begin, int length, const char* dir) { region->width = toInt(tuple); region->height = toInt(tuple + 1); + region->u = region->x / (float)page->width; + region->v = region->y / (float)page->height; + region->u2 = (region->x + region->width) / (float)page->width; + region->v2 = (region->y + region->height) / (float)page->height; + int count; if (!(count = readTuple(end, tuple))) return abortAtlas(self); if (count == 4) { /* split is optional */ diff --git a/spine-c/src/spine/AtlasAttachmentLoader.c b/spine-c/src/spine/AtlasAttachmentLoader.c index 21f2f10c0..2000e384e 100644 --- a/spine-c/src/spine/AtlasAttachmentLoader.c +++ b/spine-c/src/spine/AtlasAttachmentLoader.c @@ -39,7 +39,9 @@ Attachment* _AtlasAttachmentLoader_newAttachment (AttachmentLoader* loader, Skin _AttachmentLoader_setError(loader, "Region not found: ", name); return 0; } - return SUPER_CAST(Attachment, RegionAttachment_create(name, region)) ; + RegionAttachment* attachment = RegionAttachment_create(name); + attachment->region = region; + return SUPER(attachment); } default: _AttachmentLoader_setUnknownTypeError(loader, type); diff --git a/spine-c/src/spine/Attachment.c b/spine-c/src/spine/Attachment.c index ffa83dfe9..fb122cd3d 100644 --- a/spine-c/src/spine/Attachment.c +++ b/spine-c/src/spine/Attachment.c @@ -32,17 +32,14 @@ namespace spine { #endif typedef struct _AttachmentVtable { - void (*draw) (Attachment* self, struct Slot* slot); void (*dispose) (Attachment* self); } _AttachmentVtable; -void _Attachment_init (Attachment* self, const char* name, AttachmentType type, /**/ - void (*dispose) (Attachment* self), /**/ - void (*draw) (Attachment* self, struct Slot* slot)) { +void _Attachment_init (Attachment* self, const char* name, AttachmentType type, // + void (*dispose) (Attachment* self)) { CONST_CAST(_AttachmentVtable*, self->vtable) = NEW(_AttachmentVtable); VTABLE(Attachment, self) ->dispose = dispose; - VTABLE(Attachment, self) ->draw = draw; MALLOC_STR(self->name, name); self->type = type; @@ -57,10 +54,6 @@ void Attachment_dispose (Attachment* self) { VTABLE(Attachment, self) ->dispose(self); } -void Attachment_draw (Attachment* self, Slot* slot) { - VTABLE(Attachment, self) ->draw(self, slot); -} - #ifdef __cplusplus } #endif diff --git a/spine-c/src/spine/AttachmentLoader.c b/spine-c/src/spine/AttachmentLoader.c index 65e1d4e43..2a1bcf227 100644 --- a/spine-c/src/spine/AttachmentLoader.c +++ b/spine-c/src/spine/AttachmentLoader.c @@ -36,8 +36,8 @@ typedef struct _AttachmentLoaderVtable { void (*dispose) (AttachmentLoader* self); } _AttachmentLoaderVtable; -void _AttachmentLoader_init (AttachmentLoader* self, /**/ - void (*dispose) (AttachmentLoader* self), /**/ +void _AttachmentLoader_init (AttachmentLoader* self, // + void (*dispose) (AttachmentLoader* self), // Attachment* (*newAttachment) (AttachmentLoader* self, Skin* skin, AttachmentType type, const char* name)) { CONST_CAST(_AttachmentLoaderVtable*, self->vtable) = NEW(_AttachmentLoaderVtable); VTABLE(AttachmentLoader, self) ->dispose = dispose; diff --git a/spine-c/src/spine/RegionAttachment.c b/spine-c/src/spine/RegionAttachment.c index dba55a589..daf064ecb 100644 --- a/spine-c/src/spine/RegionAttachment.c +++ b/spine-c/src/spine/RegionAttachment.c @@ -31,16 +31,12 @@ namespace spine { #endif -void _RegionAttachment_init (RegionAttachment* self, const char* name, /**/ - void (*dispose) (Attachment* self), /**/ - void (*draw) (Attachment* self, struct Slot* slot)) { +RegionAttachment* RegionAttachment_create (const char* name) { + RegionAttachment* self = NEW(RegionAttachment); self->scaleX = 1; self->scaleY = 1; - _Attachment_init(SUPER(self), name, ATTACHMENT_REGION, dispose, draw); -} - -void _RegionAttachment_deinit (RegionAttachment* self) { - _Attachment_deinit(SUPER(self)); + _Attachment_init(SUPER(self), name, ATTACHMENT_REGION, _Attachment_deinit); + return self; } void RegionAttachment_updateOffset (RegionAttachment* self) { @@ -63,14 +59,27 @@ void RegionAttachment_updateOffset (RegionAttachment* self) { float localX2Sin = localX2 * sine; float localY2Cos = localY2 * cosine + self->y; float localY2Sin = localY2 * sine; - self->offset[0] = localXCos - localYSin; - self->offset[1] = localYCos + localXSin; - self->offset[2] = localXCos - localY2Sin; - self->offset[3] = localY2Cos + localXSin; - self->offset[4] = localX2Cos - localY2Sin; - self->offset[5] = localY2Cos + localX2Sin; - self->offset[6] = localX2Cos - localYSin; - self->offset[7] = localYCos + localX2Sin; + self->offset[VERTEX_X1] = localXCos - localYSin; + self->offset[VERTEX_Y1] = localYCos + localXSin; + self->offset[VERTEX_X2] = localXCos - localY2Sin; + self->offset[VERTEX_Y2] = localY2Cos + localXSin; + self->offset[VERTEX_X3] = localX2Cos - localY2Sin; + self->offset[VERTEX_Y3] = localY2Cos + localX2Sin; + self->offset[VERTEX_X4] = localX2Cos - localYSin; + self->offset[VERTEX_Y4] = localYCos + localX2Sin; +} + +void RegionAttachment_updateVertices (RegionAttachment* self, Slot* slot) { + float* offset = self->offset; + Bone* bone = slot->bone; + self->vertices[VERTEX_X1] = offset[VERTEX_X1] * bone->m00 + offset[VERTEX_Y1] * bone->m01 + bone->worldX; + self->vertices[VERTEX_Y1] = offset[VERTEX_X1] * bone->m10 + offset[VERTEX_Y1] * bone->m11 + bone->worldY; + self->vertices[VERTEX_X2] = offset[VERTEX_X2] * bone->m00 + offset[VERTEX_Y2] * bone->m01 + bone->worldX; + self->vertices[VERTEX_Y2] = offset[VERTEX_X2] * bone->m10 + offset[VERTEX_Y2] * bone->m11 + bone->worldY; + self->vertices[VERTEX_X3] = offset[VERTEX_X3] * bone->m00 + offset[VERTEX_Y3] * bone->m01 + bone->worldX; + self->vertices[VERTEX_Y3] = offset[VERTEX_X3] * bone->m10 + offset[VERTEX_Y3] * bone->m11 + bone->worldY; + self->vertices[VERTEX_X4] = offset[VERTEX_X4] * bone->m00 + offset[VERTEX_Y4] * bone->m01 + bone->worldX; + self->vertices[VERTEX_Y4] = offset[VERTEX_X4] * bone->m10 + offset[VERTEX_Y4] * bone->m11 + bone->worldY; } #ifdef __cplusplus diff --git a/spine-c/src/spine/Skeleton.c b/spine-c/src/spine/Skeleton.c index d84819ca5..14380bc6e 100644 --- a/spine-c/src/spine/Skeleton.c +++ b/spine-c/src/spine/Skeleton.c @@ -31,16 +31,10 @@ namespace spine { #endif -typedef struct _SkeletonVtable { - void (*dispose) (Skeleton* skeleton); -} _SkeletonVtable; - -void _Skeleton_init (Skeleton* self, SkeletonData* data, void (*dispose) (Skeleton* skeleton)) { +Skeleton* Skeleton_create (SkeletonData* data) { + Skeleton* self = NEW(Skeleton); CONST_CAST(SkeletonData*, self->data) = data; - CONST_CAST(_SkeletonVtable*, self->vtable) = NEW(_SkeletonVtable); - VTABLE(Skeleton, self) ->dispose = dispose; - self->boneCount = self->data->boneCount; self->bones = MALLOC(Bone*, self->boneCount); int i, ii; @@ -84,11 +78,11 @@ void _Skeleton_init (Skeleton* self, SkeletonData* data, void (*dispose) (Skelet self->g = 1; self->b = 1; self->a = 1; + + return self; } -void _Skeleton_deinit (Skeleton* self) { - FREE(self->vtable); - +void Skeleton_dispose (Skeleton* self) { int i; for (i = 0; i < self->boneCount; ++i) Bone_dispose(self->bones[i]); @@ -101,10 +95,6 @@ void _Skeleton_deinit (Skeleton* self) { FREE(self->drawOrder); } -void Skeleton_dispose (Skeleton* self) { - VTABLE(Skeleton, self) ->dispose(self); -} - void Skeleton_updateWorldTransform (const Skeleton* self) { int i; for (i = 0; i < self->boneCount; ++i) diff --git a/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.h b/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.h index 08242a050..557f9aec0 100644 --- a/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.h +++ b/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.h @@ -29,22 +29,6 @@ #include #include "cocos2d.h" -#ifdef __cplusplus -namespace spine { -extern "C" { -#endif - -ccV3F_C4B_T2F_Quad* RegionAttachment_updateQuad (Attachment* self, Slot* slot); -ccV3F_C4B_T2F_Quad* RegionAttachment_getQuad (RegionAttachment* self); - -#ifdef __cplusplus -} -} -using namespace spine; -#endif - -/**/ - @interface CCSkeleton : CCNodeRGBA { @private bool ownsSkeleton; @@ -58,9 +42,6 @@ using namespace spine; bool debugSlots; bool debugBones; - CCTextureAtlas* textureAtlas; // All region attachments for a skeleton must use the same texture. - unsigned int quadCount; - ccBlendFunc blendFunc; } @@ -109,4 +90,19 @@ using namespace spine; @end +/**/ + +#ifdef __cplusplus +namespace spine { +extern "C" { +#endif + +void RegionAttachment_updateQuad (RegionAttachment* self, Slot* slot, ccV3F_C4B_T2F_Quad* quad); + +#ifdef __cplusplus +} +} +using namespace spine; +#endif + #endif /* SPINE_COCOS2D_H_ */ diff --git a/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m b/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m index b0e04ec78..3be613468 100644 --- a/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m +++ b/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m @@ -30,77 +30,33 @@ namespace spine { #endif -typedef struct { - AtlasPage super; - CCTexture2D* texture; - CCTextureAtlas* textureAtlas; -} Cocos2dAtlasPage; - -void _Cocos2dAtlasPage_dispose (AtlasPage* page) { - Cocos2dAtlasPage* self = SUB_CAST(Cocos2dAtlasPage, page); - _AtlasPage_deinit(SUPER(self)); - - [self->texture release]; - [self->textureAtlas release]; - - FREE(page); +void _AtlasPage_createTexture (AtlasPage* self, const char* path) { + CCTexture2D* texture = [[CCTextureCache sharedTextureCache] addImage:@(path)]; + CCTextureAtlas* textureAtlas = [[CCTextureAtlas alloc] initWithTexture:texture capacity:4]; + [textureAtlas retain]; + self->texture = textureAtlas; + CGSize size = texture.contentSizeInPixels; + self->width = size.width; + self->height = size.height; } -AtlasPage* AtlasPage_create (const char* name, const char* path) { - Cocos2dAtlasPage* self = NEW(Cocos2dAtlasPage); - _AtlasPage_init(SUPER(self), name, _Cocos2dAtlasPage_dispose); +void _AtlasPage_disposeTexture (AtlasPage* self) { + [(CCTextureAtlas*)self->texture release]; +} - self->texture = [[CCTextureCache sharedTextureCache] addImage:@(path)]; - [self->texture retain]; - self->textureAtlas = [[CCTextureAtlas alloc] initWithTexture:self->texture capacity:4]; - [self->textureAtlas retain]; - - return SUPER(self); +char* _Util_readFile (const char* path, int* length) { + return _readFile([[[CCFileUtils sharedFileUtils] fullPathForFilename:@(path)] UTF8String], length); } /**/ -typedef struct { - Skeleton super; - CCSkeleton* node; -} Cocos2dSkeleton; +void RegionAttachment_updateQuad (RegionAttachment* self, Slot* slot, ccV3F_C4B_T2F_Quad* quad) { + RegionAttachment_updateVertices(self, slot); -void _Cocos2dSkeleton_dispose (Skeleton* self) { - _Skeleton_deinit(self); - FREE(self); -} - -Skeleton* _Cocos2dSkeleton_create (SkeletonData* data, CCSkeleton* node) { - Cocos2dSkeleton* self = NEW(Cocos2dSkeleton); - _Skeleton_init(SUPER(self), data, _Cocos2dSkeleton_dispose); - - self->node = node; - - return SUPER(self); -} - -/**/ - -typedef struct { - RegionAttachment super; - ccV3F_C4B_T2F_Quad quad; - CCTextureAtlas* textureAtlas; -} Cocos2dRegionAttachment; - -void _Cocos2dRegionAttachment_dispose (Attachment* self) { - _RegionAttachment_deinit(SUB_CAST(RegionAttachment, self) ); - FREE(self); -} - -ccV3F_C4B_T2F_Quad* RegionAttachment_updateQuad (Attachment* attachment, Slot* slot) { - Cocos2dRegionAttachment* self = SUB_CAST(Cocos2dRegionAttachment, attachment); - Cocos2dSkeleton* skeleton = SUB_CAST(Cocos2dSkeleton, slot->skeleton); - - GLubyte r = SUPER(skeleton)->r * slot->r * 255; - GLubyte g = SUPER(skeleton)->g * slot->g * 255; - GLubyte b = SUPER(skeleton)->b * slot->b * 255; - GLubyte a = SUPER(skeleton)->a * slot->a * 255; - ccV3F_C4B_T2F_Quad* quad = &self->quad; + GLubyte r = slot->skeleton->r * slot->r * 255; + GLubyte g = slot->skeleton->g * slot->g * 255; + GLubyte b = slot->skeleton->b * slot->b * 255; + GLubyte a = slot->skeleton->a * slot->a * 255; quad->bl.colors.r = r; quad->bl.colors.g = g; quad->bl.colors.b = b; @@ -118,82 +74,35 @@ ccV3F_C4B_T2F_Quad* RegionAttachment_updateQuad (Attachment* attachment, Slot* s quad->br.colors.b = b; quad->br.colors.a = a; - float* offset = SUPER(self)->offset; - quad->bl.vertices.x = offset[0] * slot->bone->m00 + offset[1] * slot->bone->m01 + slot->bone->worldX; - quad->bl.vertices.y = offset[0] * slot->bone->m10 + offset[1] * slot->bone->m11 + slot->bone->worldY; - quad->tl.vertices.x = offset[2] * slot->bone->m00 + offset[3] * slot->bone->m01 + slot->bone->worldX; - quad->tl.vertices.y = offset[2] * slot->bone->m10 + offset[3] * slot->bone->m11 + slot->bone->worldY; - quad->tr.vertices.x = offset[4] * slot->bone->m00 + offset[5] * slot->bone->m01 + slot->bone->worldX; - quad->tr.vertices.y = offset[4] * slot->bone->m10 + offset[5] * slot->bone->m11 + slot->bone->worldY; - quad->br.vertices.x = offset[6] * slot->bone->m00 + offset[7] * slot->bone->m01 + slot->bone->worldX; - quad->br.vertices.y = offset[6] * slot->bone->m10 + offset[7] * slot->bone->m11 + slot->bone->worldY; + float* offset = self->offset; + quad->bl.vertices.x = offset[VERTEX_X1] * slot->bone->m00 + offset[VERTEX_Y1] * slot->bone->m01 + slot->bone->worldX; + quad->bl.vertices.y = offset[VERTEX_X1] * slot->bone->m10 + offset[VERTEX_Y1] * slot->bone->m11 + slot->bone->worldY; + quad->tl.vertices.x = offset[VERTEX_X2] * slot->bone->m00 + offset[VERTEX_Y2] * slot->bone->m01 + slot->bone->worldX; + quad->tl.vertices.y = offset[VERTEX_X2] * slot->bone->m10 + offset[VERTEX_Y2] * slot->bone->m11 + slot->bone->worldY; + quad->tr.vertices.x = offset[VERTEX_X3] * slot->bone->m00 + offset[VERTEX_Y3] * slot->bone->m01 + slot->bone->worldX; + quad->tr.vertices.y = offset[VERTEX_X3] * slot->bone->m10 + offset[VERTEX_Y3] * slot->bone->m11 + slot->bone->worldY; + quad->br.vertices.x = offset[VERTEX_X4] * slot->bone->m00 + offset[VERTEX_Y4] * slot->bone->m01 + slot->bone->worldX; + quad->br.vertices.y = offset[VERTEX_X4] * slot->bone->m10 + offset[VERTEX_Y4] * slot->bone->m11 + slot->bone->worldY; - return quad; -} - -void _Cocos2dRegionAttachment_draw (Attachment* attachment, Slot* slot) { - RegionAttachment_updateQuad(attachment, slot); - - Cocos2dRegionAttachment* self = SUB_CAST(Cocos2dRegionAttachment, attachment); - Cocos2dSkeleton* skeleton = SUB_CAST(Cocos2dSkeleton, slot->skeleton); - - // Cocos2d doesn't handle batching for us, so we'll just force a single texture per skeleton. - skeleton->node->textureAtlas = self->textureAtlas; - while (self->textureAtlas.capacity <= skeleton->node->quadCount) { - if (![self->textureAtlas resizeCapacity:self->textureAtlas.capacity * 2]) return; - } - [self->textureAtlas updateQuad:&self->quad atIndex:skeleton->node->quadCount++]; -} - -RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) { - Cocos2dRegionAttachment* self = NEW(Cocos2dRegionAttachment); - _RegionAttachment_init(SUPER(self), name, _Cocos2dRegionAttachment_dispose, _Cocos2dRegionAttachment_draw); - - Cocos2dAtlasPage* page = SUB_CAST(Cocos2dAtlasPage, region->page); - self->textureAtlas = page->textureAtlas; - CGSize size = page->texture.contentSizeInPixels; - float u = region->x / size.width; - float u2 = (region->x + region->width) / size.width; - float v = region->y / size.height; - float v2 = (region->y + region->height) / size.height; - ccV3F_C4B_T2F_Quad* quad = &self->quad; - if (region->rotate) { - quad->tl.texCoords.u = u; - quad->tl.texCoords.v = v2; - quad->tr.texCoords.u = u; - quad->tr.texCoords.v = v; - quad->br.texCoords.u = u2; - quad->br.texCoords.v = v; - quad->bl.texCoords.u = u2; - quad->bl.texCoords.v = v2; + if (self->region->rotate) { + quad->tl.texCoords.u = self->region->u; + quad->tl.texCoords.v = self->region->v2; + quad->tr.texCoords.u = self->region->u; + quad->tr.texCoords.v = self->region->v; + quad->br.texCoords.u = self->region->u2; + quad->br.texCoords.v = self->region->v; + quad->bl.texCoords.u = self->region->u2; + quad->bl.texCoords.v = self->region->v2; } else { - quad->bl.texCoords.u = u; - quad->bl.texCoords.v = v2; - quad->tl.texCoords.u = u; - quad->tl.texCoords.v = v; - quad->tr.texCoords.u = u2; - quad->tr.texCoords.v = v; - quad->br.texCoords.u = u2; - quad->br.texCoords.v = v2; + quad->bl.texCoords.u = self->region->u; + quad->bl.texCoords.v = self->region->v2; + quad->tl.texCoords.u = self->region->u; + quad->tl.texCoords.v = self->region->v; + quad->tr.texCoords.u = self->region->u2; + quad->tr.texCoords.v = self->region->v; + quad->br.texCoords.u = self->region->u2; + quad->br.texCoords.v = self->region->v2; } - - quad->bl.vertices.z = 0; - quad->tl.vertices.z = 0; - quad->tr.vertices.z = 0; - quad->br.vertices.z = 0; - - return SUPER(self); -} - -ccV3F_C4B_T2F_Quad* RegionAttachment_getQuad (RegionAttachment* attachment) { - Cocos2dRegionAttachment* self = SUB_CAST(Cocos2dRegionAttachment, attachment); - return &self->quad; -} - -/**/ - -char* _Util_readFile (const char* path, int* length) { - return _readFile([[[CCFileUtils sharedFileUtils] fullPathForFilename:@(path)] UTF8String], length); } #ifdef __cplusplus @@ -211,11 +120,13 @@ char* _Util_readFile (const char* path, int* length) { + (CCSkeleton*) create:(NSString*)skeletonDataFile atlas:(Atlas*)atlas scale:(float)scale { NSAssert(skeletonDataFile, @"skeletonDataFile cannot be nil."); NSAssert(atlas, @"atlas cannot be nil."); + SkeletonJson* json = SkeletonJson_create(atlas); json->scale = scale; SkeletonData* skeletonData = SkeletonJson_readSkeletonDataFile(json, [skeletonDataFile UTF8String]); NSAssert(skeletonData, ([NSString stringWithFormat:@"Error reading skeleton data file: %@\nError: %s", skeletonDataFile, json->error])); SkeletonJson_dispose(json); + CCSkeleton* node = skeletonData ? [CCSkeleton create:skeletonData] : 0; node->ownsSkeleton = true; return node; @@ -228,9 +139,11 @@ char* _Util_readFile (const char* path, int* length) { + (CCSkeleton*) create:(NSString*)skeletonDataFile atlasFile:(NSString*)atlasFile scale:(float)scale { NSAssert(skeletonDataFile, @"skeletonDataFile cannot be nil."); NSAssert(atlasFile, @"atlasFile cannot be nil."); + Atlas* atlas = Atlas_readAtlasFile([atlasFile UTF8String]); NSAssert(atlas, ([NSString stringWithFormat:@"Error reading atlas file: %@", atlasFile])); if (!atlas) return 0; + SkeletonJson* json = SkeletonJson_create(atlas); json->scale = scale; SkeletonData* skeletonData = SkeletonJson_readSkeletonDataFile(json, [skeletonDataFile UTF8String]); @@ -240,6 +153,7 @@ char* _Util_readFile (const char* path, int* length) { Atlas_dispose(atlas); return 0; } + CCSkeleton* node = [CCSkeleton create:skeletonData]; node->ownsSkeleton = true; node->atlas = atlas; @@ -264,7 +178,7 @@ char* _Util_readFile (const char* path, int* length) { self = [super init]; if (!self) return nil; - CONST_CAST(Skeleton*, skeleton) = _Cocos2dSkeleton_create(skeletonData, self); + CONST_CAST(Skeleton*, skeleton) = Skeleton_create(skeletonData); if (!stateData) { stateData = AnimationStateData_create(skeletonData); @@ -308,23 +222,43 @@ char* _Util_readFile (const char* path, int* length) { skeleton->b = color.b / (float)255; skeleton->a = self.opacity / (float)255; - quadCount = 0; - for (int i = 0, n = skeleton->slotCount; i < n; ++i) - if (skeleton->slots[i]->attachment) Attachment_draw(skeleton->slots[i]->attachment, skeleton->slots[i]); - if (textureAtlas) [textureAtlas drawNumberOfQuads:quadCount]; + CCTextureAtlas* textureAtlas = 0; + int quadCount = 0; + for (int i = 0, n = skeleton->slotCount; i < n; i++) { + Slot* slot = skeleton->slots[i]; + if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue; + RegionAttachment* attachment = (RegionAttachment*)slot->attachment; + CCTextureAtlas* regionTextureAtlas = (CCTextureAtlas*)attachment->region->page->texture; + if (regionTextureAtlas != textureAtlas) { + if (textureAtlas) { + [textureAtlas drawNumberOfQuads:quadCount]; + quadCount = 0; + } + } + textureAtlas = regionTextureAtlas; + if (textureAtlas.capacity == quadCount && ![textureAtlas resizeCapacity:quadCount * 2]) return; + RegionAttachment_updateQuad(attachment, slot, &textureAtlas.quads[quadCount++]); + } + if (textureAtlas) { + [textureAtlas drawNumberOfQuads:quadCount]; + quadCount = 0; + } if (debugSlots) { // Slots. ccDrawColor4B(0, 0, 255, 255); glLineWidth(1); CGPoint points[4]; - for (int i = 0, n = skeleton->slotCount; i < n; ++i) { - if (!skeleton->slots[i]->attachment) continue; - ccV3F_C4B_T2F_Quad* quad = &((Cocos2dRegionAttachment*)skeleton->slots[i]->attachment)->quad; - points[0] = ccp(quad->bl.vertices.x, quad->bl.vertices.y); - points[1] = ccp(quad->br.vertices.x, quad->br.vertices.y); - points[2] = ccp(quad->tr.vertices.x, quad->tr.vertices.y); - points[3] = ccp(quad->tl.vertices.x, quad->tl.vertices.y); + ccV3F_C4B_T2F_Quad quad; + for (int i = 0, n = skeleton->slotCount; i < n; i++) { + Slot* slot = skeleton->slots[i]; + if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue; + RegionAttachment* attachment = (RegionAttachment*)slot->attachment; + RegionAttachment_updateQuad(attachment, slot, &quad); + points[0] = ccp(quad.bl.vertices.x, quad.bl.vertices.y); + points[1] = ccp(quad.br.vertices.x, quad.br.vertices.y); + points[2] = ccp(quad.tr.vertices.x, quad.tr.vertices.y); + points[3] = ccp(quad.tl.vertices.x, quad.tl.vertices.y); ccDrawPoly(points, 4, true); } } @@ -332,7 +266,7 @@ char* _Util_readFile (const char* path, int* length) { // Bone lengths. glLineWidth(2); ccDrawColor4B(255, 0, 0, 255); - for (int i = 0, n = skeleton->boneCount; i < n; ++i) { + for (int i = 0, n = skeleton->boneCount; i < n; i++) { Bone *bone = skeleton->bones[i]; float x = bone->data->length * bone->m00 + bone->worldX; float y = bone->data->length * bone->m10 + bone->worldY; @@ -341,7 +275,7 @@ char* _Util_readFile (const char* path, int* length) { // Bone origins. ccPointSize(4); ccDrawColor4B(0, 0, 255, 255); // Root bone is blue. - for (int i = 0, n = skeleton->boneCount; i < n; ++i) { + for (int i = 0, n = skeleton->boneCount; i < n; i++) { Bone *bone = skeleton->bones[i]; ccDrawPoint(ccp(bone->worldX, bone->worldY)); if (i == 0) ccDrawColor4B(0, 255, 0, 255); @@ -353,27 +287,28 @@ char* _Util_readFile (const char* path, int* length) { float minX = FLT_MAX, minY = FLT_MAX, maxX = FLT_MIN, maxY = FLT_MIN; float scaleX = self.scaleX; float scaleY = self.scaleY; + ccV3F_C4B_T2F_Quad quad; for (int i = 0; i < skeleton->slotCount; ++i) { Slot* slot = skeleton->slots[i]; - Attachment* attachment = slot->attachment; - if (!attachment || attachment->type != ATTACHMENT_REGION) continue; - Cocos2dRegionAttachment* regionAttachment = SUB_CAST(Cocos2dRegionAttachment, attachment); - minX = fmin(minX, regionAttachment->quad.bl.vertices.x * scaleX); - minY = fmin(minY, regionAttachment->quad.bl.vertices.y * scaleY); - maxX = fmax(maxX, regionAttachment->quad.bl.vertices.x * scaleX); - maxY = fmax(maxY, regionAttachment->quad.bl.vertices.y * scaleY); - minX = fmin(minX, regionAttachment->quad.br.vertices.x * scaleX); - minY = fmin(minY, regionAttachment->quad.br.vertices.y * scaleY); - maxX = fmax(maxX, regionAttachment->quad.br.vertices.x * scaleX); - maxY = fmax(maxY, regionAttachment->quad.br.vertices.y * scaleY); - minX = fmin(minX, regionAttachment->quad.tl.vertices.x * scaleX); - minY = fmin(minY, regionAttachment->quad.tl.vertices.y * scaleY); - maxX = fmax(maxX, regionAttachment->quad.tl.vertices.x * scaleX); - maxY = fmax(maxY, regionAttachment->quad.tl.vertices.y * scaleY); - minX = fmin(minX, regionAttachment->quad.tr.vertices.x * scaleX); - minY = fmin(minY, regionAttachment->quad.tr.vertices.y * scaleY); - maxX = fmax(maxX, regionAttachment->quad.tr.vertices.x * scaleX); - maxY = fmax(maxY, regionAttachment->quad.tr.vertices.y * scaleY); + if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue; + RegionAttachment* attachment = (RegionAttachment*)slot->attachment; + RegionAttachment_updateQuad(attachment, slot, &quad); + minX = fmin(minX, quad.bl.vertices.x * scaleX); + minY = fmin(minY, quad.bl.vertices.y * scaleY); + maxX = fmax(maxX, quad.bl.vertices.x * scaleX); + maxY = fmax(maxY, quad.bl.vertices.y * scaleY); + minX = fmin(minX, quad.br.vertices.x * scaleX); + minY = fmin(minY, quad.br.vertices.y * scaleY); + maxX = fmax(maxX, quad.br.vertices.x * scaleX); + maxY = fmax(maxY, quad.br.vertices.y * scaleY); + minX = fmin(minX, quad.tl.vertices.x * scaleX); + minY = fmin(minY, quad.tl.vertices.y * scaleY); + maxX = fmax(maxX, quad.tl.vertices.x * scaleX); + maxY = fmax(maxY, quad.tl.vertices.y * scaleY); + minX = fmin(minX, quad.tr.vertices.x * scaleX); + minY = fmin(minY, quad.tr.vertices.y * scaleY); + maxX = fmax(maxX, quad.tr.vertices.x * scaleX); + maxY = fmax(maxY, quad.tr.vertices.y * scaleY); } minX = self.position.x + minX; minY = self.position.y + minY; diff --git a/spine-cocos2dx/src/spine/spine-cocos2dx.cpp b/spine-cocos2dx/src/spine/spine-cocos2dx.cpp index 7af5fcdfd..2b5c89690 100644 --- a/spine-cocos2dx/src/spine/spine-cocos2dx.cpp +++ b/spine-cocos2dx/src/spine/spine-cocos2dx.cpp @@ -31,43 +31,85 @@ using std::min; using std::max; namespace spine { -void _Cocos2dxAtlasPage_dispose (AtlasPage* page) { - Cocos2dxAtlasPage* self = SUB_CAST(Cocos2dxAtlasPage, page); - _AtlasPage_deinit(SUPER(self)); - - CC_SAFE_RELEASE_NULL(self->texture); - CC_SAFE_RELEASE_NULL(self->textureAtlas); - - FREE(page); +void _AtlasPage_createTexture (AtlasPage* self, const char* path) { + CCTexture2D* texture = CCTextureCache::sharedTextureCache()->addImage(path); + CCTextureAtlas* textureAtlas = CCTextureAtlas::createWithTexture(texture, 4); + textureAtlas->retain(); + self->texture = textureAtlas; + self->width = texture->getPixelsWide(); + self->height = texture->getPixelsHigh(); } -AtlasPage* AtlasPage_create (const char* name, const char* path) { - Cocos2dxAtlasPage* self = NEW(Cocos2dxAtlasPage); - _AtlasPage_init(SUPER(self), name, _Cocos2dxAtlasPage_dispose); +void _AtlasPage_disposeTexture (AtlasPage* self) { + ((CCTextureAtlas*)self->texture)->release(); +} - self->texture = CCTextureCache::sharedTextureCache()->addImage(path); - self->texture->retain(); - self->textureAtlas = CCTextureAtlas::createWithTexture(self->texture, 4); - self->textureAtlas->retain(); - - return SUPER(self); +char* _Util_readFile (const char* path, int* length) { + unsigned long size; + char* data = reinterpret_cast(CCFileUtils::sharedFileUtils()->getFileData( + CCFileUtils::sharedFileUtils()->fullPathForFilename(path).c_str(), "r", &size)); + *length = size; + return data; } /**/ -void _Cocos2dxSkeleton_dispose (Skeleton* self) { - _Skeleton_deinit(self); - FREE(self); +void RegionAttachment_updateQuad (RegionAttachment* self, Slot* slot, ccV3F_C4B_T2F_Quad* quad) { + RegionAttachment_updateVertices(self, slot); + + GLubyte r = slot->skeleton->r * slot->r * 255; + GLubyte g = slot->skeleton->g * slot->g * 255; + GLubyte b = slot->skeleton->b * slot->b * 255; + GLubyte a = slot->skeleton->a * slot->a * 255; + quad->bl.colors.r = r; + quad->bl.colors.g = g; + quad->bl.colors.b = b; + quad->bl.colors.a = a; + quad->tl.colors.r = r; + quad->tl.colors.g = g; + quad->tl.colors.b = b; + quad->tl.colors.a = a; + quad->tr.colors.r = r; + quad->tr.colors.g = g; + quad->tr.colors.b = b; + quad->tr.colors.a = a; + quad->br.colors.r = r; + quad->br.colors.g = g; + quad->br.colors.b = b; + quad->br.colors.a = a; + + float* offset = self->offset; + quad->bl.vertices.x = offset[VERTEX_X1] * slot->bone->m00 + offset[VERTEX_Y1] * slot->bone->m01 + slot->bone->worldX; + quad->bl.vertices.y = offset[VERTEX_X1] * slot->bone->m10 + offset[VERTEX_Y1] * slot->bone->m11 + slot->bone->worldY; + quad->tl.vertices.x = offset[VERTEX_X2] * slot->bone->m00 + offset[VERTEX_Y2] * slot->bone->m01 + slot->bone->worldX; + quad->tl.vertices.y = offset[VERTEX_X2] * slot->bone->m10 + offset[VERTEX_Y2] * slot->bone->m11 + slot->bone->worldY; + quad->tr.vertices.x = offset[VERTEX_X3] * slot->bone->m00 + offset[VERTEX_Y3] * slot->bone->m01 + slot->bone->worldX; + quad->tr.vertices.y = offset[VERTEX_X3] * slot->bone->m10 + offset[VERTEX_Y3] * slot->bone->m11 + slot->bone->worldY; + quad->br.vertices.x = offset[VERTEX_X4] * slot->bone->m00 + offset[VERTEX_Y4] * slot->bone->m01 + slot->bone->worldX; + quad->br.vertices.y = offset[VERTEX_X4] * slot->bone->m10 + offset[VERTEX_Y4] * slot->bone->m11 + slot->bone->worldY; + + if (self->region->rotate) { + quad->tl.texCoords.u = self->region->u; + quad->tl.texCoords.v = self->region->v2; + quad->tr.texCoords.u = self->region->u; + quad->tr.texCoords.v = self->region->v; + quad->br.texCoords.u = self->region->u2; + quad->br.texCoords.v = self->region->v; + quad->bl.texCoords.u = self->region->u2; + quad->bl.texCoords.v = self->region->v2; + } else { + quad->bl.texCoords.u = self->region->u; + quad->bl.texCoords.v = self->region->v2; + quad->tl.texCoords.u = self->region->u; + quad->tl.texCoords.v = self->region->v; + quad->tr.texCoords.u = self->region->u2; + quad->tr.texCoords.v = self->region->v; + quad->br.texCoords.u = self->region->u2; + quad->br.texCoords.v = self->region->v2; + } } -Skeleton* _Cocos2dxSkeleton_create (SkeletonData* data, CCSkeleton* node) { - Cocos2dxSkeleton* self = NEW(Cocos2dxSkeleton); - _Skeleton_init(SUPER(self), data, _Cocos2dxSkeleton_dispose); - - self->node = node; - - return SUPER(self); -} +/**/ CCSkeleton* CCSkeleton::create (const char* skeletonDataFile, Atlas* atlas, float scale) { SkeletonJson* json = SkeletonJson_create(atlas); @@ -105,7 +147,7 @@ CCSkeleton* CCSkeleton::create (SkeletonData* skeletonData, AnimationStateData* CCSkeleton::CCSkeleton (SkeletonData *skeletonData, AnimationStateData *stateData) : ownsSkeleton(false), ownsStateData(false), atlas(0), skeleton(0), state(0), debugSlots(false), debugBones(false) { - CONST_CAST(Skeleton*, skeleton) = _Cocos2dxSkeleton_create(skeletonData, this); + CONST_CAST(Skeleton*, skeleton) = Skeleton_create(skeletonData); if (!stateData) { stateData = AnimationStateData_create(skeletonData); @@ -146,23 +188,43 @@ void CCSkeleton::draw () { skeleton->b = color.b / (float)255; skeleton->a = getOpacity() / (float)255; - quadCount = 0; - for (int i = 0, n = skeleton->slotCount; i < n; i++) - if (skeleton->slots[i]->attachment) Attachment_draw(skeleton->slots[i]->attachment, skeleton->slots[i]); - if (textureAtlas) textureAtlas->drawNumberOfQuads(quadCount); + CCTextureAtlas* textureAtlas = 0; + int quadCount = 0; + for (int i = 0, n = skeleton->slotCount; i < n; i++) { + Slot* slot = skeleton->slots[i]; + if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue; + RegionAttachment* attachment = (RegionAttachment*)slot->attachment; + CCTextureAtlas* regionTextureAtlas = (CCTextureAtlas*)attachment->region->page->texture; + if (regionTextureAtlas != textureAtlas) { + if (textureAtlas) { + textureAtlas->drawNumberOfQuads(quadCount); + quadCount = 0; + } + } + textureAtlas = regionTextureAtlas; + if (textureAtlas->getCapacity() == quadCount && !textureAtlas->resizeCapacity(quadCount * 2)) return; + RegionAttachment_updateQuad(attachment, slot, &textureAtlas->getQuads()[quadCount++]); + } + if (textureAtlas) { + textureAtlas->drawNumberOfQuads(quadCount); + quadCount = 0; + } if (debugSlots) { // Slots. ccDrawColor4B(0, 0, 255, 255); glLineWidth(1); CCPoint points[4]; + ccV3F_C4B_T2F_Quad quad; for (int i = 0, n = skeleton->slotCount; i < n; i++) { - if (!skeleton->slots[i]->attachment) continue; - ccV3F_C4B_T2F_Quad* quad = &((Cocos2dxRegionAttachment*)skeleton->slots[i]->attachment)->quad; - points[0] = ccp(quad->bl.vertices.x, quad->bl.vertices.y); - points[1] = ccp(quad->br.vertices.x, quad->br.vertices.y); - points[2] = ccp(quad->tr.vertices.x, quad->tr.vertices.y); - points[3] = ccp(quad->tl.vertices.x, quad->tl.vertices.y); + Slot* slot = skeleton->slots[i]; + if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue; + RegionAttachment* attachment = (RegionAttachment*)slot->attachment; + RegionAttachment_updateQuad(attachment, slot, &quad); + points[0] = ccp(quad.bl.vertices.x, quad.bl.vertices.y); + points[1] = ccp(quad.br.vertices.x, quad.br.vertices.y); + points[2] = ccp(quad.tr.vertices.x, quad.tr.vertices.y); + points[3] = ccp(quad.tl.vertices.x, quad.tl.vertices.y); ccDrawPoly(points, 4, true); } } @@ -191,27 +253,28 @@ CCRect CCSkeleton::boundingBox () { float minX = FLT_MAX, minY = FLT_MAX, maxX = FLT_MIN, maxY = FLT_MIN; float scaleX = getScaleX(); float scaleY = getScaleY(); + ccV3F_C4B_T2F_Quad quad; for (int i = 0; i < skeleton->slotCount; ++i) { Slot* slot = skeleton->slots[i]; - Attachment* attachment = slot->attachment; - if (!attachment || attachment->type != ATTACHMENT_REGION) continue; - Cocos2dxRegionAttachment* regionAttachment = SUB_CAST(Cocos2dxRegionAttachment, attachment); - minX = min(minX, regionAttachment->quad.bl.vertices.x * scaleX); - minY = min(minY, regionAttachment->quad.bl.vertices.y * scaleY); - maxX = max(maxX, regionAttachment->quad.bl.vertices.x * scaleX); - maxY = max(maxY, regionAttachment->quad.bl.vertices.y * scaleY); - minX = min(minX, regionAttachment->quad.br.vertices.x * scaleX); - minY = min(minY, regionAttachment->quad.br.vertices.y * scaleY); - maxX = max(maxX, regionAttachment->quad.br.vertices.x * scaleX); - maxY = max(maxY, regionAttachment->quad.br.vertices.y * scaleY); - minX = min(minX, regionAttachment->quad.tl.vertices.x * scaleX); - minY = min(minY, regionAttachment->quad.tl.vertices.y * scaleY); - maxX = max(maxX, regionAttachment->quad.tl.vertices.x * scaleX); - maxY = max(maxY, regionAttachment->quad.tl.vertices.y * scaleY); - minX = min(minX, regionAttachment->quad.tr.vertices.x * scaleX); - minY = min(minY, regionAttachment->quad.tr.vertices.y * scaleY); - maxX = max(maxX, regionAttachment->quad.tr.vertices.x * scaleX); - maxY = max(maxY, regionAttachment->quad.tr.vertices.y * scaleY); + if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue; + RegionAttachment* attachment = (RegionAttachment*)slot->attachment; + RegionAttachment_updateQuad(attachment, slot, &quad); + minX = min(minX, quad.bl.vertices.x * scaleX); + minY = min(minY, quad.bl.vertices.y * scaleY); + maxX = max(maxX, quad.bl.vertices.x * scaleX); + maxY = max(maxY, quad.bl.vertices.y * scaleY); + minX = min(minX, quad.br.vertices.x * scaleX); + minY = min(minY, quad.br.vertices.y * scaleY); + maxX = max(maxX, quad.br.vertices.x * scaleX); + maxY = max(maxY, quad.br.vertices.y * scaleY); + minX = min(minX, quad.tl.vertices.x * scaleX); + minY = min(minY, quad.tl.vertices.y * scaleY); + maxX = max(maxX, quad.tl.vertices.x * scaleX); + maxY = max(maxY, quad.tl.vertices.y * scaleY); + minX = min(minX, quad.tr.vertices.x * scaleX); + minY = min(minY, quad.tr.vertices.y * scaleY); + maxX = max(maxX, quad.tr.vertices.x * scaleX); + maxY = max(maxY, quad.tr.vertices.y * scaleY); } CCPoint position = getPosition(); minX = position.x + minX; @@ -283,114 +346,4 @@ void CCSkeleton::setBlendFunc (ccBlendFunc blendFunc) { this->blendFunc = blendFunc; } -/**/ - -void _Cocos2dxRegionAttachment_dispose (Attachment* self) { - _RegionAttachment_deinit(SUB_CAST(RegionAttachment, self) ); - FREE(self); -} - -ccV3F_C4B_T2F_Quad* RegionAttachment_updateQuad (Attachment* attachment, Slot* slot) { - Cocos2dxRegionAttachment* self = SUB_CAST(Cocos2dxRegionAttachment, attachment); - Cocos2dxSkeleton* skeleton = SUB_CAST(Cocos2dxSkeleton, slot->skeleton); - - GLubyte r = SUPER(skeleton)->r * slot->r * 255; - GLubyte g = SUPER(skeleton)->g * slot->g * 255; - GLubyte b = SUPER(skeleton)->b * slot->b * 255; - GLubyte a = SUPER(skeleton)->a * slot->a * 255; - ccV3F_C4B_T2F_Quad* quad = &self->quad; - quad->bl.colors.r = r; - quad->bl.colors.g = g; - quad->bl.colors.b = b; - quad->bl.colors.a = a; - quad->tl.colors.r = r; - quad->tl.colors.g = g; - quad->tl.colors.b = b; - quad->tl.colors.a = a; - quad->tr.colors.r = r; - quad->tr.colors.g = g; - quad->tr.colors.b = b; - quad->tr.colors.a = a; - quad->br.colors.r = r; - quad->br.colors.g = g; - quad->br.colors.b = b; - quad->br.colors.a = a; - - float* offset = SUPER(self)->offset; - quad->bl.vertices.x = offset[0] * slot->bone->m00 + offset[1] * slot->bone->m01 + slot->bone->worldX; - quad->bl.vertices.y = offset[0] * slot->bone->m10 + offset[1] * slot->bone->m11 + slot->bone->worldY; - quad->tl.vertices.x = offset[2] * slot->bone->m00 + offset[3] * slot->bone->m01 + slot->bone->worldX; - quad->tl.vertices.y = offset[2] * slot->bone->m10 + offset[3] * slot->bone->m11 + slot->bone->worldY; - quad->tr.vertices.x = offset[4] * slot->bone->m00 + offset[5] * slot->bone->m01 + slot->bone->worldX; - quad->tr.vertices.y = offset[4] * slot->bone->m10 + offset[5] * slot->bone->m11 + slot->bone->worldY; - quad->br.vertices.x = offset[6] * slot->bone->m00 + offset[7] * slot->bone->m01 + slot->bone->worldX; - quad->br.vertices.y = offset[6] * slot->bone->m10 + offset[7] * slot->bone->m11 + slot->bone->worldY; - - return quad; -} - -void _Cocos2dxRegionAttachment_draw (Attachment* attachment, Slot* slot) { - RegionAttachment_updateQuad(attachment, slot); - - Cocos2dxRegionAttachment* self = SUB_CAST(Cocos2dxRegionAttachment, attachment); - Cocos2dxSkeleton* skeleton = SUB_CAST(Cocos2dxSkeleton, slot->skeleton); - - // cocos2dx doesn't handle batching for us, so we force a single texture per skeleton. - skeleton->node->textureAtlas = self->textureAtlas; - while (self->textureAtlas->getCapacity() <= skeleton->node->quadCount) { - if (!self->textureAtlas->resizeCapacity(self->textureAtlas->getCapacity() * 2)) return; - } - self->textureAtlas->updateQuad(&self->quad, skeleton->node->quadCount++); -} - -RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) { - Cocos2dxRegionAttachment* self = NEW(Cocos2dxRegionAttachment); - _RegionAttachment_init(SUPER(self), name, _Cocos2dxRegionAttachment_dispose, _Cocos2dxRegionAttachment_draw); - - Cocos2dxAtlasPage* page = SUB_CAST(Cocos2dxAtlasPage, region->page); - self->textureAtlas = page->textureAtlas; - const CCSize& size = page->texture->getContentSizeInPixels(); - float u = region->x / size.width; - float u2 = (region->x + region->width) / size.width; - float v = region->y / size.height; - float v2 = (region->y + region->height) / size.height; - ccV3F_C4B_T2F_Quad* quad = &self->quad; - if (region->rotate) { - quad->tl.texCoords.u = u; - quad->tl.texCoords.v = v2; - quad->tr.texCoords.u = u; - quad->tr.texCoords.v = v; - quad->br.texCoords.u = u2; - quad->br.texCoords.v = v; - quad->bl.texCoords.u = u2; - quad->bl.texCoords.v = v2; - } else { - quad->bl.texCoords.u = u; - quad->bl.texCoords.v = v2; - quad->tl.texCoords.u = u; - quad->tl.texCoords.v = v; - quad->tr.texCoords.u = u2; - quad->tr.texCoords.v = v; - quad->br.texCoords.u = u2; - quad->br.texCoords.v = v2; - } - - quad->bl.vertices.z = 0; - quad->tl.vertices.z = 0; - quad->tr.vertices.z = 0; - quad->br.vertices.z = 0; - - return SUPER(self); -} - -/**/ - -char* _Util_readFile (const char* path, int* length) { - unsigned long size; - char* data = reinterpret_cast(CCFileUtils::sharedFileUtils()->getFileData( - CCFileUtils::sharedFileUtils()->fullPathForFilename(path).c_str(), "r", &size)); - *length = size; - return data; -} - } diff --git a/spine-cocos2dx/src/spine/spine-cocos2dx.h b/spine-cocos2dx/src/spine/spine-cocos2dx.h index 167c4aa1f..9ff6e857c 100644 --- a/spine-cocos2dx/src/spine/spine-cocos2dx.h +++ b/spine-cocos2dx/src/spine/spine-cocos2dx.h @@ -31,21 +31,6 @@ namespace spine { -typedef struct { - AtlasPage super; - cocos2d::CCTexture2D* texture; - cocos2d::CCTextureAtlas* textureAtlas; -} Cocos2dxAtlasPage; - -/**/ - -class CCSkeleton; - -typedef struct { - Skeleton super; - CCSkeleton* node; -} Cocos2dxSkeleton; - class CCSkeleton: public cocos2d::CCNodeRGBA, public cocos2d::CCBlendProtocol { private: bool ownsSkeleton; @@ -59,9 +44,6 @@ public: bool debugSlots; bool debugBones; - cocos2d::CCTextureAtlas* textureAtlas; // All region attachments for a skeleton must use the same texture. - unsigned int quadCount; - static CCSkeleton* create (const char* skeletonDataFile, Atlas* atlas, float scale = 1); static CCSkeleton* create (const char* skeletonDataFile, const char* atlasFile, float scale = 1); static CCSkeleton* create (SkeletonData* skeletonData, AnimationStateData* stateData = 0); @@ -110,13 +92,7 @@ public: /**/ -typedef struct { - RegionAttachment super; - cocos2d::ccV3F_C4B_T2F_Quad quad; - cocos2d::CCTextureAtlas* textureAtlas; -} Cocos2dxRegionAttachment; - -cocos2d::ccV3F_C4B_T2F_Quad* RegionAttachment_updateQuad (Attachment* self, Slot* slot); +void RegionAttachment_updateQuad (RegionAttachment* self, Slot* slot, cocos2d::ccV3F_C4B_T2F_Quad* quad); } diff --git a/spine-sfml/src/spine/spine-sfml.cpp b/spine-sfml/src/spine/spine-sfml.cpp index 99fcbc5ef..c2500bb7a 100644 --- a/spine-sfml/src/spine/spine-sfml.cpp +++ b/spine-sfml/src/spine/spine-sfml.cpp @@ -31,58 +31,35 @@ #include #include -using sf::Quads; -using sf::RenderTarget; -using sf::RenderStates; -using sf::Texture; -using sf::Uint8; -using sf::Vertex; -using sf::VertexArray; +using namespace sf; namespace spine { -void _SfmlAtlasPage_dispose (AtlasPage* page) { - SfmlAtlasPage* self = SUB_CAST(SfmlAtlasPage, page); - _AtlasPage_deinit(SUPER(self)); - - delete self->texture; - - FREE(page); +void _AtlasPage_createTexture (AtlasPage* self, const char* path) { + Texture* texture = new Texture(); + if (!texture->loadFromFile(path)) return; + self->texture = texture; + Vector2u size = texture->getSize(); + self->width = size.x; + self->height = size.x; } -AtlasPage* AtlasPage_create (const char* name, const char* path) { - SfmlAtlasPage* self = NEW(SfmlAtlasPage); - _AtlasPage_init(SUPER(self), name, _SfmlAtlasPage_dispose); +void _AtlasPage_disposeTexture (AtlasPage* self) { + delete (Texture*)self->texture; +} - self->texture = new Texture(); - self->texture->loadFromFile(path); - - return SUPER(self); +char* _Util_readFile (const char* path, int* length) { + return _readFile(path, length); } /**/ -void _SfmlSkeleton_dispose (Skeleton* self) { - _Skeleton_deinit(self); - FREE(self); -} - -Skeleton* _SfmlSkeleton_create (SkeletonData* data, SkeletonDrawable* drawable) { - Bone_setYDown(1); - - SfmlSkeleton* self = NEW(SfmlSkeleton); - _Skeleton_init(SUPER(self), data, _SfmlSkeleton_dispose); - - CONST_CAST(SkeletonDrawable*, self->drawable) = drawable; - - return SUPER(self); -} - SkeletonDrawable::SkeletonDrawable (SkeletonData* skeletonData, AnimationStateData* stateData) : timeScale(1), - vertexArray(new VertexArray(Quads, skeletonData->boneCount * 4)), - texture(0) { - skeleton = _SfmlSkeleton_create(skeletonData, this); + vertexArray(new VertexArray(Quads, skeletonData->boneCount * 4)) { + Bone_setYDown(true); + + skeleton = Skeleton_create(skeletonData); state = AnimationState_create(stateData); } @@ -101,99 +78,77 @@ void SkeletonDrawable::update (float deltaTime) { void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const { vertexArray->clear(); - for (int i = 0; i < skeleton->slotCount; ++i) - if (skeleton->slots[i]->attachment) Attachment_draw(skeleton->slots[i]->attachment, skeleton->slots[i]); - states.texture = texture; + for (int i = 0; i < skeleton->slotCount; ++i) { + Slot* slot = skeleton->slots[i]; + Attachment* attachment = slot->attachment; + if (!attachment || attachment->type != ATTACHMENT_REGION) continue; + RegionAttachment* regionAttachment = (RegionAttachment*)attachment; + RegionAttachment_updateVertices(regionAttachment, slot); + + Uint8 r = skeleton->r * slot->r * 255; + Uint8 g = skeleton->g * slot->g * 255; + Uint8 b = skeleton->b * slot->b * 255; + Uint8 a = skeleton->a * slot->a * 255; + + sf::Vertex vertices[4]; + vertices[0].color.r = r; + vertices[0].color.g = g; + vertices[0].color.b = b; + vertices[0].color.a = a; + vertices[1].color.r = r; + vertices[1].color.g = g; + vertices[1].color.b = b; + vertices[1].color.a = a; + vertices[2].color.r = r; + vertices[2].color.g = g; + vertices[2].color.b = b; + vertices[2].color.a = a; + vertices[3].color.r = r; + vertices[3].color.g = g; + vertices[3].color.b = b; + vertices[3].color.a = a; + + vertices[0].position.x = regionAttachment->vertices[VERTEX_X1]; + vertices[0].position.y = regionAttachment->vertices[VERTEX_Y1]; + vertices[1].position.x = regionAttachment->vertices[VERTEX_X2]; + vertices[1].position.y = regionAttachment->vertices[VERTEX_Y2]; + vertices[2].position.x = regionAttachment->vertices[VERTEX_X3]; + vertices[2].position.y = regionAttachment->vertices[VERTEX_Y3]; + vertices[3].position.x = regionAttachment->vertices[VERTEX_X4]; + vertices[3].position.y = regionAttachment->vertices[VERTEX_Y4]; + + int u = regionAttachment->region->x; + int u2 = u + regionAttachment->region->width; + int v = regionAttachment->region->y; + int v2 = v + regionAttachment->region->height; + if (regionAttachment->region->rotate) { + vertices[1].texCoords.x = u; + vertices[1].texCoords.y = v2; + vertices[2].texCoords.x = u; + vertices[2].texCoords.y = v; + vertices[3].texCoords.x = u2; + vertices[3].texCoords.y = v; + vertices[0].texCoords.x = u2; + vertices[0].texCoords.y = v2; + } else { + vertices[0].texCoords.x = u; + vertices[0].texCoords.y = v2; + vertices[1].texCoords.x = u; + vertices[1].texCoords.y = v; + vertices[2].texCoords.x = u2; + vertices[2].texCoords.y = v; + vertices[3].texCoords.x = u2; + vertices[3].texCoords.y = v2; + } + + // SMFL doesn't handle batching for us, so we'll just force a single texture per skeleton. + states.texture = (Texture*)regionAttachment->region->page->texture; + vertexArray->append(vertices[0]); + vertexArray->append(vertices[1]); + vertexArray->append(vertices[2]); + vertexArray->append(vertices[3]); + } target.draw(*vertexArray, states); } -/**/ - -void _SfmlRegionAttachment_dispose (Attachment* self) { - _RegionAttachment_deinit(SUB_CAST(RegionAttachment, self) ); - FREE(self); -} - -void _SfmlRegionAttachment_draw (Attachment* attachment, Slot* slot) { - SfmlRegionAttachment* self = SUB_CAST(SfmlRegionAttachment, attachment); - SfmlSkeleton* skeleton = (SfmlSkeleton*)slot->skeleton; - Uint8 r = SUPER(skeleton)->r * slot->r * 255; - Uint8 g = SUPER(skeleton)->g * slot->g * 255; - Uint8 b = SUPER(skeleton)->b * slot->b * 255; - Uint8 a = SUPER(skeleton)->a * slot->a * 255; - sf::Vertex* vertices = self->vertices; - vertices[0].color.r = r; - vertices[0].color.g = g; - vertices[0].color.b = b; - vertices[0].color.a = a; - vertices[1].color.r = r; - vertices[1].color.g = g; - vertices[1].color.b = b; - vertices[1].color.a = a; - vertices[2].color.r = r; - vertices[2].color.g = g; - vertices[2].color.b = b; - vertices[2].color.a = a; - vertices[3].color.r = r; - vertices[3].color.g = g; - vertices[3].color.b = b; - vertices[3].color.a = a; - - float* offset = SUPER(self)->offset; - Bone* bone = slot->bone; - vertices[0].position.x = offset[0] * bone->m00 + offset[1] * bone->m01 + bone->worldX; - vertices[0].position.y = offset[0] * bone->m10 + offset[1] * bone->m11 + bone->worldY; - vertices[1].position.x = offset[2] * bone->m00 + offset[3] * bone->m01 + bone->worldX; - vertices[1].position.y = offset[2] * bone->m10 + offset[3] * bone->m11 + bone->worldY; - vertices[2].position.x = offset[4] * bone->m00 + offset[5] * bone->m01 + bone->worldX; - vertices[2].position.y = offset[4] * bone->m10 + offset[5] * bone->m11 + bone->worldY; - vertices[3].position.x = offset[6] * bone->m00 + offset[7] * bone->m01 + bone->worldX; - vertices[3].position.y = offset[6] * bone->m10 + offset[7] * bone->m11 + bone->worldY; - - // SMFL doesn't handle batching for us, so we'll just force a single texture per skeleton. - skeleton->drawable->texture = self->texture; - skeleton->drawable->vertexArray->append(vertices[0]); - skeleton->drawable->vertexArray->append(vertices[1]); - skeleton->drawable->vertexArray->append(vertices[2]); - skeleton->drawable->vertexArray->append(vertices[3]); -} - -RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) { - SfmlRegionAttachment* self = NEW(SfmlRegionAttachment); - _RegionAttachment_init(SUPER(self), name, _SfmlRegionAttachment_dispose, _SfmlRegionAttachment_draw); - - self->texture = ((SfmlAtlasPage*)region->page)->texture; - int u = region->x; - int u2 = u + region->width; - int v = region->y; - int v2 = v + region->height; - if (region->rotate) { - self->vertices[1].texCoords.x = u; - self->vertices[1].texCoords.y = v2; - self->vertices[2].texCoords.x = u; - self->vertices[2].texCoords.y = v; - self->vertices[3].texCoords.x = u2; - self->vertices[3].texCoords.y = v; - self->vertices[0].texCoords.x = u2; - self->vertices[0].texCoords.y = v2; - } else { - self->vertices[0].texCoords.x = u; - self->vertices[0].texCoords.y = v2; - self->vertices[1].texCoords.x = u; - self->vertices[1].texCoords.y = v; - self->vertices[2].texCoords.x = u2; - self->vertices[2].texCoords.y = v; - self->vertices[3].texCoords.x = u2; - self->vertices[3].texCoords.y = v2; - } - - return SUPER(self); -} - -/**/ - -char* _Util_readFile (const char* path, int* length) { - return _readFile(path, length); -} - } /* namespace spine */ diff --git a/spine-sfml/src/spine/spine-sfml.h b/spine-sfml/src/spine/spine-sfml.h index ec6c70bc5..a2fdf7784 100644 --- a/spine-sfml/src/spine/spine-sfml.h +++ b/spine-sfml/src/spine/spine-sfml.h @@ -52,7 +52,6 @@ public: AnimationState* state; float timeScale; sf::VertexArray* vertexArray; - sf::Texture* texture; // All region attachments must use the same texture. SkeletonDrawable (SkeletonData* skeleton, AnimationStateData* stateData = 0); ~SkeletonDrawable ();