using System.Collections; using System.Collections.Generic; using Godot; using System; namespace Rokojori { public enum TextureCombinerBlendMode { Normal, Add, Multiply, Screen, Overlay, HardLight, SoftLight } public class TextureCombinerBlendModeAlgorithm { public static void Blend( TextureCombinerBlendMode blendMode, int x, int y, int w, int h, float topOpacity, TextureCombinerBuffer bottom, TextureCombinerBuffer top, TextureCombinerBuffer output ) { if ( TextureCombinerBlendMode.Normal == blendMode ) { BlendMode( ColorX.Blend, x, y, w, h, topOpacity, bottom, top, output ); } else if ( TextureCombinerBlendMode.Add == blendMode ) { BlendMode( ColorX.BlendAdd, x, y, w, h, topOpacity, bottom, top, output ); } else if ( TextureCombinerBlendMode.Multiply == blendMode ) { BlendMode( ColorX.BlendMultiply, x, y, w, h, topOpacity, bottom, top, output ); } else if ( TextureCombinerBlendMode.Screen == blendMode ) { BlendMode( ColorX.BlendScreen, x, y, w, h, topOpacity, bottom, top, output ); } else if ( TextureCombinerBlendMode.Overlay == blendMode ) { BlendMode( ColorX.BlendOverlay, x, y, w, h, topOpacity, bottom, top, output ); } else if ( TextureCombinerBlendMode.HardLight == blendMode ) { BlendMode( ColorX.BlendHardLight, x, y, w, h, topOpacity, bottom, top, output ); } else if ( TextureCombinerBlendMode.SoftLight == blendMode ) { BlendMode( ColorX.BlendSoftLight, x, y, w, h, topOpacity, bottom, top, output ); } } static void BlendMode( System.Func blender, int x, int y, int w, int h, float topOpacity, TextureCombinerBuffer bottom, TextureCombinerBuffer top, TextureCombinerBuffer output ) { for ( int i = 0; i < w; i++ ) { var rx = x + i; for ( int j = 0; j < h; j++ ) { var ry = y + j; var index = output.ComputeIndexFromPosition( rx, ry ); var topColor = top.GetIndexed( index ); var bottomColor = bottom.GetIndexed( index ); var outputColor = blender( bottomColor, topColor ); outputColor = bottomColor.Blend( outputColor.FadeAlpha( topOpacity ) ); output.SetIndexed( index, outputColor ); } } } public static void BlendMasked( TextureCombinerBlendMode blendMode, int x, int y, int w, int h, float topOpacity, TextureCombinerBuffer mask, TextureCombinerBuffer bottom, TextureCombinerBuffer top, TextureCombinerBuffer output ) { if ( TextureCombinerBlendMode.Normal == blendMode ) { BlendModeMasked( ColorX.Blend, x, y, w, h, topOpacity, mask, bottom, top, output ); } else if ( TextureCombinerBlendMode.Add == blendMode ) { BlendModeMasked( ColorX.BlendAdd, x, y, w, h, topOpacity, mask, bottom, top, output ); } else if ( TextureCombinerBlendMode.Multiply == blendMode ) { BlendModeMasked( ColorX.BlendMultiply, x, y, w, h, topOpacity, mask, bottom, top, output ); } else if ( TextureCombinerBlendMode.Screen == blendMode ) { BlendModeMasked( ColorX.BlendScreen, x, y, w, h, topOpacity, mask, bottom, top, output ); } else if ( TextureCombinerBlendMode.Overlay == blendMode ) { BlendModeMasked( ColorX.BlendOverlay, x, y, w, h, topOpacity, mask, bottom, top, output ); } else if ( TextureCombinerBlendMode.HardLight == blendMode ) { BlendModeMasked( ColorX.BlendHardLight, x, y, w, h, topOpacity, mask, bottom, top, output ); } else if ( TextureCombinerBlendMode.SoftLight == blendMode ) { BlendModeMasked( ColorX.BlendSoftLight, x, y, w, h, topOpacity, mask, bottom, top, output ); } } static void BlendModeMasked( System.Func blender, int x, int y, int w, int h, float topOpacity, TextureCombinerBuffer mask, TextureCombinerBuffer bottom, TextureCombinerBuffer top, TextureCombinerBuffer output ) { for ( int i = 0; i < w; i++ ) { var rx = x + i; for ( int j = 0; j < h; j++ ) { var ry = y + j; var index = output.ComputeIndexFromPosition( rx, ry ); var topColor = top.GetIndexed( index ); var bottomColor = bottom.GetIndexed( index ); var outputColor = blender( bottomColor, topColor ); var maskOpacity = mask.GetIndexed( index ); outputColor = bottomColor.Blend( outputColor.FadeAlpha( topOpacity * maskOpacity.R ) ); output.SetIndexed( index, outputColor ); } } } } }