rj-action-library/Runtime/Rendering/TextureAttributes/TextureAttributes.cs

178 lines
3.2 KiB
C#

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<System.Action<Image>> _updates = new List<System.Action<Image>>();
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<Image> action )
{
_updates.Add( action );
}
public void Flush()
{
_updates.ForEach( u => u( image ) );
_updates.Clear();
texture.Update( image );
}
}
}