ModifyImageRightNode.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. using PixiEditor.ChangeableDocument.Changeables.Graph.Context;
  2. using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
  3. using PixiEditor.ChangeableDocument.Rendering;
  4. using Drawie.Backend.Core;
  5. using Drawie.Backend.Core.Shaders.Generation;
  6. using Drawie.Backend.Core.Shaders.Generation.Expressions;
  7. using Drawie.Backend.Core.Surfaces;
  8. using Drawie.Backend.Core.Surfaces.PaintImpl;
  9. using Drawie.Numerics;
  10. namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
  11. [NodeInfo("ModifyImageRight")]
  12. [PairNode(typeof(ModifyImageLeftNode), "ModifyImageZone")]
  13. public class ModifyImageRightNode : RenderNode, IPairNode, ICustomShaderNode
  14. {
  15. public Guid OtherNode { get; set; }
  16. private Paint drawingPaint = new Paint() { BlendMode = BlendMode.SrcOver };
  17. public FuncInputProperty<Float2> Coordinate { get; }
  18. public FuncInputProperty<Half4> Color { get; }
  19. private string _lastSksl;
  20. private VecI? size;
  21. protected override bool ExecuteOnlyOnCacheChange => true;
  22. public ModifyImageRightNode()
  23. {
  24. Coordinate = CreateFuncInput(nameof(Coordinate), "UV", new Float2("coords"));
  25. Color = CreateFuncInput(nameof(Color), "COLOR", new Half4(""));
  26. }
  27. protected override void OnExecute(RenderContext renderContext)
  28. {
  29. base.OnExecute(renderContext);
  30. if (OtherNode == null || OtherNode == default)
  31. {
  32. OtherNode = FindStartNode()?.Id ?? default;
  33. if (OtherNode == null || OtherNode == default)
  34. {
  35. return;
  36. }
  37. }
  38. var startNode = FindStartNode();
  39. if (startNode == null)
  40. {
  41. return;
  42. }
  43. OtherNode = startNode.Id;
  44. if (startNode.Image.Value is not { Size: var imgSize })
  45. {
  46. return;
  47. }
  48. size = imgSize;
  49. ShaderBuilder builder = new(size.Value);
  50. FuncContext context = new(renderContext, builder);
  51. if (Coordinate.Connection != null)
  52. {
  53. var coordinate = Coordinate.Value(context);
  54. if (string.IsNullOrEmpty(coordinate.VariableName))
  55. {
  56. builder.SetConstant(context.SamplePosition, coordinate);
  57. }
  58. else
  59. {
  60. builder.Set(context.SamplePosition, coordinate);
  61. }
  62. }
  63. else
  64. {
  65. var constCoords = Coordinate.NonOverridenValue(FuncContext.NoContext);
  66. constCoords.VariableName = "constCords";
  67. builder.AddUniform(constCoords.VariableName, constCoords.ConstantValue);
  68. builder.Set(context.SamplePosition, constCoords);
  69. }
  70. if (Color.Connection != null)
  71. {
  72. builder.ReturnVar(Color.Value(context));
  73. }
  74. else
  75. {
  76. Half4 color = Color.NonOverridenValue(FuncContext.NoContext);
  77. color.VariableName = "color";
  78. builder.AddUniform(color.VariableName, color.ConstantValue);
  79. builder.ReturnVar(color);
  80. }
  81. string sksl = builder.ToSkSl();
  82. if (sksl != _lastSksl)
  83. {
  84. _lastSksl = sksl;
  85. drawingPaint?.Shader?.Dispose();
  86. drawingPaint.Shader = builder.BuildShader();
  87. }
  88. else
  89. {
  90. drawingPaint.Shader = drawingPaint.Shader.WithUpdatedUniforms(builder.Uniforms);
  91. }
  92. builder.Dispose();
  93. }
  94. protected override void OnPaint(RenderContext renderContext, DrawingSurface targetSurface)
  95. {
  96. if (size == null)
  97. {
  98. return;
  99. }
  100. targetSurface.Canvas.DrawRect(0, 0, size.Value.X, size.Value.Y, drawingPaint);
  101. }
  102. public override RectD? GetPreviewBounds(int frame, string elementToRenderName = "")
  103. {
  104. var startNode = FindStartNode();
  105. if (startNode != null)
  106. {
  107. return startNode.GetPreviewBounds(frame, elementToRenderName);
  108. }
  109. return null;
  110. }
  111. public override bool RenderPreview(DrawingSurface renderOn, RenderContext context, string elementToRenderName)
  112. {
  113. var startNode = FindStartNode();
  114. if (drawingPaint != null && startNode != null && startNode.Image.Value != null)
  115. {
  116. renderOn.Canvas.DrawRect(0, 0, startNode.Image.Value.Size.X, startNode.Image.Value.Size.Y, drawingPaint);
  117. return true;
  118. }
  119. return false;
  120. }
  121. public override void Dispose()
  122. {
  123. base.Dispose();
  124. drawingPaint?.Dispose();
  125. }
  126. private ModifyImageLeftNode FindStartNode()
  127. {
  128. ModifyImageLeftNode startNode = null;
  129. TraverseBackwards(node =>
  130. {
  131. if (node is ModifyImageLeftNode leftNode)
  132. {
  133. startNode = leftNode;
  134. return false;
  135. }
  136. return true;
  137. });
  138. return startNode;
  139. }
  140. public override Node CreateCopy() => new ModifyImageRightNode();
  141. }