diff --git a/formatters/build.gradle b/formatters/build.gradle index ff7ff04fb..2886d7a77 100644 --- a/formatters/build.gradle +++ b/formatters/build.gradle @@ -21,12 +21,20 @@ spotless { 'spine-cocos2dx/src/**/*.h', 'spine-cocos2dx/example/Classes/**/*.cpp', 'spine-cocos2dx/example/Classes/**/*.h', - 'spine-sdl/**/*.c', - 'spine-sdl/**/*.cpp', - 'spine-sdl/**/*.h', - 'spine-sfml/**/*.c', - 'spine-sfml/**/*.cpp', - 'spine-sfml/**/*.h', + 'spine-glfw/src/**/*.cpp', + 'spine-glfw/src/**/*.h', + 'spine-glfw/example/**/*.cpp', + 'spine-glfw/example/**/*.h', + 'spine-sdl/src/**/*.c', + 'spine-sdl/src/**/*.cpp', + 'spine-sdl/src/**/*.h', + 'spine-sdl/example/**/*.c', + 'spine-sdl/example/**/*.cpp', + 'spine-sdl/example/**/*.h', + 'spine-sfml/c/src/**/*.c', + 'spine-sfml/c/src/**/*.h', + 'spine-sfml/cpp/src/**/*.cpp', + 'spine-sfml/cpp/src/**/*.h', 'spine-ue/**/*.cpp', 'spine-ue/**/*.h', 'spine-godot/spine_godot/*.cpp', diff --git a/spine-cpp/spine-cpp-lite/spine-cpp-lite.cpp b/spine-cpp/spine-cpp-lite/spine-cpp-lite.cpp index 7037f29a5..236d8166d 100644 --- a/spine-cpp/spine-cpp-lite/spine-cpp-lite.cpp +++ b/spine-cpp/spine-cpp-lite/spine-cpp-lite.cpp @@ -81,7 +81,7 @@ public: } void compress() { - if (blocks.size() == 1) return; + if (blocks.size() == 1) return; int totalSize = 0; for (int i = 0, n = blocks.size(); i < n; i++) { totalSize += blocks[i].size; diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonRenderer.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonRenderer.cpp index 560ab788a..7be7770c4 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonRenderer.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonRenderer.cpp @@ -39,210 +39,210 @@ using namespace spine; -SkeletonRenderer::SkeletonRenderer(): _allocator(4096), _worldVertices(), _quadIndices(), _clipping(), _renderCommands() { - _quadIndices.add(0); - _quadIndices.add(1); - _quadIndices.add(2); - _quadIndices.add(2); - _quadIndices.add(3); - _quadIndices.add(0); +SkeletonRenderer::SkeletonRenderer() : _allocator(4096), _worldVertices(), _quadIndices(), _clipping(), _renderCommands() { + _quadIndices.add(0); + _quadIndices.add(1); + _quadIndices.add(2); + _quadIndices.add(2); + _quadIndices.add(3); + _quadIndices.add(0); } SkeletonRenderer::~SkeletonRenderer() { } static RenderCommand *createRenderCommand(BlockAllocator &allocator, int numVertices, int32_t numIndices, BlendMode blendMode, void *texture) { - RenderCommand *cmd = allocator.allocate(1); - cmd->positions = allocator.allocate(numVertices << 1); - cmd->uvs = allocator.allocate(numVertices << 1); - cmd->colors = allocator.allocate(numVertices); - cmd->darkColors = allocator.allocate(numVertices); - cmd->numVertices = numVertices; - cmd->indices = allocator.allocate(numIndices); - cmd->numIndices = numIndices; - cmd->blendMode = blendMode; - cmd->texture = texture; - cmd->next = nullptr; - return cmd; + RenderCommand *cmd = allocator.allocate(1); + cmd->positions = allocator.allocate(numVertices << 1); + cmd->uvs = allocator.allocate(numVertices << 1); + cmd->colors = allocator.allocate(numVertices); + cmd->darkColors = allocator.allocate(numVertices); + cmd->numVertices = numVertices; + cmd->indices = allocator.allocate(numIndices); + cmd->numIndices = numIndices; + cmd->blendMode = blendMode; + cmd->texture = texture; + cmd->next = nullptr; + return cmd; } static RenderCommand *batchSubCommands(BlockAllocator &allocator, Vector &commands, int first, int last, int numVertices, int numIndices) { - RenderCommand *batched = createRenderCommand(allocator, numVertices, numIndices, commands[first]->blendMode, commands[first]->texture); - float *positions = batched->positions; - float *uvs = batched->uvs; - uint32_t *colors = batched->colors; - uint32_t *darkColors = batched->darkColors; - uint16_t *indices = batched->indices; - int indicesOffset = 0; - for (int i = first; i <= last; i++) { - RenderCommand *cmd = commands[i]; - memcpy(positions, cmd->positions, sizeof(float) * 2 * cmd->numVertices); - memcpy(uvs, cmd->uvs, sizeof(float) * 2 * cmd->numVertices); - memcpy(colors, cmd->colors, sizeof(int32_t) * cmd->numVertices); - memcpy(darkColors, cmd->darkColors, sizeof(int32_t) * cmd->numVertices); - for (int ii = 0; ii < cmd->numIndices; ii++) - indices[ii] = cmd->indices[ii] + indicesOffset; - indicesOffset += cmd->numVertices; - positions += 2 * cmd->numVertices; - uvs += 2 * cmd->numVertices; - colors += cmd->numVertices; - darkColors += cmd->numVertices; - indices += cmd->numIndices; - } - return batched; + RenderCommand *batched = createRenderCommand(allocator, numVertices, numIndices, commands[first]->blendMode, commands[first]->texture); + float *positions = batched->positions; + float *uvs = batched->uvs; + uint32_t *colors = batched->colors; + uint32_t *darkColors = batched->darkColors; + uint16_t *indices = batched->indices; + int indicesOffset = 0; + for (int i = first; i <= last; i++) { + RenderCommand *cmd = commands[i]; + memcpy(positions, cmd->positions, sizeof(float) * 2 * cmd->numVertices); + memcpy(uvs, cmd->uvs, sizeof(float) * 2 * cmd->numVertices); + memcpy(colors, cmd->colors, sizeof(int32_t) * cmd->numVertices); + memcpy(darkColors, cmd->darkColors, sizeof(int32_t) * cmd->numVertices); + for (int ii = 0; ii < cmd->numIndices; ii++) + indices[ii] = cmd->indices[ii] + indicesOffset; + indicesOffset += cmd->numVertices; + positions += 2 * cmd->numVertices; + uvs += 2 * cmd->numVertices; + colors += cmd->numVertices; + darkColors += cmd->numVertices; + indices += cmd->numIndices; + } + return batched; } static RenderCommand *batchCommands(BlockAllocator &allocator, Vector &commands) { - if (commands.size() == 0) return nullptr; + if (commands.size() == 0) return nullptr; - RenderCommand *root = nullptr; - RenderCommand *last = nullptr; + RenderCommand *root = nullptr; + RenderCommand *last = nullptr; - RenderCommand *first = commands[0]; - int startIndex = 0; - int i = 1; - int numVertices = first->numVertices; - int numIndices = first->numIndices; - while (i <= (int) commands.size()) { - RenderCommand *cmd = i < (int) commands.size() ? commands[i] : nullptr; + RenderCommand *first = commands[0]; + int startIndex = 0; + int i = 1; + int numVertices = first->numVertices; + int numIndices = first->numIndices; + while (i <= (int) commands.size()) { + RenderCommand *cmd = i < (int) commands.size() ? commands[i] : nullptr; - if (cmd && cmd->numVertices == 0 && cmd->numIndices == 0) { - i++; - continue; - } + if (cmd && cmd->numVertices == 0 && cmd->numIndices == 0) { + i++; + continue; + } - if (cmd != nullptr && cmd->texture == first->texture && - cmd->blendMode == first->blendMode && - cmd->colors[0] == first->colors[0] && - cmd->darkColors[0] == first->darkColors[0] && - numIndices + cmd->numIndices < 0xffff) { - numVertices += cmd->numVertices; - numIndices += cmd->numIndices; - } else { - RenderCommand *batched = batchSubCommands(allocator, commands, startIndex, i - 1, numVertices, numIndices); - if (!last) { - root = last = batched; - } else { - last->next = batched; - last = batched; - } - if (i == (int) commands.size()) break; - first = commands[i]; - startIndex = i; - numVertices = first->numVertices; - numIndices = first->numIndices; - } - i++; - } - return root; + if (cmd != nullptr && cmd->texture == first->texture && + cmd->blendMode == first->blendMode && + cmd->colors[0] == first->colors[0] && + cmd->darkColors[0] == first->darkColors[0] && + numIndices + cmd->numIndices < 0xffff) { + numVertices += cmd->numVertices; + numIndices += cmd->numIndices; + } else { + RenderCommand *batched = batchSubCommands(allocator, commands, startIndex, i - 1, numVertices, numIndices); + if (!last) { + root = last = batched; + } else { + last->next = batched; + last = batched; + } + if (i == (int) commands.size()) break; + first = commands[i]; + startIndex = i; + numVertices = first->numVertices; + numIndices = first->numIndices; + } + i++; + } + return root; } RenderCommand *SkeletonRenderer::render(Skeleton &skeleton) { - _allocator.compress(); - _renderCommands.clear(); + _allocator.compress(); + _renderCommands.clear(); - SkeletonClipping &clipper = _clipping; + SkeletonClipping &clipper = _clipping; - for (unsigned i = 0; i < skeleton.getSlots().size(); ++i) { - Slot &slot = *skeleton.getDrawOrder()[i]; - Attachment *attachment = slot.getAttachment(); - if (!attachment) { - clipper.clipEnd(slot); - continue; - } + for (unsigned i = 0; i < skeleton.getSlots().size(); ++i) { + Slot &slot = *skeleton.getDrawOrder()[i]; + Attachment *attachment = slot.getAttachment(); + if (!attachment) { + clipper.clipEnd(slot); + 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; - } + // 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 *worldVertices = &_worldVertices; - Vector *quadIndices = &_quadIndices; - Vector *vertices = worldVertices; - int32_t verticesCount; - Vector *uvs; - Vector *indices; - int32_t indicesCount; - Color *attachmentColor; - void *texture; + Vector *worldVertices = &_worldVertices; + Vector *quadIndices = &_quadIndices; + Vector *vertices = worldVertices; + int32_t verticesCount; + Vector *uvs; + Vector *indices; + int32_t indicesCount; + Color *attachmentColor; + void *texture; - if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) { - RegionAttachment *regionAttachment = (RegionAttachment *) attachment; - attachmentColor = ®ionAttachment->getColor(); + if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) { + RegionAttachment *regionAttachment = (RegionAttachment *) attachment; + attachmentColor = ®ionAttachment->getColor(); - // Early out if the slot color is 0 - if (attachmentColor->a == 0) { - clipper.clipEnd(slot); - continue; - } + // 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 = ®ionAttachment->getUVs(); - indices = quadIndices; - indicesCount = 6; - texture = regionAttachment->getRegion()->rendererObject; + worldVertices->setSize(8, 0); + regionAttachment->computeWorldVertices(slot, *worldVertices, 0, 2); + verticesCount = 4; + uvs = ®ionAttachment->getUVs(); + indices = quadIndices; + indicesCount = 6; + texture = regionAttachment->getRegion()->rendererObject; - } else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) { - MeshAttachment *mesh = (MeshAttachment *) attachment; - attachmentColor = &mesh->getColor(); + } 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; - } + // Early out if the slot color is 0 + if (attachmentColor->a == 0) { + clipper.clipEnd(slot); + continue; + } - worldVertices->setSize(mesh->getWorldVerticesLength(), 0); - mesh->computeWorldVertices(slot, 0, mesh->getWorldVerticesLength(), worldVertices->buffer(), 0, 2); - verticesCount = (int32_t) (mesh->getWorldVerticesLength() >> 1); - uvs = &mesh->getUVs(); - indices = &mesh->getTriangles(); - indicesCount = (int32_t) indices->size(); - texture = mesh->getRegion()->rendererObject; + worldVertices->setSize(mesh->getWorldVerticesLength(), 0); + mesh->computeWorldVertices(slot, 0, mesh->getWorldVerticesLength(), worldVertices->buffer(), 0, 2); + verticesCount = (int32_t) (mesh->getWorldVerticesLength() >> 1); + uvs = &mesh->getUVs(); + indices = &mesh->getTriangles(); + indicesCount = (int32_t) indices->size(); + texture = mesh->getRegion()->rendererObject; - } else if (attachment->getRTTI().isExactly(ClippingAttachment::rtti)) { - ClippingAttachment *clip = (ClippingAttachment *) slot.getAttachment(); - clipper.clipStart(slot, clip); - continue; - } else - continue; + } else if (attachment->getRTTI().isExactly(ClippingAttachment::rtti)) { + ClippingAttachment *clip = (ClippingAttachment *) slot.getAttachment(); + clipper.clipStart(slot, clip); + continue; + } else + continue; - uint8_t r = static_cast(skeleton.getColor().r * slot.getColor().r * attachmentColor->r * 255); - uint8_t g = static_cast(skeleton.getColor().g * slot.getColor().g * attachmentColor->g * 255); - uint8_t b = static_cast(skeleton.getColor().b * slot.getColor().b * attachmentColor->b * 255); - uint8_t a = static_cast(skeleton.getColor().a * slot.getColor().a * attachmentColor->a * 255); - uint32_t color = (a << 24) | (r << 16) | (g << 8) | b; - uint32_t darkColor = 0xff000000; - if (slot.hasDarkColor()) { - Color &slotDarkColor = slot.getDarkColor(); - darkColor = 0xff000000 | (static_cast(slotDarkColor.r * 255) << 16) | (static_cast(slotDarkColor.g * 255) << 8) | static_cast(slotDarkColor.b * 255); - } + uint8_t r = static_cast(skeleton.getColor().r * slot.getColor().r * attachmentColor->r * 255); + uint8_t g = static_cast(skeleton.getColor().g * slot.getColor().g * attachmentColor->g * 255); + uint8_t b = static_cast(skeleton.getColor().b * slot.getColor().b * attachmentColor->b * 255); + uint8_t a = static_cast(skeleton.getColor().a * slot.getColor().a * attachmentColor->a * 255); + uint32_t color = (a << 24) | (r << 16) | (g << 8) | b; + uint32_t darkColor = 0xff000000; + if (slot.hasDarkColor()) { + Color &slotDarkColor = slot.getDarkColor(); + darkColor = 0xff000000 | (static_cast(slotDarkColor.r * 255) << 16) | (static_cast(slotDarkColor.g * 255) << 8) | static_cast(slotDarkColor.b * 255); + } - if (clipper.isClipping()) { - clipper.clipTriangles(*worldVertices, *indices, *uvs, 2); - vertices = &clipper.getClippedVertices(); - verticesCount = (int32_t) (clipper.getClippedVertices().size() >> 1); - uvs = &clipper.getClippedUVs(); - indices = &clipper.getClippedTriangles(); - indicesCount = (int32_t) (clipper.getClippedTriangles().size()); - } + if (clipper.isClipping()) { + clipper.clipTriangles(*worldVertices, *indices, *uvs, 2); + vertices = &clipper.getClippedVertices(); + verticesCount = (int32_t) (clipper.getClippedVertices().size() >> 1); + uvs = &clipper.getClippedUVs(); + indices = &clipper.getClippedTriangles(); + indicesCount = (int32_t) (clipper.getClippedTriangles().size()); + } - RenderCommand *cmd = createRenderCommand(_allocator, verticesCount, indicesCount, slot.getData().getBlendMode(), texture); - _renderCommands.add(cmd); - memcpy(cmd->positions, vertices->buffer(), (verticesCount << 1) * sizeof(float)); - memcpy(cmd->uvs, uvs->buffer(), (verticesCount << 1) * sizeof(float)); - for (int ii = 0; ii < verticesCount; ii++) { - cmd->colors[ii] = color; - cmd->darkColors[ii] = darkColor; - } - memcpy(cmd->indices, indices->buffer(), indices->size() * sizeof(uint16_t)); - clipper.clipEnd(slot); - } - clipper.clipEnd(); + RenderCommand *cmd = createRenderCommand(_allocator, verticesCount, indicesCount, slot.getData().getBlendMode(), texture); + _renderCommands.add(cmd); + memcpy(cmd->positions, vertices->buffer(), (verticesCount << 1) * sizeof(float)); + memcpy(cmd->uvs, uvs->buffer(), (verticesCount << 1) * sizeof(float)); + for (int ii = 0; ii < verticesCount; ii++) { + cmd->colors[ii] = color; + cmd->darkColors[ii] = darkColor; + } + memcpy(cmd->indices, indices->buffer(), indices->size() * sizeof(uint16_t)); + clipper.clipEnd(slot); + } + clipper.clipEnd(); - return batchCommands(_allocator, _renderCommands); + return batchCommands(_allocator, _renderCommands); } \ No newline at end of file diff --git a/spine-glfw/example/main.cpp b/spine-glfw/example/main.cpp index 2563cb5dd..61575d8e6 100644 --- a/spine-glfw/example/main.cpp +++ b/spine-glfw/example/main.cpp @@ -9,92 +9,92 @@ using namespace spine; int width = 800, height = 600; -GLFWwindow* init_glfw() { - if (!glfwInit()) { - std::cerr << "Failed to initialize GLFW" << std::endl; - return nullptr; - } - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - GLFWwindow* window = glfwCreateWindow(width, height, "spine-glfw", NULL, NULL); - if (!window) { - std::cerr << "Failed to create GLFW window" << std::endl; - glfwTerminate(); - return nullptr; - } - glfwMakeContextCurrent(window); - glbinding::initialize(glfwGetProcAddress); - return window; +GLFWwindow *init_glfw() { + if (!glfwInit()) { + std::cerr << "Failed to initialize GLFW" << std::endl; + return nullptr; + } + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + GLFWwindow *window = glfwCreateWindow(width, height, "spine-glfw", NULL, NULL); + if (!window) { + std::cerr << "Failed to create GLFW window" << std::endl; + glfwTerminate(); + return nullptr; + } + glfwMakeContextCurrent(window); + glbinding::initialize(glfwGetProcAddress); + return window; } int main() { - // Initialize GLFW and glbinding - GLFWwindow *window = init_glfw(); - if (!window) return -1; + // Initialize GLFW and glbinding + GLFWwindow *window = init_glfw(); + if (!window) return -1; - // We use a y-down coordinate system, see renderer_set_viewport_size() - Bone::setYDown(true); + // We use a y-down coordinate system, see renderer_set_viewport_size() + Bone::setYDown(true); - // Load the atlas and the skeleton data - GlTextureLoader textureLoader; - Atlas *atlas = new Atlas("data/spineboy-pma.atlas", &textureLoader); - SkeletonJson json(atlas); - SkeletonData *skeletonData = json.readSkeletonDataFile("data/spineboy-pro.json"); + // Load the atlas and the skeleton data + GlTextureLoader textureLoader; + Atlas *atlas = new Atlas("data/spineboy-pma.atlas", &textureLoader); + SkeletonJson json(atlas); + SkeletonData *skeletonData = json.readSkeletonDataFile("data/spineboy-pro.json"); - // Create a skeleton from the data, set the skeleton's position to the bottom center of - // the screen and scale it to make it smaller. - Skeleton skeleton(skeletonData); - skeleton.setPosition(width / 2, height - 100); - skeleton.setScaleX(0.3); - skeleton.setScaleY(0.3); + // Create a skeleton from the data, set the skeleton's position to the bottom center of + // the screen and scale it to make it smaller. + Skeleton skeleton(skeletonData); + skeleton.setPosition(width / 2, height - 100); + skeleton.setScaleX(0.3); + skeleton.setScaleY(0.3); - // Create an AnimationState to drive animations on the skeleton. Set the "portal" animation - // on track with index 0. - AnimationStateData animationStateData(skeletonData); - AnimationState animationState(&animationStateData); - animationState.setAnimation(0, "portal", true); + // Create an AnimationState to drive animations on the skeleton. Set the "portal" animation + // on track with index 0. + AnimationStateData animationStateData(skeletonData); + AnimationState animationState(&animationStateData); + animationState.setAnimation(0, "portal", true); - // Create the renderer and set the viewport size to match the window size. This sets up a - // pixel perfect orthogonal projection for 2D rendering. - renderer_t *renderer = renderer_create(); - renderer_set_viewport_size(renderer, width, height); + // Create the renderer and set the viewport size to match the window size. This sets up a + // pixel perfect orthogonal projection for 2D rendering. + renderer_t *renderer = renderer_create(); + renderer_set_viewport_size(renderer, width, height); - // Rendering loop - double lastTime = glfwGetTime(); - while (!glfwWindowShouldClose(window)) { - // Calculate the delta time in seconds - double currTime = glfwGetTime(); - float delta = currTime - lastTime; - lastTime = currTime; + // Rendering loop + double lastTime = glfwGetTime(); + while (!glfwWindowShouldClose(window)) { + // Calculate the delta time in seconds + double currTime = glfwGetTime(); + float delta = currTime - lastTime; + lastTime = currTime; - // Update and apply the animation state to the skeleton - animationState.update(delta); - animationState.apply(skeleton); + // Update and apply the animation state to the skeleton + animationState.update(delta); + animationState.apply(skeleton); - // Update the skeleton time (used for physics) - skeleton.update(delta); + // Update the skeleton time (used for physics) + skeleton.update(delta); - // Calculate the new pose - skeleton.updateWorldTransform(spine::Physics_Update); + // Calculate the new pose + skeleton.updateWorldTransform(spine::Physics_Update); - // Clear the screen - gl::glClear(gl::GL_COLOR_BUFFER_BIT); + // Clear the screen + gl::glClear(gl::GL_COLOR_BUFFER_BIT); - // Render the skeleton in its current pose - renderer_draw(renderer, &skeleton, true); + // Render the skeleton in its current pose + renderer_draw(renderer, &skeleton, true); - // Present the rendering results and poll for events - glfwSwapBuffers(window); - glfwPollEvents(); - } + // Present the rendering results and poll for events + glfwSwapBuffers(window); + glfwPollEvents(); + } - // Dispose everything - renderer_dispose(renderer); - delete skeletonData; - delete atlas; + // Dispose everything + renderer_dispose(renderer); + delete skeletonData; + delete atlas; - // Kill the window and GLFW - glfwTerminate(); - return 0; + // Kill the window and GLFW + glfwTerminate(); + return 0; } diff --git a/spine-glfw/src/spine-glfw.cpp b/spine-glfw/src/spine-glfw.cpp index 87aff98de..7adefcf91 100644 --- a/spine-glfw/src/spine-glfw.cpp +++ b/spine-glfw/src/spine-glfw.cpp @@ -9,231 +9,230 @@ using namespace spine; /// Set the default extension used for memory allocations and file I/O SpineExtension *spine::getDefaultExtension() { - return new spine::DefaultSpineExtension(); + return new spine::DefaultSpineExtension(); } /// A blend mode, see https://en.esotericsoftware.com/spine-slots#Blending /// Encodes the OpenGL source and destination blend function for both premultiplied and /// non-premultiplied alpha blending. typedef struct { - unsigned int source_color; - unsigned int source_color_pma; - unsigned int dest_color; - unsigned int source_alpha; + unsigned int source_color; + unsigned int source_color_pma; + unsigned int dest_color; + unsigned int source_alpha; } blend_mode_t; /// The 4 supported blend modes SPINE_BLEND_MODE_NORMAL, SPINE_BLEND_MODE_ADDITIVE, SPINE_BLEND_MODE_MULTIPLY, /// and SPINE_BLEND_MODE_SCREEN, expressed as OpenGL blend functions. blend_mode_t blend_modes[] = { - {(unsigned int)GL_SRC_ALPHA, (unsigned int)GL_ONE, (unsigned int)GL_ONE_MINUS_SRC_ALPHA, (unsigned int)GL_ONE}, - {(unsigned int)GL_SRC_ALPHA, (unsigned int)GL_ONE, (unsigned int)GL_ONE, (unsigned int)GL_ONE}, - {(unsigned int)GL_DST_COLOR, (unsigned int)GL_DST_COLOR, (unsigned int)GL_ONE_MINUS_SRC_ALPHA, (unsigned int)GL_ONE_MINUS_SRC_ALPHA}, - {(unsigned int)GL_ONE, (unsigned int)GL_ONE, (unsigned int)GL_ONE_MINUS_SRC_COLOR, (unsigned int)GL_ONE_MINUS_SRC_COLOR} -}; + {(unsigned int) GL_SRC_ALPHA, (unsigned int) GL_ONE, (unsigned int) GL_ONE_MINUS_SRC_ALPHA, (unsigned int) GL_ONE}, + {(unsigned int) GL_SRC_ALPHA, (unsigned int) GL_ONE, (unsigned int) GL_ONE, (unsigned int) GL_ONE}, + {(unsigned int) GL_DST_COLOR, (unsigned int) GL_DST_COLOR, (unsigned int) GL_ONE_MINUS_SRC_ALPHA, (unsigned int) GL_ONE_MINUS_SRC_ALPHA}, + {(unsigned int) GL_ONE, (unsigned int) GL_ONE, (unsigned int) GL_ONE_MINUS_SRC_COLOR, (unsigned int) GL_ONE_MINUS_SRC_COLOR}}; mesh_t *mesh_create() { - GLuint vao, vbo, ibo; - glGenVertexArrays(1, &vao); - glGenBuffers(1, &vbo); - glGenBuffers(1, &ibo); + GLuint vao, vbo, ibo; + glGenVertexArrays(1, &vao); + glGenBuffers(1, &vbo); + glGenBuffers(1, &ibo); - glBindVertexArray(vao); + glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (void*)offsetof(vertex_t, x)); - glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (void *) offsetof(vertex_t, x)); + glEnableVertexAttribArray(0); - glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(vertex_t), (void*)offsetof(vertex_t, color)); - glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(vertex_t), (void *) offsetof(vertex_t, color)); + glEnableVertexAttribArray(1); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (void*)offsetof(vertex_t, u)); - glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (void *) offsetof(vertex_t, u)); + glEnableVertexAttribArray(2); - glVertexAttribPointer(3, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(vertex_t), (void*)offsetof(vertex_t, darkColor)); - glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(vertex_t), (void *) offsetof(vertex_t, darkColor)); + glEnableVertexAttribArray(3); - glBindVertexArray(0); + glBindVertexArray(0); - auto *mesh = (mesh_t*)malloc(sizeof(mesh_t)); - mesh->vao = vao; - mesh->vbo = vbo; - mesh->num_vertices = 0; - mesh->ibo = ibo; - mesh->num_indices = 0; - return mesh; + auto *mesh = (mesh_t *) malloc(sizeof(mesh_t)); + mesh->vao = vao; + mesh->vbo = vbo; + mesh->num_vertices = 0; + mesh->ibo = ibo; + mesh->num_indices = 0; + return mesh; } void mesh_update(mesh_t *mesh, vertex_t *vertices, int num_vertices, uint16_t *indices, int num_indices) { - glBindVertexArray(mesh->vao); + glBindVertexArray(mesh->vao); - glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); - glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(num_vertices * sizeof(vertex_t)), vertices, GL_STATIC_DRAW); - mesh->num_vertices = num_vertices; - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->ibo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(num_indices * sizeof(uint16_t)), indices, GL_STATIC_DRAW); - mesh->num_indices = num_indices; + glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr) (num_vertices * sizeof(vertex_t)), vertices, GL_STATIC_DRAW); + mesh->num_vertices = num_vertices; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->ibo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr) (num_indices * sizeof(uint16_t)), indices, GL_STATIC_DRAW); + mesh->num_indices = num_indices; - glBindVertexArray(0); + glBindVertexArray(0); } void mesh_draw(mesh_t *mesh) { - glBindVertexArray(mesh->vao); - glDrawElements(GL_TRIANGLES, mesh->num_indices, GL_UNSIGNED_SHORT, nullptr); - glBindVertexArray(0); + glBindVertexArray(mesh->vao); + glDrawElements(GL_TRIANGLES, mesh->num_indices, GL_UNSIGNED_SHORT, nullptr); + glBindVertexArray(0); } void mesh_dispose(mesh_t *mesh) { - glDeleteBuffers(1, &mesh->vbo); - glDeleteBuffers(1, &mesh->ibo); - glDeleteVertexArrays(1, &mesh->vao); - free(mesh); + glDeleteBuffers(1, &mesh->vbo); + glDeleteBuffers(1, &mesh->ibo); + glDeleteVertexArrays(1, &mesh->vao); + free(mesh); } -GLuint compile_shader(const char* source, GLenum type) { - GLuint shader = glCreateShader(type); - glShaderSource(shader, 1, &source, nullptr); - glCompileShader(shader); +GLuint compile_shader(const char *source, GLenum type) { + GLuint shader = glCreateShader(type); + glShaderSource(shader, 1, &source, nullptr); + glCompileShader(shader); - GLint success; - glGetShaderiv(shader, GL_COMPILE_STATUS, &success); - if (!success) { - char infoLog[512]; - glGetShaderInfoLog(shader, 512, nullptr, infoLog); - printf("Error, shader compilation failed:\n%s\n", infoLog); - glDeleteShader(shader); - return 0; - } + GLint success; + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { + char infoLog[512]; + glGetShaderInfoLog(shader, 512, nullptr, infoLog); + printf("Error, shader compilation failed:\n%s\n", infoLog); + glDeleteShader(shader); + return 0; + } - return shader; + return shader; } -shader_t shader_create(const char* vertex_shader, const char* fragment_shader) { - shader_t program; +shader_t shader_create(const char *vertex_shader, const char *fragment_shader) { + shader_t program; - GLuint vertex_shader_id = compile_shader(vertex_shader, GL_VERTEX_SHADER); - GLuint fragment_shader_id = compile_shader(fragment_shader, GL_FRAGMENT_SHADER); - if (!vertex_shader_id || !fragment_shader_id) { - glDeleteShader(vertex_shader_id); - glDeleteShader(fragment_shader_id); - return 0; - } + GLuint vertex_shader_id = compile_shader(vertex_shader, GL_VERTEX_SHADER); + GLuint fragment_shader_id = compile_shader(fragment_shader, GL_FRAGMENT_SHADER); + if (!vertex_shader_id || !fragment_shader_id) { + glDeleteShader(vertex_shader_id); + glDeleteShader(fragment_shader_id); + return 0; + } - program = glCreateProgram(); - glAttachShader(program, vertex_shader_id); - glAttachShader(program, fragment_shader_id); - glLinkProgram(program); + program = glCreateProgram(); + glAttachShader(program, vertex_shader_id); + glAttachShader(program, fragment_shader_id); + glLinkProgram(program); - GLint success; - glGetProgramiv(program, GL_LINK_STATUS, &success); - if (!success) { - char infoLog[512]; - glGetProgramInfoLog(program, 512, nullptr, infoLog); - printf("Error, shader linking failed:\n%s\n", infoLog); - glDeleteProgram(program); - program = 0; - } - glDeleteShader(vertex_shader_id); - glDeleteShader(fragment_shader_id); - return program; + GLint success; + glGetProgramiv(program, GL_LINK_STATUS, &success); + if (!success) { + char infoLog[512]; + glGetProgramInfoLog(program, 512, nullptr, infoLog); + printf("Error, shader linking failed:\n%s\n", infoLog); + glDeleteProgram(program); + program = 0; + } + glDeleteShader(vertex_shader_id); + glDeleteShader(fragment_shader_id); + return program; } -void shader_set_matrix4(shader_t shader, const char* name, const float *matrix) { - shader_use(shader); - GLint location = glGetUniformLocation(shader, name); - glUniformMatrix4fv(location, 1, GL_FALSE, matrix); +void shader_set_matrix4(shader_t shader, const char *name, const float *matrix) { + shader_use(shader); + GLint location = glGetUniformLocation(shader, name); + glUniformMatrix4fv(location, 1, GL_FALSE, matrix); } -void shader_set_float(shader_t shader, const char* name, float value) { - shader_use(shader); - GLint location = glGetUniformLocation(shader, name); - glUniform1f(location, value); +void shader_set_float(shader_t shader, const char *name, float value) { + shader_use(shader); + GLint location = glGetUniformLocation(shader, name); + glUniform1f(location, value); } -void shader_set_int(shader_t shader, const char* name, int value) { - shader_use(shader); - GLint location = glGetUniformLocation(shader, name); - glUniform1i(location, value); +void shader_set_int(shader_t shader, const char *name, int value) { + shader_use(shader); + GLint location = glGetUniformLocation(shader, name); + glUniform1i(location, value); } void shader_use(shader_t program) { - glUseProgram(program); + glUseProgram(program); } void shader_dispose(shader_t program) { - glDeleteProgram(program); + glDeleteProgram(program); } texture_t texture_load(const char *file_path) { - int width, height, nrChannels; - unsigned char *data = stbi_load(file_path, &width, &height, &nrChannels, 0); - if (!data) { - printf("Failed to load texture\n"); - return 0; - } + int width, height, nrChannels; + unsigned char *data = stbi_load(file_path, &width, &height, &nrChannels, 0); + if (!data) { + printf("Failed to load texture\n"); + return 0; + } - GLenum format = GL_RGBA; - if (nrChannels == 1) - format = GL_RED; - else if (nrChannels == 3) - format = GL_RGB; - else if (nrChannels == 4) - format = GL_RGBA; + GLenum format = GL_RGBA; + if (nrChannels == 1) + format = GL_RED; + else if (nrChannels == 3) + format = GL_RGB; + else if (nrChannels == 4) + format = GL_RGBA; - texture_t texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); - glGenerateMipmap(GL_TEXTURE_2D); + texture_t texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - stbi_image_free(data); - return texture; + stbi_image_free(data); + return texture; } void texture_use(texture_t texture) { - glActiveTexture(GL_TEXTURE0); // Set active texture unit to 0 - glBindTexture(GL_TEXTURE_2D, texture); + glActiveTexture(GL_TEXTURE0);// Set active texture unit to 0 + glBindTexture(GL_TEXTURE_2D, texture); } void texture_dispose(texture_t texture) { - glDeleteTextures(1, &texture); + glDeleteTextures(1, &texture); } void matrix_ortho_projection(float *matrix, float width, float height) { - memset(matrix, 0, 16 * sizeof(float)); + memset(matrix, 0, 16 * sizeof(float)); - float left = 0.0f; - float right = width; - float bottom = height; - float top = 0.0f; - float near = -1.0f; - float far = 1.0f; + float left = 0.0f; + float right = width; + float bottom = height; + float top = 0.0f; + float near = -1.0f; + float far = 1.0f; - matrix[0] = 2.0f / (right - left); - matrix[5] = 2.0f / (top - bottom); - matrix[10] = -2.0f / (far - near); - matrix[12] = -(right + left) / (right - left); - matrix[13] = -(top + bottom) / (top - bottom); - matrix[14] = -(far + near) / (far - near); - matrix[15] = 1.0f; + matrix[0] = 2.0f / (right - left); + matrix[5] = 2.0f / (top - bottom); + matrix[10] = -2.0f / (far - near); + matrix[12] = -(right + left) / (right - left); + matrix[13] = -(top + bottom) / (top - bottom); + matrix[14] = -(far + near) / (far - near); + matrix[15] = 1.0f; } void GlTextureLoader::load(spine::AtlasPage &page, const spine::String &path) { - page.texture = (void *)(uintptr_t)texture_load(path.buffer()); + page.texture = (void *) (uintptr_t) texture_load(path.buffer()); } void GlTextureLoader::unload(void *texture) { - texture_dispose((texture_t)(uintptr_t)texture); + texture_dispose((texture_t) (uintptr_t) texture); } renderer_t *renderer_create() { - shader_t shader = shader_create(R"( + shader_t shader = shader_create(R"( #version 330 core layout (location = 0) in vec2 aPos; layout (location = 1) in vec4 aLightColor; @@ -252,7 +251,8 @@ renderer_t *renderer_create() { texCoord = aTexCoord; gl_Position = uMatrix * vec4(aPos, 0.0, 1.0); } - )", R"( + )", + R"( #version 330 core in vec4 lightColor; in vec4 darkColor; @@ -267,71 +267,71 @@ renderer_t *renderer_create() { fragColor.rgb = ((texColor.a - 1.0) * darkColor.a + 1.0 - texColor.rgb) * darkColor.rgb + texColor.rgb * lightColor.rgb; } )"); - if (!shader) return nullptr; - mesh_t *mesh = mesh_create(); - auto *renderer = (renderer_t*)malloc(sizeof(renderer_t)); - renderer->shader = shader; - renderer->mesh = mesh; - renderer->vertex_buffer_size = 0; - renderer->vertex_buffer = nullptr; - renderer->renderer = new SkeletonRenderer(); - return renderer; + if (!shader) return nullptr; + mesh_t *mesh = mesh_create(); + auto *renderer = (renderer_t *) malloc(sizeof(renderer_t)); + renderer->shader = shader; + renderer->mesh = mesh; + renderer->vertex_buffer_size = 0; + renderer->vertex_buffer = nullptr; + renderer->renderer = new SkeletonRenderer(); + return renderer; } void renderer_set_viewport_size(renderer_t *renderer, int width, int height) { - float matrix[16]; - matrix_ortho_projection(matrix, (float)width, (float)height); - shader_use(renderer->shader); - shader_set_matrix4(renderer->shader, "uMatrix", matrix); + float matrix[16]; + matrix_ortho_projection(matrix, (float) width, (float) height); + shader_use(renderer->shader); + shader_set_matrix4(renderer->shader, "uMatrix", matrix); } void renderer_draw(renderer_t *renderer, Skeleton *skeleton, bool premultipliedAlpha) { - shader_use(renderer->shader); - shader_set_int(renderer->shader, "uTexture", 0); - glEnable(GL_BLEND); + shader_use(renderer->shader); + shader_set_int(renderer->shader, "uTexture", 0); + glEnable(GL_BLEND); - RenderCommand *command = renderer->renderer->render(*skeleton); - while (command) { - int num_command_vertices = command->numVertices; - if (renderer->vertex_buffer_size < num_command_vertices) { - renderer->vertex_buffer_size = num_command_vertices; - free(renderer->vertex_buffer); - renderer->vertex_buffer = (vertex_t *)malloc(sizeof(vertex_t) * renderer->vertex_buffer_size); - } - float *positions = command->positions; - float *uvs = command->uvs; - int32_t *colors = command->colors; - int32_t *darkColors = command->darkColors; - for (int i = 0, j = 0; i < num_command_vertices; i++, j += 2) { - vertex_t *vertex = &renderer->vertex_buffer[i]; - vertex->x = positions[j]; - vertex->y = positions[j + 1]; - vertex->u = uvs[j]; - vertex->v = uvs[j+1]; - uint32_t color = colors[i]; - vertex->color = (color & 0xFF00FF00) | ((color & 0x00FF0000) >> 16) | ((color & 0x000000FF) << 16); - uint32_t darkColor = darkColors[i]; - vertex->darkColor = (darkColor & 0xFF00FF00) | ((darkColor & 0x00FF0000) >> 16) | ((darkColor & 0x000000FF) << 16); - } - int num_command_indices = command->numIndices; - uint16_t *indices = command->indices; - mesh_update(renderer->mesh, renderer->vertex_buffer, num_command_vertices, indices, num_command_indices); + RenderCommand *command = renderer->renderer->render(*skeleton); + while (command) { + int num_command_vertices = command->numVertices; + if (renderer->vertex_buffer_size < num_command_vertices) { + renderer->vertex_buffer_size = num_command_vertices; + free(renderer->vertex_buffer); + renderer->vertex_buffer = (vertex_t *) malloc(sizeof(vertex_t) * renderer->vertex_buffer_size); + } + float *positions = command->positions; + float *uvs = command->uvs; + int32_t *colors = command->colors; + int32_t *darkColors = command->darkColors; + for (int i = 0, j = 0; i < num_command_vertices; i++, j += 2) { + vertex_t *vertex = &renderer->vertex_buffer[i]; + vertex->x = positions[j]; + vertex->y = positions[j + 1]; + vertex->u = uvs[j]; + vertex->v = uvs[j + 1]; + uint32_t color = colors[i]; + vertex->color = (color & 0xFF00FF00) | ((color & 0x00FF0000) >> 16) | ((color & 0x000000FF) << 16); + uint32_t darkColor = darkColors[i]; + vertex->darkColor = (darkColor & 0xFF00FF00) | ((darkColor & 0x00FF0000) >> 16) | ((darkColor & 0x000000FF) << 16); + } + int num_command_indices = command->numIndices; + uint16_t *indices = command->indices; + mesh_update(renderer->mesh, renderer->vertex_buffer, num_command_vertices, indices, num_command_indices); - blend_mode_t blend_mode = blend_modes[command->blendMode]; - glBlendFuncSeparate(premultipliedAlpha ? (GLenum)blend_mode.source_color_pma : (GLenum)blend_mode.source_color, (GLenum)blend_mode.dest_color, (GLenum)blend_mode.source_alpha, (GLenum)blend_mode.dest_color); + blend_mode_t blend_mode = blend_modes[command->blendMode]; + glBlendFuncSeparate(premultipliedAlpha ? (GLenum) blend_mode.source_color_pma : (GLenum) blend_mode.source_color, (GLenum) blend_mode.dest_color, (GLenum) blend_mode.source_alpha, (GLenum) blend_mode.dest_color); - auto texture = (texture_t)(uintptr_t)command->texture; - texture_use(texture); + auto texture = (texture_t) (uintptr_t) command->texture; + texture_use(texture); - mesh_draw(renderer->mesh); - command = command->next; - } + mesh_draw(renderer->mesh); + command = command->next; + } } void renderer_dispose(renderer_t *renderer) { - shader_dispose(renderer->shader); - mesh_dispose(renderer->mesh); - free(renderer->vertex_buffer); - delete renderer->renderer; - free(renderer); + shader_dispose(renderer->shader); + mesh_dispose(renderer->mesh); + free(renderer->vertex_buffer); + delete renderer->renderer; + free(renderer); } \ No newline at end of file diff --git a/spine-glfw/src/spine-glfw.h b/spine-glfw/src/spine-glfw.h index 315cf91b7..94c2d0b63 100644 --- a/spine-glfw/src/spine-glfw.h +++ b/spine-glfw/src/spine-glfw.h @@ -5,20 +5,20 @@ /// A vertex of a mesh generated from a Spine skeleton struct vertex_t { - float x, y; - uint32_t color; - float u, v; - uint32_t darkColor; + float x, y; + uint32_t color; + float u, v; + uint32_t darkColor; }; /// A GPU-side mesh using OpenGL vertex arrays, vertex buffer, and /// indices buffer. typedef struct { - unsigned int vao; - unsigned int vbo; - int num_vertices; - unsigned int ibo; - int num_indices; + unsigned int vao; + unsigned int vbo; + int num_vertices; + unsigned int ibo; + int num_indices; } mesh_t; mesh_t *mesh_create(); @@ -33,13 +33,13 @@ typedef unsigned int shader_t; shader_t shader_create(const char *vertex_shader, const char *fragment_shader); /// Sets a uniform matrix by name -void shader_set_matrix4(shader_t program, const char* name, const float *matrix); +void shader_set_matrix4(shader_t program, const char *name, const float *matrix); /// Sets a uniform float by name -void shader_set_float(shader_t program, const char* name, float value); +void shader_set_float(shader_t program, const char *name, float value); /// Sets a uniform int by name -void shader_set_int(shader_t program, const char* name, int value); +void shader_set_int(shader_t program, const char *name, int value); /// Binds the shader void shader_use(shader_t shader); @@ -60,20 +60,20 @@ void texture_use(texture_t texture); void texture_dispose(texture_t texture); /// A TextureLoader implementation for OpenGL. Use this with spine::Atlas. -class GlTextureLoader: public spine::TextureLoader { +class GlTextureLoader : public spine::TextureLoader { public: - void load(spine::AtlasPage &page, const spine::String &path); - void unload(void *texture); + void load(spine::AtlasPage &page, const spine::String &path); + void unload(void *texture); }; /// Renderer capable of rendering a spine_skeleton_drawable, using a shader, a mesh, and a /// temporary CPU-side vertex buffer used to update the GPU-side mesh typedef struct { - shader_t shader; - mesh_t *mesh; - int vertex_buffer_size; - vertex_t *vertex_buffer; - spine::SkeletonRenderer *renderer; + shader_t shader; + mesh_t *mesh; + int vertex_buffer_size; + vertex_t *vertex_buffer; + spine::SkeletonRenderer *renderer; } renderer_t; /// Creates a new renderer diff --git a/spine-sdl/example/main.cpp b/spine-sdl/example/main.cpp index 2c0f70533..b01ed05a3 100644 --- a/spine-sdl/example/main.cpp +++ b/spine-sdl/example/main.cpp @@ -35,68 +35,68 @@ spine::DebugExtension dbgExtension(spine::SpineExtension::getInstance()); extern spine::SkeletonRenderer *skeletonRenderer; int main() { - spine::SpineExtension::setInstance(&dbgExtension); - { - if (SDL_Init(SDL_INIT_VIDEO)) { - printf("Error: %s", SDL_GetError()); - return -1; - } - SDL_Window *window = SDL_CreateWindow("Spine SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, - 0); - if (!window) { - printf("Error: %s", SDL_GetError()); - return -1; - } - SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); - if (!renderer) { - printf("Error: %s", SDL_GetError()); - return -1; - } + spine::SpineExtension::setInstance(&dbgExtension); + { + if (SDL_Init(SDL_INIT_VIDEO)) { + printf("Error: %s", SDL_GetError()); + return -1; + } + SDL_Window *window = SDL_CreateWindow("Spine SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, + 0); + if (!window) { + printf("Error: %s", SDL_GetError()); + return -1; + } + SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + if (!renderer) { + printf("Error: %s", SDL_GetError()); + return -1; + } - spine::SDLTextureLoader textureLoader(renderer); - 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(); - drawable.animationState->setAnimation(0, "portal", true); - drawable.animationState->addAnimation(0, "run", true, 0); - drawable.update(0, spine::Physics_Update); + spine::SDLTextureLoader textureLoader(renderer); + 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(); + drawable.animationState->setAnimation(0, "portal", true); + drawable.animationState->addAnimation(0, "run", true, 0); + drawable.update(0, spine::Physics_Update); - bool quit = false; - uint64_t lastFrameTime = SDL_GetPerformanceCounter(); - while (!quit) { - SDL_Event event; - while (SDL_PollEvent(&event) != 0) { - if (event.type == SDL_QUIT) { - quit = true; - break; - } - } + bool quit = false; + uint64_t lastFrameTime = SDL_GetPerformanceCounter(); + while (!quit) { + SDL_Event event; + while (SDL_PollEvent(&event) != 0) { + if (event.type == SDL_QUIT) { + quit = true; + break; + } + } - SDL_SetRenderDrawColor(renderer, 94, 93, 96, 255); - SDL_RenderClear(renderer); + SDL_SetRenderDrawColor(renderer, 94, 93, 96, 255); + SDL_RenderClear(renderer); - uint64_t now = SDL_GetPerformanceCounter(); - double deltaTime = (now - lastFrameTime) / (double) SDL_GetPerformanceFrequency(); - lastFrameTime = now; + uint64_t now = SDL_GetPerformanceCounter(); + double deltaTime = (now - lastFrameTime) / (double) SDL_GetPerformanceFrequency(); + lastFrameTime = now; - drawable.update(deltaTime, spine::Physics_Update); - drawable.draw(renderer); + drawable.update(deltaTime, spine::Physics_Update); + drawable.draw(renderer); - SDL_RenderPresent(renderer); - } + SDL_RenderPresent(renderer); + } - SDL_DestroyWindow(window); - SDL_Quit(); - delete skeletonData; - } - delete skeletonRenderer; - dbgExtension.reportLeaks(); + SDL_DestroyWindow(window); + SDL_Quit(); + delete skeletonData; + } + delete skeletonRenderer; + dbgExtension.reportLeaks(); return 0; } diff --git a/spine-sdl/src/spine-sdl-cpp.cpp b/spine-sdl/src/spine-sdl-cpp.cpp index fc34c9196..c944e66fd 100644 --- a/spine-sdl/src/spine-sdl-cpp.cpp +++ b/spine-sdl/src/spine-sdl-cpp.cpp @@ -62,76 +62,76 @@ void SkeletonDrawable::update(float delta, Physics physics) { } inline void toSDLColor(uint32_t color, SDL_Color *sdlColor) { - sdlColor->a = (color >> 24) & 0xFF; - sdlColor->r = (color >> 16) & 0xFF; - sdlColor->g = (color >> 8) & 0xFF; - sdlColor->b = color & 0xFF; + sdlColor->a = (color >> 24) & 0xFF; + sdlColor->r = (color >> 16) & 0xFF; + sdlColor->g = (color >> 8) & 0xFF; + sdlColor->b = color & 0xFF; } void SkeletonDrawable::draw(SDL_Renderer *renderer) { - if (!skeletonRenderer) skeletonRenderer = new (__FILE__, __LINE__) SkeletonRenderer(); - RenderCommand *command = skeletonRenderer->render(*skeleton); - while(command) { - float *positions = command->positions; - float *uvs = command->uvs; - uint32_t *colors = command->colors; - sdlVertices.clear(); - for (int ii = 0; ii < command->numVertices << 1; ii += 2) { - SDL_Vertex sdlVertex; - sdlVertex.position.x = positions[ii]; - sdlVertex.position.y = positions[ii + 1]; - sdlVertex.tex_coord.x = uvs[ii]; - sdlVertex.tex_coord.y = uvs[ii + 1]; - toSDLColor(colors[ii >> 1], &sdlVertex.color); - sdlVertices.add(sdlVertex); - } - sdlIndices.clear(); - uint16_t *indices = command->indices; - for (int ii = 0; ii < command->numIndices; ii++) - sdlIndices.add(indices[ii]); + if (!skeletonRenderer) skeletonRenderer = new (__FILE__, __LINE__) SkeletonRenderer(); + RenderCommand *command = skeletonRenderer->render(*skeleton); + while (command) { + float *positions = command->positions; + float *uvs = command->uvs; + uint32_t *colors = command->colors; + sdlVertices.clear(); + for (int ii = 0; ii < command->numVertices << 1; ii += 2) { + SDL_Vertex sdlVertex; + sdlVertex.position.x = positions[ii]; + sdlVertex.position.y = positions[ii + 1]; + sdlVertex.tex_coord.x = uvs[ii]; + sdlVertex.tex_coord.y = uvs[ii + 1]; + toSDLColor(colors[ii >> 1], &sdlVertex.color); + sdlVertices.add(sdlVertex); + } + sdlIndices.clear(); + uint16_t *indices = command->indices; + for (int ii = 0; ii < command->numIndices; ii++) + sdlIndices.add(indices[ii]); - BlendMode blendMode = command->blendMode; - SDL_Texture *texture = (SDL_Texture *)command->texture; - if (!usePremultipliedAlpha) { - switch (blendMode) { - 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 { - SDL_BlendMode target; - switch (blendMode) { - 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; - } - } + BlendMode blendMode = command->blendMode; + SDL_Texture *texture = (SDL_Texture *) command->texture; + if (!usePremultipliedAlpha) { + switch (blendMode) { + 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 { + SDL_BlendMode target; + switch (blendMode) { + 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; + } + } - SDL_RenderGeometry(renderer, texture, sdlVertices.buffer(), sdlVertices.size(), sdlIndices.buffer(), - command->numIndices); - command = command->next; - } + SDL_RenderGeometry(renderer, texture, sdlVertices.buffer(), sdlVertices.size(), sdlIndices.buffer(), + command->numIndices); + command = command->next; + } } SDL_Texture *loadTexture(SDL_Renderer *renderer, const String &path) { diff --git a/spine-sfml/cpp/src/spine/spine-sfml.cpp b/spine-sfml/cpp/src/spine/spine-sfml.cpp index 030fd773c..7a8c5d4c8 100644 --- a/spine-sfml/cpp/src/spine/spine-sfml.cpp +++ b/spine-sfml/cpp/src/spine/spine-sfml.cpp @@ -37,103 +37,102 @@ using namespace sf; using namespace spine; sf::BlendMode blendModes[] = { - sf::BlendMode(sf::BlendMode::SrcAlpha, sf::BlendMode::OneMinusSrcAlpha), - sf::BlendMode(sf::BlendMode::SrcAlpha, sf::BlendMode::One), - sf::BlendMode(sf::BlendMode::DstColor, sf::BlendMode::OneMinusSrcAlpha), - sf::BlendMode(sf::BlendMode::One, sf::BlendMode::OneMinusSrcColor) -}; + sf::BlendMode(sf::BlendMode::SrcAlpha, sf::BlendMode::OneMinusSrcAlpha), + sf::BlendMode(sf::BlendMode::SrcAlpha, sf::BlendMode::One), + sf::BlendMode(sf::BlendMode::DstColor, sf::BlendMode::OneMinusSrcAlpha), + sf::BlendMode(sf::BlendMode::One, sf::BlendMode::OneMinusSrcColor)}; sf::BlendMode blendModesPma[] = { - sf::BlendMode(sf::BlendMode::One, sf::BlendMode::OneMinusSrcAlpha), - sf::BlendMode(sf::BlendMode::One, sf::BlendMode::One), - sf::BlendMode(sf::BlendMode::DstColor, sf::BlendMode::OneMinusSrcAlpha), - sf::BlendMode(sf::BlendMode::One, sf::BlendMode::OneMinusSrcColor), + sf::BlendMode(sf::BlendMode::One, sf::BlendMode::OneMinusSrcAlpha), + sf::BlendMode(sf::BlendMode::One, sf::BlendMode::One), + sf::BlendMode(sf::BlendMode::DstColor, sf::BlendMode::OneMinusSrcAlpha), + sf::BlendMode(sf::BlendMode::One, sf::BlendMode::OneMinusSrcColor), }; SkeletonRenderer *skeletonRenderer = nullptr; SkeletonDrawable::SkeletonDrawable(SkeletonData *skeletonData, AnimationStateData *stateData) : timeScale(1), - usePremultipliedAlpha(false), - vertexArray(new VertexArray(Triangles, skeletonData->getBones().size() * 4)) { - Bone::setYDown(true); - skeleton = new (__FILE__, __LINE__) Skeleton(skeletonData); - ownsAnimationStateData = stateData == 0; - if (ownsAnimationStateData) stateData = new (__FILE__, __LINE__) AnimationStateData(skeletonData); - state = new (__FILE__, __LINE__) AnimationState(stateData); + usePremultipliedAlpha(false), + vertexArray(new VertexArray(Triangles, skeletonData->getBones().size() * 4)) { + Bone::setYDown(true); + skeleton = new (__FILE__, __LINE__) Skeleton(skeletonData); + ownsAnimationStateData = stateData == 0; + if (ownsAnimationStateData) stateData = new (__FILE__, __LINE__) AnimationStateData(skeletonData); + state = new (__FILE__, __LINE__) AnimationState(stateData); } SkeletonDrawable::~SkeletonDrawable() { - delete vertexArray; - if (ownsAnimationStateData) delete state->getData(); - delete state; - delete skeleton; + delete vertexArray; + if (ownsAnimationStateData) delete state->getData(); + delete state; + delete skeleton; } void SkeletonDrawable::update(float deltaTime, Physics physics) { - state->update(deltaTime * timeScale); - state->apply(*skeleton); - skeleton->update(deltaTime * timeScale); - skeleton->updateWorldTransform(physics); + state->update(deltaTime * timeScale); + state->apply(*skeleton); + skeleton->update(deltaTime * timeScale); + skeleton->updateWorldTransform(physics); } inline void toSFMLColor(uint32_t color, sf::Color *sfmlColor) { - sfmlColor->a = (color >> 24) & 0xFF; - sfmlColor->r = (color >> 16) & 0xFF; - sfmlColor->g = (color >> 8) & 0xFF; - sfmlColor->b = color & 0xFF; + sfmlColor->a = (color >> 24) & 0xFF; + sfmlColor->r = (color >> 16) & 0xFF; + sfmlColor->g = (color >> 8) & 0xFF; + sfmlColor->b = color & 0xFF; } void SkeletonDrawable::draw(RenderTarget &target, RenderStates states) const { - states.texture = NULL; - vertexArray->clear(); + states.texture = NULL; + vertexArray->clear(); - if (!skeletonRenderer) skeletonRenderer = new (__FILE__, __LINE__) SkeletonRenderer(); - RenderCommand *command = skeletonRenderer->render(*skeleton); - while (command) { - Vertex vertex; - float *positions = command->positions; - float *uvs = command->uvs; - uint32_t *colors = command->colors; - uint16_t *indices = command->indices; - Texture *texture = (Texture *)command->texture; - Vector2u size = texture->getSize(); - for (int i = 0, n = command->numIndices; i < n; ++i) { - int ii = indices[i]; - int index = ii << 1; - vertex.position.x = positions[index]; - vertex.position.y = positions[index + 1]; - vertex.texCoords.x = uvs[index] * size.x; - vertex.texCoords.y = uvs[index + 1] * size.y; - toSFMLColor(colors[ii], &vertex.color); - vertexArray->append(vertex); - } - BlendMode blendMode = command->blendMode; - states.blendMode = usePremultipliedAlpha ? blendModesPma[blendMode] : blendModes[blendMode]; - states.texture = texture; - target.draw(*vertexArray, states); - vertexArray->clear(); + if (!skeletonRenderer) skeletonRenderer = new (__FILE__, __LINE__) SkeletonRenderer(); + RenderCommand *command = skeletonRenderer->render(*skeleton); + while (command) { + Vertex vertex; + float *positions = command->positions; + float *uvs = command->uvs; + uint32_t *colors = command->colors; + uint16_t *indices = command->indices; + Texture *texture = (Texture *) command->texture; + Vector2u size = texture->getSize(); + for (int i = 0, n = command->numIndices; i < n; ++i) { + int ii = indices[i]; + int index = ii << 1; + vertex.position.x = positions[index]; + vertex.position.y = positions[index + 1]; + vertex.texCoords.x = uvs[index] * size.x; + vertex.texCoords.y = uvs[index + 1] * size.y; + toSFMLColor(colors[ii], &vertex.color); + vertexArray->append(vertex); + } + BlendMode blendMode = command->blendMode; + states.blendMode = usePremultipliedAlpha ? blendModesPma[blendMode] : blendModes[blendMode]; + states.texture = texture; + target.draw(*vertexArray, states); + vertexArray->clear(); - command = command->next; - } + command = command->next; + } } void SFMLTextureLoader::load(AtlasPage &page, const String &path) { - Texture *texture = new Texture(); - if (!texture->loadFromFile(path.buffer())) return; + Texture *texture = new Texture(); + if (!texture->loadFromFile(path.buffer())) return; - if (page.magFilter == TextureFilter_Linear) texture->setSmooth(true); - if (page.uWrap == TextureWrap_Repeat && page.vWrap == TextureWrap_Repeat) texture->setRepeated(true); + if (page.magFilter == TextureFilter_Linear) texture->setSmooth(true); + if (page.uWrap == TextureWrap_Repeat && page.vWrap == TextureWrap_Repeat) texture->setRepeated(true); - page.texture = texture; - Vector2u size = texture->getSize(); - page.width = size.x; - page.height = size.y; + page.texture = texture; + Vector2u size = texture->getSize(); + page.width = size.x; + page.height = size.y; } void SFMLTextureLoader::unload(void *texture) { - delete (Texture *) texture; + delete (Texture *) texture; } SpineExtension *spine::getDefaultExtension() { - return new DefaultSpineExtension(); + return new DefaultSpineExtension(); } diff --git a/spine-sfml/cpp/src/spine/spine-sfml.h b/spine-sfml/cpp/src/spine/spine-sfml.h index acaa6bebd..f3be526a8 100644 --- a/spine-sfml/cpp/src/spine/spine-sfml.h +++ b/spine-sfml/cpp/src/spine/spine-sfml.h @@ -62,7 +62,7 @@ namespace spine { private: bool ownsAnimationStateData; mutable bool usePremultipliedAlpha; - sf::VertexArray *vertexArray; + sf::VertexArray *vertexArray; }; class SFMLTextureLoader : public TextureLoader {