diff --git a/SpineViewer/MainForm.cs b/SpineViewer/MainForm.cs index 4314cf3..f475582 100644 --- a/SpineViewer/MainForm.cs +++ b/SpineViewer/MainForm.cs @@ -12,7 +12,7 @@ using SpineViewer.Exporter; namespace SpineViewer { - public partial class MainForm : Form + internal partial class MainForm : Form { private Logger logger = LogManager.GetCurrentClassLogger(); @@ -29,6 +29,19 @@ namespace SpineViewer toolStripMenuItem_ExportMp4.Tag = ExportType.MP4; toolStripMenuItem_ExportMov.Tag = ExportType.MOV; toolStripMenuItem_ExportWebm.Tag = ExportType.WebM; + + // 执行一些初始化工作 + try + { + Spine.Shader.Init(); + } + catch (Exception ex) + { + logger.Error(ex.ToString()); + logger.Error("Failed to load fragment shader"); + MessageBox.Warn("Fragment shader 加载失败,预乘Alpha通道属性失效"); + } + } /// diff --git a/SpineViewer/Spine/Implementations/Spine/Spine21.cs b/SpineViewer/Spine/Implementations/Spine/Spine21.cs index ccb40cb..a078c4b 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine21.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine21.cs @@ -331,7 +331,7 @@ namespace SpineViewer.Spine.Implementations.Spine if (vertexArray.VertexCount > 0) { if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; @@ -380,7 +380,7 @@ namespace SpineViewer.Spine.Implementations.Spine } if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; //clipping.ClipEnd(); diff --git a/SpineViewer/Spine/Implementations/Spine/Spine36.cs b/SpineViewer/Spine/Implementations/Spine/Spine36.cs index f42fc0f..4d6b99f 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine36.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine36.cs @@ -288,7 +288,7 @@ namespace SpineViewer.Spine.Implementations.Spine if (vertexArray.VertexCount > 0) { if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; @@ -338,7 +338,7 @@ namespace SpineViewer.Spine.Implementations.Spine clipping.ClipEnd(); if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; diff --git a/SpineViewer/Spine/Implementations/Spine/Spine37.cs b/SpineViewer/Spine/Implementations/Spine/Spine37.cs index 446454b..a675dc2 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine37.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine37.cs @@ -262,7 +262,7 @@ namespace SpineViewer.Spine.Implementations.Spine { // XXX: 实测不用设置 sampler2D 的值也正确 if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; @@ -312,7 +312,7 @@ namespace SpineViewer.Spine.Implementations.Spine clipping.ClipEnd(); if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; diff --git a/SpineViewer/Spine/Implementations/Spine/Spine38.cs b/SpineViewer/Spine/Implementations/Spine/Spine38.cs index 796dd3a..9273122 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine38.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine38.cs @@ -268,7 +268,7 @@ namespace SpineViewer.Spine.Implementations.Spine { // XXX: 实测不用设置 sampler2D 的值也正确 if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; @@ -318,7 +318,7 @@ namespace SpineViewer.Spine.Implementations.Spine clipping.ClipEnd(); if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; diff --git a/SpineViewer/Spine/Implementations/Spine/Spine40.cs b/SpineViewer/Spine/Implementations/Spine/Spine40.cs index 70b61bb..6566c56 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine40.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine40.cs @@ -264,7 +264,7 @@ namespace SpineViewer.Spine.Implementations.Spine { // XXX: 实测不用设置 sampler2D 的值也正确 if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; @@ -314,7 +314,7 @@ namespace SpineViewer.Spine.Implementations.Spine clipping.ClipEnd(); if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; diff --git a/SpineViewer/Spine/Implementations/Spine/Spine41.cs b/SpineViewer/Spine/Implementations/Spine/Spine41.cs index 3ce9dce..2175f4d 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine41.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine41.cs @@ -264,7 +264,7 @@ namespace SpineViewer.Spine.Implementations.Spine { // XXX: 实测不用设置 sampler2D 的值也正确 if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; @@ -314,7 +314,7 @@ namespace SpineViewer.Spine.Implementations.Spine clipping.ClipEnd(); if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; diff --git a/SpineViewer/Spine/Implementations/Spine/Spine42.cs b/SpineViewer/Spine/Implementations/Spine/Spine42.cs index b88ca44..dc77014 100644 --- a/SpineViewer/Spine/Implementations/Spine/Spine42.cs +++ b/SpineViewer/Spine/Implementations/Spine/Spine42.cs @@ -264,7 +264,7 @@ namespace SpineViewer.Spine.Implementations.Spine { // XXX: 实测不用设置 sampler2D 的值也正确 if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; @@ -314,7 +314,7 @@ namespace SpineViewer.Spine.Implementations.Spine clipping.ClipEnd(); if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive)) - states.Shader = FragmentShader; + states.Shader = Shader.FragmentShader; else states.Shader = null; diff --git a/SpineViewer/Spine/Shader.cs b/SpineViewer/Spine/Shader.cs new file mode 100644 index 0000000..fd3f206 --- /dev/null +++ b/SpineViewer/Spine/Shader.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SpineViewer.Spine +{ + public static class Shader + { + /// + /// 用于解决 PMA 和渐变动画问题的片段着色器 + /// + private const string FRAGMENT_SHADER = ( + "uniform sampler2D t;" + + "void main() { vec4 p = texture2D(t, gl_TexCoord[0].xy);" + + "if (p.a > 0) p.rgb /= max(max(max(p.r, p.g), p.b), p.a);" + + "gl_FragColor = gl_Color * p; }" + ); + + /// + /// 针对预乘 Alpha 通道的片段着色器 + /// + public static SFML.Graphics.Shader? FragmentShader { get; private set; } + + /// + /// 加载 Shader, 可能会存在异常导致着色器加载失败 + /// + /// + public static void Init() + { + FragmentShader = SFML.Graphics.Shader.FromString(null, null, FRAGMENT_SHADER); + } + } +} diff --git a/SpineViewer/Spine/Spine.cs b/SpineViewer/Spine/Spine.cs index 8ba7333..60fae32 100644 --- a/SpineViewer/Spine/Spine.cs +++ b/SpineViewer/Spine/Spine.cs @@ -48,41 +48,6 @@ namespace SpineViewer.Spine /// public const float SCALE_MIN = 0.001f; - /// - /// 用于解决 PMA 和渐变动画问题的片段着色器 - /// - private const string FRAGMENT_SHADER = ( - "uniform sampler2D t;" + - "void main() { vec4 p = texture2D(t, gl_TexCoord[0].xy);" + - "if (p.a > 0) p.rgb /= max(max(max(p.r, p.g), p.b), p.a);" + - "gl_FragColor = gl_Color * p; }" - ); - - /// - /// 用于解决 PMA 和渐变动画问题的片段着色器 - /// - protected static readonly SFML.Graphics.Shader? FragmentShader = null; - - /// - /// 静态构造函数 - /// - static Spine() - { - // 加载 FragmentShader - try - { - FragmentShader = SFML.Graphics.Shader.FromString(null, null, FRAGMENT_SHADER); - } - catch (Exception ex) - { - FragmentShader = null; - var logger = NLog.LogManager.GetCurrentClassLogger(); - logger.Error(ex.ToString()); - logger.Error("Failed to load fragment shader"); - MessageBox.Warn("Fragment shader 加载失败,预乘Alpha通道属性失效"); // TODO: 去除对窗体的调用 - } - } - /// /// 尝试检测骨骼文件版本 ///