using Godot; using Rokojori; using System.Collections.Generic; namespace Rokojori { [Tool] [GlobalClass] public partial class TextureAttributes:Node { public enum Size { _16, _32, _64, _128, _256, _512, _1024, _2048 } public enum Channel { Red, Green, Blue, Alpha } [Export] public Size sizeType =Size._64; [Export] public Image image; [Export] public Image.Format format = Image.Format.Rgb8; [Export] public ImageTexture texture; [Export] public Color fillColor; List> _updates = new List>(); public int size => _size; int _size = -1; [Export] public bool autoUpdate = true; [ExportToolButton( "Create") ] public Callable createButton => Callable.From( ()=>{ Create(); } ); [ExportGroup( "Testing" )] [Export] public int testIndex; [Export] public Color allValue = new Color( 0, 0, 0 ); [Export] public Color testValue = new Color( 1, 1, 1 ); [ExportToolButton( "Test") ] public Callable testButton => Callable.From( ()=>{ Test(); } ); public void Test() { UpdateSize(); image.Fill( allValue ); var testUV = GetUV( testIndex ); this.LogInfo( "index", testIndex, "uv", testUV, "value:", testValue ); image.SetPixelv( testUV, testValue ); texture.Update( image ); } public override void _Process( double delta ) { if ( ! autoUpdate ) { return; } if ( _updates.Count > 0 ) { UpdateSize(); Flush(); } } void UpdateSize() { _size = Mathf.RoundToInt( Mathf.Pow( 2, 4 + (int)(sizeType) ) ); } public void Create() { UpdateSize(); image = Image.CreateEmpty( _size, _size, false, format ); image.Fill( new Color( 0, 0, 0, 0 ) ); texture = ImageTexture.CreateFromImage( image ); } public Vector2I GetUV( int index ) { return new Vector2I( index % _size, index / _size ); } public void SetColor( int index, Color value ) { Update( ( Image i ) => { var uv = GetUV( index ); i.SetPixelv( uv, value ); } ); } public void SetChannel( int index, float value, Channel channel ) { Update( ( Image i ) => { var uv = GetUV( index ); var currentValue = i.GetPixelv( uv ); if ( channel == Channel.Red ) { currentValue.R = value; } else if ( channel == Channel.Green ) { currentValue.G = value; } else if ( channel == Channel.Blue ) { currentValue.B = value; } else if ( channel == Channel.Alpha ) { currentValue.A = value; } i.SetPixelv( uv, currentValue ); } ); } public void Update( System.Action action ) { _updates.Add( action ); } public void Flush() { _updates.ForEach( u => u( image ) ); _updates.Clear(); texture.Update( image ); } } }