using System.Collections; using System.Collections.Generic; using Godot; using System; using System.Linq; namespace Rokojori { [Tool] [GlobalClass] public partial class GrabTextureRD:Action { [Export] public SubViewport viewport; [Export] public Texture2D target; [Export] public MeshInstance3D meshInstance3D; [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(); this.LogInfo( "Creating context" ); var ctx = RDContext.Local(); ctx.messageLogLevel = Messages.GetLevel( MessageType.Verbose ); this.LogInfo( "Creating program" ); ctx.SetProgramFromPath( CEG_AlphaColorDilation.shaderPath ); this.LogInfo( "Creating textures" ); var outputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat ); this.LogInfo( "Usage", RDTextureFormats.UsageInfo( outputTexture.format.UsageBits ) ); outputTexture.SetData( new Color( 1, 1, 1, 1 ) ); // var inputTexture = RDTexture.CreateCopyFrom( ctx, viewport ); var inputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat ); inputTexture.SetData( viewPortData ); // inputTexture.SetData( new Color( 0, 1, 0, 1 ) ); this.LogInfo( "Assigning input texture:", ctx.shader, ctx.shader.rid ); ctx.AssignTexture( inputTexture ); this.LogInfo( "Assigning output texture" ); ctx.AssignTexture( outputTexture ); this.LogInfo( "Compute group sizes" ); ctx.CalculateComputeGroups( 8, viewport.Size ); this.LogInfo( "Process compute program" ); ctx.ProcessComputeProgram(); this.LogInfo( "Waiting to render" ); ctx.SubmitAndSync(); var width = outputTexture.width; var height = outputTexture.height; var format = outputTexture.imageFormat; var data = outputTexture.GetData(); data = data.ToList().ToArray(); this.LogInfo( "Copying texture" ); ctx.SubmitAndSync(); await this.RequestNextFrame(); 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(); } } }