196 lines
5.4 KiB
C#
196 lines
5.4 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Godot;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool]
|
|
[GlobalClass]
|
|
public partial class TextureDilate:SequenceAction
|
|
{
|
|
[Export]
|
|
public SubViewport viewport;
|
|
|
|
[Export]
|
|
public Texture2D target;
|
|
|
|
[Export( PropertyHint.Range, "0,15" ) ]
|
|
public int steps = 0;
|
|
|
|
[Export]
|
|
public bool useSRGB = true;
|
|
|
|
[ExportToolButton( "Grab Texture")]
|
|
public Callable GrabButton => Callable.From(
|
|
() =>
|
|
{
|
|
Grab( useSRGB, true );
|
|
}
|
|
);
|
|
|
|
public void SetDilationRadius( int pixelSize )
|
|
{
|
|
steps = ( Mathf.RoundToInt( MathX.Exponent( 2, pixelSize ) ) - 1 );
|
|
}
|
|
|
|
public void SetDilationRadius( Vector2 size )
|
|
{
|
|
SetDilationRadius( Mathf.RoundToInt( Mathf.Max( size.X, size.Y ) ) );
|
|
}
|
|
|
|
public async Task<Texture2D> Grab( bool srgb, bool alpha, bool mipmaps = false )
|
|
{
|
|
var updateMode = viewport.RenderTargetUpdateMode;
|
|
|
|
if ( updateMode != SubViewport.UpdateMode.Always )
|
|
{
|
|
viewport.RenderTargetUpdateMode = SubViewport.UpdateMode.Always;
|
|
await this.RequestNextFrame();
|
|
viewport.RenderTargetUpdateMode = updateMode;
|
|
}
|
|
|
|
var viewPortFormat = RDTextureFormats.GetDataFormat( viewport );
|
|
var viewPortData = viewport.GetTexture().GetImage().GetData();
|
|
var viewPortSize = viewport.Size;
|
|
|
|
this.LogInfo( "Grabbed viewport context", viewPortFormat, viewPortSize );
|
|
|
|
this.LogInfo( "Creating context" );
|
|
var ctx = RDContext.Local();
|
|
ctx.computeSize = viewPortSize;
|
|
// ctx.messageLogLevel = Messages.GetLevel( MessageType.Verbose );
|
|
|
|
|
|
this.LogInfo( "Creating textures" );
|
|
|
|
var bufferTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
|
var bufferTexture2 = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
|
var resultTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
|
var initTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
|
|
|
|
|
var inputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
|
inputTexture.SetData( viewPortData );
|
|
|
|
this.LogInfo( "Creating graph" );
|
|
|
|
var graph = CreateGraph( ctx, inputTexture, initTexture, bufferTexture, bufferTexture2, resultTexture );
|
|
|
|
this.LogInfo( "Process graph" );
|
|
graph.ProcessForView();
|
|
|
|
ctx.SubmitAndSync();
|
|
|
|
var exportTexture = resultTexture;
|
|
var width = exportTexture.width;
|
|
var height = exportTexture.height;
|
|
var format = exportTexture.imageFormat;
|
|
|
|
var data = exportTexture.GetData();
|
|
|
|
ctx.SubmitAndSync();
|
|
await this.RequestNextFrame();
|
|
|
|
|
|
this.LogInfo( "Copying texture:", format );
|
|
|
|
var image = Image.CreateFromData( width, height, false, format, data );
|
|
|
|
var gammaConversion = 0;
|
|
|
|
if ( RenderingDevice.DataFormat.R16G16B16A16Sfloat == viewPortFormat && srgb )
|
|
{
|
|
gammaConversion = -1;
|
|
}
|
|
|
|
var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ), gammaConversion );
|
|
var texture = buffer.CreateImageTexture( alpha, mipmaps );
|
|
|
|
|
|
|
|
target = texture;
|
|
|
|
ctx.CleanUp();
|
|
|
|
return texture;
|
|
|
|
}
|
|
|
|
RDGraph CreateGraph( RDContext ctx, RDTexture it, RDTexture ii, RDTexture b1, RDTexture b2, RDTexture rt )
|
|
{
|
|
var graph = new RDGraph( ctx );
|
|
|
|
var viewTexture = CEG_BufferTexture.From( graph, it );
|
|
var initTexture = CEG_BufferTexture.From( graph, ii );
|
|
var bufferTexture = CEG_BufferTexture.From( graph, b1 );
|
|
var bufferTexture2 = CEG_BufferTexture.From( graph, b2 );
|
|
var resultTexture = CEG_BufferTexture.From( graph, rt );
|
|
|
|
ctx.Verbose( "Init Texture:", initTexture.GetTexture() );
|
|
|
|
var jfaInititialize = new CEG_JFAInitialize( graph );
|
|
jfaInititialize.constants.Set( 0.95f );
|
|
|
|
var copy = new CEG_Copy( graph );
|
|
var jfaIterate = new CEG_JFAIterate( graph );
|
|
var jfaAssign = new CEG_JFAAssign( graph );
|
|
var repeat = new RG_SwapRepeat( graph );
|
|
|
|
var numSteps = steps == 0 ?
|
|
( Mathf.RoundToInt( MathX.Exponent( 2, it.maxDimension ) ) - 1 ) :
|
|
steps;
|
|
|
|
// RJLog.Log( "Steps >>", numSteps, Mathf.Pow( 2, numSteps ) );
|
|
|
|
repeat.repeats = numSteps;
|
|
repeat.imageProcessor = jfaIterate;
|
|
|
|
repeat.onPreProcess =
|
|
( index ) =>
|
|
{
|
|
var stepIndex = numSteps - ( index + 1 );
|
|
var jump = Mathf.RoundToInt( Mathf.Pow( 2, stepIndex ) );
|
|
|
|
jfaIterate.constants.Set(
|
|
jump
|
|
);
|
|
};
|
|
|
|
|
|
|
|
graph.InitializeNodes();
|
|
|
|
|
|
jfaInititialize.SetTextureSlotInputs( viewTexture, initTexture );
|
|
copy.SetTextureSlotInputs( initTexture, bufferTexture );
|
|
repeat.SetTextureSlotInputs( bufferTexture, bufferTexture2 );
|
|
|
|
var assignTexture = steps % 2 == 0 ? bufferTexture : bufferTexture2;
|
|
jfaAssign.SetTextureSlotInputs( assignTexture, resultTexture );
|
|
jfaAssign.AddTextureSlotInput( viewTexture );
|
|
|
|
graph.SetProcessOrder(
|
|
viewTexture,
|
|
bufferTexture,
|
|
bufferTexture2,
|
|
initTexture,
|
|
resultTexture,
|
|
jfaInititialize,
|
|
copy,
|
|
repeat,
|
|
jfaAssign
|
|
);
|
|
|
|
|
|
|
|
return graph;
|
|
}
|
|
|
|
|
|
}
|
|
} |