Pārlūkot izejas kodu

[flutter] Implement blend modes, see #2200

Mario Zechner 2 gadi atpakaļ
vecāks
revīzija
714edf501c

+ 9 - 9
spine-flutter/example/pubspec.lock

@@ -21,10 +21,10 @@ packages:
     dependency: transitive
     description:
       name: collection
-      sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
+      sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
       url: "https://pub.dev"
     source: hosted
-    version: "1.17.0"
+    version: "1.17.1"
   crypto:
     dependency: transitive
     description:
@@ -98,10 +98,10 @@ packages:
     dependency: transitive
     description:
       name: js
-      sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
       url: "https://pub.dev"
     source: hosted
-    version: "0.6.5"
+    version: "0.6.7"
   lints:
     dependency: transitive
     description:
@@ -122,10 +122,10 @@ packages:
     dependency: transitive
     description:
       name: meta
-      sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
+      sha256: "12307e7f0605ce3da64cf0db90e5fcab0869f3ca03f76be6bb2991ce0a55e82b"
       url: "https://pub.dev"
     source: hosted
-    version: "1.8.0"
+    version: "1.9.0"
   ordered_set:
     dependency: transitive
     description:
@@ -169,7 +169,7 @@ packages:
       path: ".."
       relative: true
     source: path
-    version: "4.2.11"
+    version: "4.2.12"
   string_scanner:
     dependency: transitive
     description:
@@ -211,5 +211,5 @@ packages:
     source: hosted
     version: "0.7.4"
 sdks:
-  dart: ">=2.18.0 <3.0.0"
-  flutter: ">=3.7.3"
+  dart: ">=2.19.0 <4.0.0"
+  flutter: ">=3.7.6"

+ 23 - 12
spine-flutter/lib/spine_flutter.dart

