Mario Zechner 3 жил өмнө
parent
commit
af9561de19
1 өөрчлөгдсөн 130 нэмэгдсэн , 4 устгасан
  1. 130 4
      spine-sdl/example/main.cpp

+ 130 - 4
spine-sdl/example/main.cpp

@@ -11,6 +11,9 @@ namespace spine {
         Skeleton *skeleton;
         bool ownsAnimationStateData;
         AnimationState *animationState;
+        SkeletonClipping clipper;
+        Vector<float> worldVertices;
+        Vector<unsigned short> quadIndices;
 
         SkeletonDrawable(SkeletonData *skeletonData, AnimationStateData *animationStateData = nullptr) {
             Bone::setYDown(true);
@@ -19,6 +22,12 @@ namespace spine {
             ownsAnimationStateData = animationStateData == 0;
             if (ownsAnimationStateData) animationStateData = new(__FILE__, __LINE__) AnimationStateData(skeletonData);
             animationState = new(__FILE__, __LINE__) AnimationState(animationStateData);
+            quadIndices.add(0);
+            quadIndices.add(1);
+            quadIndices.add(2);
+            quadIndices.add(2);
+            quadIndices.add(3);
+            quadIndices.add(0);
         }
 
         ~SkeletonDrawable() {
@@ -33,18 +42,124 @@ namespace spine {
             skeleton->updateWorldTransform();
         }
 
-        void draw() {
-
+        void draw(SDL_Renderer *renderer) {
+            SDL_Texture *texture;
+            spine::Vector<SDL_Vertex> sdlVertices;
+            SDL_Vertex sdlVertex;
+            Vector<int> sdlIndices;
+            for (unsigned i = 0; i < skeleton->getSlots().size(); ++i) {
+                Slot &slot = *skeleton->getDrawOrder()[i];
+                Attachment *attachment = slot.getAttachment();
+                if (!attachment) continue;
+
+                // Early out if the slot color is 0 or the bone is not active
+                if (slot.getColor().a == 0 || !slot.getBone().isActive()) {
+                    clipper.clipEnd(slot);
+                    continue;
+                }
+
+                Vector<float> *vertices = &worldVertices;
+                int verticesCount = 0;
+                Vector<float> *uvs = NULL;
+                Vector<unsigned short> *indices;
+                int indicesCount = 0;
+                Color *attachmentColor;
+
+                if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) {
+                    RegionAttachment *regionAttachment = (RegionAttachment *) attachment;
+                    attachmentColor = &regionAttachment->getColor();
+
+                    // Early out if the slot color is 0
+                    if (attachmentColor->a == 0) {
+                        clipper.clipEnd(slot);
+                        continue;
+                    }
+
+                    worldVertices.setSize(8, 0);
+                    regionAttachment->computeWorldVertices(slot, worldVertices, 0, 2);
+                    verticesCount = 4;
+                    uvs = &regionAttachment->getUVs();
+                    indices = &quadIndices;
+                    indicesCount = 6;
+                    texture = (SDL_Texture *) ((AtlasRegion *) regionAttachment->getRendererObject())->page->getRendererObject();
+
+                } else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) {
+                    MeshAttachment *mesh = (MeshAttachment *) attachment;
+                    attachmentColor = &mesh->getColor();
+
+                    // Early out if the slot color is 0
+                    if (attachmentColor->a == 0) {
+                        clipper.clipEnd(slot);
+                        continue;
+                    }
+
+                    worldVertices.setSize(mesh->getWorldVerticesLength(), 0);
+                    texture = (SDL_Texture *) ((AtlasRegion *) mesh->getRendererObject())->page->getRendererObject();
+                    mesh->computeWorldVertices(slot, 0, mesh->getWorldVerticesLength(), worldVertices.buffer(), 0, 2);
+                    verticesCount = mesh->getWorldVerticesLength() >> 1;
+                    uvs = &mesh->getUVs();
+                    indices = &mesh->getTriangles();
+                    indicesCount = indices->size();
+
+                } else if (attachment->getRTTI().isExactly(ClippingAttachment::rtti)) {
+                    ClippingAttachment *clip = (ClippingAttachment *) slot.getAttachment();
+                    clipper.clipStart(slot, clip);
+                    continue;
+                } else
+                    continue;
+
+                Uint8 r = static_cast<Uint8>(skeleton->getColor().r * slot.getColor().r * attachmentColor->r * 255);
+                Uint8 g = static_cast<Uint8>(skeleton->getColor().g * slot.getColor().g * attachmentColor->g * 255);
+                Uint8 b = static_cast<Uint8>(skeleton->getColor().b * slot.getColor().b * attachmentColor->b * 255);
+                Uint8 a = static_cast<Uint8>(skeleton->getColor().a * slot.getColor().a * attachmentColor->a * 255);
+                sdlVertex.color.r = r;
+                sdlVertex.color.g = g;
+                sdlVertex.color.b = b;
+                sdlVertex.color.a = a;
+
+                Color light;
+                light.r = r / 255.0f;
+                light.g = g / 255.0f;
+                light.b = b / 255.0f;
+                light.a = a / 255.0f;
+
+                if (clipper.isClipping()) {
+                    clipper.clipTriangles(worldVertices, *indices, *uvs, 2);
+                    vertices = &clipper.getClippedVertices();
+                    verticesCount = clipper.getClippedVertices().size() >> 1;
+                    uvs = &clipper.getClippedUVs();
+                    indices = &clipper.getClippedTriangles();
+                    indicesCount = clipper.getClippedTriangles().size();
+                }
+
+
+                sdlVertices.clear();
+                for (int ii = 0; ii < verticesCount; ++ii) {
+                    sdlVertex.position.x = (*vertices)[ii];
+                    sdlVertex.position.y = (*vertices)[ii + 1];
+                    sdlVertex.tex_coord.x = (*uvs)[ii];
+                    sdlVertex.tex_coord.y = (*uvs)[ii + 1];
+                    sdlVertices.add(sdlVertex);
+                }
+                sdlIndices.clear();
+                for (int ii = 0; ii < indices->size(); ii++)
+                    sdlIndices.add((*indices)[ii]);
+
+                SDL_RenderGeometry(renderer, texture, sdlVertices.buffer(), sdlVertices.size(), sdlIndices.buffer(), indicesCount);
+                clipper.clipEnd(slot);
+            }
+            clipper.clipEnd();
         }
     };
 
     class SDLTextureLoader : public spine::TextureLoader {
         SDL_Renderer *renderer;
 
+    public:
         SDLTextureLoader(SDL_Renderer *renderer): renderer(renderer) {
         }
 
-        SDL_Texture *loadTexture(SDL_Renderer *renderer, const spine::String &path) {
+        SDL_Texture *loadTexture(const spine::String &path) {
             int width, height, components;
             stbi_uc *imageData = stbi_load(path.buffer(), &width, &height, &components, 4);
             if (!imageData) return nullptr;
@@ -62,7 +177,7 @@ namespace spine {
         }
 
         void load(AtlasPage &page, const String &path) {
-            SDL_Texture *texture = loadTexture(renderer, path);
+            SDL_Texture *texture = loadTexture(path);
             if (!texture) return;
             page.setRendererObject(texture);
             SDL_QueryTexture(texture, nullptr, nullptr, &page.width, &page.height);
@@ -100,6 +215,16 @@ int main() {
         printf("Error: %s", SDL_GetError());
         return -1;
     }
+
+    spine::SDLTextureLoader textureLoader(renderer);
+    spine::Atlas atlas("/Users/badlogic/workspaces/spine-runtimes/examples/spineboy/export/spineboy.atlas", &textureLoader);
+    spine::AtlasAttachmentLoader attachmentLoader(&atlas);
+    spine::SkeletonJson json(&attachmentLoader);
+    spine::SkeletonData *skeletonData = json.readSkeletonDataFile("/Users/badlogic/workspaces/spine-runtimes/examples/spineboy/export/spineboy-pro.json");
+    spine::SkeletonDrawable drawable(skeletonData);
+    drawable.skeleton->setPosition(400, 500);
+    drawable.update(0);
+
     // spine::SkeletonDrawable skeletonDrawable(nullptr, nullptr);
 
     bool quit = false;
@@ -114,6 +239,7 @@ int main() {
 
         SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
         SDL_RenderClear(renderer);
+        drawable.draw(renderer);
         SDL_RenderPresent(renderer);
     }