spine-sdl 运行时文档

Licensing

将官方的Spine Runtime整合到你的应用程序前请务必先阅读 Spine 运行时许可证.

开始使用

spine-sdl 是一个基于 C 和 C++ 的运行时, 用于通过 SDL 加载、操作和渲染 Spine skeleton.

spine-sdl 需要 SDL 2.0.18+ 版本, 并支持除双色着色(tint)外的全部 Spine 功能.

安装

spine-sdl 运行时以 C 和 C++ API 的形式提供. 两种 API 都基于 spine-cspine-cpp 运行时. 请注意, spine-c 依赖于 spine-cpp, 因此无论你选择使用哪种 API, 两者都是必需的.

使用 CMake 集成(推荐)

将 spine-sdl 集成到你的项目中最简单的方法是通过 CMake FetchContent:

cmake
cmake_minimum_required(VERSION 3.16)
project(MySpineProject)

include(FetchContent)
FetchContent_Declare(
   spine-sdl
   GIT_REPOSITORY https://github.com/esotericsoftware/spine-runtimes.git
   GIT_TAG 4.3
   SOURCE_SUBDIR spine-sdl
)
FetchContent_MakeAvailable(spine-sdl)

# Create your executable
add_executable(MyApp main.cpp)

# For C API
target_link_libraries(MyApp spine-sdl-c)

# For C++ API
target_link_libraries(MyApp spine-sdl-cpp)

这将自动获取并构建 spine-sdl 及其所有依赖项(spine-c、spine-cpp 和 SDL).

手动集成