@@ -102,7 +102,7 @@ class Vec2 {
 class Atlas {
   final spine_atlas _atlas;
   final List<Image> atlasPages;
-  final List<Paint> atlasPagePaints;
+  final List<Map<BlendMode, Paint>> atlasPagePaints;
   bool _disposed;
 
   Atlas._(this._atlas, this.atlasPages, this.atlasPagePaints) : _disposed = false;
@@ -122,7 +122,7 @@ class Atlas {
 
     final atlasDir = path.dirname(atlasFileName);
     List<Image> atlasPages = [];
-    List<Paint> atlasPagePaints = [];
+    List<Map<BlendMode, Paint>> atlasPagePaints = [];
     final numImagePaths = _bindings.spine_atlas_get_num_image_paths(atlas);
     for (int i = 0; i < numImagePaths; i++) {
       final Pointer<Utf8> atlasPageFile = _bindings.spine_atlas_get_image_path(atlas, i).cast();
@@ -132,9 +132,16 @@ class Atlas {
       final FrameInfo frameInfo = await codec.getNextFrame();
       final Image image = frameInfo.image;
       atlasPages.add(image);
-      atlasPagePaints.add(Paint()
-        ..shader = ImageShader(image, TileMode.clamp, TileMode.clamp, Matrix4.identity().storage, filterQuality: FilterQuality.high)
-        ..isAntiAlias = true);
+      Map<BlendMode, Paint> paints = {};
+      for (final blendMode in BlendMode.values) {
+        paints[blendMode] = Paint()
+          ..shader = ImageShader(image, TileMode.clamp, TileMode.clamp, Matrix4
+              .identity()
+              .storage, filterQuality: FilterQuality.high)
+          ..isAntiAlias = true
+          ..blendMode = blendMode.canvasBlendMode;
+      }
+      atlasPagePaints.add(paints);
     }
 
     return Atlas._(atlas, atlasPages, atlasPagePaints);
@@ -540,14 +547,15 @@ class SkeletonData {
 /// Determines how images are blended with existing pixels when drawn. See [Blending](http://esotericsoftware.com/spine-slots#Blending) in
 /// the Spine User Guide.
 enum BlendMode {
-  normal(0),
-  additive(1),
-  multiply(2),
-  screen(3);
+  normal(0, rendering.BlendMode.srcOver),
+  additive(1, rendering.BlendMode.plus),
+  multiply(2, rendering.BlendMode.modulate),
+  screen(3, rendering.BlendMode.screen);
 
   final int value;
+  final rendering.BlendMode canvasBlendMode;
 
-  const BlendMode(this.value);
+  const BlendMode(this.value, this.canvasBlendMode);
 }
 
 /// Determines how a bone inherits world transforms from parent bones. See [Transform inheritance](esotericsoftware.com/spine-bones#Transform-inheritance)
@@ -3968,11 +3976,12 @@ class SkeletonDrawable {
 
   /// Renders the skeleton drawable's current pose to the given [canvas]. Does not perform any
   /// scaling or fitting.
-  void renderToCanvas(Canvas canvas) {
+  List<RenderCommand> renderToCanvas(Canvas canvas) {
     var commands = render();
     for (final cmd in commands) {
-      canvas.drawVertices(cmd.vertices, rendering.BlendMode.modulate, atlas.atlasPagePaints[cmd.atlasPageIndex]);
+      canvas.drawVertices(cmd.vertices, rendering.BlendMode.modulate, atlas.atlasPagePaints[cmd.atlasPageIndex][cmd.blendMode]!);
     }
+    return commands;
   }
 
   /// Renders the skeleton drawable's current pose to a [PictureRecorder] with the given [width] and [height].
@@ -4041,6 +4050,7 @@ class RenderCommand {
   late final Float32List uvs;
   late final Int32List colors;
   late final Uint16List indices;
+  late final BlendMode blendMode;
 
   RenderCommand._(spine_render_command nativeCmd, double pageWidth, double pageHeight) {
     atlasPageIndex = _bindings.spine_render_command_get_atlas_page(nativeCmd);
@@ -4054,6 +4064,7 @@ class RenderCommand {
     }
     colors = _bindings.spine_render_command_get_colors(nativeCmd).asTypedList(numVertices);
     indices = _bindings.spine_render_command_get_indices(nativeCmd).asTypedList(numIndices);
+    blendMode = BlendMode.values[_bindings.spine_render_command_get_blend_mode(nativeCmd)];
 
     if (!kIsWeb) {
       // We pass the native data as views directly to Vertices.raw. According to the sources, the data

+ 1 - 4
spine-flutter/lib/spine_widget.dart

@@ -670,10 +670,7 @@ class _SpineRenderObject extends RenderBox {
     _setCanvasTransform(canvas, offset);
 
     _controller.onBeforePaint?.call(_controller, canvas);
-    var commands = _skeletonDrawable.render();
-    for (final cmd in commands) {
-      canvas.drawVertices(cmd.vertices, rendering.BlendMode.modulate, _skeletonDrawable.atlas.atlasPagePaints[cmd.atlasPageIndex]);
-    }
+    final commands = _skeletonDrawable.renderToCanvas(canvas);
     _controller.onAfterPaint?.call(_controller, canvas, commands);
 
     canvas.restore();

+ 2 - 2
spine-flutter/pubspec.yaml

@@ -1,6 +1,6 @@
 name: spine_flutter
 description: The official Spine Flutter Runtime to load, display and interact with Spine animations.
-version: 4.2.11
+version: 4.2.12
 homepage: https://esotericsoftware.com
 repository: https://github.com/esotericsoftware/spine-runtimes
 issue_tracker: https://github.com/esotericsoftware/spine-runtimes/issues
@@ -8,7 +8,7 @@ documentation: https://esotericsoftware.com/spine-flutter
 
 environment:
   sdk: ">=2.17.6 <3.0.0"
-  flutter: ">=3.7.3"
+  flutter: ">=3.7.6"
 
 dependencies:
   flutter: