184 lines
5.0 KiB
C#
184 lines
5.0 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;
|
||
|
|
||
|
[ExportToolButton( "Grab Texture")]
|
||
|
public Callable GrabButton => Callable.From(
|
||
|
() =>
|
||
|
{
|
||
|
Grab();
|
||
|
}
|
||
|
);
|
||
|
|
||
|
public async Task<Texture2D> Grab()
|
||
|
{
|
||
|
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 )
|
||
|
{
|
||
|
gammaConversion = -1;
|
||
|
}
|
||
|
|
||
|
var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ), gammaConversion );
|
||
|
var texture = buffer.CreateImageTexture();
|
||
|
|
||
|
|
||
|
|
||
|
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.5f );
|
||
|
|
||
|
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 ) );
|
||
|
|
||
|
this.LogInfo( "Jump:", jump );
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|