using System.Collections; using System.Collections.Generic; using Godot; using System; using System.Linq; namespace Rokojori { [Tool] [GlobalClass] public partial class GrabTexture2:Action { [Export] public SubViewport viewport; [Export] public Texture2D target; [Export] public MeshInstance3D meshInstance3D; [Export( PropertyHint.Range, "0,1" ) ] public float intensity; [Export( PropertyHint.Range, "0,100" ) ] public float noise; [Export( PropertyHint.Range, "1,100" ) ] public float kernelOffset; [Export( PropertyHint.Range, "1,50" ) ] public float kernelRadius; [ExportToolButton( "Grab Texture")] public Callable GrabButton => Callable.From( () => { Grab(); } ); async void 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( "Creating context" ); var ctx = RDContext.Local(); ctx.computeSize = viewPortSize; ctx.messageLogLevel = Messages.GetLevel( MessageType.Verbose ); this.LogInfo( "Creating textures" ); var outputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat ); this.LogInfo( "Usage", RDTextureFormats.UsageInfo( outputTexture.format.UsageBits ) ); var inputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat ); inputTexture.SetData( viewPortData ); this.LogInfo( "Creating graph" ); var graph = CreateGraph( ctx, inputTexture, outputTexture ); this.LogInfo( "Process graph" ); graph.ProcessForView(); ctx.SubmitAndSync(); var width = inputTexture.width; var height = inputTexture.height; var format = inputTexture.imageFormat; var data = inputTexture.GetData(); ctx.SubmitAndSync(); await this.RequestNextFrame(); this.LogInfo( "Copying texture" ); var image = Image.CreateFromData( width, height, false, format, data ); var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ) ); target = buffer.CreateImageTexture(); var material3D = (StandardMaterial3D) meshInstance3D.MaterialOverride; material3D.AlbedoTexture = target; ctx.CleanUp(); await this.RequestNextFrame(); } RDGraph CreateGraph( RDContext ctx, RDTexture it, RDTexture ot ) { var graph = new RDGraph( ctx ); var viewTexture = CEG_BufferTexture.From( graph, it ); var bufferTexture = CEG_BufferTexture.From( graph, ot ); var copy = new CEG_Copy( graph ); var blur = new RD_BoxBlur( graph ); graph.InitializeNodes(); copy.SetTextureSlotInputs( viewTexture, bufferTexture ); blur.SetTextureSlotInputs( copy.output, copy.input ); graph.SetProcessOrder( viewTexture, bufferTexture, copy, blur ); blur.constants.Set( intensity, noise, kernelOffset, kernelRadius ); ctx.Verbose( "Radial Blur constants:", blur.constants.size ); return graph; } } }