- 已编辑
My own runtime progress (iOS)
I figured I might as well document my own runtime progress here. Hopefully I will be able to lift some of the C++ runtime for the more complicated bits.
Goal: iOS runtime, using TexturePacker, OpenGLES2.0 and obj-C
Progress so far:
Imported Texture Packer SpineBoy
Wrote custom Shader to display Spineboy with one call to glDrawArrays()
Imported JSON Data
Next to do:
Process JSON Data, and match elements to Texture Packer elements (gulp)
Nothing much to see so far, except my test of Spineboy parts individually placeable and rotatable. Hopefully after next step, at least SpineBoy will look complete again
Loading Image
I'm curious why you would choose not to use the existing C++ runtime? It's working really well for me on iOS.
My preference would be to use Texture Packer, so I found extracting the Atlas stuff from the C++ runtime a bit tricky. I would be interested to see how you integrated it with obj-c though. I looked at it, and couldn't see a clean way.
I figured it would only take a few hours to re-write the runtime in obj-c ....
I'm using TexturePacker too.
I'm not working in Obj-C, though. I renamed my view controller to ViewController.mm (Obj-C++) which can use class pointers and call my C++ functions. Everything else is just C++ code.
Sounds like my obj-c implementation has some merit then. The apple libraries read JSON data into an NSDictionary, so I am trying to feed that data nicely into the front end at the moment. I have converted a number of classes already, but if you have any guidance on the changes needed for the c++ runtime where it deals with the atlas, I will gladly accept the help
Edit:
Got to be said, some comments wouldn't have gone amiss in these runtimes lol - especially the skin stuff ! very confusing. My rudimentary C++ is letting me down
Having lots of trouble extracting the JSON skin data, as none of it is keyed
getting the bones and slots like this:
NSArray *attachments = [SkeletonJSON objectForKey:@"bones"];
for(NSDictionary *object in attachments) {
NSLog(@"%@", [object objectForKey:@"name"]);
NSLog(@"%@", [object objectForKey:@"parent"]);
NSLog(@"%@", [object objectForKey:@"length"]);
NSLog(@"%@", [object objectForKey:@"x"]);
NSLog(@"%@", [object objectForKey:@"y"]);
NSLog(@"%@", [object objectForKey:@"scaleX"]);
NSLog(@"%@", [object objectForKey:@"scaleY"]);
NSLog(@"%@", [object objectForKey:@"rotation"]);
}
NSArray *attachments1 = [SkeletonJSON objectForKey:@"slots"];
for(NSDictionary *object in attachments1) {
NSLog(@"%@", [object objectForKey:@"name"]);
NSLog(@"%@", [object objectForKey:@"bone"]);
NSLog(@"%@", [object objectForKey:@"color"]);
NSLog(@"%@", [object objectForKey:@"attachment"]);
}
Finally (after much trial and error) getting the skin info using this code, although it doesn't seem so intuitive ..... (plus I don't have a Spine export with an attachment 'type', so not reading that yet)
NSDictionary *skinNames = [SkeletonJSON objectForKey:@"skins"];
NSArray*keys=[skinNames allKeys];
for (int i=0; i<[keys count]; i++) {
NSLog(@"Skin %@",keys[i]);
NSDictionary *slotNames = [skinNames objectForKey:keys[i]];
NSArray*keys1=[slotNames allKeys];
for (int ii=0; ii<[keys1 count]; ii++) {
NSDictionary *attachmentNames = [slotNames objectForKey:keys1[ii]];
NSLog(@"Slot %@",keys1[ii]);
NSArray*keys2=[attachmentNames allKeys];
for (int iii=0; iii<[keys2 count]; iii++) {
NSLog(@"Attachment %@",keys2[iii]);
NSDictionary *attachments2 = [attachmentNames objectForKey:keys2[iii]];
NSLog(@"%@", [attachments2 objectForKey:@"x"]);
NSLog(@"%@", [attachments2 objectForKey:@"y"]);
NSLog(@"%@", [attachments2 objectForKey:@"scaleX"]);
NSLog(@"%@", [attachments2 objectForKey:@"scaleY"]);
NSLog(@"%@", [attachments2 objectForKey:@"rotation"]);
NSLog(@"%@", [attachments2 objectForKey:@"width"]);
NSLog(@"%@", [attachments2 objectForKey:@"height"]);
}
}
}
I don't know obj-c but I already done the skeleton load in my runtime.
The slots and bones have data as array.
This is an array in JSON:
[ {data}, {data}, {data} ]
And the skin have another dictionary inside.
This isn't an array, this is an dictionary:
"dictionary": {
"another_dictionary_here": {
data
}
}
So the Spine JSON format is:
{
"bones": [ // array
{ "name": "root", "scaleX": 1, "scaleY": 1 } // dictionary
],
"slots": [ // array
{ "name": "right", "bone": "right", "attachment": "right" } // dictionary
],
"skins": { // dictionary
"default": { // dictionary
"template": { // dictionary
"spineboy": { "y": 167.82, "width": 145, "height": 341 } // dictionary
}
}
}
}
You need a lot of loops to process this...
yeah thats pretty much what I have in the NSDictionary, so my processing loops are correct. thanks for validating that. Just trying to keep it all as neat as I can.
I started mine as well and was able to get everything loaded. My biggest challenge has been understanding how the bones relate to each other. They are ALL over the place for me and though it makes sense where they are being placed I don't understand why exactly.
I am coming from cocos2d-iphone perspective and trying to make a good fit.
Why don't we create a github project and work on this together?
Writing your own runtime is fine if you like to do it, but the spine-cpp runtime can be used on iOS, using TexturePacker, OpenGLES2.0 and ObjC. spine-cpp already has code to load an atlas in the libgdx atlas format. TexturePacker can output the libgdx atlas format. spine-cpp also parses all the JSON. Seems the only need for a rewrite in ObjC would be to use ObjC, but you can easily mix C++ with ObjC
something like just renaming your class to ".mm". spine-cpp doesn't use any fancy C++ features, using it should be straightforward. If you must have ObjC, maybe you could write an ObjC wrapper around the C++? Always better if the code for the core functionality can be reused.
I have been using the SFML example to try and work through this but getting stuck at a couple spots.
Personally I would love for the runtime to be supported in one place. I am just under a deadline to get this working. I can't say enough great things about this tool. You guys rock. But I am just getting impatient for this to work with cocos2d-iphone projects.
I would love to be able to leverage the drawing in cocos2d-iphone as well.
I'm just doing this because I like to understand the detail, and using my own rendering engine I can get some really good speed, which means more objects on the screen animating at once. I'm not taking anything away from the cpp runtime, as I'm sure its fine. However, it wasn't put together in an end to end iOS or Android example, so that means we have to make it work with our own workflows we have set up. One size doesn't fit all.
@authbattkledamage sorry, not sure about working with someone else though, as I can only really drop in and out as I get time.
@authbattkledamage, aye, sorry about the delay. I've been stuck getting the core of the editor to be stable on Mac. Recent changes to Apple supporting Java in the latest OS versions broke things in the low level OpenGL lib I was using. Have now wrapped GLFW and have that working nicely on Mac, however it doesn't play well with AWT on Linux. Once I figure that out I'll release an update with the new backend and hopefully things will stabilize and I can move on to working on runtimes. I hate this quagmire I'm stuck in.
@Lazrhog, I don't know that a rewrite of spine-cpp will result in more speed, certainly not drawing speed since it doesn't actually draw anything. spine-cpp doesn't enforce any workflow, it just provides the basics for loading the data into an object model and applying animations to those objects. You are left to do the drawing on your own, but it provides the transformed image vertices so this should be quite easy with OpenGL. See the spine-sfml example for how drawing can be done. You just need to extend a few classes in spine-cpp. You could then hide all the spine-cpp stuff behind your own API.
I honestly don't mind if you'd rather write your own runtime, I just wanted to make it clear that the idea behind spine-cpp is that it is easily reused so people don't have to struggle with loading data and getting the transforms exactly correct.
BTW, this might help (click for full size):
Loading Image
Let me say after watching the coding workshop I understand what you guys are doing better. And I am impressed. I feel like the runtime you guys have developed is really thought out.
Great job!
What can we in the cocos2d-iphone community do to help this along?
Thanks! :$ I'm afraid not much. Once I get rolling on actual Spine development instead of dorking around in the low level layers for the editor, things will move quickly.
Ahh thanks for the class diagram, it really does help. I have no idea whether what I am doing will be better or not, I just eventually want to get as much of the processing into a shader as possible and free up the CPU. I am hoping to get the animation into a vertex shader eventually. Once I have worked out all the details. One step at a time though
Little progress update, Skeleton Data now all reads in using obj-c runtime. Just gotta tie things all up and see if something draws now ... (no animation yet, as I haven't loaded that data yet)
Hmm, something not quite right, although at least its all in obj-c . Can't see where I'm going wrong at the moment. Does Spine assume images rotate from the centre, and their x/y coordinates are in the centre too ? Not that offsetting them by widths/heights seems to make any difference at the moment.
Loading Image