如果你更喜欢手动集成:

  1. 使用 git 下载 Spine Runtimes 源码(git clone https://github.com/esotericsoftware/spine-runtimes)或下载为 zip 文件.
  2. 将所需的源文件添加到你的项目中:
    • 对于 C API: 添加 spine-cpp/srcspine-c/srcspine-sdl/src/spine-sdl-c.c 中的源文件
    • 对于 C++ API: 添加 spine-cpp/srcspine-c/srcspine-sdl/src/spine-sdl-cpp.cpp 中的源文件

  3. 添加包含目录: spine-cpp/includespine-c/includespine-sdl/src
  4. 链接到 SDL2

在你的 C 或 C++ 代码中, 包含以下任一头文件以访问 spine-sdl API:

C++
// C API
#include <spine-sdl-c.h>

// C++ API
#include <spine-sdl-cpp.h>

注意: spine-sdl 需要自 SDL 2.0.18 起可用的 SDL_RenderGeometry API. 早期版本的 SDL 与 spine-sdl 不兼容.

示例

spine-sdl 示例可在 Windows、Linux 和 Mac OS X 上运行. 对于基于 spine-c 的示例, 请参见 example/main.c;对于 spine-cpp 示例, 请参见 example/main.cpp.

Windows

  1. 安装 Visual Studio Community. 确保安装 C++ 和 CMake 支持.
  2. 使用 git 下载 Spine Runtimes 存储库(git clone https://github.com/esotericsoftware/spine-runtimes)或下载为 zip 文件.
  3. 打开 Visual Studio Community, 然后通过 Visual Studio Community 启动器中的 打开本地文件夹 按钮打开 spine-sdl/ 文件夹.
  4. 等待 CMake 完成, 然后选择 spine-sdl-c-example.exespine-sdl-cpp-example.exe 作为启动项目并开始调试.

Linux

  1. 安装依赖项:

    bash
    sudo apt-get install cmake ninja-build # Ubuntu/Debian
    # 或适用于你的发行版的等效命令
  2. 克隆存储库: git clone https://github.com/esotericsoftware/spine-runtimes

  3. 构建并运行:

    bash
    cd spine-runtimes/spine-sdl
    ./build.sh
    ./build/debug/spine-sdl-c-example   # Run C example
    ./build/debug/spine-sdl-cpp-example # Run C++ example

macOS

  1. 安装 Xcode

  2. 安装 Homebrew

  3. 安装依赖项:

    bash
    brew install cmake ninja
  4. 克隆存储库: git clone https://github.com/esotericsoftware/spine-runtimes

  5. 构建并运行:

    bash
    cd spine-runtimes/spine-sdl
    ./build.sh
    ./build/debug/spine-sdl-c-example   # Run C example
    ./build/debug/spine-sdl-cpp-example # Run C++ example

使用 spine-sdl

spine-sdl 运行时支持使用 SDL 播放和操作 Spine 创建的动画. spine-sdl 运行时提供 C 和 C++ 两种实现, 分别基于通用的 spine-cspine-cpp 运行时. 它基于 SDL API 添加了加载和渲染实现.

请参阅 Spine 运行时指南 以获取 Spine 运行时架构的详细概述, 以及 spine-cspine-cpp 文档以了解用于播放和操作 Spine 动画的核心 API 信息.

为SDL导出资产

请按照 Spine 用户指南中的说明操作:

  1. 导出 skeleton & animation data
  2. 导出包含skeleton图片的texture atlases

导出skeleton数据和skeleton texture atlas将生成以下文件:

  1. skeleton-name.jsonskeleton-name.skel, 包含skeleton和动画数据.
  2. skeleton-name.atlas, 包含texture atlas的信息.
  3. 一个或多个 .png 文件, 每个文件代表texture atlas中的一页, 包含skeletons使用的打包图片.

注意: spine-sdl 运行时不支持双色着色.

加载 Spine skeletons

spine-sdl 运行时使用 SDL_Renderer API 来显示skeleton. 在从导出的文件加载skeletons之前, 必须先创建一个 SDL_Renderer:

C++
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

使用 C API 加载

使用 spine-c API 加载需要texture加载回调和手动文件读取:

C++
// Global renderer for texture loading callbacks
static SDL_Renderer *g_renderer;

// Texture loading callbacks
void *load_texture_callback(const char *path) {
   extern void *load_texture(const char *path, SDL_Renderer *renderer);
   return load_texture(path, g_renderer);
}

void unload_texture_callback(void *texture) {
   SDL_DestroyTexture((SDL_Texture*)texture);
}

// Set the global renderer
g_renderer = renderer;

// Read atlas file into memory
int atlas_length;
char *atlas_data = read_file("data/spineboy-pma.atlas", &atlas_length);

// Load atlas with callbacks
spine_atlas_result atlas_result = spine_atlas_load_callback(
   atlas_data, "data/", load_texture_callback, unload_texture_callback);
spine_atlas atlas = spine_atlas_result_get_atlas(atlas_result);

// Read skeleton file into memory
int skeleton_length;
char *skeleton_data = read_file("data/spineboy-pro.json", &skeleton_length);

// Load skeleton data
spine_skeleton_data_result skeleton_result = spine_skeleton_data_load_json(
   atlas, skeleton_data, "data/");
spine_skeleton_data skeleton_data_handle = spine_skeleton_data_result_get_data(skeleton_result);

// Free file data
free(atlas_data);
free(skeleton_data);

使用 C++ API 加载

对于 C++ API, 需要一个 SDLTextureLoader:

C++
// C++ API
spine::SDLTextureLoader textureLoader(renderer);
spine::Atlas atlas("data/spineboy-pma.atlas", &textureLoader);
spine::SkeletonJson json(atlas);
spine::SkeletonData *skeletonData = json.readSkeletonDataFile("data/spineboy-pro.json");

加载的skeleton数据和atlas可以且应该在skeletons实例之间共享, 以减少内存消耗并启用共享相同atlas数据的skeleton的批量渲染.

渲染skeleton

spine-sdl 提供了直接与skeleton和skeleton可绘制对象一起工作的简单渲染函数.

C API

C++
// Create skeleton drawable (combines skeleton + animation state)
spine_skeleton_drawable drawable = spine_skeleton_drawable_create(skeleton_data_handle);
spine_skeleton skeleton = spine_skeleton_drawable_get_skeleton(drawable);
spine_animation_state animation_state = spine_skeleton_drawable_get_animation_state(drawable);

// Setup skeleton
spine_skeleton_set_position(skeleton, 400, 500);
spine_skeleton_set_scale(skeleton, 0.5f, 0.5f);
spine_skeleton_setup_pose(skeleton);

// Setup animation
spine_animation_state_set_animation_1(animation_state, 0, "portal", false);
spine_animation_state_add_animation_1(animation_state, 0, "run", true, 0);

// Update and render (in your main loop)
spine_skeleton_drawable_update(drawable, deltaTime);
spine_sdl_draw(drawable, renderer, true); // true for premultiplied alpha

// Or draw skeleton directly without drawable
spine_sdl_draw_skeleton(skeleton, renderer, true);

// Cleanup
spine_skeleton_drawable_dispose(drawable);
spine_skeleton_data_dispose(skeleton_data_handle);
spine_atlas_dispose(atlas);
spine_skeleton_data_result_dispose(skeleton_result);
spine_atlas_result_dispose(atlas_result);

C++ API

C++
// Create skeleton and animation state
spine::Skeleton skeleton(*skeletonData);
spine::AnimationStateData animationStateData(*skeletonData);
spine::AnimationState animationState(animationStateData);

// Setup skeleton
skeleton.setPosition(400, 500);
skeleton.setupPose();

// Setup animation
animationState.setAnimation(0, "portal", false);
animationState.addAnimation(0, "run", true, 0);

// Update and render (in your main loop)
animationState.update(deltaTime);
animationState.apply(skeleton);
skeleton.update(deltaTime);
skeleton.updateWorldTransform(spine::Physics_Update);

// Draw using the simple SDL_draw function
spine::SDL_draw(skeleton, renderer, true); // true for premultiplied alpha

// Cleanup
delete skeletonData;
delete &atlas;

请参阅 spine-cspine-cpp 文档以获取有关操作skeleton和动画状态的 API 的更多信息.

清理

当你不再需要skeleton和atlas数据时, 释放它们的内存:

C API

C++
// Dispose skeleton drawable and data
spine_skeleton_drawable_dispose(drawable);
spine_skeleton_data_dispose(skeleton_data_handle);
spine_atlas_dispose(atlas);
spine_skeleton_data_result_dispose(skeleton_result);
spine_atlas_result_dispose(atlas_result);

// Free manually allocated file data
free(atlas_data);
free(skeleton_data);

C++ API

C++
// C++ API cleanup
delete skeletonData;
delete &atlas; // If allocated with new

注意: 释放skeleton数据和atlas实例将通过texture加载器自动处置任何关联的 SDL texture.