Another AI answer. The native spine plugin would be a good reference, thank you @ depilz for the great work. Next I will look into setting up building the rive-runtime for Solar2D plugin
Yes, the texture handling in the Spine plugin for Solar2D is conceptually similar to what I described for the Graphics Extensions (Gfxe) plugin and a hypothetical Rive plugin. Let’s break down the parallels and differences:
1. Texture Workflow Similarities
a. Texture Creation & Sharing
-
Spine Plugin:
- Uses OpenGL to render Spine skeletal animations into textures.
- Shares GPU textures with Solar2D via native plugin code (e.g.,
CoronaExternalTextureCallbacks). - Example code from
spinePlugin:// Create OpenGL texture for Spine atlas glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(..., atlas->getPixels()); - Solar2D Lua binds to this texture via
graphics.newTexture().
-
Gfxe/Rive Analog:
- Both would use similar OpenGL/Vulkan texture workflows.
- For Rive, replace
atlas->getPixels()with Rive’s renderer output (e.g.,rive::Renderer::draw()).
b. Dynamic Texture Updates
-
Spine Plugin:
- Updates textures on every frame by rendering Spine animations into OpenGL textures.
- Syncs with Solar2D’s frame loop via
enterFramelisteners.
-
Gfxe/Rive:
- Gfxe updates textures by pushing decoded image data (e.g., PNG/JPEG) via
CoronaExternalPushTexture. - For Rive, you’d render frames into a GPU texture (shared or copied) and update it dynamically.
- Gfxe updates textures by pushing decoded image data (e.g., PNG/JPEG) via
2. Key Differences
a. Rendering Backend
- Spine: Uses its own OpenGL renderer for skeletal animations.
- Rive: Uses Rive’s renderer (OpenGL/Metal/Vulkan) for vector animations.
- Gfxe: Focuses on static image decoding (no runtime animation).
b. Data Flow
-
Spine:
- Requires a
.atlasfile and texture atlas (prebaked). - Animations are driven by Spine’s runtime (C++/Java).
- Requires a
-
Rive:
- Uses
.rivfiles with vector paths and state machines. - Requires runtime interpolation of vector data (more dynamic than Spine’s skeletal system).
- Uses
3. Example Workflow Comparison
Spine Plugin (Reference)
- Load Assets:
// spinePlugin.cpp spine::Atlas* atlas = new spine::Atlas("skeleton.atlas", new MyTextureLoader()); spine::SkeletonJson json(atlas); spine::SkeletonData* skeletonData = json.readSkeletonDataFile("skeleton.json"); - Render Frame:
void update(lua_State* L) { spineRenderer->draw(); // Renders to OpenGL texture CoronaExternalPushTexture(L, textureCallbacks); // Update Solar2D texture }
Rive Plugin (Hypothetical)
- Load Rive File:
// rivePlugin.cpp rive::File* file = rive::File::open("animation.riv"); rive::Artboard* artboard = file->artboard(); rive::Renderer* renderer = artboard->renderer(); - Render Frame:
void update(lua_State* L) { renderer->draw(); // Renders to OpenGL/Metal/Vulkan texture CoronaExternalPushTexture(L, textureCallbacks); // Share with Solar2D }
4. Critical Code Snippets
Texture Callbacks (Shared Between Plugins)
// Similar in Spine, Gfxe, and Rive plugins
CoronaExternalTextureCallbacks textureCallbacks;
textureCallbacks.size = sizeof(textureCallbacks);
textureCallbacks.getWidth = [](void* context) { return width; };
textureCallbacks.getHeight = [](void* context) { return height; };
textureCallbacks.onRequestBitmap = [](void* context, CoronaBitmap* bitmap) {
// Copy pixel data (Gfxe) or bind GPU texture (Spine/Rive)
};
Solar2D Lua Integration
-- Spine, Gfxe, or Rive would expose similar APIs
local spine = require "plugin.spine"
local rive = require "plugin.rive"
local spineActor = spine.newActor("skeleton.json", "atlas.atlas")
local riveAnimation = rive.newAnimation("animation.riv")
5. Takeaways
- Shared Pattern: All plugins (Spine, Gfxe, Rive) use native code to generate/update textures and expose them to Solar2D via
CoronaExternalTextureCallbacks. - Rendering Differences:
- Spine: Prebaked atlas + skeletal deformation.
- Rive: Vector paths + runtime interpolation.
- Performance: Direct GPU texture sharing (Spine/Rive) is more efficient than CPU pixel copying (Gfxe).
For a Rive plugin, you’d adapt the Spine plugin’s OpenGL texture workflow but replace Spine’s renderer with Rive’s. The Graphics Extensions Plugin is also a useful reference for handling dynamic pixel data.